+.PHONY: repo
+
+####################
+# 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
+# <module>/<module>.spec while svn modules just define it as <module>.spec
+#
+define stage1_variables
+$(1).spec = $(notdir $($(1)-SPEC))
+$(1).specpath = SPECS/$(1).spec
+$(1).module = $(firstword $($(1)-MODULES))
+$(1)-SVNPATH = $(strip $($(1)-SVNPATH))
+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)
+# myplc-native does not need this trick
+#
+define package_hasdate
+$(1).has-date = $(if $(subst myplc,,$(1)), \
+ $(if $($($(1).module)-SVNPATH),\
+ $(if $(findstring /trunk,$($($(1).module)-SVNPATH)),yes,),\
+ $(if $(findstring HEAD,$($($(1).module)-TAG)),yes,)), \
+ yes)
+endef
+
+$(foreach package, $(ALL), $(eval $(call package_hasdate,$(package))))
+
+### the common header for generated specfiles
+# useful when trying new specfiles manually
+header.spec:
+ (echo -n "# Generated by planetlab build from $($(1)-SPEC) on " ; date) > $@
+ echo "%define distro $(DISTRO)" >> $@
+ echo "%define distrorelease $(RELEASE)" >> $@
+ echo "%define distroname $(DISTRONAME)" >> $@
+ echo "%define pldistro $(PLDISTRO)" >> $@
+ echo "%define plrelease $(PLANETLAB_RELEASE)" >> $@
+
+### extract spec file from scm
+define target_spec
+$($(1).specpath): header.spec
+ mkdir -p SPECS
+ cat header.spec > $($(1).specpath)
+ $(if $($(1).has-date),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) ;))
+ echo "# included from $($(1)-SPEC)" >> $($(1).specpath)
+ $(if $($($(1).module)-SVNPATH),\
+ svn cat $($($(1).module)-SVNPATH)/$($(1)-SPEC) >> $($(1).specpath) || rm $($(1).specpath),\
+ cvs -d $($($(1).module)-CVSROOT) checkout \
+ -r $($($(1).module)-TAG) \
+ -p $($(1).module)/$($(1)-SPEC) >> $($(1).specpath))
+endef
+
+$(foreach package,$(ALL),$(eval $(call target_spec,$(package))))
+
+###
+# Base rpmbuild in the current directory
+# issues on fedora 8 : see the following posts
+# http://forums.fedoraforum.org/showthread.php?t=39625 - and more specifically post#6
+# https://www.redhat.com/archives/fedora-devel-list/2007-November/msg00171.html
+REALROOT=/build
+FAKEROOT=/longbuildroot
+PWD=$(shell /bin/pwd)
+ifeq "$(PWD)" "$(REALROOT)"
+export HOME := $(FAKEROOT)
+else
+export HOME := $(PWD)
+endif
+.rpmmacros:
+ifeq "$(shell pwd)" "/build"
+ rm -f $(FAKEROOT) ; ln -s $(REALROOT) $(FAKEROOT)
+endif
+ rm -f $@
+ echo "%_topdir $(HOME)" >> $@
+ echo "%_tmppath $(HOME)/tmp" >> $@
+ ./getrpmmacros.sh >> $@
+
+### 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
+
+### 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
+
+#################### regular make
+
+define stage2_variables
+### devel dependencies
+$(1).rpmbuild = $(if $($(1)-RPMBUILD),$($(1)-RPMBUILD),$(RPMBUILD)) $($(1)-RPMFLAGS)
+$(1).all-devel-rpm-paths := $(foreach rpm,$($(1)-DEPEND-DEVEL-RPMS),$($(rpm).rpm-path))
+$(1).depend-devel-packages := $(sort $(foreach rpm,$($(1)-DEPEND-DEVEL-RPMS),$($(rpm).package)))
+ALL-DEVEL-RPMS += $($(1)-DEPEND-DEVEL-RPMS)
+endef
+
+$(foreach package,$(ALL),$(eval $(call stage2_variables,$(package))))
+ALL-DEVEL-RPMS := $(sort $(ALL-DEVEL-RPMS))
+
+
+### pack sources into tarballs
+ALLTARBALLS:= $(foreach package, $(ALL), $($(package).tarballs))
+tarballs: $(ALLTARBALLS)
+ @echo $(words $(ALLTARBALLS)) source tarballs OK
+.PHONY: tarballs
+
+SOURCES/%.tar.bz2: SOURCES/%
+ tar chpjf $@ -C SOURCES $*