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