2 # Thierry Parmentelat - INRIA Sophia Antipolis
6 # run 'make help' for more info
8 #################### Makefile
18 ########## pldistro.mk holds PLDISTRO - it is generated at stage1 (see below)
23 #################### include onelab.mk
24 # describes the set of components
25 PLDISTROCONTENTS := $(PLDISTRO).mk
26 include $(PLDISTROCONTENTS)
28 #################### include <pldistro>-tags.mk
29 # describes where to fetch components, and the related tags if using cvs
30 PLDISTROTAGS := $(PLDISTRO)-tags.mk
31 include $(PLDISTROTAGS)
33 ########## stage1 and stage2
34 # extract specs and compute .mk files by running
36 # entering stage1, we compute all the spec files
37 # then we use stage2 to compute the .mk iteratively,
38 # ensuring that the n-1 first makefiles are loaded when creating the n-th one
39 # when stage2 is set, it is supposed to be an index (starting at 1) in $(ALL)
41 ALLMKS := $(foreach package, $(ALL), MAKE/$(package).mk)
43 ### stage2 : need some arithmetic, see
44 # http://www.cmcrossroads.com/articles/ask-mr.-make/learning-gnu-make-functions-with-arithmetic.html
46 # the first n packages
47 packages := $(wordlist 1,$(words $(stage2)),$(ALL))
49 package := $(word $(words $(packages)),$(packages))
50 # the n-1 first packages
51 stage2_1 := $(wordlist 2,$(words $(stage2)),$(stage2))
52 previous := $(wordlist 1,$(words $(stage2_1)),$(ALL))
53 previousmks := $(foreach package,$(previous),MAKE/$(package).mk)
54 include $(previousmks)
57 @echo "========== stage2 : $(package)"
58 @echo "stage2 : included .mk files : $(previousmks)"
59 all: $($(package)_specpath)
60 all: MAKE/$(package).mk
66 @echo "========== stage1"
69 # specs and makes are done sequentially by stage2
72 arg=""; for n in $(ALL) ; do arg="$$arg x"; $(MAKE) --no-print-directory stage2="$$arg"; done
75 ### once .mks are OK, you can run make normally
82 # mention $(ALL) here rather than rpms
83 # this is because the inter-package dependencies are expressed like
84 # util-vserver: util-python
91 # gather build information for the 'About' page
92 SOURCES/myplc-release:
93 @echo 'Creating myplc-release'
96 (echo -n 'Build bdate: ' ; date '+%Y.%m.%d') >> $@
97 (echo -n 'Build btime: ' ; date '+%H:%M') >> $@
98 (echo -n 'Build hostname: ' ; hostname) >> $@
99 (echo -n 'Build location: ' ; pwd) >> $@
100 (echo -n 'Build tags file: ' ; fgrep '$$''Id' $(PLDISTROTAGS)) >> $@
101 echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx modules versions info" >> $@
102 $(MAKE) --no-print-directory versions >> $@
106 # * to make configuration easier, we always use the first module's
107 # definitions (CVSROOT,TAG, or SVNPATH) to extract the spec file
108 # * for the same reason, in case cvs is used, the first module name is added to
109 # $(package)-SPEC - otherwise the cvs modules have to define spec as
110 # <module>/<module>.spec while svn modules just define it as <module>.spec
112 define stage1_variables
113 $(1)_spec = $(notdir $($(1)-SPEC))
114 $(1)_specpath = SPECS/$(notdir $($(1)-SPEC))
115 $(1)_module = $(firstword $($(1)-MODULE))
118 $(foreach package, $(ALL), $(eval $(call stage1_variables,$(package))))
121 # for each package, compute whether we need to set date (i.e. whether we use the trunk)
122 # the myplc package is forced to have a date, because it is more convenient
123 # (we cannot bump its number everytime something changes in the system)
125 define package_hasdate
126 $(1)_hasdate = $(if $(subst myplc,,$(1)), \
127 $(if $($(1)-SVNPATH),\
128 $(if $(findstring /trunk,$($(1)-SVNPATH)),yes,),\
129 $(if $(findstring HEAD,$($(1)-TAG)),yes,)), \
133 $(foreach package, $(ALL), $(eval $(call package_hasdate,$(package))))
135 ### extract spec file from scm
136 # usage: extract_spec_file package
137 # see early releases for comments on other possible implementations
138 # cannot use variables in such rules, we need to inline everything, sigh
142 echo "%define pldistro $(PLDISTRO)" > $($(1)_specpath)
143 $(if $($(1)_hasdate),echo "%define date $(shell date +%Y.%m.%d)" >> $($(1)_specpath),)
144 $(if $($(1)-SPECVARS), \
145 $(foreach line,$($(1)-SPECVARS), \
146 echo "%define" $(word 1,$(subst =, ,$(line))) "$(word 2,$(subst =, ,$(line)))" >> $($(1)_specpath) ;))
147 $(if $($($(1)_module)-SVNPATH),\
148 svn cat $($($(1)_module)-SVNPATH)/$($(1)-SPEC) >> $($(1)_specpath),\
149 cvs -d $($($(1)_module)-CVSROOT) checkout \
150 -r $($($(1)_module)-TAG) \
151 -p $($(1)_module)/$($(1)-SPEC) >> $($(1)_specpath))
152 @if [ -z $($(1)_specpath) ] ; then rm $($(1)_specpath) ; exit 1 ; fi
155 $(foreach package,$(ALL),$(eval $(call target_spec,$(package))))
157 ### this utility allows to extract various info from a spec file
158 ### and to define them in makefiles
159 spec2make: spec2make.c
160 $(CC) -g -Wall $< -o $@ -lrpm -lrpmbuild
162 # Base rpmbuild in the current directory
163 export HOME := $(shell pwd)
165 echo "%_topdir $(HOME)" > $@
166 echo "%_tmppath $(HOME)/tmp" >> $@
168 ### run spec2make on the spec file and include the result
169 # usage: spec2make package
171 MAKE/$(1).mk: $($(1)_specpath) spec2make .rpmmacros
173 ./spec2make $($(1)-RPMFLAGS) $($(1)_specpath) $(1) > MAKE/$(1).mk
174 @if [ -z MAKE/$(1).mk ] ; then rm MAKE/$(1).mk ; exit 1 ; fi
177 $(foreach package,$(ALL),$(eval $(call target_mk,$(package))))
179 # stores PLDISTRO in a file
180 # this is done at stage1. later run wont get confused
182 echo "PLDISTRO:=$(PLDISTRO)" > $@
183 echo "PLDISTROTAGS:=$(PLDISTROTAGS)" >> $@
185 savepldistro: pldistro.mk
188 # always refresh this
192 ### pack sources into tarballs
193 ALLTARBALLS:= $(foreach package, $(ALL), $($(package)-TARBALL))
194 tarballs: $(ALLTARBALLS)
195 @echo $(words $(ALLTARBALLS)) source tarballs OK
198 SOURCES/%.tar.bz2: SOURCES/%
199 tar chpjf $@ -C SOURCES $*
201 SOURCES/%.tar.gz: SOURCES/%
202 tar chpzf $@ -C SOURCES $*
204 SOURCES/%.tgz: SOURCES/%
205 tar chpzf $@ -C SOURCES $*
207 ### the directory SOURCES/<package>-<version> is made
208 # with a copy -rl from CODEBASES/<package>
209 # the former is $(package-SOURCE) and the latter is $(package-CODEBASE)
210 ALLSOURCES:=$(foreach package, $(ALL), $($(package)-SOURCE))
211 # so that make does not use the rule below directly for creating the tarball files
212 .SECONDARY: $(ALLSOURCES)
214 sources: $(ALLSOURCES)
215 @echo $(words $(ALLSOURCES)) versioned source trees OK
218 define target_link_codebase_sources
219 $($(1)-SOURCE): $($(1)-CODEBASE) ; mkdir -p SOURCES ; cp -rl $($(1)-CODEBASE) $($(1)-SOURCE)
222 $(foreach package,$(ALL),$(eval $(call target_link_codebase_sources,$(package))))
224 ### codebase extraction
225 ALLCODEBASES:=$(foreach package, $(ALL), $($(package)-CODEBASE))
226 # so that make does not use the rule below directly for creating the tarball files
227 .SECONDARY: $(ALLCODEBASES)
229 codebases : $(ALLCODEBASES)
230 @echo $(words $(ALLCODEBASES)) codebase OK
234 # usage: extract_single_module package
235 define extract_single_module
237 $(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))
240 # usage: extract_multi_module package
241 define extract_multi_module
242 mkdir -p CODEBASES/$(1) && cd CODEBASES/$(1) && (\
243 $(foreach m,$($(1)-MODULE), $(if $($(m)-SVNPATH), svn export $($(m)-SVNPATH) $(m);, cvs -d $($(m)-CVSROOT) export -r $($(m)-TAG) $(m);)))
246 CODEBASES/%: package=$(notdir $@)
247 CODEBASES/%: module=$($(package)-MODULE)
248 CODEBASES/%: multi_module=$(word 2,$(module))
250 @(echo -n "XXXXXXXXXXXXXXX -- BEG CODEBASE $(package) : $@ " ; date)
251 $(if $(multi_module),\
252 $(call extract_multi_module,$(package)),\
253 $(call extract_single_module,$(package)))
254 @(echo -n "XXXXXXXXXXXXXXX -- END CODEBASE $(package) : $@ " ; date)
256 ### rpmbuild invokation
257 ALLRPMS:=$(foreach package,$(ALL),$($(package)-RPM))
258 # same as above, mention $(ALL) and not $(ALLRPMS)
260 @echo $(words $(ALLRPMS)) binary rpms OK
263 # usage: build_binary_rpm package
264 # xxx hacky - invoke createrepo if DEPENDFILES mentions RPMS/yumgroups.xml
265 define target_binary_rpm
266 $($(1)-RPM): $($(1)_specpath) $($(1)-TARBALL) .rpmmacros
267 mkdir -p BUILD RPMS tmp
268 @(echo -n "XXXXXXXXXXXXXXX -- BEG RPM $(1) " ; date)
269 $(if $(findstring RPMS/yumgroups.xml,$($(1)-DEPENDFILES)), createrepo --quiet -g yumgroups.xml RPMS/ , )
270 $(if $($(1)-RPMBUILD),\
271 $($(1)-RPMBUILD) $($(1)-RPMFLAGS) -bb $($(1)_specpath), \
272 $(RPMBUILD) $($(1)-RPMFLAGS) -bb $($(1)_specpath))
273 @(echo -n "XXXXXXXXXXXXXXX -- END RPM $(1) " ; date)
276 $(foreach package,$(ALL),$(eval $(call target_binary_rpm,$(package))))
279 ALLSRPMS:=$(foreach package,$(ALL),$($(package)-SRPM))
281 @echo $(words $(ALLSRPMS)) source rpms OK
284 # usage: build_source_rpm package
285 define target_source_rpm
286 $($(1)-SRPM): $($(1)_specpath) $($(1)-TARBALL) .rpmmacros
287 mkdir -p BUILD SRPMS tmp
288 @(echo -n "XXXXXXXXXXXXXXX -- BEG SRPM $(1) " ; date)
289 $(if $($(1)-RPMBUILD),\
290 $($(1)-RPMBUILD) $($(1)-RPMFLAGS) -bs $($(1)_specpath),
291 $(RPMBUILD) $($(1)-RPMFLAGS) -bs $($(1)_specpath))
292 @(echo -n "XXXXXXXXXXXXXXX -- END SRPM $(1) " ; date)
295 $(foreach package,$(ALL),$(eval $(call target_source_rpm,$(package))))
297 ### RPMS/yumgroups.xml
299 YUMGROUPS := groups/$(PLDISTRO).xml
301 RPMS/yumgroups.xml: $(YUMGROUPS)
302 install -D -m 644 $(YUMGROUPS) $@
305 # e.g. make proper -> does propers rpms
306 # usage shorthand_target package
307 define target_shorthand
308 $(1): $($(package)-RPM)
310 $(1)-spec: $($(package)-SPEC)
312 $(1)-mk: $($(package)-MK)
314 $(1)-tarball: $($(package)-TARBALL)
316 $(1)-codebase: $($(package)-CODEBASE)
318 $(1)-source: $($(package)-SOURCE)
319 .PHONY: $(1)-codebase
320 $(1)-rpm: $($(package)-RPM)
322 $(1)-srpm: $($(package)-SRPM)
326 $(foreach package,$(ALL),$(eval $(call target_shorthand,$(package))))
329 define package_depends_on_file
334 define target_dependfiles
335 $(foreach file,$($(1)-DEPENDFILES),$(eval $(call package_depends_on_file,$(1),$(file))))
338 define package_depends_on_package
341 $($(1)-RPM):$($(2)-RPM)
344 define target_depends
345 $(foreach package,$($(1)-DEPENDS),$(eval $(call package_depends_on_package,$(1),$(package))))
348 $(foreach package,$(ALL),$(eval $(call target_depends,$(package))))
349 $(foreach package,$(ALL),$(eval $(call target_dependfiles,$(package))))
353 # usage: target_clean package
356 rm -rf $($(1)-CODEBASE)
357 .PHONY: $(1)-clean-codebase
358 CLEANS += $(1)-clean-codebase
360 rm -rf $($(1)-SOURCE)
361 .PHONY: $(1)-clean-source
362 CLEANS += $(1)-clean-source
364 rm -rf $($(1)-TARBALL)
365 .PHONY: $(1)-clean-tarball
366 CLEANS += $(1)-clean-tarball
369 .PHONY: $(1)-clean-rpm
370 CLEANS += $(1)-clean-rpm
373 .PHONY: $(1)-clean-srpm
374 CLEANS += $(1)-clean-srpm
375 $(1)-clean: $(1)-clean-codebase $(1)-clean-source $(1)-clean-tarball $(1)-clean-rpm $(1)-clean-srpm
379 $(foreach package,$(ALL),$(eval $(call target_clean,$(package))))
387 @echo Available clean targets
390 ### brute force clean
392 rm -rf pldistro.mk .rpmmacros spec2make SPECS MAKE
394 rm -rf CODEBASES SOURCES BUILD RPMS SRPMS tmp
395 distclean: distclean1 distclean2
396 .PHONY: distclean1 distclean2 distclean
398 # xxx tmp - I cannot use this on my mac for local testing
399 ISMACOS=$(findstring Darwin,$(shell uname))
400 ifneq "$(ISMACOS)" ""
401 #################### produce reliable version information
403 VFORMAT="%30s := %s\n"
406 @$(if $($(1)-SVNPATH),\
407 printf $(VFORMAT) $(1)-SVNPATH "$($(1)-SVNPATH)",\
408 printf $(VFORMAT) $(1)-CVSROOT "$($(1)-CVSROOT)" ; printf $(VFORMAT) $(1)-TAG "$($(1)-TAG)")
411 # compute all modules
413 $(foreach package,$(ALL), $(eval ALL-MODULES+=$($(package)-MODULE)))
414 ALL-MODULES:=$(sort $(ALL-MODULES))
416 $(foreach module,$(ALL-MODULES), $(eval $(call print_version,$(module))))
418 versions: $(foreach module, $(ALL-MODULES), $(module)-version)
421 @echo "warning : the 'versions' target is not supported on macos"
424 #################### include install Makefile
425 # the default is to use the distro-dependent install file
426 # however the main distro file can redefine PLDISTROINSTALL
427 ifndef PLDISTROINSTALL
428 PLDISTROINSTALL := $(PLDISTRO)-install.mk
431 -include $(PLDISTROINSTALL)
435 @echo "Known pakages are"
437 @echo "Run make in two stages:"
439 @echo "make stage1=true PLDISTRO=onelab"
440 @echo " -> extracts all spec files in SPECS/ and mk files in MAKE/"
441 @echo " as well as save PLDISTRO for subsequent runs"
443 @echo "Then you can use the following targets"
445 @echo " rebuilds everything"
446 @echo '$ make util-vserver'
447 @echo " makes the RPMS related to util-vserver"
448 @echo " equivalent to 'make util-vserver-rpm'"
450 @echo "Or, vertically - step-by-step for a given package"
451 @echo '$ make util-vserver-codebase'
452 @echo " performs codebase extraction in CODEBASES/util-vserver"
453 @echo '$ make util-vserver-source'
454 @echo " creates source link in SOURCES/util-vserver-<version>"
455 @echo '$ make util-vserver-tarball'
456 @echo " creates source tarball in SOURCES/util-vserver-<version>.<tarextension>"
457 @echo '$ make util-vserver-rpm'
458 @echo " build rpm(s) in RPMS/"
459 @echo '$ make util-vserver-srpm'
460 @echo " build source rpm in SRPMS/"
462 @echo "Or, horizontally, reach a step for all known packages"
463 @echo '$ make codebases'
464 @echo '$ make sources'
465 @echo '$ make tarballs'
469 @echo "Cleaning examples"
471 @echo " removes the files made by make"
472 @echo "$ make distclean"
473 @echo " brute-force cleaning, removes entire directories - requires a new stage1"
474 @echo "$ make util-vserver-clean"
475 @echo " removes codebase, source, tarball, rpm and srpm for util-vserver"
476 @echo "$ make util-vserver-clean-codebase"
480 #################### convenience, for debugging only
481 # make +foo : prints the value of $(foo)
482 # make ++foo : idem but verbose, i.e. foo=$(foo)
483 ++%: varname=$(subst +,,$@)
485 @echo "$(varname)=$($(varname))"
486 +%: varname=$(subst +,,$@)
488 @echo "$($(varname))"