---+++ Planetlab 3.1 RC2
[build.git] / Makerules
1 #
2 # PlanetLab RPM generation
3 #
4 # Mark Huang <mlhuang@cs.princeton.edu>
5 # Copyright (C) 2003-2005 The Trustees of Princeton University
6 #
7 # $Id: Makerules,v 1.14 2005/05/04 19:13:14 mlhuang Exp $
8 #
9
10 # Base cvsps and rpmbuild in the current directory
11 export HOME := $(shell pwd)
12 export CVSROOT CVS_RSH
13
14 #
15 # Parse spec file template
16 #
17
18 MK := SPECS/$(patsubst %.spec,%.mk,$(notdir $(SPEC)))
19
20 $(MK): SPECS/$(notdir $(SPEC)).in
21         # Substitute '$' for '%' and 'name := value' for '%define name value' or 'name: value'
22         sed -n \
23         -e 's/%{/$${/g' \
24         -e 's/%\([[:alnum:]]\+\)/$${\1}/g' \
25         -e 's/^$${define}[       ]*\([^  ]*\)[   ]*\([^  ]*\)/\1 := \2/p' \
26         -e 's/^\([^      ]*\):[  ]*\([^  ]*\)/\1 := \2/p' \
27         $< > $@
28 ifneq ($(INITIAL),$(TAG))
29         # Get list of PatchSets
30         cvsps --cvs-direct --root $(CVSROOT) -r $(INITIAL) $(if $(TAG:HEAD=),-r $(TAG)) $(MODULE) | \
31         sed -ne 's|^PatchSet[    ]*\([0-9]*\)|PATCHES += \1|p' >> $@
32 ifeq ($(shell echo $(MAKE_VERSION) | awk '{ print ($$1 < 3.80) }'),1)
33         # make-3.80 can use $(eval) instead (see below)
34         cvsps --cvs-direct --root $(CVSROOT) -r $(INITIAL) $(if $(TAG:HEAD=),-r $(TAG)) $(MODULE) | \
35         sh Patchrules >> $@
36 endif
37 endif
38
39 SPECS/$(notdir $(SPEC)).in:
40         mkdir -p SPECS
41         cvs -d $(CVSROOT) checkout -r $(TAG) -p $(SPEC) > $@
42
43 include $(MK)
44
45 #
46 # Generate tarball
47 #
48
49 # Get rid of URL
50 Source0 := $(notdir $(if $(Source),$(Source),$(Source0)))
51
52 # Add tarball to the list of sources
53 SOURCES += SOURCES/$(Source0)
54
55 # Get rid of .tar.bz2 or .tar.gz or .tgz
56 Base0 := $(Source0:.tgz=)
57 Base0 := $(Base0:.bz2=)
58 Base0 := $(Base0:.gz=)
59 Base0 := $(Base0:.tar=)
60
61 # Export module
62 SOURCES/$(Base0):
63         mkdir -p SOURCES
64         cd SOURCES && cvs -d $(CVSROOT) export -r $(INITIAL) -d $(Base0) $(MODULE)
65
66 .SECONDARY: $(SOURCES)/$(Base0)
67
68 # Generate tarball
69 SOURCES/$(Base0).tar.bz2: SOURCES/$(Base0)
70         tar cpjf $@ -C SOURCES $(Base0)
71
72 SOURCES/$(Base0).tar.gz SOURCES/$(Base0).tgz: SOURCES/$(Base0)
73         tar cpzf $@ -C SOURCES $(Base0)
74
75 SOURCES/$(Base0).tar: SOURCES/$(Base0)
76         tar cpf $@ -C SOURCES $(Base0)
77
78 #
79 # Generate patches
80 #
81
82 define PATCH_template
83
84 # In case the spec file did not explicitly list the PatchSet
85 ifeq ($$(origin Patch$(1)),undefined)
86 Patch$(1) := $$(package)-$(1).patch.bz2
87 endif
88
89 # Get rid of URL
90 Patch$(1) := $$(notdir $$(Patch$(1)))
91
92 # Add patch to the list of sources
93 SOURCES += SOURCES/$$(Patch$(1))
94
95 # Generate uncompressed patch
96 SOURCES/$$(patsubst %.gz,%,$$(patsubst %.bz2,%,$$(Patch$(1)))):
97         mkdir -p SOURCES
98         cvsps --cvs-direct --root $$(CVSROOT) -g -s $(1) $$(MODULE) > $$@
99
100 endef
101
102 # bzip2
103 %.bz2: %
104         bzip2 -c $< > $@
105
106 # gzip
107 %.gz: %
108         gzip -c $< > $@
109
110 # Generate rules to generate patches (make-3.80 and above expands this)
111 $(foreach n,$(PATCHES),$(eval $(call PATCH_template,$(n))))
112
113 #
114 # Generate spec file
115 #
116
117 ifeq ($(TAG),HEAD)
118 # Define date for untagged builds
119 DATE := $(shell date +%Y.%m.%d)
120 endif
121
122 # Generate spec file
123 SPECS/$(notdir $(SPEC)): SPECS/$(notdir $(SPEC)).in
124         rm -f $@
125 ifeq ($(TAG),HEAD)
126         # Define date for untagged builds
127         echo "%define date $(DATE)" >> $@
128 endif
129         # Rewrite patch sections of spec file
130         perl -n -e ' \
131         next if /^Patch.*/; \
132         next if /^%patch.*/; \
133         print; \
134         if (/^Source.*/) { $(foreach n,$(PATCHES),print "Patch$(n): $(Patch$(n))\n";) } \
135         if (/^%setup.*/) { $(foreach n,$(PATCHES),print "%patch$(n) -p1\n";) } \
136         ' $< >> $@
137
138 #
139 # Build
140 #
141
142 ifeq ($(TAG),HEAD)
143 RPMFLAGS += --define "date $(DATE)"
144 endif
145 PACKAGES := $(shell rpmquery $(RPMFLAGS) --specfile SPECS/$(notdir $(SPEC)).in 2>/dev/null)
146 NVR := $(word 1,$(PACKAGES))
147 ARCH := $(shell rpmquery $(RPMFLAGS) --queryformat '%{ARCH}\n' --specfile SPECS/$(notdir $(SPEC)).in 2>/dev/null | head -1)
148
149 all: RPMS/$(ARCH)/$(NVR).$(ARCH).rpm SRPMS/$(NVR).src.rpm
150
151 # Build RPM
152 RPMS/$(ARCH)/$(NVR).$(ARCH).rpm: SPECS/$(notdir $(SPEC)) $(SOURCES) .rpmmacros
153         mkdir -p BUILD RPMS
154         rpmbuild $(RPMFLAGS) -bb $<
155
156 # Build SRPM
157 SRPMS/$(NVR).src.rpm: SPECS/$(notdir $(SPEC)) $(SOURCES) .rpmmacros
158         mkdir -p SRPMS
159         rpmbuild $(RPMFLAGS) -bs $<
160
161 # Base rpmbuild in the current directory
162 .rpmmacros:
163         echo "%_topdir $(HOME)" > $@
164         echo "%_tmppath $(HOME)/tmp" >> $@
165
166 # Remove files generated by this package
167 clean:
168         rm -rf \
169         BUILD/$(Base0) \
170         $(foreach subpackage,$(PACKAGES),RPMS/*/$(subpackage)*) \
171         SOURCES/$(Base0)* SOURCES/$(package)* \
172         SPECS/$(notdir $(SPEC)).in SPECS/$(notdir $(SPEC)) $(MK) \
173         SRPMS/$(NVR).src.rpm \
174         tmp \
175         .cvsps/$(subst /,#,$(CVSROOT)/$(MODULE))
176
177 .PHONY: all clean