chiark / gitweb /
Makefile: Don't insist on `/usr/lib/.../coreutils/'.
[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 .PHONY: all clean check
31 .SECONDEXPANSION: #sorry
32
33 ###--------------------------------------------------------------------------
34 ### Configuration.
35
36 CONFIG_VARS              =
37
38 ## Level of pickiness to aspire to.
39 NOTIFY_FATAL             = 1
40
41 ## Volume group from which to allocate chroot volumes and snapshots.
42 CONFIG_VARS             += VG LVPREFIX
43 VG                      := vg-$(shell hostname)
44 LVPREFIX                 =
45
46 ## Logical volume size, as an LVM option.
47 CONFIG_VARS             += LVSZ SNAPOPT
48 LVSZ                     = -L8G
49 SNAPOPT                  = -L8G
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
61 ## place, set $(_$f_APTCONFSRC).
62 CONFIG_VARS             += APTCONF $(foreach f,$(APTCONF),_$f_APTCONFSRC)
63 APTCONF                  = $(notdir $(wildcard etc/apt-conf.d/[0-9]*[!~]))
64
65 ## Proxy setting.
66 CONFIG_VARS             += PROXY
67 PROXY                    = $(shell \
68         eval $$(apt-config $(foreach a,$(APTCONF),-cetc/apt-conf.d/$a) \
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
79 MYARCH                  := $(shell dpkg --print-architecture)
80 OTHERARCHS              := $(shell dpkg --print-foreign-architectures)
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.
88 CONFIG_VARS             += NATIVE_CHROOTS FOREIGN_CHROOTS
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
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) \
158                 /usr/lib/gcc-cross/$a/ \
159                 /usr/$a/include/c++)
160
161 ## Local packages to be compiled and installed in chroots.  Archives can be
162 ## found in `pkg/'.
163 CONFIG_VARS             += LOCALPKGS $(foreach p,$(LOCALPKGS),$p_DEPS)
164 LOCALPKGS                = mLib checkpath
165 mLib_DEPS                =
166 checkpath_DEPS           = mLib
167
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
175 CONFIG_VARS             += $(foreach a,$(FOREIGN_ARCHS),$a_QEMUHOST)
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
182 ## Which distribution of Qemu to use.
183 CONFIG_VARS             += $(foreach d,$(DISTS),$d_QEMUDIST)
184 stretch_QEMUDIST         = buster
185
186 ## Qemu architecture names.  These tell us which Qemu binary to use for a
187 ## particular Debian architecture.
188 CONFIG_VARS             += $(foreach a,$(FOREIGN_ARCHS),$a_QEMUARCH)
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.
196 CONFIG_VARS             += $(foreach d,$(DISTS),$d_ALIASES)
197 stretch_ALIASES          = oldstable
198 buster_ALIASES           = stable
199 bullseye_ALIASES         = testing
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.
212 CONFIG_VARS             += LOCAL ABSLOCAL
213 LOCAL                    = local.schroot
214 ABSLOCAL                 = $(abspath $(LOCAL))
215
216 ## How to run a command as a privileged user.
217 CONFIG_VARS             += ROOTLY
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.
228 CONFIG_VARS             += ALL_ARCHS ALL_CHROOTS
229 ALL_ARCHS                = $(NATIVE_ARCHS) $(FOREIGN_ARCHS)
230 ALL_CHROOTS              = $(NATIVE_CHROOTS) $(FOREIGN_CHROOTS)
231
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
238 ###--------------------------------------------------------------------------
239 ### Utilities.
240
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
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
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.
282 squote                   = '$(subst ','\'',$1)'
283 #'
284
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
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
310 ##      $(call native-chroot-p,D-A) -> D | <empty>
311 ##
312 ## Answer whether D-A is a native chroot.
313 native-chroot-p          = $(filter $(call chroot-arch,$1),$(NATIVE_ARCHS))
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
320 ##      $(call chroot-deps,PRE,D-A) -> PREDD-AA ... | <empty>
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),, \
326                                 $(addprefix $1$(call chroot-dist,$2)-,\
327                                         $(sort $(TOOLSARCH) \
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
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 ###--------------------------------------------------------------------------
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 ###--------------------------------------------------------------------------
425 ### Scripts.
426
427 SCRIPTS                 += chroot-maint
428 SCRIPTS                 += mkchrootconf
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 $@
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.
448 APT_SOURCES              = $(foreach d,$(DISTS),$(LOCAL)/etc/apt/sources.$d)
449 all:: $(APT_SOURCES)
450
451 $(foreach d,$(DISTS),$(STATE)/etc/apt/aptsrc.$d): $(STATE)/etc/apt/aptsrc.%:
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 $@
465 CLEANFILES              += $(APT_SOURCES)
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/%: \
472                 $$(or $$(_$$*_APTCONFSRC) etc/apt-conf.d/$$*)
473         $(V_AT)mkdir -p $(dir $@)
474         $(call v_tag,COPY)cp $< $@.new && mv $@.new $@
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)
498
499 ###--------------------------------------------------------------------------
500 ### `schroot' and `sbuild' configuration.
501
502 all:: schroot-config
503 schroot-config::
504 .PHONY: schroot-config
505
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
510 %print-varlist           = { \
511         echo "\#\#\# -*-sh-*- GENERATED by distorted-chroot: do not edit"; \
512         $(foreach v,$1,$(if $(call definedp,$v),\
513                 echo $v=\'$(call squote,$($v))\';)) \
514 }
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-*
522         $(call v_tag,GEN)$(call %print-varlist,$(CONFIG_VARS)) \
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
529 schroot-config:: $(LOCAL)/etc/schroot/sbuild.schroot
530 $(LOCAL)/etc/schroot/sbuild.schroot: $(STATE)/bin/mkchrootconf
531         $(V_AT)mkdir -p $(dir $@)
532         $(call v_tag,GEN)$(STATE)/bin/mkchrootconf >$@.new && \
533                 $(ROOTLY) chown root:root $@.new && mv $@.new $@
534 CLEANFILES              += $(LOCAL)/etc/schroot/sbuild.schroot
535 check::; $(call check-symlink,WARN,/etc/schroot/chroot.d/sbuild,$(ABSLOCAL)/etc/schroot/sbuild.schroot)
536
537 schroot-config:: $(LOCAL)/etc/schroot/sbuild.profile/copyfiles
538 $(LOCAL)/etc/schroot/sbuild.profile/copyfiles: $(schroot-config_STAMP)
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 $@
544 CLEANFILES              += $(LOCAL)/etc/schroot/sbuild.profile/copyfiles
545
546 schroot-config:: $(LOCAL)/etc/schroot/sbuild.profile/nssdatabases
547 $(LOCAL)/etc/schroot/sbuild.profile/nssdatabases: $(schroot-config_STAMP)
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 $@
553 CLEANFILES              += $(LOCAL)/etc/schroot/sbuild.profile/nssdatabases
554
555 schroot-config:: $(LOCAL)/etc/schroot/sbuild.profile/fstab
556 $(LOCAL)/etc/schroot/sbuild.profile/fstab: \
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 $@
561 CLEANFILES              += $(LOCAL)/etc/schroot/sbuild.profile/fstab
562
563 check::; $(call check-symlink,WARN,/etc/schroot/sbuild,$(ABSLOCAL)/etc/schroot/sbuild.profile)
564
565 schroot-config:: $(LOCAL)/etc/sbuild.conf
566 $(LOCAL)/etc/sbuild.conf: etc/sbuild.conf.in $(schroot-config_STAMP)
567         $(V_AT)mkdir -p $(dir $@)
568         $(call v_tag,SUBST)$(call subst-file,### -*-perl-*-) \
569                 <$< >$@.new && mv $@.new $@
570 CLEANFILES              += $(LOCAL)/etc/sbuild.conf
571 check::; $(call check-symlink,WARN,/etc/sbuild/sbuild.conf,$(ABSLOCAL)/etc/sbuild.conf)
572 check::; $(call check-executable,WARN,/usr/local.schroot/hacks/apt-get)
573
574 SCHROOT_SCRIPTS         += 11private
575 SCHROOT_SCRIPTS         += 15binfmt
576 SCHROOT_SCRIPTS         += 51chrootenv
577 COPY_SCHROOT_SCRIPTS     = $(addprefix $(LOCAL)/etc/schroot/setup.d/,$(SCHROOT_SCRIPTS))
578 schroot-config:: $(COPY_SCHROOT_SCRIPTS)
579 $(COPY_SCHROOT_SCRIPTS): \
580                 $(LOCAL)/etc/schroot/setup.d/%: etc/schroot-scripts/%
581         $(V_AT)mkdir -p $(dir $@)
582         $(call v_tag,COPY)cp $< $@.new && mv $@.new $@
583 CLEANFILES              += $(COPY_SCHROOT_SCRIPTS)
584
585 CHECK_SCHROOT_SCRIPTS    = $(addprefix check-script/,$(SCHROOT_SCRIPTS))
586 check:: $(CHECK_SCHROOT_SCRIPTS)
587 $(CHECK_SCHROOT_SCRIPTS): check-script/%:
588         $(call check-symlink,WARN,/etc/schroot/setup.d/$*,$(ABSLOCAL)/etc/schroot/setup.d/$*)
589 .PHONY: $(addprefix check-script/,$(SCHROOT_SCRIPTS))
590
591 ###--------------------------------------------------------------------------
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 ###--------------------------------------------------------------------------
603 ### `/usr/local/' structure.
604
605 LOCAL_COMMON_DIRS        = share/ src/
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):
609         $(V_AT)mkdir -p $(dir $(patsubst %/,%,$@))
610         $(call v_tag,MKDIR)mkdir $@
611
612 LOCAL_ARCH_DIRS          = bin/ etc/ games/ include/ include.aside/
613 LOCAL_ARCH_DIRS         += lib/ libexec/ sbin/
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
639 ###--------------------------------------------------------------------------
640 ### Main chroot maintenance.
641
642 OPTS                     =
643 FRESH                    = 1w
644 JOBS                     = chroot cross-tools pkg-build
645
646 MAINTQ_                  = -q
647 MAINTQ_0                 = -q
648 MAINT                    = +$(call v_tag,MAINT)\
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
655
656 ###--------------------------------------------------------------------------
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 ###--------------------------------------------------------------------------
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 --------------------------------------------------