Makefile: Introduce and use some improved pathname manipulation functions.
[distorted-chroot] / Makefile
index 6870ddc..9b52893 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@
 ### Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 ### USA.
 
-all::
+all:
 clean::
 check::
 .PHONY: all clean check
@@ -38,13 +38,9 @@ CONFIG_VARS           =
 ## Level of pickiness to aspire to.
 NOTIFY_FATAL            = 1
 
-## Path to this working tree.
-CONFIG_VARS            += HERE
-HERE                    = $(abspath .)
-
 ## Volume group from which to allocate chroot volumes and snapshots.
 CONFIG_VARS            += VG LVPREFIX
-VG                      = vg-$(shell hostname)
+VG                     := vg-$(shell hostname)
 LVPREFIX                =
 
 ## Logical volume size, as an LVM option.
@@ -68,7 +64,7 @@ APTCONF                        = $(notdir $(wildcard etc/apt-conf.d/[0-9]*[!~]))
 
 ## Proxy setting.
 CONFIG_VARS            += PROXY
-PROXY                  := $(shell \
+PROXY                   = $(shell \
        eval $$(apt-config $(foreach a,$(APTCONF),-cetc/apt-conf.d/$a) \
                shell proxy Acquire::http::proxy); \
        case $${proxy+t} in (t) echo "$$proxy" ;; (*) echo nil ;; esac)
@@ -80,8 +76,8 @@ DISTS                  = $(PRIMARY_DIST) buster bullseye sid
 
 ## Host's native architecture(s).
 CONFIG_VARS            += MYARCH NATIVE_ARCHS
-MYARCH                  = $(shell dpkg --print-architecture)
-OTHERARCHS              = $(shell dpkg --print-foreign-architectures)
+MYARCH                 := $(shell dpkg --print-architecture)
+OTHERARCHS             := $(shell dpkg --print-foreign-architectures)
 NATIVE_ARCHS            = $(MYARCH) $(OTHERARCHS)
 
 ## Foreign (emulated) architectures to support.
@@ -138,7 +134,7 @@ CROSS_PATHS         += \
                sha256sum sha384sum sha512sum shred shuf sort split stat \
                stdbuf sum tac tail tee test timeout tr truncate tsort tty \
                unexpand uniq unlink users wc who whoami yes) \
-       /usr/lib/MULTI/coreutils/ \
+       ?/usr/lib/MULTI/coreutils/ \
        $(addprefix /lib/MULTI/, \
                libnsl.so.* libnss_*.so.*) \
        /usr/bin/gpgv \
@@ -159,7 +155,8 @@ CROSS_PATHS         += \
                $(addprefix /usr/bin/$a-, \
                        cpp gcc g++ gcov gcov-dump gcov-tool gprof \
                        gcc-ar gcc-nm gcc-ranlib) \
-               /usr/lib/gcc-cross/$a/)
+               /usr/lib/gcc-cross/$a/ \
+               /usr/$a/include/c++)
 
 ## Local packages to be compiled and installed in chroots.  Archives can be
 ## found in `pkg/'.
@@ -182,6 +179,10 @@ arm64_QEMUHOST              = $(64BIT_QEMUHOST)
 i386_QEMUHOST           = $(32BIT_QEMUHOST)
 amd64_QEMUHOST          = $(64BIT_QEMUHOST)
 
+## Which distribution of Qemu to use.
+CONFIG_VARS            += $(foreach d,$(DISTS),$d_QEMUDIST)
+stretch_QEMUDIST        = buster
+
 ## Qemu architecture names.  These tell us which Qemu binary to use for a
 ## particular Debian architecture.
 CONFIG_VARS            += $(foreach a,$(FOREIGN_ARCHS),$a_QEMUARCH)
@@ -208,8 +209,9 @@ STATE                        = state
 
 ## A directory which will be spliced into chroots as `/usr/local.schroot/'.
 ## This will be our primary point of contact with the chroot.
-CONFIG_VARS            += LOCAL
+CONFIG_VARS            += LOCAL ABSLOCAL
 LOCAL                   = local.schroot
+ABSLOCAL                = $(abspath $(LOCAL))
 
 ## How to run a command as a privileged user.
 CONFIG_VARS            += ROOTLY
@@ -263,6 +265,24 @@ CLEANFILES         += log/*.log
 SILENCE_LVM             = \
        LVM_SUPPRESS_FD_WARNINGS=1; export LVM_SUPPRESS_FD_WARNINGS
 
+##     $(call file-name,PATH)
+##
+## Strip any trailing `/' from the PATH.
+file-name               = $(1:/=)
+
+##     $(call base-name,PATH)
+##
+## Expand to the last component of PATH, whether or not it's a directory
+## name with a trailing `/'.
+base-name               = $(notdir $(call file-name,$1))
+
+##     $(call parent-dir,PATH)
+##
+## Expand to the parent directory of PATH, whether or not it's a directory
+## name with a trailing `/'.
+## `/'.
+parent-dir              = $(dir $(call file-name,$1))
+
 ##     $(call definedp,VAR)
 ##
 ## Expand non-empty if and only if VAR is defined (but possibly empty).
@@ -277,7 +297,8 @@ throwrc                      = { $1; echo $$? >&4; }
 ##     $(call squote,TXT)
 ##
 ## Single-quote TXT.
-squote                  = '$(subst ','\\'',$1)'
+squote                  = '$(subst ','\'',$1)'
+#'
 
 ##     $(call chroot-dist,D-A) -> D
 ##     $(call chroot-arch,D-A) -> A
@@ -413,7 +434,7 @@ $(PYEXT_ALLOBJ): $(STATE)/obj/%.o: src/%.c
        $(call v_tag,CC)$(CC) -c $(CFLAGS) $(PYEXT_CFLAGS) -o$@ $<
 
 PYMODULES               = $(foreach x,$(PYEXTS),$(STATE)/lib/python/$x.so)
-all:: $(PYMODULES)
+all: $(PYMODULES)
 $(PYMODULES): $(STATE)/lib/python/%.so: $$(call c-object,$$($$*_SOURCES))
        $(V_AT)mkdir -p $(dir $@)
        $(call v_tag,LD)$(LD) $(LDFLAGS) $(PYEXT_LDFLAGS) -o$@ $^
@@ -422,12 +443,10 @@ $(PYMODULES): $(STATE)/lib/python/%.so: $$(call c-object,$$($$*_SOURCES))
 ### Scripts.
 
 SCRIPTS                        += chroot-maint
-SCRIPTS                        += mkbuildchroot
 SCRIPTS                        += mkchrootconf
-SCRIPTS                        += install-cross-tools update-cross-tools
 
 SUBST_SCRIPTS           = $(addprefix $(STATE)/bin/,$(SCRIPTS))
-all:: $(SUBST_SCRIPTS)
+all: $(SUBST_SCRIPTS)
 $(SUBST_SCRIPTS): $(STATE)/bin/%: bin/% $(STATE)/config.sh
        $(V_AT)mkdir -p $(dir $@)
        $(call v_tag,SUBST){ \
@@ -445,7 +464,7 @@ $(SUBST_SCRIPTS): $(STATE)/bin/%: bin/% $(STATE)/config.sh
 ## In a chroot, `/etc/apt/sources.list' links to
 ## `/usr/local.schroot/etc/apt/sources.$d' for the appropriate distribution.
 APT_SOURCES             = $(foreach d,$(DISTS),$(LOCAL)/etc/apt/sources.$d)
-all:: $(APT_SOURCES)
+all: $(APT_SOURCES)
 
 $(foreach d,$(DISTS),$(STATE)/etc/apt/aptsrc.$d): $(STATE)/etc/apt/aptsrc.%:
        $(V_AT)mkdir -p $(dir $@)
@@ -466,7 +485,7 @@ CLEANFILES          += $(APT_SOURCES)
 ## In a chroot, a link `/etc/apt/apt.conf.d/FOO' is created for each file in
 ## `/usr/local.schroot/etc/apt/apt.conf.d/FOO'.
 APT_CONFIGS           = $(addprefix $(LOCAL)/etc/apt/apt.conf.d/,$(APTCONF))
-all:: $(APT_CONFIGS)
+all: $(APT_CONFIGS)
 $(APT_CONFIGS): $(LOCAL)/etc/apt/apt.conf.d/%: \
                $$(or $$(_$$*_APTCONFSRC) etc/apt-conf.d/$$*)
        $(V_AT)mkdir -p $(dir $@)
@@ -480,7 +499,7 @@ check::; $(call check-executable,ERR,/usr/bin/eatmydata)
 
 EATMYDATA_HACKS                += apt-get aptitude dpkg
 SYMLINK_EATMYDATA_HACKS         = $(addprefix $(LOCAL)/hacks/,$(EATMYDATA_HACKS))
-all:: $(SYMLINK_EATMYDATA_HACKS)
+all: $(SYMLINK_EATMYDATA_HACKS)
 $(SYMLINK_EATMYDATA_HACKS): $(LOCAL)/hacks/%: \
                $$(if $$(call symlink-ok-p,$$@,/usr/bin/eatmydata),,_force)
        $(V_AT)mkdir -p $(dir $@)
@@ -489,7 +508,7 @@ clean::; rm -f $(SYMLINK_EATMYDATA_HACKS)
 
 SCRIPT_HACKS           += buildwrap
 COPY_SCRIPT_HACKS       = $(addprefix $(LOCAL)/hacks/,$(SCRIPT_HACKS))
-all:: $(COPY_SCRIPT_HACKS)
+all: $(COPY_SCRIPT_HACKS)
 $(COPY_SCRIPT_HACKS): $(LOCAL)/hacks/%: bin/%
        $(V_AT)mkdir -p $(dir $@)
        $(call v_tag,COPY)cp $< $@.new && mv $@.new $@
@@ -498,8 +517,8 @@ clean::; rm -f $(COPY_SCRIPT_HACKS)
 ###--------------------------------------------------------------------------
 ### `schroot' and `sbuild' configuration.
 
-all:: schroot-config
-schroot-config::
+all: schroot-config
+schroot-config:
 .PHONY: schroot-config
 
 check::; $(call check-mountpoint,WARN,/var/lib/sbuild/build)
@@ -521,19 +540,19 @@ $(schroot-config_FILE):
        $(call v_tag,GEN)$(call %print-varlist,$(CONFIG_VARS)) \
                >$@.new && mv $@.new $@
 
-schroot-config:: $(STATE)/config.sh
+schroot-config: $(STATE)/config.sh
 $(STATE)/config.sh: $(schroot-config_FILE)
        $(call v_tag,SYMLINK)ln -sf $(notdir $<) $@
 
-schroot-config:: $(LOCAL)/etc/schroot/sbuild.schroot
+schroot-config: $(LOCAL)/etc/schroot/sbuild.schroot
 $(LOCAL)/etc/schroot/sbuild.schroot: $(STATE)/bin/mkchrootconf
        $(V_AT)mkdir -p $(dir $@)
        $(call v_tag,GEN)$(STATE)/bin/mkchrootconf >$@.new && \
                $(ROOTLY) chown root:root $@.new && mv $@.new $@
 CLEANFILES             += $(LOCAL)/etc/schroot/sbuild.schroot
-check::; $(call check-symlink,WARN,/etc/schroot/chroot.d/sbuild,$(HERE)/$(LOCAL)/etc/schroot/sbuild.schroot)
+check::; $(call check-symlink,WARN,/etc/schroot/chroot.d/sbuild,$(ABSLOCAL)/etc/schroot/sbuild.schroot)
 
-schroot-config:: $(LOCAL)/etc/schroot/sbuild.profile/copyfiles
+schroot-config: $(LOCAL)/etc/schroot/sbuild.profile/copyfiles
 $(LOCAL)/etc/schroot/sbuild.profile/copyfiles: $(schroot-config_STAMP)
        $(V_AT)mkdir -p $(dir $@)
        $(call v_tag,GEN){ \
@@ -542,7 +561,7 @@ $(LOCAL)/etc/schroot/sbuild.profile/copyfiles: $(schroot-config_STAMP)
        } >$@.new && mv $@.new $@
 CLEANFILES             += $(LOCAL)/etc/schroot/sbuild.profile/copyfiles
 
-schroot-config:: $(LOCAL)/etc/schroot/sbuild.profile/nssdatabases
+schroot-config: $(LOCAL)/etc/schroot/sbuild.profile/nssdatabases
 $(LOCAL)/etc/schroot/sbuild.profile/nssdatabases: $(schroot-config_STAMP)
        $(V_AT)mkdir -p $(dir $@)
        $(call v_tag,GEN){ \
@@ -551,7 +570,7 @@ $(LOCAL)/etc/schroot/sbuild.profile/nssdatabases: $(schroot-config_STAMP)
        } >$@.new && mv $@.new $@
 CLEANFILES             += $(LOCAL)/etc/schroot/sbuild.profile/nssdatabases
 
-schroot-config:: $(LOCAL)/etc/schroot/sbuild.profile/fstab
+schroot-config: $(LOCAL)/etc/schroot/sbuild.profile/fstab
 $(LOCAL)/etc/schroot/sbuild.profile/fstab: \
                etc/sbuild.fstab.in $(schroot-config_STAMP)
        $(V_AT)mkdir -p $(dir $@)
@@ -559,22 +578,22 @@ $(LOCAL)/etc/schroot/sbuild.profile/fstab: \
                <$< >$@.new && mv $@.new $@
 CLEANFILES             += $(LOCAL)/etc/schroot/sbuild.profile/fstab
 
-check::; $(call check-symlink,WARN,/etc/schroot/sbuild,$(HERE)/$(LOCAL)/etc/schroot/sbuild.profile)
+check::; $(call check-symlink,WARN,/etc/schroot/sbuild,$(ABSLOCAL)/etc/schroot/sbuild.profile)
 
-schroot-config:: $(LOCAL)/etc/sbuild.conf
+schroot-config: $(LOCAL)/etc/sbuild.conf
 $(LOCAL)/etc/sbuild.conf: etc/sbuild.conf.in $(schroot-config_STAMP)
        $(V_AT)mkdir -p $(dir $@)
        $(call v_tag,SUBST)$(call subst-file,### -*-perl-*-) \
                <$< >$@.new && mv $@.new $@
 CLEANFILES             += $(LOCAL)/etc/sbuild.conf
-check::; $(call check-symlink,WARN,/etc/sbuild/sbuild.conf,$(HERE)/$(LOCAL)/etc/sbuild.conf)
+check::; $(call check-symlink,WARN,/etc/sbuild/sbuild.conf,$(ABSLOCAL)/etc/sbuild.conf)
 check::; $(call check-executable,WARN,/usr/local.schroot/hacks/apt-get)
 
 SCHROOT_SCRIPTS                += 11private
 SCHROOT_SCRIPTS                += 15binfmt
 SCHROOT_SCRIPTS                += 51chrootenv
 COPY_SCHROOT_SCRIPTS    = $(addprefix $(LOCAL)/etc/schroot/setup.d/,$(SCHROOT_SCRIPTS))
-schroot-config:: $(COPY_SCHROOT_SCRIPTS)
+schroot-config: $(COPY_SCHROOT_SCRIPTS)
 $(COPY_SCHROOT_SCRIPTS): \
                $(LOCAL)/etc/schroot/setup.d/%: etc/schroot-scripts/%
        $(V_AT)mkdir -p $(dir $@)
@@ -584,23 +603,35 @@ CLEANFILES                += $(COPY_SCHROOT_SCRIPTS)
 CHECK_SCHROOT_SCRIPTS   = $(addprefix check-script/,$(SCHROOT_SCRIPTS))
 check:: $(CHECK_SCHROOT_SCRIPTS)
 $(CHECK_SCHROOT_SCRIPTS): check-script/%:
-       $(call check-symlink,WARN,/etc/schroot/setup.d/$*,$(HERE)/$(LOCAL)/etc/schroot/setup.d/$*)
+       $(call check-symlink,WARN,/etc/schroot/setup.d/$*,$(ABSLOCAL)/etc/schroot/setup.d/$*)
 .PHONY: $(addprefix check-script/,$(SCHROOT_SCRIPTS))
 
 ###--------------------------------------------------------------------------
+### Ccache setup.
+
+CCACHE_CONFIGS          = $(foreach r,$(ALL_CHROOTS), \
+       /var/lib/sbuild/build/.ccache/$(LVPREFIX)$r/ccache.conf)
+all: $(CCACHE_CONFIGS)
+$(CCACHE_CONFIGS): /var/lib/sbuild/build/.ccache/$(LVPREFIX)%/ccache.conf: \
+               etc/ccache.conf
+       $(V_AT)mkdir -p $(dir $@)
+       $(call v_tag,COPY)cp $< $@.new && mv $@.new $@
+
+###--------------------------------------------------------------------------
 ### `/usr/local/' structure.
 
 LOCAL_COMMON_DIRS       = share/ src/
 LOCAL_EXTRA_DIRS        = share/man/
-all:: $(foreach d,$(LOCAL_COMMON_DIRS) $(LOCAL_EXTRA_DIRS),$(LOCAL)/$d)
+all: $(foreach d,$(LOCAL_COMMON_DIRS) $(LOCAL_EXTRA_DIRS),$(LOCAL)/$d)
 $(foreach d,$(LOCAL_COMMON_DIRS) $(LOCAL_EXTRA_DIRS),$(LOCAL)/$d):
-       $(V_AT)mkdir -p $(dir $(patsubst %/,%,$@))
+       $(V_AT)mkdir -p $(call parent-dir $@)
        $(call v_tag,MKDIR)mkdir $@
 
-LOCAL_ARCH_DIRS                 = bin/ etc/ games/ include/ lib/ libexec/ sbin/
+LOCAL_ARCH_DIRS                 = bin/ etc/ games/ include/ include.aside/
+LOCAL_ARCH_DIRS                += lib/ libexec/ sbin/
 LOCAL_ARCH_LINKS        = man
 man_LINKDEST            = share/man
-all:: $(foreach a,$(ALL_ARCHS),\
+all: $(foreach a,$(ALL_ARCHS),\
        $(LOCAL)/$a/ \
        $(foreach d,$(LOCAL_ARCH_DIRS),$(LOCAL)/$a/$d) \
        $(foreach d,$(LOCAL_ARCH_LINKS),$(LOCAL)/$a/$d) \
@@ -610,29 +641,29 @@ $(foreach a,$(ALL_ARCHS),$(LOCAL)/$a/):
        $(call v_tag,MKDIR)mkdir $@
 $(foreach a,$(ALL_ARCHS),\
   $(foreach d,$(LOCAL_ARCH_DIRS),$(LOCAL)/$a/$d)):
-       $(V_AT)mkdir -p $(dir $(patsubst %/,%,$@))
+       $(V_AT)mkdir -p $(call parent-dir,$@)
        $(call v_tag,MKDIR)mkdir $@
 $(foreach a,$(ALL_ARCHS),\
   $(foreach d,$(LOCAL_ARCH_LINKS),$(LOCAL)/$a/$d)): \
-               $$(if $$(call symlink-ok-p,$$@,$$($$(notdir $$@)_LINKDEST)),,_force)
-       $(V_AT)mkdir -p $(notdir $@)
-       $(call v_tag,SYMLINK)ln -sf $($(notdir $@)_LINKDEST) $@
+               $$(if $$(call symlink-ok-p,$$@,$$($$(call base-name,$$@)_LINKDEST)),,_force) \
+       $(V_AT)mkdir -p $(call parent-dir,$@)
+       $(call v_tag,SYMLINK)ln -sf $($(call base-name,$@)_LINKDEST) $@
 $(foreach a,$(ALL_ARCHS),\
   $(foreach d,$(LOCAL_COMMON_DIRS),$(LOCAL)/$a/$d)): \
-               $$(if $$(call symlink-ok-p,$$@,../$$(notdir $$(patsubst %/,%,$$@))),,_force)
-       $(V_AT)mkdir -p $(dir $(patsubst %/,%,$@))
-       $(call v_tag,SYMLINK)ln -sf ../$(notdir $(patsubst %/,%,$@)) $(patsubst %/,%,$@)
+               $$(if $$(call symlink-ok-p,$$@,../$$(call base-name,$$@)),,_force) \
+       $(V_AT)mkdir -p $(call parent-dir,$@)
+       $(call v_tag,SYMLINK)ln -sf ../$(call base-name,$@) $(call file-name,$@)
 
 ###--------------------------------------------------------------------------
 ### Main chroot maintenance.
 
 OPTS                    =
-FRESH                   = create
+FRESH                   = 1w
 JOBS                    = chroot cross-tools pkg-build
 
 MAINTQ_                         = -q
 MAINTQ_0                = -q
-MAINT                   = +$(call v_tag,RUN)\
+MAINT                   = +$(call v_tag,MAINT)\
        PYTHONPATH=$(STATE)/lib/python $(STATE)/bin/chroot-maint \
                $(MAINTQ_$V) $(OPTS)
 
@@ -641,6 +672,19 @@ maint: all check
 .PHONY: maint
 
 ###--------------------------------------------------------------------------
+### Running random commands.
+
+CMD                     = echo %d %a
+subst-command           = $(subst %d,$(call chroot-dist,$1), \
+                               $(subst %a,$(call chroot-arch,$1), \
+                                       $(subst %r,$1, $(CMD))))
+
+run: $(foreach c,$(ALL_CHROOTS),run/$c)
+$(foreach c,$(ALL_CHROOTS),run/$c): run/%:
+       $(V_AT)$(call v_print,RUN,$(call subst-command,$*))\
+               $(call subst-command,$*)
+
+###--------------------------------------------------------------------------
 ### Other maintenance targets.
 
 show:; : $x