summaryrefslogtreecommitdiff
path: root/rules/_generic/Makefile
diff options
context:
space:
mode:
Diffstat (limited to 'rules/_generic/Makefile')
-rw-r--r--rules/_generic/Makefile145
1 files changed, 145 insertions, 0 deletions
diff --git a/rules/_generic/Makefile b/rules/_generic/Makefile
new file mode 100644
index 0000000..fa5e845
--- /dev/null
+++ b/rules/_generic/Makefile
@@ -0,0 +1,145 @@
+#!/usr/bin/make -f
+
+# Install paths
+DESTDIR ?=
+MAVEN_LOCAL_REPO ?= ~/.m2
+
+# Utilities
+CP = cp
+ECHO = echo
+EXISTS = test -e
+FAIL = exit 1
+FIND = find
+INSTALL = install
+JAR = jar
+JAVA = java
+JAVAC = javac
+MKDIRS = mkdir -p
+PRINTF = printf
+RM = rm -f
+SED = sed
+TOUCH = touch
+XMLSTARLET = xml
+
+JAVAC_FLAGS += $(if $(javac_source),-source $(javac_source))
+JAVAC_FLAGS += $(if $(javac_target),-target $(javac_target))
+JAVAC_FLAGS += $(if $(javac_encoding),-encoding $(javac_encoding))
+
+# Detect information from POMs
+pom_get = $(shell $(XMLSTARLET) sel -T -t $(foreach xpath,$1, -v '$(subst /,/_:,$(xpath))' -n) pom.xml)
+plugin_conf = /project/build/plugins/plugin[./artifactId[text()="$1"]]/configuration/$2
+
+artifactId := $(call pom_get,/project/artifactId)
+version := $(firstword $(call pom_get,/project/version /project/parent/version) $(value version))
+groupId := $(firstword $(call pom_get,/project/groupId /project/parent/groupId))
+
+sourceDirectory := $(firstword $(call pom_get,/project/build/sourceDirectory) $(value sourceDirectory) src/main/java )
+resources := $(firstword $(call pom_get,/project/build/resources ) $(value resources) src/main/resources)
+
+# The order of precidence with these isn't quite right, but it's rare that multiple are set.
+javac_source := $(firstword $(call pom_get,/project/properties/maven.compile.source /project/properties/maven.compiler.source $(call plugin_conf,maven-compiler-plugin,source) ) $(value javac_source))
+javac_target := $(firstword $(call pom_get,/project/properties/maven.compile.target /project/properties/maven.compiler.target $(call plugin_conf,maven-compiler-plugin,target) ) $(value javac_target))
+javac_encoding := $(firstword $(call pom_get,/project/properties/project.build.sourceEncoding $(call plugin_conf,maven-compiler-plugin,encoding)) $(value javac_encoding))
+
+basedir = .
+project.basedir = $(basedir)
+subdirs = $(patsubst %/pom.xml,%,$(wildcard */pom.xml))
+targets = pom $(if $(wildcard src/main/ $(sourceDirectory) $(resources)),jar)
+
+# Post-processing
+
+inherit_vars = version sourceDirectory resources javac_source javac_target javac_encoding
+$(foreach var,$(inherit_vars),$(eval $(var) = $($(var))))
+
+$(if $(extra_makefiles),$(eval include $(extra_makefiles)))
+
+subdirs := $(subdirs)
+targets := $(targets)
+
+################################################################################
+
+dep_dir = $1 $(shell $(FIND) $1 2>/dev/null)
+dep_optdir = $(shell $(FIND) $1 2>/dev/null)
+
+all: PHONY \
+ $(addprefix target/$(artifactId)-$(version).,$(targets)) \
+ $(addsuffix /all,$(subdirs))
+
+# generate-sources #############################################################
+
+target/generated-sources:
+ $(if $^,for dep in $^; do $(EXISTS) $$dep || { $(RM) -r $@; $(FAIL); }; done,$(MKDIRS) $@)
+ $(TOUCH) $@
+
+# generate-resources ###########################################################
+
+target/generated-resources: \
+ target/generated-resources/META-INF/maven/$(groupId)/$(artifactId)/pom.properties \
+ target/generated-resources/META-INF/maven/$(groupId)/$(artifactId)/pom.xml
+ for dep in $^; do $(EXISTS) $$dep || { $(RM) -r $@; $(FAIL); }; done
+ $(TOUCH) $@
+
+target/generated-resources/META-INF/maven/$(groupId)/$(artifactId)/pom.xml: pom.xml
+ $(INSTALL) -Dm644 $< $@
+
+# This is almost the default date format for locale=C, but the DOM is
+# 0-padded instead of space-padded.
+target/generated-resources/META-INF/maven/$(groupId)/$(artifactId)/pom.properties: pom.xml
+ $(MKDIRS) $(@D)
+ $(PRINTF) '#Generated by %s\n#%s\n\nversion=%s\ngroupId=%s\nartifactId=%s\n' \
+ Make "$$(LC_ALL=C date '+%a %b %d %H:%M:%S %Z %Y')" '$(version)' '$(groupId)' '$(artifactId)' \
+ > $@
+
+# compile ######################################################################
+
+# Maven puts `target/classes` in the classpath, but that's unnecessary
+# here, as we don't do incremental/segmented compilation.
+target/classes: \
+ $(call dep_optdir,$(sourceDirectory) $(resources)) \
+ $(call dep_dir,target/generated-sources target/generated-resources)
+ $(RM) -r $@
+ $(MKDIRS) $@
+ $(FIND) $(wildcard $(resources) target/generated-resources) -mindepth 1 -maxdepth 1 -exec $(CP) -r {} $@ \; || { $(RM) -r $@; $(FAIL); } # process-resources
+ $(FIND) $(wildcard $(sourceDirectory) target/generated-sources) -name '*.java' -exec $(JAVAC) $(JAVAC_FLAGS) -d $@ {} + || { $(RM) -r $@; $(FAIL); } # compile
+ $(TOUCH) $@
+
+# package ######################################################################
+
+target/$(artifactId)-$(version).pom: pom.xml
+ $(INSTALL) -Dm644 $< $@
+
+target/$(artifactId)-$(version).jar: target/classes
+ $(JAR) -cf $@ -C $< .
+
+# install ######################################################################
+
+mvndir = $(subst .,/,$(groupId))/$(artifactId)/$(version)
+
+install: PHONY \
+ $(addprefix $(DESTDIR)$(MAVEN_LOCAL_REPO)/$(mvndir)/$(artifactId)-$(version).,$(targets)) \
+ $(addsuffix /install,$(subdirs))
+
+$(DESTDIR)$(MAVEN_LOCAL_REPO)/$(mvndir)/%: target/%
+ $(INSTALL) -Dm644 $< $@
+
+# clean ########################################################################
+
+clean: PHONY $(addsuffix /clean,$(subdirs))
+ rm -rf target
+
+# recurse ######################################################################
+
+deps2jars = $(wildcard $(patsubst %/all,%/target/*.jar,$(filter $(addsuffix /all,$(subdirs)),$1)))
+deps2classpath = $(shell $(ECHO) $(abspath $(call deps2jars,$1)) $(CLASSPATH) | $(SED) 'y/ /:/')
+
+define recurse-rule
+$1/%: PHONY $(addsuffix /all,$($1_deps))
+ CLASSPATH='$$(call deps2classpath,$$^)' $(foreach var,$(inherit_vars),$(subst .,_,$(var))='$$(value $(var))') $$(MAKE) -C '$1' -f '$$(abspath $$(firstword $$(MAKEFILE_LIST)))' '$$*'
+endef
+$(foreach subdir,$(subdirs),$(eval $(call recurse-rule,$(subdir))))
+
+# boilerplate ##################################################################
+
+.PHONY: PHONY FORCE
+.DELETE_ON_ERROR:
+.SECONDARY: