+endef
+
+$(foreach package,$(ALL),$(eval $(call target_source_rpm,$(package))))
+
+### binary rpms are made from source rpm
+ALLRPMS:=$(foreach package,$(ALL),$($(package).rpms))
+# same as above, mention $(ALL) and not $(ALLRPMS)
+rpms: $(ALLRPMS)
+ @echo $(words $(ALLRPMS)) binary rpms OK
+.PHONY: rpms
+
+# use tmp dirs when building binary rpm so make remains idempotent
+# otherwise SOURCES/ or SPEC gets touched again - which leads to rebuilding
+RPM-USE-TMP-DIRS = --define "_sourcedir $(HOME)/tmp" --define "_specdir $(HOME)/tmp"
+RPM-USE-COMPILE-DIRS = --define "_sourcedir $(HOME)/COMPILE" --define "_specdir $(HOME)/COMPILE"
+
+# usage: build_binary_rpm package
+# xxx hacky - invoke createrepo if DEPEND-FILES mentions RPMS/yumgroups.xml
+define target_binary_rpm
+$($(1).rpms): $($(1).srpm)
+ mkdir -p RPMS tmp
+ @(echo -n "XXXXXXXXXXXXXXX -- BEG RPM $(1) " ; date)
+ $(if $(findstring RPMS/yumgroups.xml,$($(1)-DEPEND-FILES)), $(createrepo) , )
+ $(call rpmyum_install_stock_rpms,$(1))
+ $(call rpmyum_install_local_rpms,$(1))
+ $($(1).rpmbuild) --rebuild $(RPM-USE-TMP-DIRS) $($(1).srpm)
+ $(call rpmyum_uninstall_stock_rpms,$(1))
+ @(echo -n "XXXXXXXXXXXXXXX -- END RPM $(1) " ; date)
+# for manual use only - in case we need to investigate the results of an rpmbuild
+$(1)-compile: $($(1).srpm)
+ mkdir -p COMPILE tmp
+ @(echo -n "XXXXXXXXXXXXXXX -- BEG compile $(1) " ; date)
+ $(if $(findstring RPMS/yumgroups.xml,$($(1)-DEPEND-FILES)), $(createrepo) , )
+ $(call rpmyum_install_stock_rpms,$(1))
+ $(call rpmyum_install_local_rpms,$(1))
+ $($(1).rpmbuild) --recompile $(RPM-USE-TMP-DIRS) $($(1).srpm)
+ $(call rpmyum_uninstall_stock_rpms,$(1))
+ @(echo -n "XXXXXXXXXXXXXXX -- END compile $(1) " ; date)
+.PHONY: $(1)-compile
+endef
+
+$(foreach package,$(ALL),$(eval $(call target_binary_rpm,$(package))))
+### shorthand target
+# e.g. make proper -> does propers rpms
+# usage shorthand_target package
+define target_shorthand
+$(1): $($(1).rpms)
+.PHONY: $(1)
+$(1)-spec: $($(1)-SPEC)
+.PHONY: $(1)-spec
+$(1)-mk: $($(1)-MK)
+.PHONY: $(1)-mk
+$(1)-tarball: $($(1).tarballs)
+.PHONY: $(1)-tarball
+.PHONY: $(1)-source
+$(1)-source: $($(1).source)
+$(1)-rpms: $($(1).rpms)
+.PHONY: $(1)-rpms
+$(1)-srpm: $($(1).srpm)
+.PHONY: $(1)-srpm
+endef
+
+$(foreach package,$(ALL),$(eval $(call target_shorthand,$(package))))
+
+### file dependencies
+define package_depends_on_file
+$(1):$(2)
+$($(1).srpm):$(2)
+endef
+
+define target_dependfiles
+$(foreach file,$($(1)-DEPEND-FILES),$(eval $(call package_depends_on_file,$(1),$(file))))
+endef
+
+$(foreach package,$(ALL),$(eval $(call target_dependfiles,$(package))))
+
+### package dependencies
+define package_depends_on_package
+$(1):$(2)
+$(1):$($(2).rpms)
+$($(1).srpm):$($(2).rpms)
+endef
+
+define target_depends
+$(foreach package,$($(1)-DEPEND-PACKAGES) $($(1).depend-devel-packages),$(eval $(call package_depends_on_package,$(1),$(package))))
+endef
+
+$(foreach package,$(ALL),$(eval $(call target_depends,$(package))))
+
+####################
+# debian meta-target
+ALL-DEBIAN := $(foreach target,$(ALL),$(target)-debian)
+debian: $(ALL-DEBIAN)
+
+####################
+# very rough for now (one module per package), targets only sfa for now
+# the general idea here is, changing the specfile (for version number and all) is enough, and this
+# gets passed to "make debian" in the module
+# PREFIX: at one point we had passed PREFIX=/usr to this 'make debian'
+# however it turned out we could manage this some other way (see manifold)
+# so I'm reverting to simplicity
+define target_debian
+$(1)-debian: $(1)-tarball
+ $(call dpkgapt_install_local_debs,$(1))
+ $(call dpkgapt_install_stock_debs,$(1))
+ mkdir -p DEBIAN/$(1)
+ rsync -a MODULES/$($(1).module)/ DEBIAN/$(1)/
+ make -C DEBIAN/$(1) "RPMTARBALL=$(HOME)/$($(1).tarballs)" "RPMVERSION=$($(1).rpm-version)" "RPMRELEASE=$($(1).rpm-release)" "RPMNAME=$($(1).rpm-name)" debian
+ $(call dpkgapt_uninstall_stock_debs,$(1))
+endef
+
+$(foreach package,$(ALL),$(eval $(call target_debian,$(package))))
+
+### clean target
+# usage: target_clean package
+define target_clean
+$(1)-clean-modules:
+ $(foreach module,$($(1)-MODULES),rm -rf MODULES/$(module);)
+.PHONY: $(1)-clean-modules
+CLEANS += $(1)-clean-modules
+$(1)-clean-source:
+ rm -rf $($(1).source)
+.PHONY: $(1)-clean-source
+CLEANS += $(1)-clean-source
+$(1)-clean-tarball:
+ rm -rf $($(1).tarballs)
+.PHONY: $(1)-clean-tarball
+CLEANS += $(1)-clean-tarball
+$(1)-clean-build:
+ rm -rf BUILD/$(notdir $($(1).source))
+CLEANS += $(1)-clean-build
+$(1)-clean-rpms:
+ rm -rf $($(1).rpms)
+.PHONY: $(1)-clean-rpms
+CLEANS += $(1)-clean-rpms
+$(1)-clean-srpm:
+ rm -rf $($(1).srpm)
+.PHONY: $(1)-clean-srpm
+CLEANS += $(1)-clean-srpm
+$(1)-clean-debian:
+ rm -rf DEBIAN/$(1)
+.PHONY: $(1)-clean-srpm
+CLEANS += $(1)-clean-srpm
+$(1)-codeclean: $(1)-clean-source $(1)-clean-tarball $(1)-clean-build $(1)-clean-rpms $(1)-clean-srpm $(1)-clean-debian
+$(1)-clean: $(1)-clean-modules $(1)-codeclean
+.PHONY: $(1)-codeclean $(1)-clean
+$(1)-clean-spec:
+ rm -rf $($(1).specpath)
+.PHONY: $(1)-clean-spec
+$(1)-clean-make:
+ rm -rf MAKE/$(1).mk
+.PHONY: $(1)-clean-make
+$(1)-distclean: $(1)-distclean1 $(1)-distclean2
+$(1)-distclean1: $(1)-clean-spec $(1)-clean-make
+$(1)-distclean2: $(1)-clean
+.PHONY: $(1)-distclean $(1)-distclean1 $(1)-distclean2
+endef
+
+$(foreach package,$(ALL),$(eval $(call target_clean,$(package))))
+
+### clean precisely
+clean:
+ $(MAKE) $(CLEANS)
+.PHONY: clean
+
+clean-help:
+ @echo Available clean targets
+ @echo $(CLEANS)
+
+### brute force clean
+distclean1:
+ rm -rf envfrompreviousrun.mk .rpmmacros spec2make header.spec SPECS MAKE $(DISTCLEANS)
+distclean2:
+ rm -rf MODULES SOURCES BUILD BUILDROOT RPMS SRPMS DEBIAN tmp
+distclean: distclean1 distclean2
+.PHONY: distclean1 distclean2 distclean
+
+develclean:
+ -$(RPMYUM-UNINSTALL-STOCK) $(ALL-STOCK-DEVEL-RPMS)
+
+####################
+# gather build information for the 'About' page
+# when run from crontab, INIT_CWD not properly set (says /root ..)
+# so, the nightly build passes BASE here
+# also store BASE in .base for any post-processing purposes
+myplc-release:
+ @echo 'Creating myplc-release'
+ rm -f $@
+ echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx build info" >> $@
+ $(MAKE) --no-print-directory version-build >> $@
+ echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx svn info" >> $@
+ $(MAKE) --no-print-directory version-tags >> $@
+ echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx rpm info" >> $@
+ $(MAKE) --no-print-directory version-rpms >> $@
+ @echo $(BASE) > .base
+
+version-build:
+ @echo -n 'Build build-date: ' ; date '+%Y.%m.%d'
+ @echo -n 'Build build-time: ' ; date '+%H:%M-%Z'
+ @echo -n 'Build build-hostname: ' ; hostname
+ @echo "Build build-base: $(BASE)"
+ @echo "Build planetlab-distro: $(PLDISTRO)"
+ @echo "Build planetlab-tags: $(PLDISTROTAGS)"
+ @echo "Build target-arch: $(HOSTARCH)"
+ @echo "Build target-distro: $(DISTRO)"
+ @echo "Build target-distroname: $(DISTRONAME)"
+ @echo "Build target-release: $(RELEASE)"
+ @echo "Build target-personality: $(PERSONALITY)"
+
+####################
+# for a given module
+VFORMAT="%30s := %s\n"
+define print_tag_target
+$(1)-version-tag:
+ @$(if $($(1)-SVNPATH),\
+ printf $(VFORMAT) $(1)-SVNPATH "$($(1)-SVNPATH)",\
+ printf $(VFORMAT) $(1)-GITPATH "$($(1)-GITPATH)" )
+endef
+
+$(foreach module,$(ALL.modules), $(eval $(call print_tag_target,$(module))))
+
+version-tags: $(foreach module, $(ALL.modules), $(module)-version-tag)
+
+RFORMAT="%20s :: version=%s release=%s\n"
+define rpm_version_target
+$(1)-version-rpm:
+ @printf $(RFORMAT) $($(1).rpm-name) $($(1).rpm-version) $($(1).rpm-release)
+version-rpms: $(1)-version-rpm
+endef
+
+$(foreach package,$(sort $(ALL)), $(eval $(call rpm_version_target,$(package))))
+
+versions: myplc-release version-build version-tags version-rpms
+.PHONY: versions version-build version-rpms version-tags
+
+#################### package info
+PKGKEYS := tarballs source srpm rpms rpmnames rpm-release rpm-name rpm-version rpm-subversion
+%-pkginfo: package=$(subst -pkginfo,,$@)
+%-pkginfo:
+ @$(foreach key,$(PKGKEYS),echo "$(package).$(key)=$($(package).$(key))";)
+## rpm info
+RPMKEYS := rpm-path package
+%-rpminfo: rpm=$(subst -rpminfo,,$@)
+%-rpminfo:
+ @$(foreach key,$(RPMKEYS),echo "$(rpm).$(key)=$($(rpm).$(key))";)
+
+#################### various lists - designed to run with stage1=true
+info-packages:
+ @$(foreach package,$(ALL), echo package=$(package) ref_module=$($(package).module) modules=$($(package)-MODULES) rpmnames=$($(package).rpmnames); )
+
+info-modules:
+ @$(foreach module,$(ALL.modules), echo module=$(module) \
+ $(if $($(module)-SVNPATH),svnpath=$($(module)-SVNPATH),gitpath=$($(module)-GITPATH)) ; )
+
+info-branches:
+ @$(foreach module,$(ALL.modules), \
+ $(if $($(module)-BRANCH),echo module=$(module) branch=$($(module)-BRANCH);))
+
+module-tools:
+ @$(foreach module,$(ALL.modules), \
+ $(if $($(module)-GITPATH), \
+ $(if $($(module)-BRANCH), \
+ echo $(module):$($(module)-BRANCH); , \
+ echo $(module); ), \
+ $(if $($(module)-BRANCH), \
+ echo $(module):$($(module)-BRANCH); , \
+ echo $(module); )))
+
+info: info-packages info-modules info-branches
+
+.PHONY: info info-packages info-modules info-branches module-tools
+
+show-multi-modules:
+ @$(foreach package,$(ALL),$(if $(subst x1,,x$(words $($(package)-MODULES))), echo p=$(package) mods=$($(package)-MODULES) ;))
+.PHONY: show-multi-modules
+####################
+help:
+ @echo "********** Run make in two stages:"
+ @echo ""
+ @echo "make stage1=true PLDISTRO=onelab"
+ @echo " -> extracts all spec files in SPECS/ and mk files in MAKE/"
+ @echo " as well as save PLDISTRO for subsequent runs"
+ @echo ""
+ @echo "********** Then you can use the following targets"
+ @echo 'make'
+ @echo " rebuilds everything"
+ @echo 'make util-vserver'
+ @echo " makes the RPMS related to util-vserver"
+ @echo " equivalent to 'make util-vserver-rpms'"
+ @echo ""
+ @echo "********** Or, vertically - step-by-step for a given package"
+ @echo 'make util-vserver-source'
+ @echo " creates source link in SOURCES/util-vserver-<version>"
+ @echo 'make util-vserver-tarball'
+ @echo " creates source tarball in SOURCES/util-vserver-<version>.<tarextension>"
+ @echo 'make util-vserver-srpm'
+ @echo " build source rpm in SRPMS/"
+ @echo 'make util-vserver-rpms'
+ @echo " build rpm(s) in RPMS/"
+ @echo ""
+ @echo "********** Or, horizontally, reach a step for all known packages"
+ @echo 'make sources'
+ @echo 'make tarballs'
+ @echo 'make srpms'
+ @echo 'make rpms'
+ @echo ""
+ @echo "********** Manual targets"
+ @echo "make package-compile"
+ @echo " The regular process uses rpmbuild --rebuild, that performs"
+ @echo " a compilation directory cleanup upon completion. If you need to investigate"
+ @echo " the intermediate compilation directory, use the -compile targets"
+ @echo "********** Cleaning examples"
+ @echo "make clean"
+ @echo " removes the files made by make"
+ @echo "make distclean"
+ @echo " brute-force cleaning, removes entire directories - requires a new stage1"
+ @echo "make develclean"
+ @echo " rpm-uninstalls all devel packages installed during build"
+ @echo ""
+ @echo "make iptables-distclean"
+ @echo " deep clean for a given package"
+ @echo "make iptables-codeclean"
+ @echo " run this if you've made a local/manual change in the MODULES area for iptables"
+ @echo ""
+ @echo "make util-vserver-clean"
+ @echo " removes codebase, source, tarball, build, rpm and srpm for util-vserver"
+ @echo "make util-vserver-clean-modules"
+ @echo " and so on for source, tarball, build, rpm and srpm"
+ @echo ""
+ @echo "********** Info examples"
+ @echo "make ++ALL"
+ @echo " Displays the value of a given variable (here ALL)"
+ @echo " with only a single plus sign only the value is displayed"
+ @echo "make info"
+ @echo " is equivalent to make packages modules branches"
+ @echo " provides various info on these objects"
+ @echo "make ulogd-pkginfo"
+ @echo " Displays know attributes of a package"
+ @echo "make kernel-devel-rpminfo"
+ @echo " Displays know attributes of an rpm"
+ @echo "make stage1=true PLDISTROTAGS=planetlab-tags-4.2.mk packages modules branches module-tools"
+ @echo " Lists mentioned items - module-tools is used in modules.update"
+ @echo ""
+ @echo "********** Known pakages are"
+ @echo "$(ALL)"
+
+#################### convenience, for debugging only
+# make +foo : prints the value of $(foo)
+# make ++foo : idem but verbose, i.e. foo=$(foo)
+++%: varname=$(subst +,,$@)
+++%:
+ @echo "$(varname)=$($(varname))"
++%: varname=$(subst +,,$@)
++%:
+ @echo "$($(varname))"