X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=Makefile;h=bbdfa8d20d94ac38355498c9569c392c36602782;hb=ea8c64fd415283b3e3cadd438d8b19be96261cad;hp=76c5d261b46689a084728ea97e685fb5ab5a6f75;hpb=82d0ea88d1a4213e553b6d3d276aeef26a81bd1d;p=build.git diff --git a/Makefile b/Makefile index 76c5d261..bbdfa8d2 100644 --- a/Makefile +++ b/Makefile @@ -1,59 +1,488 @@ # -# PlanetLab RPM generation -# -# Mark Huang -# Copyright (C) 2003-2006 The Trustees of Princeton University -# -# $Id: Makefile,v 1.89 2007/09/12 20:26:20 mef Exp $ +# Thierry Parmentelat - INRIA Sophia Antipolis # +### $Id: Makefile 1088 2007-11-15 14:51:33Z thierry $ +# +# run 'make help' for more info +#################### Makefile # Default target all: +.PHONY:all + +### default values +PLDISTRO := onelab +RPMBUILD := rpmbuild +export CVS_RSH := ssh + +########## pldistro.mk holds PLDISTRO - it is generated at stage1 (see below) +ifeq "$(stage1)" "" +include pldistro.mk +endif -# By default, the naming convention for built RPMS is -# --...rpm -# Set PLDISTRO on the command line to differentiate between downstream -# variants. -PLDISTRO := planetlab +#################### include onelab.mk +# describes the set of components +PLDISTROCONTENTS := $(PLDISTRO).mk +include $(PLDISTROCONTENTS) -include $(PLDISTRO).mk +#################### include -tags.mk +# describes where to fetch components, and the related tags if using cvs +PLDISTROTAGS := $(PLDISTRO)-tags.mk +include $(PLDISTROTAGS) -RPMBUILD ?= bash ./rpmbuild.sh -CVS_RSH ?= ssh +########## stage1 and stage2 +# extract specs and compute .mk files by running +# make stage1=true +# entering stage1, we compute all the spec files +# then we use stage2 to compute the .mk iteratively, +# ensuring that the n-1 first makefiles are loaded when creating the n-th one +# when stage2 is set, it is supposed to be an index (starting at 1) in $(ALL) -ifeq ($(findstring $(package),$(ALL)),) +ALLMKS := $(foreach package, $(ALL), MAKE/$(package).mk) -# Build all packages +### stage2 : need some arithmetic, see +# http://www.cmcrossroads.com/articles/ask-mr.-make/learning-gnu-make-functions-with-arithmetic.html +ifneq "$(stage2)" "" +# the first n packages +packages := $(wordlist 1,$(words $(stage2)),$(ALL)) +# the n-th package +package := $(word $(words $(packages)),$(packages)) +# the n-1 first packages +stage2_1 := $(wordlist 2,$(words $(stage2)),$(stage2)) +previous := $(wordlist 1,$(words $(stage2_1)),$(ALL)) +previousmks := $(foreach package,$(previous),MAKE/$(package).mk) +include $(previousmks) +all: verbose +verbose: + @echo "========== stage2 : $(package)" + @echo "stage2 : included .mk files : $(previousmks)" +all: $($(package)_specpath) +all: MAKE/$(package).mk +else +### stage1 +ifneq "$(stage1)" "" +all : verbose +verbose : + @echo "========== stage1" +all : spec2make +all : .rpmmacros +# specs and makes are done sequentially by stage2 +all : stage2 +stage2: + arg=""; for n in $(ALL) ; do arg="$$arg x"; $(MAKE) --no-print-directory stage2="$$arg"; done +### regular make +else +### once .mks are OK, you can run make normally +include $(ALLMKS) +#all : tarballs +#all : sources +#all : codebases +#all : rpms +#all : srpms +# mention $(ALL) here rather than rpms +# this is because the inter-package dependencies are expressed like +# util-vserver: util-python all: $(ALL) +all: srpms +endif +endif + +#################### +# gather build information for the 'About' page +SOURCES/myplc-release: + @echo 'Creating myplc-release' + mkdir -p SOURCES + rm -f $@ + (echo -n 'Build bdate: ' ; date '+%Y.%m.%d') >> $@ + (echo -n 'Build btime: ' ; date '+%H:%M') >> $@ + (echo -n 'Build hostname: ' ; hostname) >> $@ + (echo -n 'Build location: ' ; pwd) >> $@ + (echo -n 'Build tags file: ' ; fgrep '$$''Id' $(PLDISTROTAGS)) >> $@ + echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx modules versions info" >> $@ + $(MAKE) --no-print-directory versions >> $@ + +#################### +# notes: +# * to make configuration easier, we always use the first module's +# definitions (CVSROOT,TAG, or SVNPATH) to extract the spec file +# * for the same reason, in case cvs is used, the first module name is added to +# $(package)-SPEC - otherwise the cvs modules have to define spec as +# /.spec while svn modules just define it as .spec +# +define stage1_variables +$(1)_spec = $(notdir $($(1)-SPEC)) +$(1)_specpath = SPECS/$(notdir $($(1)-SPEC)) +$(1)_module = $(firstword $($(1)-MODULE)) +endef + +$(foreach package, $(ALL), $(eval $(call stage1_variables,$(package)))) + +# +# for each package, compute whether we need to set date (i.e. whether we use the trunk) +# the myplc package is forced to have a date, because it is more convenient +# (we cannot bump its number everytime something changes in the system) +# +define package_hasdate +$(1)_hasdate = $(if $(subst myplc,,$(1)), \ + $(if $($(1)-SVNPATH),\ + $(if $(findstring /trunk,$($(1)-SVNPATH)),yes,),\ + $(if $(findstring HEAD,$($(1)-TAG)),yes,)), \ + yes) +endef + +$(foreach package, $(ALL), $(eval $(call package_hasdate,$(package)))) + +### extract spec file from scm +# usage: extract_spec_file package +# see early releases for comments on other possible implementations +# cannot use variables in such rules, we need to inline everything, sigh +define target_spec +$($(1)_specpath): + mkdir -p SPECS + echo "%define pldistro $(PLDISTRO)" > $($(1)_specpath) + $(if $($(1)_hasdate),echo "%define date $(shell date +%Y.%m.%d)" >> $($(1)_specpath),) + $(if $($(1)-SPECVARS), \ + $(foreach line,$($(1)-SPECVARS), \ + echo "%define" $(word 1,$(subst =, ,$(line))) "$(word 2,$(subst =, ,$(line)))" >> $($(1)_specpath) ;)) + $(if $($($(1)_module)-SVNPATH),\ + svn cat $($($(1)_module)-SVNPATH)/$($(1)-SPEC) >> $($(1)_specpath),\ + cvs -d $($($(1)_module)-CVSROOT) checkout \ + -r $($($(1)_module)-TAG) \ + -p $($(1)_module)/$($(1)-SPEC) >> $($(1)_specpath)) + @if [ -z $($(1)_specpath) ] ; then rm $($(1)_specpath) ; exit 1 ; fi +endef + +$(foreach package,$(ALL),$(eval $(call target_spec,$(package)))) + +### this utility allows to extract various info from a spec file +### and to define them in makefiles +spec2make: spec2make.c + $(CC) -g -Wall $< -o $@ -lrpm -lrpmbuild + +# Base rpmbuild in the current directory +export HOME := $(shell pwd) +.rpmmacros: + echo "%_topdir $(HOME)" > $@ + echo "%_tmppath $(HOME)/tmp" >> $@ + +### run spec2make on the spec file and include the result +# usage: spec2make package +define target_mk +MAKE/$(1).mk: $($(1)_specpath) spec2make .rpmmacros + mkdir -p MAKE + ./spec2make $($(1)-RPMFLAGS) $($(1)_specpath) $(1) > MAKE/$(1).mk + @if [ -z MAKE/$(1).mk ] ; then rm MAKE/$(1).mk ; exit 1 ; fi +endef + +$(foreach package,$(ALL),$(eval $(call target_mk,$(package)))) + +# stores PLDISTRO in a file +# this is done at stage1. later run wont get confused +pldistro.mk: + echo "PLDISTRO:=$(PLDISTRO)" > $@ + echo "PLDISTROTAGS:=$(PLDISTROTAGS)" >> $@ + +savepldistro: pldistro.mk +.PHONY: savepldistro + +# always refresh this +all: savepldistro + +#################### +### pack sources into tarballs +ALLTARBALLS:= $(foreach package, $(ALL), $($(package)-TARBALL)) +tarballs: $(ALLTARBALLS) + @echo $(words $(ALLTARBALLS)) source tarballs OK +.PHONY: tarballs + +SOURCES/%.tar.bz2: SOURCES/% + tar chpjf $@ -C SOURCES $* + +SOURCES/%.tar.gz: SOURCES/% + tar chpzf $@ -C SOURCES $* + +SOURCES/%.tgz: SOURCES/% + tar chpzf $@ -C SOURCES $* + +### the directory SOURCES/- is made +# with a copy -rl from CODEBASES/ +# the former is $(package-SOURCE) and the latter is $(package-CODEBASE) +ALLSOURCES:=$(foreach package, $(ALL), $($(package)-SOURCE)) +# so that make does not use the rule below directly for creating the tarball files +.SECONDARY: $(ALLSOURCES) + +sources: $(ALLSOURCES) + @echo $(words $(ALLSOURCES)) versioned source trees OK +.PHONY: sources -# Recurse -$(ALL): - @echo -n "XXXXXXXXXXXXXXX -- BEG $@ " ; date - $(MAKE) package=$@ - @echo -n "XXXXXXXXXXXXXXX -- END $@ " ; date +define target_link_codebase_sources +$($(1)-SOURCE): $($(1)-CODEBASE) ; mkdir -p SOURCES ; cp -rl $($(1)-CODEBASE) $($(1)-SOURCE) +endef -# Remove files generated by this package -$(foreach package,$(ALL),$(package)-clean): %-clean: - $(MAKE) package=$* clean +$(foreach package,$(ALL),$(eval $(call target_link_codebase_sources,$(package)))) -# Remove all generated files +### codebase extraction +ALLCODEBASES:=$(foreach package, $(ALL), $($(package)-CODEBASE)) +# so that make does not use the rule below directly for creating the tarball files +.SECONDARY: $(ALLCODEBASES) + +codebases : $(ALLCODEBASES) + @echo $(words $(ALLCODEBASES)) codebase OK +.PHONY: codebases + +### extract codebase +# usage: extract_single_module package +define extract_single_module + mkdir -p CODEBASES + $(if $($($(1)_module)-SVNPATH), cd CODEBASES && svn export $($($(1)_module)-SVNPATH) $(1), cd CODEBASES && cvs -d $($($(1)_module)-CVSROOT) export -r $($($(1)_module)-TAG) -d $(1) $($(1)_module)) +endef + +# usage: extract_multi_module package +define extract_multi_module + mkdir -p CODEBASES/$(1) && cd CODEBASES/$(1) && (\ + $(foreach m,$($(1)-MODULE), $(if $($(m)-SVNPATH), svn export $($(m)-SVNPATH) $(m);, cvs -d $($(m)-CVSROOT) export -r $($(m)-TAG) $(m);))) +endef + +CODEBASES/%: package=$(notdir $@) +CODEBASES/%: module=$($(package)-MODULE) +CODEBASES/%: multi_module=$(word 2,$(module)) +CODEBASES/%: + @(echo -n "XXXXXXXXXXXXXXX -- BEG CODEBASE $(package) : $@ " ; date) + $(if $(multi_module),\ + $(call extract_multi_module,$(package)),\ + $(call extract_single_module,$(package))) + @(echo -n "XXXXXXXXXXXXXXX -- END CODEBASE $(package) : $@ " ; date) + +### rpmbuild invokation +ALLRPMS:=$(foreach package,$(ALL),$($(package)-RPM)) +# same as above, mention $(ALL) and not $(ALLRPMS) +rpms: $(ALL) + @echo $(words $(ALLRPMS)) binary rpms OK +.PHONY: rpms + +# usage: build_binary_rpm package +# xxx hacky - invoke createrepo if DEPENDFILES mentions RPMS/yumgroups.xml +define target_binary_rpm +$($(1)-RPM): $($(1)_specpath) $($(1)-TARBALL) .rpmmacros + mkdir -p BUILD RPMS tmp + @(echo -n "XXXXXXXXXXXXXXX -- BEG RPM $(1) " ; date) + $(if $(findstring RPMS/yumgroups.xml,$($(1)-DEPENDFILES)), createrepo --quiet -g yumgroups.xml RPMS/ , ) + $(if $($(1)-RPMBUILD),\ + $($(1)-RPMBUILD) $($(1)-RPMFLAGS) -bb $($(1)_specpath), \ + $(RPMBUILD) $($(1)-RPMFLAGS) -bb $($(1)_specpath)) + @(echo -n "XXXXXXXXXXXXXXX -- END RPM $(1) " ; date) +endef + +$(foreach package,$(ALL),$(eval $(call target_binary_rpm,$(package)))) + +### source rpms +ALLSRPMS:=$(foreach package,$(ALL),$($(package)-SRPM)) +srpms: $(ALLSRPMS) + @echo $(words $(ALLSRPMS)) source rpms OK +.PHONY: srpms + +# usage: build_source_rpm package +define target_source_rpm +$($(1)-SRPM): $($(1)_specpath) $($(1)-TARBALL) .rpmmacros + mkdir -p BUILD SRPMS tmp + @(echo -n "XXXXXXXXXXXXXXX -- BEG SRPM $(1) " ; date) + $(if $($(1)-RPMBUILD),\ + $($(1)-RPMBUILD) $($(1)-RPMFLAGS) -bs $($(1)_specpath), + $(RPMBUILD) $($(1)-RPMFLAGS) -bs $($(1)_specpath)) + @(echo -n "XXXXXXXXXXXXXXX -- END SRPM $(1) " ; date) +endef + +$(foreach package,$(ALL),$(eval $(call target_source_rpm,$(package)))) + +### RPMS/yumgroups.xml +ifndef YUMGROUPS +YUMGROUPS := groups/$(PLDISTRO).xml +endif +RPMS/yumgroups.xml: $(YUMGROUPS) + install -D -m 644 $(YUMGROUPS) $@ + +### shorthand target +# e.g. make proper -> does propers rpms +# usage shorthand_target package +define target_shorthand +$(1): $($(package)-RPM) +.PHONY: $(1) +$(1)-spec: $($(package)-SPEC) +.PHONY: $(1)-spec +$(1)-mk: $($(package)-MK) +.PHONY: $(1)-mk +$(1)-tarball: $($(package)-TARBALL) +.PHONY: $(1)-tarball +$(1)-codebase: $($(package)-CODEBASE) +.PHONY: $(1)-source +$(1)-source: $($(package)-SOURCE) +.PHONY: $(1)-codebase +$(1)-rpm: $($(package)-RPM) +.PHONY: $(1)-rpm +$(1)-srpm: $($(package)-SRPM) +.PHONY: $(1)-srpm +endef + +$(foreach package,$(ALL),$(eval $(call target_shorthand,$(package)))) + +### dependencies +define package_depends_on_file +$(1):$(2) +$($(1)-RPM):$(2) +endef + +define target_dependfiles +$(foreach file,$($(1)-DEPENDFILES),$(eval $(call package_depends_on_file,$(1),$(file)))) +endef + +define package_depends_on_package +$(1):$(2) +$(1):$($(2)-RPM) +$($(1)-RPM):$($(2)-RPM) +endef + +define target_depends +$(foreach package,$($(1)-DEPENDS),$(eval $(call package_depends_on_package,$(1),$(package)))) +endef + +$(foreach package,$(ALL),$(eval $(call target_depends,$(package)))) +$(foreach package,$(ALL),$(eval $(call target_dependfiles,$(package)))) + + +### clean target +# usage: target_clean package +define target_clean +$(1)-clean-codebase: + rm -rf $($(1)-CODEBASE) +.PHONY: $(1)-clean-codebase +CLEANS += $(1)-clean-codebase +$(1)-clean-source: + rm -rf $($(1)-SOURCE) +.PHONY: $(1)-clean-source +CLEANS += $(1)-clean-source +$(1)-clean-tarball: + rm -rf $($(1)-TARBALL) +.PHONY: $(1)-clean-tarball +CLEANS += $(1)-clean-tarball +$(1)-clean-rpm: + rm -rf $($(1)-RPM) +.PHONY: $(1)-clean-rpm +CLEANS += $(1)-clean-rpm +$(1)-clean-srpm: + rm -rf $($(1)-SRPM) +.PHONY: $(1)-clean-srpm +CLEANS += $(1)-clean-srpm +$(1)-clean: $(1)-clean-codebase $(1)-clean-source $(1)-clean-tarball $(1)-clean-rpm $(1)-clean-srpm +.PHONY: $(1)-clean +endef + +$(foreach package,$(ALL),$(eval $(call target_clean,$(package)))) + +### clean precisely clean: - rm -rf BUILD RPMS SOURCES SPECS SRPMS .rpmmacros tmp parseSpec + $(MAKE) $(CLEANS) +.PHONY: clean -.PHONY: all $(ALL) $(foreach package,$(ALL),$(package)-clean) clean +clean-help: + @echo Available clean targets + @echo $(CLEANS) -else +### brute force clean +distclean1: + rm -rf pldistro.mk .rpmmacros spec2make SPECS MAKE +distclean2: + rm -rf CODEBASES SOURCES BUILD RPMS SRPMS tmp +distclean: distclean1 distclean2 +.PHONY: distclean1 distclean2 distclean -# Define variables for Rules.mk -#CVSROOT := $(if $($(package)-CVSROOT),$($(package)-CVSROOT),$(CVSROOT)) -#SVNPATH := $(if $($(package)-SVNPATH),$($(package)-SVNPATH),$(SVNPATH)) -TAG := $(if $($(package)-TAG),$($(package)-TAG),$(TAG)) -MODULE := $($(package)-MODULE) -SPEC := $($(package)-SPEC) -RPMFLAGS := $(if $($(package)-RPMFLAGS),$($(package)-RPMFLAGS),$(RPMFLAGS)) -RPMBUILD := $(if $($(package)-RPMBUILD),$($(package)-RPMBUILD),$(RPMBUILD)) -CVS_RSH := $(if $($(package)-CVS_RSH),$($(package)-CVS_RSH),$(CVS_RSH)) +# xxx tmp - I cannot use this on my mac for local testing +ISMACOS=$(findstring Darwin,$(shell uname)) +ifneq "$(ISMACOS)" "" +#################### produce reliable version information +# for a given module +VFORMAT="%30s := %s\n" +define print_version +$(1)-version: + @$(if $($(1)-SVNPATH),\ + printf $(VFORMAT) $(1)-SVNPATH "$($(1)-SVNPATH)",\ + printf $(VFORMAT) $(1)-CVSROOT "$($(1)-CVSROOT)" ; printf $(VFORMAT) $(1)-TAG "$($(1)-TAG)") +endef -include Rules.mk +# compute all modules +ALL-MODULES := +$(foreach package,$(ALL), $(eval ALL-MODULES+=$($(package)-MODULE))) +ALL-MODULES:=$(sort $(ALL-MODULES)) +$(foreach module,$(ALL-MODULES), $(eval $(call print_version,$(module)))) + +versions: $(foreach module, $(ALL-MODULES), $(module)-version) +else +versions: + @echo "warning : the 'versions' target is not supported on macos" +endif + +#################### include install Makefile +# the default is to use the distro-dependent install file +# however the main distro file can redefine PLDISTROINSTALL +ifndef PLDISTROINSTALL +PLDISTROINSTALL := $(PLDISTRO)-install.mk endif +# only if present +-include $(PLDISTROINSTALL) + +#################### +help: + @echo "Known pakages are" + @echo " $(ALL)" + @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-rpm'" + @echo "" + @echo "Or, vertically - step-by-step for a given package" + @echo '$ make util-vserver-codebase' + @echo " performs codebase extraction in CODEBASES/util-vserver" + @echo '$ make util-vserver-source' + @echo " creates source link in SOURCES/util-vserver-" + @echo '$ make util-vserver-tarball' + @echo " creates source tarball in SOURCES/util-vserver-." + @echo '$ make util-vserver-rpm' + @echo " build rpm(s) in RPMS/" + @echo '$ make util-vserver-srpm' + @echo " build source rpm in SRPMS/" + @echo "" + @echo "Or, horizontally, reach a step for all known packages" + @echo '$ make codebases' + @echo '$ make sources' + @echo '$ make tarballs' + @echo '$ make rpms' + @echo '$ make srpms' + @echo "" + @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 util-vserver-clean" + @echo " removes codebase, source, tarball, rpm and srpm for util-vserver" + @echo "$ make util-vserver-clean-codebase" + @echo " and so on" + + +#################### 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))"