Commit | Line | Data |
---|---|---|
e36b4f25 MW |
1 | ### -*-makefile-*- |
2 | ### | |
3 | ### Main maintenance script for chroots | |
4 | ### | |
5 | ### (c) 2018 Mark Wooding | |
6 | ### | |
7 | ||
8 | ###----- Licensing notice --------------------------------------------------- | |
9 | ### | |
10 | ### This file is part of the distorted.org.uk chroot maintenance tools. | |
11 | ### | |
12 | ### distorted-chroot is free software: you can redistribute it and/or | |
13 | ### modify it under the terms of the GNU General Public License as | |
14 | ### published by the Free Software Foundation; either version 2 of the | |
15 | ### License, or (at your option) any later version. | |
16 | ### | |
17 | ### distorted-chroot is distributed in the hope that it will be useful, | |
18 | ### but WITHOUT ANY WARRANTY; without even the implied warranty of | |
19 | ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
20 | ### General Public License for more details. | |
21 | ### | |
22 | ### You should have received a copy of the GNU General Public License | |
23 | ### along with distorted-chroot. If not, write to the Free Software | |
24 | ### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
25 | ### USA. | |
26 | ||
27 | all:: | |
28 | clean:: | |
3e5b03e2 MW |
29 | check:: |
30 | .PHONY: all clean check | |
e36b4f25 MW |
31 | .SECONDEXPANSION: #sorry |
32 | ||
33 | ###-------------------------------------------------------------------------- | |
34 | ### Configuration. | |
35 | ||
36 | CONFIG_VARS = | |
37 | ||
3e5b03e2 MW |
38 | ## Level of pickiness to aspire to. |
39 | NOTIFY_FATAL = 1 | |
40 | ||
e36b4f25 MW |
41 | ## Volume group from which to allocate chroot volumes and snapshots. |
42 | CONFIG_VARS += VG LVPREFIX | |
afb5d051 | 43 | VG := vg-$(shell hostname) |
e36b4f25 MW |
44 | LVPREFIX = |
45 | ||
46 | ## Logical volume size, as an LVM option. | |
3e5b03e2 | 47 | CONFIG_VARS += LVSZ SNAPOPT |
e36b4f25 | 48 | LVSZ = -L8G |
3e5b03e2 | 49 | SNAPOPT = -L8G |
e36b4f25 MW |
50 | |
51 | ## Debian mirror. | |
52 | CONFIG_VARS += DEBMIRROR | |
53 | DEBMIRROR = http://deb.debian.org/debian/ | |
54 | ||
55 | ## APT sources configurations. (Also, $($d_APTSRC) for each $d in $(DISTS).) | |
56 | CONFIG_VARS += APTSRC | |
57 | APTSRC = etc/aptsrc.conf $(wildcard etc/aptsrc.local.conf) | |
58 | ||
59 | ## APT configuration fragment names. These will be linked into | |
60 | ## `/etc/apt/apt.conf.d' in each chroot. To put a fragment f in a surprising | |
a98c9dba MW |
61 | ## place, set $(_$f_APTCONFSRC). |
62 | CONFIG_VARS += APTCONF $(foreach f,$(APTCONF),_$f_APTCONFSRC) | |
63 | APTCONF = $(notdir $(wildcard etc/apt-conf.d/[0-9]*[!~])) | |
e36b4f25 MW |
64 | |
65 | ## Proxy setting. | |
66 | CONFIG_VARS += PROXY | |
4d529157 | 67 | PROXY = $(shell \ |
a98c9dba | 68 | eval $$(apt-config $(foreach a,$(APTCONF),-cetc/apt-conf.d/$a) \ |
e36b4f25 MW |
69 | shell proxy Acquire::http::proxy); \ |
70 | case $${proxy+t} in (t) echo "$$proxy" ;; (*) echo nil ;; esac) | |
71 | ||
72 | ## Debian distributions to support. | |
73 | CONFIG_VARS += PRIMARY_DIST DISTS | |
74 | PRIMARY_DIST = stretch | |
75 | DISTS = $(PRIMARY_DIST) buster bullseye sid | |
76 | ||
77 | ## Host's native architecture(s). | |
78 | CONFIG_VARS += MYARCH NATIVE_ARCHS | |
afb5d051 MW |
79 | MYARCH := $(shell dpkg --print-architecture) |
80 | OTHERARCHS := $(shell dpkg --print-foreign-architectures) | |
e36b4f25 MW |
81 | NATIVE_ARCHS = $(MYARCH) $(OTHERARCHS) |
82 | ||
83 | ## Foreign (emulated) architectures to support. | |
84 | CONFIG_VARS += FOREIGN_ARCHS | |
85 | FOREIGN_ARCHS = | |
86 | ||
87 | ## Master lists of chroots to build and maintain. | |
a98c9dba | 88 | CONFIG_VARS += NATIVE_CHROOTS FOREIGN_CHROOTS |
e36b4f25 MW |
89 | NATIVE_CHROOTS = $(foreach a,$(NATIVE_ARCHS), \ |
90 | $(foreach d,$(or $($a_DISTS) $(DISTS)), \ | |
91 | $d-$a)) | |
92 | FOREIGN_CHROOTS = $(foreach a,$(FOREIGN_ARCHS), \ | |
93 | $(foreach d,$(or $($a_DISTS) $(DISTS)), \ | |
94 | $d-$a)) | |
95 | ||
a98c9dba MW |
96 | ## Extra packages to be installed in chroots. `BASE_PACKAGES' are installed |
97 | ## through `debootstrap'; `EXTRA_PACKAGES' are installed later, using Apt, | |
98 | ## which is faster in foreign chroots. | |
99 | CONFIG_VARS += BASE_PACKAGES EXTRA_PACKAGES | |
100 | BASE_PACKAGES = eatmydata | |
101 | EXTRA_PACKAGES = build-essential | |
102 | EXTRA_PACKAGES += ccache | |
103 | EXTRA_PACKAGES += fakeroot | |
104 | EXTRA_PACKAGES += libfile-fcntllock-perl | |
105 | EXTRA_PACKAGES += locales | |
106 | ||
107 | ## Extra packages from which to install the cross tools. | |
108 | CONFIG_VARS += CROSS_PACKAGES | |
109 | CROSS_PACKAGES = bash coreutils dash findutils | |
110 | CROSS_PACKAGES += gzip m4 mawk sed tar xz-utils | |
111 | CROSS_PACKAGES += apt ccache eatmydata fakeroot make | |
112 | CROSS_PACKAGES += qemu-user-static | |
113 | CROSS_PACKAGES += $(foreach a,$(FOREIGN_GNUARCHS),\ | |
114 | gcc-$a g++-$a binutils-$a) | |
115 | ||
116 | ## Native files to install in place of the foreign versions. `MULTI' here | |
117 | ## stands for the donor's GNU multiarch name. | |
118 | CONFIG_VARS += CROSS_PATHS | |
119 | CROSS_PATHS += \ | |
120 | $(addprefix /usr/bin/, \ | |
121 | apt apt-cache apt-config apt-get apt-key apt-mark) \ | |
122 | $(addprefix /usr/lib/apt/, \ | |
123 | methods/ solvers/) \ | |
124 | $(addprefix /bin/, \ | |
125 | cat chgrp chown cp date dd df dir echo false ln ls mkdir \ | |
126 | mknod mktemp mv pwd readlink rm rmdir sleep stty sync touch \ | |
127 | true uname vdir) \ | |
128 | $(addprefix /usr/bin/, \ | |
129 | [ arch b2sum base32 base64 basename chcon cksum comm \ | |
130 | csplit cut dircolors dirname du env expand expr factor fmt \ | |
131 | fold groups head hostid id install join link logname md5sum \ | |
132 | mkfifo nice nl nohup nproc numfmt od paste pathchk pinky pr \ | |
133 | printenv printf ptx realpath runcon seq sha1sum sha224sum \ | |
134 | sha256sum sha384sum sha512sum shred shuf sort split stat \ | |
135 | stdbuf sum tac tail tee test timeout tr truncate tsort tty \ | |
136 | unexpand uniq unlink users wc who whoami yes) \ | |
137 | /usr/lib/MULTI/coreutils/ \ | |
138 | $(addprefix /lib/MULTI/, \ | |
139 | libnsl.so.* libnss_*.so.*) \ | |
140 | /usr/bin/gpgv \ | |
141 | /usr/bin/qemu-*-static \ | |
142 | $(addprefix /bin/, \ | |
143 | bash dash gzip sed tar) \ | |
144 | $(addprefix /usr/bin/, \ | |
145 | ccache find m4 make mawk xargs xz) \ | |
146 | $(addprefix /usr/lib/MULTI/, \ | |
147 | libeatmydata.so* libfakeroot/) \ | |
148 | $(addprefix /etc/ld.so.conf.d/, \ | |
149 | MULTI.conf fakeroot*.conf) \ | |
150 | $(foreach a,$(FOREIGN_GNUARCHS), \ | |
151 | $(addprefix /usr/bin/$a-, \ | |
152 | addr2line ar as c++filt dwp elfedit gprof ld ld.* \ | |
153 | nm objcopy objdump ranlib readelf size strings \ | |
154 | strip) \ | |
155 | $(addprefix /usr/bin/$a-, \ | |
156 | cpp gcc g++ gcov gcov-dump gcov-tool gprof \ | |
157 | gcc-ar gcc-nm gcc-ranlib) \ | |
44dfbdf5 MW |
158 | /usr/lib/gcc-cross/$a/ \ |
159 | /usr/$a/include/c++) | |
3e5b03e2 MW |
160 | |
161 | ## Local packages to be compiled and installed in chroots. Archives can be | |
162 | ## found in `pkg/'. | |
a98c9dba | 163 | CONFIG_VARS += LOCALPKGS $(foreach p,$(LOCALPKGS),$p_DEPS) |
3e5b03e2 | 164 | LOCALPKGS = mLib checkpath |
a98c9dba MW |
165 | mLib_DEPS = |
166 | checkpath_DEPS = mLib | |
3e5b03e2 | 167 | |
e36b4f25 MW |
168 | ## Which host architecture to use for foreign architectures. It turns out |
169 | ## that it's best to use a Qemu with the same host bitness as the target | |
170 | ## architecture; otherwise it has to do a difficult job of converting | |
171 | ## arguments and results between kernel ABI flavours. | |
172 | 32BIT_QEMUHOST = $(or $(filter i386,$(NATIVE_ARCHS)),$(TOOLSARCH)) | |
173 | 64BIT_QEMUHOST = $(or $(filter amd64,$(NATIVE_ARCHS)),$(TOOLSARCH)) | |
174 | ||
a98c9dba | 175 | CONFIG_VARS += $(foreach a,$(FOREIGN_ARCHS),$a_QEMUHOST) |
e36b4f25 MW |
176 | armel_QEMUHOST = $(32BIT_QEMUHOST) |
177 | armhf_QEMUHOST = $(32BIT_QEMUHOST) | |
178 | arm64_QEMUHOST = $(64BIT_QEMUHOST) | |
179 | i386_QEMUHOST = $(32BIT_QEMUHOST) | |
180 | amd64_QEMUHOST = $(64BIT_QEMUHOST) | |
181 | ||
d9f036c4 MW |
182 | ## Which distribution of Qemu to use. |
183 | CONFIG_VARS += $(foreach d,$(DISTS),$d_QEMUDIST) | |
a02fd5c0 | 184 | stretch_QEMUDIST = buster |
d9f036c4 | 185 | |
e36b4f25 MW |
186 | ## Qemu architecture names. These tell us which Qemu binary to use for a |
187 | ## particular Debian architecture. | |
a98c9dba | 188 | CONFIG_VARS += $(foreach a,$(FOREIGN_ARCHS),$a_QEMUARCH) |
e36b4f25 MW |
189 | armel_QEMUARCH = arm |
190 | armhf_QEMUARCH = arm | |
191 | arm64_QEMUARCH = aarch64 | |
192 | i386_QEMUARCH = i386 | |
193 | amd64_QEMUARCH = x86_64 | |
194 | ||
195 | ## Alias mapping for chroots. | |
a98c9dba | 196 | CONFIG_VARS += $(foreach d,$(DISTS),$d_ALIASES) |
e36b4f25 MW |
197 | stretch_ALIASES = oldstable |
198 | buster_ALIASES = stable | |
a98c9dba | 199 | bullseye_ALIASES = testing |
e36b4f25 MW |
200 | sid_ALIASES = unstable |
201 | ||
202 | ## Which host architecture to use for commonly used tools in foreign chroots. | |
203 | CONFIG_VARS += TOOLSARCH | |
204 | TOOLSARCH = $(MYARCH) | |
205 | ||
206 | ## A directory in which we can maintain private files and state. | |
207 | CONFIG_VARS += STATE | |
208 | STATE = state | |
209 | ||
210 | ## A directory which will be spliced into chroots as `/usr/local.schroot/'. | |
211 | ## This will be our primary point of contact with the chroot. | |
8918e451 | 212 | CONFIG_VARS += LOCAL ABSLOCAL |
e36b4f25 | 213 | LOCAL = local.schroot |
8918e451 | 214 | ABSLOCAL = $(abspath $(LOCAL)) |
e36b4f25 MW |
215 | |
216 | ## How to run a command as a privileged user. | |
a98c9dba | 217 | CONFIG_VARS += ROOTLY |
e36b4f25 MW |
218 | ROOTLY = sudo |
219 | ||
220 | ## Files to be copied into a chroot from the host. | |
221 | SCHROOT_COPYFILES = /etc/resolv.conf | |
222 | SCHROOT_NSSDATABASES = passwd shadow group gshadow | |
223 | ||
224 | ## Local configuration hook. | |
225 | -include local.mk | |
226 | ||
227 | ## All chroot names. | |
3e5b03e2 MW |
228 | CONFIG_VARS += ALL_ARCHS ALL_CHROOTS |
229 | ALL_ARCHS = $(NATIVE_ARCHS) $(FOREIGN_ARCHS) | |
e36b4f25 MW |
230 | ALL_CHROOTS = $(NATIVE_CHROOTS) $(FOREIGN_CHROOTS) |
231 | ||
a98c9dba MW |
232 | ## GNU names for foreign architectures. |
233 | CONFIG_VARS += FOREIGN_GNUARCHS | |
234 | FOREIGN_GNUARCHS := $(foreach a,$(FOREIGN_ARCHS),\ | |
235 | $(shell dpkg-architecture -A$a \ | |
236 | -qDEB_TARGET_GNU_TYPE)) | |
237 | ||
e36b4f25 MW |
238 | ###-------------------------------------------------------------------------- |
239 | ### Utilities. | |
240 | ||
3e5b03e2 MW |
241 | ## Hack to force rebuilding. |
242 | _force: | |
243 | .PHONY: _force | |
244 | ||
245 | ## Hack to not delimit function arguments. (Ugh!) | |
246 | comma = , | |
247 | ||
248 | ## Silent-rules machinery. | |
249 | V = 0 | |
250 | V_AT = $(V_AT_$V) | |
251 | V_AT_0 = @ | |
252 | v_print = $(call v_print_$V,$1,$2) | |
253 | v_print_0 = printf " %-8s %s\n" "$1" $(call squote,$2); | |
254 | v_tag = $(V_AT)$(call v_print,$1,$@) | |
255 | v_log = $(call v_log_$V,$1,$2) | |
256 | v_log_ = $(call v_log_1,$1,$2) | |
257 | v_log_0 = $2 >log/$1.log 2>&1 | |
258 | v_log_1 = $(call catchrc,$(call throwrc,$2) 2>&1 | tee log/$1.log) | |
259 | v_echo = $(call v_echo_$V,$1) | |
260 | v_echo_0 = : | |
261 | v_echo_1 = printf "%s\n" $1 | |
262 | CLEANFILES += log/*.log | |
263 | ||
264 | ## Oh, shut up. | |
265 | SILENCE_LVM = \ | |
266 | LVM_SUPPRESS_FD_WARNINGS=1; export LVM_SUPPRESS_FD_WARNINGS | |
267 | ||
a98c9dba MW |
268 | ## $(call definedp,VAR) |
269 | ## | |
270 | ## Expand non-empty if and only if VAR is defined (but possibly empty). | |
271 | definedp = $(filter-out undefined,$(origin $1)) | |
272 | ||
3e5b03e2 MW |
273 | ## $(call catchrc,...$(call throwrc,CMD)...) |
274 | ## | |
275 | ## Catch the exit status of some subpart of a complicated shell rune. | |
276 | catchrc = (exec 3>&1; exit $$({ $1; } 4>&1 >&3 3>&-)) | |
277 | throwrc = { $1; echo $$? >&4; } | |
278 | ||
279 | ## $(call squote,TXT) | |
280 | ## | |
281 | ## Single-quote TXT. | |
1727e3c6 MW |
282 | squote = '$(subst ','\'',$1)' |
283 | #' | |
3e5b03e2 | 284 | |
e36b4f25 MW |
285 | ## $(call chroot-dist,D-A) -> D |
286 | ## $(call chroot-arch,D-A) -> A | |
287 | ## | |
288 | ## Parse chroot descriptions. | |
289 | chroot-dist = $(patsubst %/,%,$(dir $(subst -,/,$1))) | |
290 | chroot-arch = $(notdir $(subst -,/,$1)) | |
291 | ||
3e5b03e2 MW |
292 | ## $(call package-dir-name,P-V) -> P |
293 | ## $(call package-dir-version,P-V) -> V | |
294 | ## | |
295 | ## Parse (source) package directory names. | |
296 | package-dir-name = $(sort $(foreach p,$(LOCALPKGS),$(if $(filter $p-$($p_VERSION),$1),$p))) | |
297 | package-dir-version = $($(call package-dir-name,$1)_VERSION) | |
298 | ||
299 | ## $(call package-dir,P-V.A) -> P-V | |
300 | ## $(call package-name,P-V.A) -> P | |
301 | ## $(call package-version,P-V.A) -> V | |
302 | ## $(call package-arch,P-V.A) -> A | |
303 | ## | |
304 | ## Parse package stamp names. | |
305 | package-dir = $(basename $1) | |
306 | package-name = $(call package-dir-name,$(call package-dir,$1)) | |
307 | package-version = $(call package-dir-version,$(call package-dir,$1)) | |
308 | package-arch = $(patsubst .%,%,$(suffix $1)) | |
309 | ||
e36b4f25 MW |
310 | ## $(call native-chroot-p,D-A) -> D | <empty> |
311 | ## | |
312 | ## Answer whether D-A is a native chroot. | |
3e5b03e2 | 313 | native-chroot-p = $(filter $(call chroot-arch,$1),$(NATIVE_ARCHS)) |
e36b4f25 MW |
314 | |
315 | ## $(call chroot-qemuhost,D-A) -> AA | |
316 | ## | |
317 | ## Answer the apporopriate Qemu host architecture for foreign chroot D-A. | |
318 | chroot-qemuhost = $($(call chroot-arch,$1)_QEMUHOST) | |
319 | ||
3e5b03e2 | 320 | ## $(call chroot-deps,PRE,D-A) -> PREDD-AA ... | <empty> |
e36b4f25 MW |
321 | ## |
322 | ## Answer a list of additional dependencies for the chroot D-A: specifically, | |
323 | ## if D-A is foreign then include PRE/DD-AA entries for the tools | |
324 | ## architecture, and Qemu host architecture (if that's different). | |
325 | chroot-deps = $(if $(call native-chroot-p,$2),, \ | |
3e5b03e2 MW |
326 | $(addprefix $1$(call chroot-dist,$2)-,\ |
327 | $(sort $(TOOLSARCH) \ | |
e36b4f25 MW |
328 | $(call chroot-qemuhost,$2)))) |
329 | ||
330 | ## Substituting placeholders in files. | |
331 | SUBSTITUTIONS := local=$(shell realpath $(LOCAL)) | |
332 | SUBSTITUTIONS += primary-dist=$(PRIMARY_DIST) | |
333 | subst-file = { \ | |
334 | echo "$1 GENERATED by distorted-chroot: do not edit"; \ | |
335 | substs=""; \ | |
336 | for v in $(SUBSTITUTIONS); do \ | |
337 | var=$${v%%=*} value=$${v\#*=}; \ | |
338 | substs="$$substs s\a@$$var@\a$$value\ag;"; \ | |
339 | done; \ | |
340 | sed "$$substs"; \ | |
341 | } | |
342 | ||
3e5b03e2 MW |
343 | ### $(call symlink-ok-p,LINK,DEST) |
344 | ### | |
345 | ### Expand to `t' if LINK is a symbolic link to DEST, and empty otherwise. | |
346 | symlink-ok-p = $(shell \ | |
347 | case $$(readlink 2>/dev/null $(patsubst %/,%,$1)) in ($2) echo t ;; esac) | |
348 | ||
349 | ### $(call general-notify,SEV,COLOUR,PREFIX,MSG) | |
350 | ### | |
351 | ### Report a message, highlighted in the right way, and maybe fail | |
352 | general-notify = { \ | |
353 | echo "$$(tput bold; tput setaf $2)$3 "$4"$$(tput sgr0; tput op)"; \ | |
354 | if [ "$1" -le "$(NOTIFY_FATAL)" ]; then exit 2; fi; \ | |
355 | } | |
356 | ||
357 | ### $(call report/SEV,MSG) | |
358 | ### | |
359 | ### Report a notification of a particular severity. | |
360 | notify/INFO = $(call general-notify,3,6,---,$1) | |
361 | notify/WARN = $(call general-notify,2,5,???,$1) | |
362 | notify/ERR = $(call general-notify,1,1,!!!,$1) | |
363 | ||
364 | ## $(call check,SEV,MSG,UNLESS) | |
365 | ## | |
366 | ## If UNLESS completes successfully, all is OK; otherwise print MSG to stderr | |
367 | ## and fail. | |
368 | check = @{ \ | |
369 | $(call v_echo,'check: '$(call squote,$3)''); \ | |
370 | if ! { $3; }; then $(call notify/$1,$2); fi; \ | |
371 | } | |
372 | ||
373 | ## $(call check-executable,SEV,PATH) | |
374 | ## | |
375 | ## Verify that PATH is an executable program. | |
376 | check-executable = $(call check,$1,"\`$2' is not an executable", \ | |
377 | [ -x "$2" ]) | |
378 | ||
379 | ## $(call check-mountpoint,SEV,DIR) | |
380 | ## | |
381 | ## Verify that DIR is a mountpoint. | |
382 | check-mountpoint = $(call check,$1,"\`$2' is not a mount point", \ | |
383 | mountpoint -q "$2") | |
384 | ||
385 | ## $(call check-symlink,SEV,LINK,DEST) | |
386 | ## | |
387 | ## Verify that LINK is a symbolic link pointing to DEST. | |
388 | check-symlink = $(call check,$1,"\`$2' is not a link to \`$3'", \ | |
389 | [ -L "$2" ] && [ "$$(readlink "$2")" = "$3" ]) | |
390 | ||
391 | ###-------------------------------------------------------------------------- | |
a4c5d71a MW |
392 | ### Python extensions. |
393 | ||
394 | CC = gcc | |
395 | CFLAGS = -O2 -g -Wall | |
396 | ||
397 | LD = $(CC) | |
398 | LDFLAGS = | |
399 | ||
400 | c-source = $(foreach c,$1,src/$c) | |
401 | c-object = $(foreach c,$1,$(STATE)/obj/$(basename $c).o) | |
402 | ||
403 | PYEXT_PKGFLAGS := $(shell pkg-config --cflags python2) | |
404 | PYEXT_CFLAGS = -fPIC -fno-strict-aliasing $(PYEXT_PKGFLAGS) | |
405 | PYEXT_LDFLAGS = -shared | |
406 | ||
407 | PYEXTS += jobclient | |
408 | jobclient_SOURCES = jobclient.c | |
409 | ||
410 | PYEXT_ALLSRC = $(foreach x,$(PYEXTS),\ | |
411 | $(call c-source,$($x_SOURCES))) | |
412 | PYEXT_ALLOBJ = $(foreach x,$(PYEXTS),\ | |
413 | $(call c-object,$($x_SOURCES))) | |
414 | $(PYEXT_ALLOBJ): $(STATE)/obj/%.o: src/%.c | |
415 | $(V_AT)mkdir -p $(dir $@) | |
416 | $(call v_tag,CC)$(CC) -c $(CFLAGS) $(PYEXT_CFLAGS) -o$@ $< | |
417 | ||
418 | PYMODULES = $(foreach x,$(PYEXTS),$(STATE)/lib/python/$x.so) | |
419 | all:: $(PYMODULES) | |
420 | $(PYMODULES): $(STATE)/lib/python/%.so: $$(call c-object,$$($$*_SOURCES)) | |
421 | $(V_AT)mkdir -p $(dir $@) | |
422 | $(call v_tag,LD)$(LD) $(LDFLAGS) $(PYEXT_LDFLAGS) -o$@ $^ | |
423 | ||
424 | ###-------------------------------------------------------------------------- | |
3e5b03e2 MW |
425 | ### Scripts. |
426 | ||
a98c9dba | 427 | SCRIPTS += chroot-maint |
3e5b03e2 | 428 | SCRIPTS += mkchrootconf |
3e5b03e2 MW |
429 | |
430 | SUBST_SCRIPTS = $(addprefix $(STATE)/bin/,$(SCRIPTS)) | |
431 | all:: $(SUBST_SCRIPTS) | |
432 | $(SUBST_SCRIPTS): $(STATE)/bin/%: bin/% $(STATE)/config.sh | |
433 | $(V_AT)mkdir -p $(dir $@) | |
434 | $(call v_tag,SUBST){ \ | |
435 | sed \ | |
436 | -e '2i### GENERATED by distorted-chroot: do not edit' \ | |
437 | -e '/@@@config@@@/ {' \ | |
438 | -e 'r $(STATE)/config.sh' \ | |
439 | -e 'd'\ | |
440 | -e '}' $<; \ | |
441 | } >$@.new && chmod +x $@.new && mv $@.new $@ | |
e36b4f25 MW |
442 | |
443 | ###-------------------------------------------------------------------------- | |
444 | ### APT configuration. | |
445 | ||
446 | ## In a chroot, `/etc/apt/sources.list' links to | |
447 | ## `/usr/local.schroot/etc/apt/sources.$d' for the appropriate distribution. | |
4004ed52 | 448 | APT_SOURCES = $(foreach d,$(DISTS),$(LOCAL)/etc/apt/sources.$d) |
e36b4f25 MW |
449 | all:: $(APT_SOURCES) |
450 | ||
4004ed52 | 451 | $(foreach d,$(DISTS),$(STATE)/etc/apt/aptsrc.$d): $(STATE)/etc/apt/aptsrc.%: |
e36b4f25 MW |
452 | $(V_AT)mkdir -p $(dir $@) |
453 | $(call v_tag,GEN){ \ | |
454 | echo "### -*-conf-*- GENERATED by distorted-chroot: do not edit"; \ | |
455 | echo "subscribe"; \ | |
456 | echo " debian : $*"; \ | |
457 | } >$@.new && mv $@.new $@ | |
458 | ||
459 | $(APT_SOURCES): $(LOCAL)/etc/apt/sources.%: \ | |
460 | $$(APTSRC) $$($$*_APTSRC) $$(STATE)/etc/apt/aptsrc.$$* | |
461 | $(V_AT)mkdir -p $(dir $@) | |
462 | $(call v_tag,GEN)bin/mkaptsrc \ | |
463 | $(APTSRC) $($*_APTSRC) $(STATE)/etc/apt/aptsrc.$* \ | |
464 | >$@.new && mv $@.new $@ | |
0539140c | 465 | CLEANFILES += $(APT_SOURCES) |
e36b4f25 MW |
466 | |
467 | ## In a chroot, a link `/etc/apt/apt.conf.d/FOO' is created for each file in | |
468 | ## `/usr/local.schroot/etc/apt/apt.conf.d/FOO'. | |
469 | APT_CONFIGS = $(addprefix $(LOCAL)/etc/apt/apt.conf.d/,$(APTCONF)) | |
470 | all:: $(APT_CONFIGS) | |
471 | $(APT_CONFIGS): $(LOCAL)/etc/apt/apt.conf.d/%: \ | |
a98c9dba | 472 | $$(or $$(_$$*_APTCONFSRC) etc/apt-conf.d/$$*) |
e36b4f25 MW |
473 | $(V_AT)mkdir -p $(dir $@) |
474 | $(call v_tag,COPY)cp $< $@.new && mv $@.new $@ | |
3e5b03e2 MW |
475 | clean::; rm -f $(APT_CONFIGS) |
476 | ||
477 | ###-------------------------------------------------------------------------- | |
478 | ### Build hacks. | |
479 | ||
480 | check::; $(call check-executable,ERR,/usr/bin/eatmydata) | |
481 | ||
482 | EATMYDATA_HACKS += apt-get aptitude dpkg | |
483 | SYMLINK_EATMYDATA_HACKS = $(addprefix $(LOCAL)/hacks/,$(EATMYDATA_HACKS)) | |
484 | all:: $(SYMLINK_EATMYDATA_HACKS) | |
485 | $(SYMLINK_EATMYDATA_HACKS): $(LOCAL)/hacks/%: \ | |
486 | $$(if $$(call symlink-ok-p,$$@,/usr/bin/eatmydata),,_force) | |
487 | $(V_AT)mkdir -p $(dir $@) | |
488 | $(call v_tag,SYMLINK)ln -sf /usr/bin/eatmydata $@.new && mv $@.new $@ | |
489 | clean::; rm -f $(SYMLINK_EATMYDATA_HACKS) | |
490 | ||
491 | SCRIPT_HACKS += buildwrap | |
492 | COPY_SCRIPT_HACKS = $(addprefix $(LOCAL)/hacks/,$(SCRIPT_HACKS)) | |
493 | all:: $(COPY_SCRIPT_HACKS) | |
494 | $(COPY_SCRIPT_HACKS): $(LOCAL)/hacks/%: bin/% | |
495 | $(V_AT)mkdir -p $(dir $@) | |
496 | $(call v_tag,COPY)cp $< $@.new && mv $@.new $@ | |
497 | clean::; rm -f $(COPY_SCRIPT_HACKS) | |
e36b4f25 MW |
498 | |
499 | ###-------------------------------------------------------------------------- | |
500 | ### `schroot' and `sbuild' configuration. | |
501 | ||
502 | all:: schroot-config | |
503 | schroot-config:: | |
504 | .PHONY: schroot-config | |
505 | ||
3e5b03e2 MW |
506 | check::; $(call check-mountpoint,WARN,/var/lib/sbuild/build) |
507 | check::; $(call check-symlink,WARN,/build,/var/lib/sbuild/build) | |
508 | check::; $(call check-symlink,ERR,/schroot,/run/schroot/mount) | |
509 | ||
e36b4f25 MW |
510 | %print-varlist = { \ |
511 | echo "\#\#\# -*-sh-*- GENERATED by distorted-chroot: do not edit"; \ | |
a98c9dba MW |
512 | $(foreach v,$1,$(if $(call definedp,$v),\ |
513 | echo $v=\'$(call squote,$($v))\';)) \ | |
fb28f2a8 | 514 | } |
e36b4f25 MW |
515 | schroot-config_HASH := \ |
516 | $(shell $(call %print-varlist,$(CONFIG_VARS)) | \ | |
517 | sha256sum | cut -c1-32) | |
518 | schroot-config_FILE = $(STATE)/config.sh-$(schroot-config_HASH) | |
519 | $(schroot-config_FILE): | |
520 | $(V_AT)mkdir -p $(STATE) | |
521 | $(V_AT)rm -f $(STATE)/config.sh-* | |
6ccac28c | 522 | $(call v_tag,GEN)$(call %print-varlist,$(CONFIG_VARS)) \ |
e36b4f25 MW |
523 | >$@.new && mv $@.new $@ |
524 | ||
525 | schroot-config:: $(STATE)/config.sh | |
526 | $(STATE)/config.sh: $(schroot-config_FILE) | |
527 | $(call v_tag,SYMLINK)ln -sf $(notdir $<) $@ | |
528 | ||
67a8479c MW |
529 | schroot-config:: $(LOCAL)/etc/schroot/sbuild.schroot |
530 | $(LOCAL)/etc/schroot/sbuild.schroot: $(STATE)/bin/mkchrootconf | |
e36b4f25 | 531 | $(V_AT)mkdir -p $(dir $@) |
3e5b03e2 MW |
532 | $(call v_tag,GEN)$(STATE)/bin/mkchrootconf >$@.new && \ |
533 | $(ROOTLY) chown root:root $@.new && mv $@.new $@ | |
67a8479c | 534 | CLEANFILES += $(LOCAL)/etc/schroot/sbuild.schroot |
8918e451 | 535 | check::; $(call check-symlink,WARN,/etc/schroot/chroot.d/sbuild,$(ABSLOCAL)/etc/schroot/sbuild.schroot) |
e36b4f25 | 536 | |
67a8479c MW |
537 | schroot-config:: $(LOCAL)/etc/schroot/sbuild.profile/copyfiles |
538 | $(LOCAL)/etc/schroot/sbuild.profile/copyfiles: $(schroot-config_STAMP) | |
e36b4f25 MW |
539 | $(V_AT)mkdir -p $(dir $@) |
540 | $(call v_tag,GEN){ \ | |
541 | echo "### -*-conf-*- GENERATED by distorted-chroot: do not edit"; \ | |
542 | for i in $(SCHROOT_COPYFILES); do echo "$$i"; done; \ | |
543 | } >$@.new && mv $@.new $@ | |
67a8479c | 544 | CLEANFILES += $(LOCAL)/etc/schroot/sbuild.profile/copyfiles |
e36b4f25 | 545 | |
67a8479c MW |
546 | schroot-config:: $(LOCAL)/etc/schroot/sbuild.profile/nssdatabases |
547 | $(LOCAL)/etc/schroot/sbuild.profile/nssdatabases: $(schroot-config_STAMP) | |
e36b4f25 MW |
548 | $(V_AT)mkdir -p $(dir $@) |
549 | $(call v_tag,GEN){ \ | |
550 | echo "### -*-conf-*- GENERATED by distorted-chroot: do not edit"; \ | |
551 | for i in $(SCHROOT_NSSDATABASES); do echo "$$i"; done; \ | |
552 | } >$@.new && mv $@.new $@ | |
67a8479c | 553 | CLEANFILES += $(LOCAL)/etc/schroot/sbuild.profile/nssdatabases |
e36b4f25 | 554 | |
67a8479c MW |
555 | schroot-config:: $(LOCAL)/etc/schroot/sbuild.profile/fstab |
556 | $(LOCAL)/etc/schroot/sbuild.profile/fstab: \ | |
e36b4f25 MW |
557 | etc/sbuild.fstab.in $(schroot-config_STAMP) |
558 | $(V_AT)mkdir -p $(dir $@) | |
559 | $(call v_tag,SUBST)$(call subst-file,### -*-conf-*-) \ | |
560 | <$< >$@.new && mv $@.new $@ | |
67a8479c | 561 | CLEANFILES += $(LOCAL)/etc/schroot/sbuild.profile/fstab |
e36b4f25 | 562 | |
8918e451 | 563 | check::; $(call check-symlink,WARN,/etc/schroot/sbuild,$(ABSLOCAL)/etc/schroot/sbuild.profile) |
3e5b03e2 | 564 | |
67a8479c MW |
565 | schroot-config:: $(LOCAL)/etc/sbuild.conf |
566 | $(LOCAL)/etc/sbuild.conf: etc/sbuild.conf.in $(schroot-config_STAMP) | |
e36b4f25 MW |
567 | $(V_AT)mkdir -p $(dir $@) |
568 | $(call v_tag,SUBST)$(call subst-file,### -*-perl-*-) \ | |
569 | <$< >$@.new && mv $@.new $@ | |
67a8479c | 570 | CLEANFILES += $(LOCAL)/etc/sbuild.conf |
8918e451 | 571 | check::; $(call check-symlink,WARN,/etc/sbuild/sbuild.conf,$(ABSLOCAL)/etc/sbuild.conf) |
d56d9258 | 572 | check::; $(call check-executable,WARN,/usr/local.schroot/hacks/apt-get) |
e36b4f25 | 573 | |
3e5b03e2 MW |
574 | SCHROOT_SCRIPTS += 11private |
575 | SCHROOT_SCRIPTS += 15binfmt | |
576 | SCHROOT_SCRIPTS += 51chrootenv | |
67a8479c | 577 | COPY_SCHROOT_SCRIPTS = $(addprefix $(LOCAL)/etc/schroot/setup.d/,$(SCHROOT_SCRIPTS)) |
3e5b03e2 MW |
578 | schroot-config:: $(COPY_SCHROOT_SCRIPTS) |
579 | $(COPY_SCHROOT_SCRIPTS): \ | |
67a8479c | 580 | $(LOCAL)/etc/schroot/setup.d/%: etc/schroot-scripts/% |
3e5b03e2 MW |
581 | $(V_AT)mkdir -p $(dir $@) |
582 | $(call v_tag,COPY)cp $< $@.new && mv $@.new $@ | |
67a8479c | 583 | CLEANFILES += $(COPY_SCHROOT_SCRIPTS) |
3e5b03e2 MW |
584 | |
585 | CHECK_SCHROOT_SCRIPTS = $(addprefix check-script/,$(SCHROOT_SCRIPTS)) | |
586 | check:: $(CHECK_SCHROOT_SCRIPTS) | |
587 | $(CHECK_SCHROOT_SCRIPTS): check-script/%: | |
8918e451 | 588 | $(call check-symlink,WARN,/etc/schroot/setup.d/$*,$(ABSLOCAL)/etc/schroot/setup.d/$*) |
3e5b03e2 MW |
589 | .PHONY: $(addprefix check-script/,$(SCHROOT_SCRIPTS)) |
590 | ||
591 | ###-------------------------------------------------------------------------- | |
0a9fcbbc MW |
592 | ### Ccache setup. |
593 | ||
594 | CCACHE_CONFIGS = $(foreach r,$(ALL_CHROOTS), \ | |
595 | /var/lib/sbuild/build/.ccache/$(LVPREFIX)$r/ccache.conf) | |
596 | all:: $(CCACHE_CONFIGS) | |
597 | $(CCACHE_CONFIGS): /var/lib/sbuild/build/.ccache/$(LVPREFIX)%/ccache.conf: \ | |
598 | etc/ccache.conf | |
599 | $(V_AT)mkdir -p $(dir $@) | |
600 | $(call v_tag,COPY)cp $< $@.new && mv $@.new $@ | |
601 | ||
602 | ###-------------------------------------------------------------------------- | |
3e5b03e2 MW |
603 | ### `/usr/local/' structure. |
604 | ||
605 | LOCAL_COMMON_DIRS = share/ src/ | |
27922408 MW |
606 | LOCAL_EXTRA_DIRS = share/man/ |
607 | all:: $(foreach d,$(LOCAL_COMMON_DIRS) $(LOCAL_EXTRA_DIRS),$(LOCAL)/$d) | |
608 | $(foreach d,$(LOCAL_COMMON_DIRS) $(LOCAL_EXTRA_DIRS),$(LOCAL)/$d): | |
3e5b03e2 MW |
609 | $(V_AT)mkdir -p $(dir $(patsubst %/,%,$@)) |
610 | $(call v_tag,MKDIR)mkdir $@ | |
611 | ||
942fed18 MW |
612 | LOCAL_ARCH_DIRS = bin/ etc/ games/ include/ include.aside/ |
613 | LOCAL_ARCH_DIRS += lib/ libexec/ sbin/ | |
3e5b03e2 MW |
614 | LOCAL_ARCH_LINKS = man |
615 | man_LINKDEST = share/man | |
616 | all:: $(foreach a,$(ALL_ARCHS),\ | |
617 | $(LOCAL)/$a/ \ | |
618 | $(foreach d,$(LOCAL_ARCH_DIRS),$(LOCAL)/$a/$d) \ | |
619 | $(foreach d,$(LOCAL_ARCH_LINKS),$(LOCAL)/$a/$d) \ | |
620 | $(foreach d,$(LOCAL_COMMON_DIRS),$(LOCAL)/$a/$d)) | |
621 | ||
622 | $(foreach a,$(ALL_ARCHS),$(LOCAL)/$a/): | |
623 | $(call v_tag,MKDIR)mkdir $@ | |
624 | $(foreach a,$(ALL_ARCHS),\ | |
625 | $(foreach d,$(LOCAL_ARCH_DIRS),$(LOCAL)/$a/$d)): | |
626 | $(V_AT)mkdir -p $(dir $(patsubst %/,%,$@)) | |
627 | $(call v_tag,MKDIR)mkdir $@ | |
628 | $(foreach a,$(ALL_ARCHS),\ | |
629 | $(foreach d,$(LOCAL_ARCH_LINKS),$(LOCAL)/$a/$d)): \ | |
630 | $$(if $$(call symlink-ok-p,$$@,$$($$(notdir $$@)_LINKDEST)),,_force) | |
631 | $(V_AT)mkdir -p $(notdir $@) | |
632 | $(call v_tag,SYMLINK)ln -sf $($(notdir $@)_LINKDEST) $@ | |
633 | $(foreach a,$(ALL_ARCHS),\ | |
634 | $(foreach d,$(LOCAL_COMMON_DIRS),$(LOCAL)/$a/$d)): \ | |
635 | $$(if $$(call symlink-ok-p,$$@,../$$(notdir $$(patsubst %/,%,$$@))),,_force) | |
636 | $(V_AT)mkdir -p $(dir $(patsubst %/,%,$@)) | |
637 | $(call v_tag,SYMLINK)ln -sf ../$(notdir $(patsubst %/,%,$@)) $(patsubst %/,%,$@) | |
638 | ||
e36b4f25 | 639 | ###-------------------------------------------------------------------------- |
a98c9dba | 640 | ### Main chroot maintenance. |
e36b4f25 | 641 | |
a98c9dba | 642 | OPTS = |
642f47f9 | 643 | FRESH = 1w |
a98c9dba MW |
644 | JOBS = chroot cross-tools pkg-build |
645 | ||
646 | MAINTQ_ = -q | |
647 | MAINTQ_0 = -q | |
fe87403b | 648 | MAINT = +$(call v_tag,MAINT)\ |
a98c9dba MW |
649 | PYTHONPATH=$(STATE)/lib/python $(STATE)/bin/chroot-maint \ |
650 | $(MAINTQ_$V) $(OPTS) | |
651 | ||
652 | maint: all check | |
653 | $(MAINT) -f$(FRESH) $(JOBS) | |
654 | .PHONY: maint | |
e36b4f25 MW |
655 | |
656 | ###-------------------------------------------------------------------------- | |
7443a1fb MW |
657 | ### Running random commands. |
658 | ||
659 | CMD = echo %d %a | |
660 | subst-command = $(subst %d,$(call chroot-dist,$1), \ | |
661 | $(subst %a,$(call chroot-arch,$1), \ | |
662 | $(subst %r,$1, $(CMD)))) | |
663 | ||
664 | run: $(foreach c,$(ALL_CHROOTS),run/$c) | |
665 | $(foreach c,$(ALL_CHROOTS),run/$c): run/%: | |
666 | $(V_AT)$(call v_print,RUN,$(call subst-command,$*))\ | |
667 | $(call subst-command,$*) | |
668 | ||
669 | ###-------------------------------------------------------------------------- | |
e36b4f25 MW |
670 | ### Other maintenance targets. |
671 | ||
672 | show:; : $x | |
673 | ||
674 | clean:: | |
675 | rm -f $(CLEANFILES) | |
676 | rm -rf $(STATE) | |
677 | ||
678 | realclean:: clean | |
679 | rm -rf $(LOCAL) | |
680 | ||
681 | ###----- That's all, folks -------------------------------------------------- |