3 ### Main maintenance script for chroots
5 ### (c) 2018 Mark Wooding
8 ###----- Licensing notice ---------------------------------------------------
10 ### This file is part of the distorted.org.uk chroot maintenance tools.
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.
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.
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,
30 .PHONY
: all clean check
31 .SECONDEXPANSION
: #sorry
33 ###--------------------------------------------------------------------------
38 ## Level of pickiness to aspire to.
41 ## Path to this working tree.
45 ## Volume group from which to allocate chroot volumes and snapshots.
46 CONFIG_VARS
+= VG LVPREFIX
47 VG
= vg-
$(shell hostname
)
50 ## Logical volume size, as an LVM option.
51 CONFIG_VARS
+= LVSZ SNAPOPT
56 CONFIG_VARS
+= DEBMIRROR
57 DEBMIRROR
= http
://deb.debian.org
/debian
/
59 ## APT sources configurations. (Also, $($d_APTSRC) for each $d in $(DISTS).)
61 APTSRC
= etc
/aptsrc.conf
$(wildcard etc
/aptsrc.local.conf
)
63 ## APT configuration fragment names. These will be linked into
64 ## `/etc/apt/apt.conf.d' in each chroot. To put a fragment f in a surprising
65 ## place, set $($f_APTCONFSRC).
66 CONFIG_VARS
+= APTCONF
67 APTCONF_DIR
= etc
/apt-conf.d
68 APTCONF
= $(notdir $(wildcard $(APTCONF_DIR
)/[0-9]*[!~
]))
73 eval
$$(apt-config
$(foreach a
,$(APTCONF
), -c
$(APTCONF_DIR
)/$a) \
74 shell proxy Acquire
::http
::proxy
); \
75 case
$${proxy
+t
} in
(t
) echo
"$$proxy" ;; (*) echo nil
;; esac
)
77 ## Debian distributions to support.
78 CONFIG_VARS
+= PRIMARY_DIST DISTS
79 PRIMARY_DIST
= stretch
80 DISTS
= $(PRIMARY_DIST
) buster bullseye sid
82 ## Host's native architecture(s).
83 CONFIG_VARS
+= MYARCH NATIVE_ARCHS
84 MYARCH
= $(shell dpkg
--print-architecture
)
85 OTHERARCHS
= $(shell dpkg
--print-foreign-architectures
)
86 NATIVE_ARCHS
= $(MYARCH
) $(OTHERARCHS
)
88 ## Foreign (emulated) architectures to support.
89 CONFIG_VARS
+= FOREIGN_ARCHS
92 ## Master lists of chroots to build and maintain.
93 NATIVE_CHROOTS
= $(foreach a
,$(NATIVE_ARCHS
), \
94 $(foreach d
,$(or
$($a_DISTS) $(DISTS
)), \
96 FOREIGN_CHROOTS
= $(foreach a
,$(FOREIGN_ARCHS
), \
97 $(foreach d
,$(or
$($a_DISTS) $(DISTS
)), \
100 ## Extra packages to be installed in chroots.
101 CONFIG_VARS
+= BASE_PACKAGES NATIVE_BASE_PACKAGES FOREIGN_BASE_PACKAGES
102 BASE_PACKAGES
= ccache
103 BASE_PACKAGES
+= eatmydata fakeroot
104 BASE_PACKAGES
+= locales tzdata
105 BASE_PACKAGES
+= libfile-fcntllock-perl
106 NATIVE_BASE_PACKAGES
= build-essential
107 FOREIGN_BASE_PACKAGES
=
109 ## Local packages to be compiled and installed in chroots. Archives can be
111 LOCALPKGS
= mLib checkpath
113 ## Which host architecture to use for foreign architectures. It turns out
114 ## that it's best to use a Qemu with the same host bitness as the target
115 ## architecture; otherwise it has to do a difficult job of converting
116 ## arguments and results between kernel ABI flavours.
117 32BIT_QEMUHOST
= $(or
$(filter i386
,$(NATIVE_ARCHS
)),$(TOOLSARCH
))
118 64BIT_QEMUHOST
= $(or
$(filter amd64
,$(NATIVE_ARCHS
)),$(TOOLSARCH
))
120 CONFIG_VARS
+= $(foreach a
,$(FOREIGN_ARCHS
), $a_QEMUHOST)
121 armel_QEMUHOST
= $(32BIT_QEMUHOST
)
122 armhf_QEMUHOST
= $(32BIT_QEMUHOST
)
123 arm64_QEMUHOST
= $(64BIT_QEMUHOST
)
124 i386_QEMUHOST
= $(32BIT_QEMUHOST
)
125 amd64_QEMUHOST
= $(64BIT_QEMUHOST
)
127 ## Qemu architecture names. These tell us which Qemu binary to use for a
128 ## particular Debian architecture.
129 CONFIG_VARS
+= $(foreach a
,$(FOREIGN_ARCHS
), $a_QEMUARCH)
132 arm64_QEMUARCH
= aarch64
134 amd64_QEMUARCH
= x86_64
136 ## Alias mapping for chroots.
137 CONFIG_VARS
+= $(foreach d
,$(DISTS
), $d_ALIASES)
138 stretch_ALIASES
= oldstable
139 buster_ALIASES
= stable
140 bullseye_ALIASE
= testing
141 sid_ALIASES
= unstable
143 ## Which host architecture to use for commonly used tools in foreign chroots.
144 CONFIG_VARS
+= TOOLSARCH
145 TOOLSARCH
= $(MYARCH
)
147 ## A directory in which we can maintain private files and state.
151 ## A directory which will be spliced into chroots as `/usr/local.schroot/'.
152 ## This will be our primary point of contact with the chroot.
154 LOCAL
= local.schroot
156 ## How to run a command as a privileged user.
159 ## Files to be copied into a chroot from the host.
160 SCHROOT_COPYFILES
= /etc
/resolv.conf
161 SCHROOT_NSSDATABASES
= passwd shadow group gshadow
163 ## Local configuration hook.
167 CONFIG_VARS
+= ALL_ARCHS ALL_CHROOTS
168 ALL_ARCHS
= $(NATIVE_ARCHS
) $(FOREIGN_ARCHS
)
169 ALL_CHROOTS
= $(NATIVE_CHROOTS
) $(FOREIGN_CHROOTS
)
171 ###--------------------------------------------------------------------------
174 ## Hack to force rebuilding.
178 ## Hack to not delimit function arguments. (Ugh!)
181 ## Silent-rules machinery.
185 v_print
= $(call v_print_
$V,$1,$2)
186 v_print_0
= printf
" %-8s %s\n" "$1" $(call squote
,$2);
187 v_tag
= $(V_AT
)$(call v_print
,$1,$@
)
188 v_log
= $(call v_log_
$V,$1,$2)
189 v_log_
= $(call v_log_1
,$1,$2)
190 v_log_0
= $2 >log
/$1.log
2>&1
191 v_log_1
= $(call catchrc
,$(call throwrc
,$2) 2>&1 | tee log
/$1.log
)
192 v_echo
= $(call v_echo_
$V,$1)
194 v_echo_1
= printf
"%s\n" $1
195 CLEANFILES
+= log
/*.log
199 LVM_SUPPRESS_FD_WARNINGS
=1; export LVM_SUPPRESS_FD_WARNINGS
201 ## $(call catchrc,...$(call throwrc,CMD)...)
203 ## Catch the exit status of some subpart of a complicated shell rune.
204 catchrc
= (exec
3>&1; exit
$$({ $1; } 4>&1 >&3 3>&-))
205 throwrc
= { $1; echo
$$?
>&4; }
207 ## $(call squote,TXT)
210 squote
= '$(subst ','\\'',$1)'
212 ## $(call chroot-dist,D-A) -> D
213 ## $(call chroot-arch,D-A) -> A
215 ## Parse chroot descriptions.
216 chroot-dist
= $(patsubst %/,%,$(dir $(subst -,/,$1)))
217 chroot-arch
= $(notdir $(subst -,/,$1))
219 ## $(call package-dir-name,P-V) -> P
220 ## $(call package-dir-version,P-V) -> V
222 ## Parse (source) package directory names.
223 package-dir-name
= $(sort $(foreach p
,$(LOCALPKGS
),$(if
$(filter $p-$($p_VERSION),$1),$p)))
224 package-dir-version
= $($(call package-dir-name
,$1)_VERSION
)
226 ## $(call package-dir,P-V.A) -> P-V
227 ## $(call package-name,P-V.A) -> P
228 ## $(call package-version,P-V.A) -> V
229 ## $(call package-arch,P-V.A) -> A
231 ## Parse package stamp names.
232 package-dir
= $(basename $1)
233 package-name
= $(call package-dir-name
,$(call package-dir
,$1))
234 package-version
= $(call package-dir-version
,$(call package-dir
,$1))
235 package-arch
= $(patsubst .
%,%,$(suffix $1))
237 ## $(call native-chroot-p,D-A) -> D | <empty>
239 ## Answer whether D-A is a native chroot.
240 native-chroot-p
= $(filter $(call chroot-arch
,$1),$(NATIVE_ARCHS
))
242 ## $(call chroot-qemuhost,D-A) -> AA
244 ## Answer the apporopriate Qemu host architecture for foreign chroot D-A.
245 chroot-qemuhost
= $($(call chroot-arch
,$1)_QEMUHOST
)
247 ## $(call chroot-deps,PRE,D-A) -> PREDD-AA ... | <empty>
249 ## Answer a list of additional dependencies for the chroot D-A: specifically,
250 ## if D-A is foreign then include PRE/DD-AA entries for the tools
251 ## architecture, and Qemu host architecture (if that's different).
252 chroot-deps
= $(if
$(call native-chroot-p
,$2),, \
253 $(addprefix $1$(call chroot-dist
,$2)-,\
254 $(sort $(TOOLSARCH
) \
255 $(call chroot-qemuhost
,$2))))
257 ## Substituting placeholders in files.
258 SUBSTITUTIONS
:= local
=$(shell realpath
$(LOCAL
))
259 SUBSTITUTIONS
+= primary-dist
=$(PRIMARY_DIST
)
261 echo
"$1 GENERATED by distorted-chroot: do not edit"; \
263 for v in
$(SUBSTITUTIONS
); do \
264 var
=$${v
%%=*} value
=$${v\
#*=}; \
265 substs
="$$substs s\a@$$var@\a$$value\ag;"; \
270 ### $(call symlink-ok-p,LINK,DEST)
272 ### Expand to `t' if LINK is a symbolic link to DEST, and empty otherwise.
273 symlink-ok-p
= $(shell \
274 case
$$(readlink
2>/dev
/null
$(patsubst %/,%,$1)) in
($2) echo t
;; esac
)
276 ### $(call general-notify,SEV,COLOUR,PREFIX,MSG)
278 ### Report a message, highlighted in the right way, and maybe fail
280 echo
"$$(tput bold; tput setaf $2)$3 "$4"$$(tput sgr0; tput op)"; \
281 if
[ "$1" -le
"$(NOTIFY_FATAL)" ]; then exit
2; fi
; \
284 ### $(call report/SEV,MSG)
286 ### Report a notification of a particular severity.
287 notify
/INFO
= $(call general-notify
,3,6,---,$1)
288 notify
/WARN
= $(call general-notify
,2,5,???
,$1)
289 notify
/ERR
= $(call general-notify
,1,1,!!!,$1)
291 ## $(call check,SEV,MSG,UNLESS)
293 ## If UNLESS completes successfully, all is OK; otherwise print MSG to stderr
296 $(call v_echo
,'check: '$(call squote
,$3)''); \
297 if
! { $3; }; then
$(call notify
/$1,$2); fi
; \
300 ## $(call check-executable,SEV,PATH)
302 ## Verify that PATH is an executable program.
303 check-executable
= $(call
check,$1,"\`$2' is not an executable", \
306 ## $(call check-mountpoint,SEV,DIR)
308 ## Verify that DIR is a mountpoint.
309 check-mountpoint
= $(call
check,$1,"\`$2' is not a mount point", \
312 ## $(call check-symlink,SEV,LINK,DEST)
314 ## Verify that LINK is a symbolic link pointing to DEST.
315 check-symlink
= $(call
check,$1,"\`$2' is not a link to \`$3'", \
316 [ -L
"$2" ] && [ "$$(readlink "$2")" = "$3" ])
318 ###--------------------------------------------------------------------------
319 ### Python extensions.
322 CFLAGS
= -O2
-g
-Wall
327 c-source
= $(foreach c
,$1,src
/$c)
328 c-object
= $(foreach c
,$1,$(STATE
)/obj
/$(basename $c).o
)
330 PYEXT_PKGFLAGS
:= $(shell pkg-config
--cflags python2
)
331 PYEXT_CFLAGS
= -fPIC
-fno-strict-aliasing
$(PYEXT_PKGFLAGS
)
332 PYEXT_LDFLAGS
= -shared
335 jobclient_SOURCES
= jobclient.c
337 PYEXT_ALLSRC
= $(foreach x
,$(PYEXTS
),\
338 $(call c-source
,$($x_SOURCES)))
339 PYEXT_ALLOBJ
= $(foreach x
,$(PYEXTS
),\
340 $(call c-object
,$($x_SOURCES)))
341 $(PYEXT_ALLOBJ
): $(STATE
)/obj
/%.o
: src
/%.c
342 $(V_AT
)mkdir
-p
$(dir $@
)
343 $(call v_tag
,CC
)$(CC
) -c
$(CFLAGS
) $(PYEXT_CFLAGS
) -o
$@
$<
345 PYMODULES
= $(foreach x
,$(PYEXTS
),$(STATE
)/lib
/python
/$x.so
)
347 $(PYMODULES
): $(STATE
)/lib
/python
/%.so
: $$(call c-object
,$$($$*_SOURCES
))
348 $(V_AT
)mkdir
-p
$(dir $@
)
349 $(call v_tag
,LD
)$(LD
) $(LDFLAGS
) $(PYEXT_LDFLAGS
) -o
$@
$^
351 ###--------------------------------------------------------------------------
354 SCRIPTS
+= mkbuildchroot
355 SCRIPTS
+= mkchrootconf
356 SCRIPTS
+= install-cross-tools update-cross-tools
358 SUBST_SCRIPTS
= $(addprefix $(STATE
)/bin
/,$(SCRIPTS
))
359 all:: $(SUBST_SCRIPTS
)
360 $(SUBST_SCRIPTS
): $(STATE
)/bin
/%: bin
/% $(STATE
)/config.sh
361 $(V_AT
)mkdir
-p
$(dir $@
)
362 $(call v_tag
,SUBST
){ \
364 -e
'2i### GENERATED by distorted-chroot: do not edit' \
365 -e
'/@@@config@@@/ {' \
366 -e
'r $(STATE)/config.sh' \
369 } >$@.new
&& chmod
+x
$@.new
&& mv
$@.new
$@
371 ###--------------------------------------------------------------------------
372 ### APT configuration.
374 ## In a chroot, `/etc/apt/sources.list' links to
375 ## `/usr/local.schroot/etc/apt/sources.$d' for the appropriate distribution.
376 APT_SOURCES
= $(foreach d
,$(DISTS
), $(LOCAL
)/etc
/apt
/sources.
$d)
379 $(foreach d
,$(DISTS
), $(STATE
)/etc
/apt
/aptsrc.
$d): $(STATE
)/etc
/apt
/aptsrc.
%:
380 $(V_AT
)mkdir
-p
$(dir $@
)
382 echo
"### -*-conf-*- GENERATED by distorted-chroot: do not edit"; \
384 echo
" debian : $*"; \
385 } >$@.new
&& mv
$@.new
$@
387 $(APT_SOURCES
): $(LOCAL
)/etc
/apt
/sources.
%: \
388 $$(APTSRC
) $$($$*_APTSRC
) $$(STATE
)/etc
/apt
/aptsrc.
$$*
389 $(V_AT
)mkdir
-p
$(dir $@
)
390 $(call v_tag
,GEN
)bin
/mkaptsrc \
391 $(APTSRC
) $($*_APTSRC
) $(STATE
)/etc
/apt
/aptsrc.
$* \
392 >$@.new
&& mv
$@.new
$@
393 CLEANFILES
+= $(APT_SOURCES
)
395 ## In a chroot, a link `/etc/apt/apt.conf.d/FOO' is created for each file in
396 ## `/usr/local.schroot/etc/apt/apt.conf.d/FOO'.
397 APT_CONFIGS
= $(addprefix $(LOCAL
)/etc
/apt
/apt.conf.d
/,$(APTCONF
))
399 $(APT_CONFIGS
): $(LOCAL
)/etc
/apt
/apt.conf.d
/%: \
400 $$(or
$$($$*_APTCONFSRC
) $$(APTCONF_DIR
)/$$*)
401 $(V_AT
)mkdir
-p
$(dir $@
)
402 $(call v_tag
,COPY
)cp
$< $@.new
&& mv
$@.new
$@
403 clean::; rm -f
$(APT_CONFIGS
)
405 ###--------------------------------------------------------------------------
408 check::; $(call check-executable
,ERR
,/usr
/bin
/eatmydata
)
410 EATMYDATA_HACKS
+= apt-get aptitude dpkg
411 SYMLINK_EATMYDATA_HACKS
= $(addprefix $(LOCAL
)/hacks
/,$(EATMYDATA_HACKS
))
412 all:: $(SYMLINK_EATMYDATA_HACKS
)
413 $(SYMLINK_EATMYDATA_HACKS
): $(LOCAL
)/hacks
/%: \
414 $$(if
$$(call symlink-ok-p
,$$@
,/usr
/bin
/eatmydata
),,_force
)
415 $(V_AT
)mkdir
-p
$(dir $@
)
416 $(call v_tag
,SYMLINK
)ln
-sf
/usr
/bin
/eatmydata
$@.new
&& mv
$@.new
$@
417 clean::; rm -f
$(SYMLINK_EATMYDATA_HACKS
)
419 SCRIPT_HACKS
+= buildwrap
420 COPY_SCRIPT_HACKS
= $(addprefix $(LOCAL
)/hacks
/,$(SCRIPT_HACKS
))
421 all:: $(COPY_SCRIPT_HACKS
)
422 $(COPY_SCRIPT_HACKS
): $(LOCAL
)/hacks
/%: bin
/%
423 $(V_AT
)mkdir
-p
$(dir $@
)
424 $(call v_tag
,COPY
)cp
$< $@.new
&& mv
$@.new
$@
425 clean::; rm -f
$(COPY_SCRIPT_HACKS
)
427 ###--------------------------------------------------------------------------
428 ### `schroot' and `sbuild' configuration.
432 .PHONY
: schroot-config
434 check::; $(call check-mountpoint
,WARN
,/var
/lib
/sbuild
/build
)
435 check::; $(call check-symlink
,WARN
,/build
,/var
/lib
/sbuild
/build
)
436 check::; $(call check-symlink
,ERR
,/schroot
,/run
/schroot
/mount
)
439 echo
"\#\#\# -*-sh-*- GENERATED by distorted-chroot: do not edit"; \
440 $(foreach v
,$1, echo
$v=\''$(subst ','\'\\\'\'',$($v))'\';) \
442 schroot-config_HASH
:= \
443 $(shell $(call
%print-varlist
,$(CONFIG_VARS
)) | \
444 sha256sum | cut
-c1-32
)
445 schroot-config_FILE
= $(STATE
)/config.sh-
$(schroot-config_HASH
)
446 $(schroot-config_FILE
):
447 $(V_AT
)mkdir
-p
$(STATE
)
448 $(V_AT
)rm -f
$(STATE
)/config.sh-
*
449 $(call v_tag
,STAMP
)$(call
%print-varlist
,$(CONFIG_VARS
)) \
450 >$@.new
&& mv
$@.new
$@
452 schroot-config
:: $(STATE
)/config.sh
453 $(STATE
)/config.sh
: $(schroot-config_FILE
)
454 $(call v_tag
,SYMLINK
)ln
-sf
$(notdir $<) $@
456 schroot-config
:: $(STATE
)/etc
/schroot
/sbuild.schroot
457 $(STATE
)/etc
/schroot
/sbuild.schroot
: $(STATE
)/bin
/mkchrootconf
458 $(V_AT
)mkdir
-p
$(dir $@
)
459 $(call v_tag
,GEN
)$(STATE
)/bin
/mkchrootconf
>$@.new
&& \
460 $(ROOTLY
) chown root
:root
$@.new
&& mv
$@.new
$@
461 check::; $(call check-symlink
,WARN
,/etc
/schroot
/chroot.d
/sbuild
,$(HERE
)/$(STATE
)/etc
/schroot
/sbuild.schroot
)
463 schroot-config
:: $(STATE
)/etc
/schroot
/sbuild.profile
/copyfiles
464 $(STATE
)/etc
/schroot
/sbuild.profile
/copyfiles
: $(schroot-config_STAMP
)
465 $(V_AT
)mkdir
-p
$(dir $@
)
467 echo
"### -*-conf-*- GENERATED by distorted-chroot: do not edit"; \
468 for i in
$(SCHROOT_COPYFILES
); do echo
"$$i"; done
; \
469 } >$@.new
&& mv
$@.new
$@
471 schroot-config
:: $(STATE
)/etc
/schroot
/sbuild.profile
/nssdatabases
472 $(STATE
)/etc
/schroot
/sbuild.profile
/nssdatabases
: $(schroot-config_STAMP
)
473 $(V_AT
)mkdir
-p
$(dir $@
)
475 echo
"### -*-conf-*- GENERATED by distorted-chroot: do not edit"; \
476 for i in
$(SCHROOT_NSSDATABASES
); do echo
"$$i"; done
; \
477 } >$@.new
&& mv
$@.new
$@
479 schroot-config
:: $(STATE
)/etc
/schroot
/sbuild.profile
/fstab
480 $(STATE
)/etc
/schroot
/sbuild.profile
/fstab
: \
481 etc
/sbuild.fstab.in
$(schroot-config_STAMP
)
482 $(V_AT
)mkdir
-p
$(dir $@
)
483 $(call v_tag
,SUBST
)$(call subst-file
,### -*-conf-*-) \
484 <$< >$@.new
&& mv
$@.new
$@
486 check::; $(call check-symlink
,WARN
,/etc
/schroot
/sbuild
,$(HERE
)/$(STATE
)/etc
/schroot
/sbuild.profile
)
488 schroot-config
:: $(STATE
)/etc
/sbuild.conf
489 $(STATE
)/etc
/sbuild.conf
: etc
/sbuild.conf.in
$(schroot-config_STAMP
)
490 $(V_AT
)mkdir
-p
$(dir $@
)
491 $(call v_tag
,SUBST
)$(call subst-file
,### -*-perl-*-) \
492 <$< >$@.new
&& mv
$@.new
$@
493 check::; $(call check-symlink
,WARN
,/etc
/sbuild
/sbuild.conf
,$(HERE
)/$(STATE
)/etc
/sbuild.conf
)
494 check::; $(call check-executable
,WARN
,/usr
/local.schroot
/hacks
/apt-get
)
496 SCHROOT_SCRIPTS
+= 11private
497 SCHROOT_SCRIPTS
+= 15binfmt
498 SCHROOT_SCRIPTS
+= 51chrootenv
499 COPY_SCHROOT_SCRIPTS
= $(addprefix $(STATE
)/etc
/schroot
/setup.d
/,$(SCHROOT_SCRIPTS
))
500 schroot-config
:: $(COPY_SCHROOT_SCRIPTS
)
501 $(COPY_SCHROOT_SCRIPTS
): \
502 $(STATE
)/etc
/schroot
/setup.d
/%: etc
/schroot-scripts
/%
503 $(V_AT
)mkdir
-p
$(dir $@
)
504 $(call v_tag
,COPY
)cp
$< $@.new
&& mv
$@.new
$@
506 CHECK_SCHROOT_SCRIPTS
= $(addprefix check-script
/,$(SCHROOT_SCRIPTS
))
507 check:: $(CHECK_SCHROOT_SCRIPTS
)
508 $(CHECK_SCHROOT_SCRIPTS
): check-script
/%:
509 $(call check-symlink
,WARN
,/etc
/schroot
/setup.d
/$*,$(HERE
)/$(STATE
)/etc
/schroot
/setup.d
/$*)
510 .PHONY
: $(addprefix check-script
/,$(SCHROOT_SCRIPTS
))
512 ###--------------------------------------------------------------------------
513 ### `/usr/local/' structure.
515 LOCAL_COMMON_DIRS
= share
/ src
/
516 all:: $(foreach d
,$(LOCAL_COMMON_DIRS
),$(LOCAL
)/$d)
517 $(foreach d
,$(LOCAL_COMMON_DIRS
),$(LOCAL
)/$d):
518 $(V_AT
)mkdir
-p
$(dir $(patsubst %/,%,$@
))
519 $(call v_tag
,MKDIR
)mkdir
$@
521 LOCAL_ARCH_DIRS
= bin
/ etc
/ games
/ include/ lib
/ libexec
/ sbin
/
522 LOCAL_ARCH_LINKS
= man
523 man_LINKDEST
= share
/man
524 all:: $(foreach a
,$(ALL_ARCHS
),\
526 $(foreach d
,$(LOCAL_ARCH_DIRS
),$(LOCAL
)/$a/$d) \
527 $(foreach d
,$(LOCAL_ARCH_LINKS
),$(LOCAL
)/$a/$d) \
528 $(foreach d
,$(LOCAL_COMMON_DIRS
),$(LOCAL
)/$a/$d))
530 $(foreach a
,$(ALL_ARCHS
),$(LOCAL
)/$a/):
531 $(call v_tag
,MKDIR
)mkdir
$@
532 $(foreach a
,$(ALL_ARCHS
),\
533 $(foreach d
,$(LOCAL_ARCH_DIRS
),$(LOCAL
)/$a/$d)):
534 $(V_AT
)mkdir
-p
$(dir $(patsubst %/,%,$@
))
535 $(call v_tag
,MKDIR
)mkdir
$@
536 $(foreach a
,$(ALL_ARCHS
),\
537 $(foreach d
,$(LOCAL_ARCH_LINKS
),$(LOCAL
)/$a/$d)): \
538 $$(if
$$(call symlink-ok-p
,$$@
,$$($$(notdir $$@
)_LINKDEST
)),,_force
)
539 $(V_AT
)mkdir
-p
$(notdir $@
)
540 $(call v_tag
,SYMLINK
)ln
-sf
$($(notdir $@
)_LINKDEST
) $@
541 $(foreach a
,$(ALL_ARCHS
),\
542 $(foreach d
,$(LOCAL_COMMON_DIRS
),$(LOCAL
)/$a/$d)): \
543 $$(if
$$(call symlink-ok-p
,$$@
,..
/$$(notdir $$(patsubst %/,%,$$@
))),,_force
)
544 $(V_AT
)mkdir
-p
$(dir $(patsubst %/,%,$@
))
545 $(call v_tag
,SYMLINK
)ln
-sf ..
/$(notdir $(patsubst %/,%,$@
)) $(patsubst %/,%,$@
)
547 ###--------------------------------------------------------------------------
548 ### Constructing chroots.
550 chroot-stamp
= $(addprefix $(STATE
)/stamp
/chroot.
,$1)
551 BUILD_CHROOTS
= $(addprefix chroot
/,$(ALL_CHROOTS
))
552 CHROOT_STAMPS
= $(call chroot-stamp
,$(ALL_CHROOTS
))
553 setup-chroots
: $(BUILD_CHROOTS
)
554 $(BUILD_CHROOTS
): chroot
/%: $(STATE
)/stamp
/chroot.
%
555 .PHONY
: setup-chroots
$(BUILD_CHROOTS
)
557 $(CHROOT_STAMPS
): $(STATE
)/stamp
/chroot.
%:
558 $(V_AT
)mkdir
-p
$(dir $@
) log
/
560 $(STATE
)/bin
/mkbuildchroot
$(STATE
)/bin
/install-cross-tools \
561 $(STATE
)/etc
/schroot
/sbuild.schroot \
562 $$(call chroot-deps
,$(STATE
)/stamp
/cross-tools.
,$$*)
563 $(call v_tag
,CHROOT
)$(call v_log
,setup-chroot.
$*, \
565 $(ROOTLY
) $(STATE
)/bin
/mkbuildchroot \
566 $(call chroot-dist
,$*) $(call chroot-arch
,$*))
569 UPDATE_CHROOTS
= $(addprefix update
/,$(ALL_CHROOTS
))
570 update-chroots
: $(UPDATE_CHROOTS
)
571 $(UPDATE_CHROOTS
): update
/%: $(STATE
)/stamp
/chroot.
%
573 $(MAKE
) $(STATE
)/bin
/install-cross-tools
574 $(call v_tag
,UPDATE
)$(call v_log
,update-chroot.
$*, { \
575 schroot
-uroot
-csource
:$(LVPREFIX
)$* -- \
577 schroot
-uroot
-csource
:$(LVPREFIX
)$* -- \
578 apt-get
-y dist-upgrade
&& \
579 schroot
-uroot
-csource
:$(LVPREFIX
)$* -- \
580 apt-get
-y autoremove
&& \
581 schroot
-uroot
-csource
:$(LVPREFIX
)$* -- \
582 apt-get
-y
clean && \
583 $(if
$(filter $*,$(FOREIGN_CHROOTS
)), \
584 $(ROOTLY
) $(STATE
)/bin
/install-cross-tools \
585 $(call chroot-dist
,$*) \
586 $(call chroot-arch
,$*), \
589 .PHONY
: update-chroots
$(UPDATE_CHROOTS
)
591 cross-tools-stamp
= $(addprefix $(STATE
)/stamp
/cross-tools.
,$1)
592 CROSS_TOOLS
= $(addprefix cross-tools
/,$(NATIVE_CHROOTS
))
593 UPDATE_CROSS_TOOLS
= $(addprefix update-cross-tools
/,$(NATIVE_CHROOTS
))
594 cross-tools
: $(CROSS_TOOLS
)
595 update-cross-tools
: $(UPDATE_CROSS_TOOLS
)
596 $(CROSS_TOOLS
): cross-tools
/%: $(STATE
)/stamp
/cross-tools.
%
599 $(MAKE
) $(STATE
)/bin
/update-cross-tools
600 $(call v_tag
,UPDCROSS
)$(call v_log
,update-cross-tools.
$*, \
601 $(STATE
)/bin
/update-cross-tools \
602 $(call chroot-dist
,$*) \
603 $(call chroot-arch
,$*))
604 $(V_AT
)touch
$(call cross-tools-stamp
,$*)
606 $(call cross-tools-stamp
,$(NATIVE_CHROOTS
)): $(STATE
)/stamp
/cross-tools.
%: \
607 $$(call chroot-stamp
,$$*)
608 $(V_AT
)mkdir
-p
$(dir $@
)
610 $(UPDATE_CROSS_TOOLS
): update-cross-tools
/%: \
611 $$(call chroot-stamp
,$$*) _force
613 .PHONY
: cross-tools update-cross-tools
$(CROSS_TOOLS
) $(UPDATE_CROSS_TOOLS
)
615 ###--------------------------------------------------------------------------
616 ### Installing basic custom software.
618 $(foreach p
,$(LOCALPKGS
), $(eval
$p_VERSION := $(shell \
619 set
-- pkg
/$p-[0-9]*.
tar.gz
; \
621 (1,*\
**) echo
"NOT-FOUND"; exit
2 ;; \
622 (1,*) v
=$${1#pkg/$p-}; v=$${v%.tar.gz}; echo "$$v" ;; \
623 (*) echo
"AMBIGUOUS"; exit
2 ;; \
627 $(foreach p
,$1,$(STATE
)/stamp
/package.
$p-$($p_VERSION).
$2)
629 $(foreach p
,$1,$(STATE
)/stamp
/unpack.
$p-$($p_VERSION))
631 $(foreach a
,$(ALL_ARCHS
),$(call pkg-stamp
,$(LOCALPKGS
),$a))
632 INSTALL_PACKAGES
= $(addprefix install/,$(LOCALPKGS
))
633 install-packages
: $(INSTALL_PACKAGES
)
634 $(INSTALL_PACKAGES
): install/%: \
635 $$(foreach a
,$$(ALL_ARCHS
),$$(call pkg-stamp
,$$*,$$a))
637 $(foreach p
,$(LOCALPKGS
),$(call unpack-pkg-stamp
,$p)): \
638 $(STATE
)/stamp
/unpack.
%: pkg
/%.
tar.gz
639 $(V_AT
)mkdir
-p
$(dir $@
) $(LOCAL
)/src
/
640 $(call v_tag
,UNPACK
){ \
642 p
=$(call package-dir-name
,$*); \
643 v
=$(call package-dir-version
,$*); \
645 $(ROOTLY
) rm -rf
$$p-*; \
646 mkdir
$$p-$$v.unpack
; \
647 (cd
$$p-$$v.unpack
&& tar xf
$(HERE
)/$<); \
648 mv
$$p-$$v.unpack
/$$p-$$v $$p-$$v; \
649 rmdir
$$p-$$v.unpack
/; \
654 $(PACKAGE_STAMPS
): $(STATE
)/stamp
/package.
%: \
655 $$(call unpack-pkg-stamp
,$$(call package-name
,$$*)) \
656 $$(call chroot-stamp
,$$(PRIMARY_DIST
)-$$(call package-arch
,$$*))
657 $(V_AT
)mkdir
-p
$(dir $@
) log
/
658 $(call v_tag
,BUILD
)$(call v_log
,install-package.
$*, { \
660 schroot
-uroot
-c
$(LVPREFIX
)$(PRIMARY_DIST
)-$(call package-arch
,$*) -- \
662 mount -oremount$(comma)rw /usr/local.schroot; \
663 eatmydata apt-get update; \
664 eatmydata apt-get -y install pkg-config; \
665 p=$(call package-name,$*); \
666 v=$(call package-version,$*); \
667 a=$(call package-arch,$*); \
668 cd /usr/local/src/$$p-$$v/; \
672 ../configure PKG_CONFIG_PATH=/usr/local/lib/pkgconfig.hidden; \
675 mkdir -p /usr/local/lib/pkgconfig.hidden; \
676 mv /usr/local/lib/pkgconfig/*.pc /usr/local/lib/pkgconfig.hidden || :' && \
677 schroot
-uroot
-csource
:$(LVPREFIX
)$(PRIMARY_DIST
)-$(call package-arch
,$*) -- \
682 ###--------------------------------------------------------------------------
683 ### Other maintenance targets.
694 ###----- That's all, folks --------------------------------------------------