Package: dpkg-dev
Followup-For: Bug #872381

Hello.
The attached commits rebase the suggestions, take your answers into
account and slightly improved some style issues.
There may remain typos, nothing is tested this time.
>From d56d5af7fa1a01a581d0cc1901572ca9c407f538 Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <nico...@debian.org>
Date: Mon, 29 Jul 2019 14:38:32 +0200
Subject: [PATCH 1/8] scripts/mk: stop hard-coding dpkg_datadir, protect from
 double inclusion

The Makefile snippets include each other from their common directory,
but the path differ during tests and after installation.  Instead of
rewriting the file with a hardcoded path, compute it within Make.

Use the same variables to avoid 'include' when possible, as it
involves system calls.

When setting dpkg_datadir, prefer 'ifndef' and ':=' to '?=', so that
the value is computed at most once.
---
 build-aux/subst.am         |  6 ------
 scripts/mk/Makefile.am     | 21 ---------------------
 scripts/mk/architecture.mk |  5 +++++
 scripts/mk/buildapi.mk     |  5 +++++
 scripts/mk/buildflags.mk   |  6 ++++++
 scripts/mk/buildopts.mk    |  5 +++++
 scripts/mk/buildtools.mk   | 11 ++++++++++-
 scripts/mk/default.mk      | 10 +++++++++-
 scripts/mk/pkg-info.mk     |  5 +++++
 scripts/mk/vendor.mk       | 11 ++++++++++-
 10 files changed, 55 insertions(+), 30 deletions(-)

diff --git a/build-aux/subst.am b/build-aux/subst.am
index 5515930d0..167a71257 100644
--- a/build-aux/subst.am
+++ b/build-aux/subst.am
@@ -39,9 +39,3 @@ SUFFIXES += .pl
 	@test -d `dirname $@` || $(MKDIR_P) `dirname $@`
 	$(do_perl_subst) <$< >$@
 	$(AM_V_at) chmod +x $@
-
-# Makefile support.
-
-do_make_subst = $(AM_V_GEN) $(SED) \
-	-e "s:dpkg_datadir[[:space:]]*=[[:space:]]*[^[:space:]]*:dpkg_datadir = $(pkgdatadir):" \
-	# EOL
diff --git a/scripts/mk/Makefile.am b/scripts/mk/Makefile.am
index 257ba5252..6e85e17b9 100644
--- a/scripts/mk/Makefile.am
+++ b/scripts/mk/Makefile.am
@@ -10,24 +10,3 @@ dist_pkgdata_DATA = \
 	pkg-info.mk \
 	vendor.mk \
 	# EOL
-
-SUFFIXES =
-
-include $(top_srcdir)/build-aux/subst.am
-
-# Ideally we'd use '$(SED) -i', but unfortunately that's not portable.
-install-data-hook:
-	$(do_make_subst) <$(DESTDIR)$(pkgdatadir)/default.mk \
-	                 >$(DESTDIR)$(pkgdatadir)/default.mk.new
-	mv $(DESTDIR)$(pkgdatadir)/default.mk.new \
-	   $(DESTDIR)$(pkgdatadir)/default.mk
-
-	$(do_make_subst) <$(DESTDIR)$(pkgdatadir)/buildtools.mk \
-	                 >$(DESTDIR)$(pkgdatadir)/buildtools.mk.new
-	mv $(DESTDIR)$(pkgdatadir)/buildtools.mk.new \
-	   $(DESTDIR)$(pkgdatadir)/buildtools.mk
-
-	$(do_make_subst) <$(DESTDIR)$(pkgdatadir)/vendor.mk \
-			 >$(DESTDIR)$(pkgdatadir)/vendor.mk.new
-	mv $(DESTDIR)$(pkgdatadir)/vendor.mk.new \
-	   $(DESTDIR)$(pkgdatadir)/vendor.mk
diff --git a/scripts/mk/architecture.mk b/scripts/mk/architecture.mk
index c11cada16..2ffcee287 100644
--- a/scripts/mk/architecture.mk
+++ b/scripts/mk/architecture.mk
@@ -2,6 +2,9 @@
 # DEB_BUILD_* variables that dpkg-architecture can return. Existing values
 # of those variables are preserved as per policy.
 
+ifndef dpkg_architecture.mk_included
+dpkg_architecture.mk_included :=
+
 dpkg_lazy_eval ?= $$(or $$(value DPKG_CACHE_$(1)),$$(eval DPKG_CACHE_$(1) := $$(shell $(2)))$$(value DPKG_CACHE_$(1)))
 
 dpkg_architecture_setvar = export $(1) ?= $(call dpkg_lazy_eval,$(1),dpkg-architecture -q$(1))
@@ -9,3 +12,5 @@ dpkg_architecture_setvar = export $(1) ?= $(call dpkg_lazy_eval,$(1),dpkg-archit
 $(foreach machine,BUILD HOST TARGET,\
   $(foreach var,ARCH ARCH_ABI ARCH_LIBC ARCH_OS ARCH_CPU ARCH_BITS ARCH_ENDIAN GNU_CPU GNU_SYSTEM GNU_TYPE MULTIARCH,\
     $(eval $(call dpkg_architecture_setvar,DEB_$(machine)_$(var)))))
+
+endif
diff --git a/scripts/mk/buildapi.mk b/scripts/mk/buildapi.mk
index 668e325c8..ba6b43543 100644
--- a/scripts/mk/buildapi.mk
+++ b/scripts/mk/buildapi.mk
@@ -1,5 +1,8 @@
 # This Makefile fragment (since dpkg 1.22.0) handles the build API.
 
+ifndef dpkg_buildapi.mk_included
+dpkg_buildapi.mk_included :=
+
 # Default API level when not set.
 DPKG_BUILD_API ?= $(shell dpkg-buildapi)
 
@@ -7,3 +10,5 @@ DPKG_BUILD_API ?= $(shell dpkg-buildapi)
 # complexity given no integer operators, given that we currently have to
 # fetch the build API level anyway.
 dpkg_build_api_ge = $(shell test "$(DPKG_BUILD_API)" -ge "$(1)" && echo yes)
+
+endif
diff --git a/scripts/mk/buildflags.mk b/scripts/mk/buildflags.mk
index 4b8a3d8c4..02baa53f2 100644
--- a/scripts/mk/buildflags.mk
+++ b/scripts/mk/buildflags.mk
@@ -28,6 +28,10 @@
 # You can also export them in the environment by setting
 # DPKG_EXPORT_BUILDFLAGS to a non-empty value.
 #
+
+ifndef dpkg_buildflags.mk_included
+dpkg_buildflags.mk_included :=
+
 # This list is kept in sync with the default set of flags returned
 # by dpkg-buildflags.
 
@@ -77,3 +81,5 @@ $(foreach flag,$(DPKG_BUILDFLAGS_LIST),\
 ifdef DPKG_EXPORT_BUILDFLAGS
   export $(DPKG_BUILDFLAGS_LIST)
 endif
+
+endif
diff --git a/scripts/mk/buildopts.mk b/scripts/mk/buildopts.mk
index c95777719..6787da76f 100644
--- a/scripts/mk/buildopts.mk
+++ b/scripts/mk/buildopts.mk
@@ -5,6 +5,11 @@
 #
 #   DEB_BUILD_OPTION_PARALLEL: the argument for the parallel=N option.
 
+ifndef dpkg_buildopts.mk_included
+dpkg_buildopts.mk_included :=
+
 ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
   DEB_BUILD_OPTION_PARALLEL = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
 endif
+
+endif
diff --git a/scripts/mk/buildtools.mk b/scripts/mk/buildtools.mk
index 933fdcfaa..90770a872 100644
--- a/scripts/mk/buildtools.mk
+++ b/scripts/mk/buildtools.mk
@@ -25,8 +25,15 @@
 # The variables are not exported by default. This can be changed by
 # defining DPKG_EXPORT_BUILDTOOLS.
 
-dpkg_datadir = $(srcdir)/mk
+ifndef dpkg_buildtools.mk_included
+dpkg_buildtools.mk_included :=
+
+ifndef dpkg_architecture.mk_included
+ifndef dpkg_datadir
+  dpkg_datadir := $(patsubst %/buildtools.mk,%,$(lastword $(MAKEFILE_LIST)))
+endif
 include $(dpkg_datadir)/architecture.mk
+endif
 
 # We set the TOOL_FOR_BUILD variables to the specified value, and the TOOL
 # variables (for the host) to their triplet-prefixed form iff they are
@@ -74,3 +81,5 @@ $(eval $(call dpkg_buildtool_setvar,AR,ar))
 $(eval $(call dpkg_buildtool_setvar,RANLIB,ranlib))
 $(eval $(call dpkg_buildtool_setvar,PKG_CONFIG,pkgconf))
 $(eval $(call dpkg_buildtool_setvar,QMAKE,qmake))
+
+endif
diff --git a/scripts/mk/default.mk b/scripts/mk/default.mk
index 0b2fd4aca..61921e30e 100644
--- a/scripts/mk/default.mk
+++ b/scripts/mk/default.mk
@@ -1,7 +1,13 @@
 # This Makefile fragment (since dpkg 1.16.1) includes all the Makefile
 # fragments that define variables that can be useful within debian/rules.
 
-dpkg_datadir = $(srcdir)/mk
+ifndef dpkg_default.mk_included
+dpkg_default.mk_included :=
+
+ifndef dpkg_datadir
+  dpkg_datadir := $(patsubst %/default.mk,%,$(lastword $(MAKEFILE_LIST)))
+endif
+
 include $(dpkg_datadir)/architecture.mk
 include $(dpkg_datadir)/buildapi.mk
 ifeq ($(call dpkg_build_api_ge,1),yes)
@@ -11,3 +17,5 @@ include $(dpkg_datadir)/buildflags.mk
 include $(dpkg_datadir)/buildopts.mk
 include $(dpkg_datadir)/pkg-info.mk
 include $(dpkg_datadir)/vendor.mk
+
+endif
diff --git a/scripts/mk/pkg-info.mk b/scripts/mk/pkg-info.mk
index bccde2317..5b38d84e9 100644
--- a/scripts/mk/pkg-info.mk
+++ b/scripts/mk/pkg-info.mk
@@ -13,6 +13,9 @@
 #     specified by <https://reproducible-builds.org/specs/source-date-epoch/>
 #     (since dpkg 1.18.8).
 
+ifndef dpkg_pkg-info.mk_included
+dpkg_pkg-info.mk_included :=
+
 dpkg_late_eval ?= $(or $(value DPKG_CACHE_$(1)),$(eval DPKG_CACHE_$(1) := $(shell $(2)))$(value DPKG_CACHE_$(1)))
 
 DEB_SOURCE = $(call dpkg_late_eval,DEB_SOURCE,dpkg-parsechangelog -SSource)
@@ -25,3 +28,5 @@ DEB_DISTRIBUTION = $(call dpkg_late_eval,DEB_DISTRIBUTION,dpkg-parsechangelog -S
 SOURCE_DATE_EPOCH ?= $(call dpkg_late_eval,SOURCE_DATE_EPOCH,dpkg-parsechangelog -STimestamp)
 
 export SOURCE_DATE_EPOCH
+
+endif
diff --git a/scripts/mk/vendor.mk b/scripts/mk/vendor.mk
index f3241a57b..0ef79dace 100644
--- a/scripts/mk/vendor.mk
+++ b/scripts/mk/vendor.mk
@@ -33,8 +33,15 @@
 #     ...
 #   endif
 
-dpkg_datadir = $(srcdir)/mk
+ifndef dpkg_vendor.mk_included
+dpkg_vendor.mk_included :=
+
+ifndef dpkg_buildapi.mk_included
+ifndef dpkg_datadir
+  dpkg_datadir := $(patsubst %/vendor.mk,%,$(lastword $(MAKEFILE_LIST)))
+endif
 include $(dpkg_datadir)/buildapi.mk
+endif
 
 dpkg_late_eval ?= $(or $(value DPKG_CACHE_$(1)),$(eval DPKG_CACHE_$(1) := $(shell $(2)))$(value DPKG_CACHE_$(1)))
 
@@ -49,3 +56,5 @@ dpkg_vendor_derives_from ?= $(dpkg_vendor_derives_from_v1)
 else
 dpkg_vendor_derives_from ?= $(dpkg_vendor_derives_from_v0)
 endif
+
+endif
-- 
2.39.2

>From e4e1d52459f1e53ccc604e10bf9591560506b39e Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <nico...@debian.org>
Date: Wed, 10 Jan 2024 18:11:55 +0100
Subject: [PATCH 2/8] scripts/t: use loops instead of repetitions, check
 exports and overrides

Replace copied lines with Make loops.

Add tests:
  architecture variable override,
  buildflags set and export,
  GCJFLAGS,
  buildtool override and export.
---
 scripts/t/mk/architecture.mk | 60 +++++++++++++++------------------
 scripts/t/mk/buildflags.mk   | 52 +++++++++++++++++------------
 scripts/t/mk/buildtools.mk   | 65 +++++++++++++++++++-----------------
 3 files changed, 91 insertions(+), 86 deletions(-)

diff --git a/scripts/t/mk/architecture.mk b/scripts/t/mk/architecture.mk
index 2ac0222ca..d511cc759 100644
--- a/scripts/t/mk/architecture.mk
+++ b/scripts/t/mk/architecture.mk
@@ -1,36 +1,28 @@
+DEB_BUILD_ARCH := overridden
+
 include $(srcdir)/mk/architecture.mk
 
-test:
-	test "$(DEB_BUILD_ARCH)" = "$(TEST_DEB_BUILD_ARCH)"
-	test "$(DEB_BUILD_ARCH_ABI)" = "$(TEST_DEB_BUILD_ARCH_ABI)"
-	test "$(DEB_BUILD_ARCH_BITS)" = "$(TEST_DEB_BUILD_ARCH_BITS)"
-	test "$(DEB_BUILD_ARCH_CPU)" = "$(TEST_DEB_BUILD_ARCH_CPU)"
-	test "$(DEB_BUILD_ARCH_ENDIAN)" = "$(TEST_DEB_BUILD_ARCH_ENDIAN)"
-	test "$(DEB_BUILD_ARCH_LIBC)" = "$(TEST_DEB_BUILD_ARCH_LIBC)"
-	test "$(DEB_BUILD_ARCH_OS)" = "$(TEST_DEB_BUILD_ARCH_OS)"
-	test "$(DEB_BUILD_GNU_CPU)" = "$(TEST_DEB_BUILD_GNU_CPU)"
-	test "$(DEB_BUILD_GNU_SYSTEM)" = "$(TEST_DEB_BUILD_GNU_SYSTEM)"
-	test "$(DEB_BUILD_GNU_TYPE)" = "$(TEST_DEB_BUILD_GNU_TYPE)"
-	test "$(DEB_BUILD_MULTIARCH)" = "$(TEST_DEB_BUILD_MULTIARCH)"
-	test "$(DEB_HOST_ARCH)" = "$(TEST_DEB_HOST_ARCH)"
-	test "$(DEB_HOST_ARCH_ABI)" = "$(TEST_DEB_HOST_ARCH_ABI)"
-	test "$(DEB_HOST_ARCH_BITS)" = "$(TEST_DEB_HOST_ARCH_BITS)"
-	test "$(DEB_HOST_ARCH_CPU)" = "$(TEST_DEB_HOST_ARCH_CPU)"
-	test "$(DEB_HOST_ARCH_ENDIAN)" = "$(TEST_DEB_HOST_ARCH_ENDIAN)"
-	test "$(DEB_HOST_ARCH_LIBC)" = "$(TEST_DEB_HOST_ARCH_LIBC)"
-	test "$(DEB_HOST_ARCH_OS)" = "$(TEST_DEB_HOST_ARCH_OS)"
-	test "$(DEB_HOST_GNU_CPU)" = "$(TEST_DEB_HOST_GNU_CPU)"
-	test "$(DEB_HOST_GNU_SYSTEM)" = "$(TEST_DEB_HOST_GNU_SYSTEM)"
-	test "$(DEB_HOST_GNU_TYPE)" = "$(TEST_DEB_HOST_GNU_TYPE)"
-	test "$(DEB_HOST_MULTIARCH)" = "$(TEST_DEB_HOST_MULTIARCH)"
-	test "$(DEB_TARGET_ARCH)" = "$(TEST_DEB_TARGET_ARCH)"
-	test "$(DEB_TARGET_ARCH_ABI)" = "$(TEST_DEB_TARGET_ARCH_ABI)"
-	test "$(DEB_TARGET_ARCH_BITS)" = "$(TEST_DEB_TARGET_ARCH_BITS)"
-	test "$(DEB_TARGET_ARCH_CPU)" = "$(TEST_DEB_TARGET_ARCH_CPU)"
-	test "$(DEB_TARGET_ARCH_ENDIAN)" = "$(TEST_DEB_TARGET_ARCH_ENDIAN)"
-	test "$(DEB_TARGET_ARCH_LIBC)" = "$(TEST_DEB_TARGET_ARCH_LIBC)"
-	test "$(DEB_TARGET_ARCH_OS)" = "$(TEST_DEB_TARGET_ARCH_OS)"
-	test "$(DEB_TARGET_GNU_CPU)" = "$(TEST_DEB_TARGET_GNU_CPU)"
-	test "$(DEB_TARGET_GNU_SYSTEM)" = "$(TEST_DEB_TARGET_GNU_SYSTEM)"
-	test "$(DEB_TARGET_GNU_TYPE)" = "$(TEST_DEB_TARGET_GNU_TYPE)"
-	test "$(DEB_TARGET_MULTIARCH)" = "$(TEST_DEB_TARGET_MULTIARCH)"
+vars := $(foreach machine,BUILD HOST TARGET,$(foreach var,\
+  ARCH \
+  ARCH_ABI \
+  ARCH_BITS \
+  ARCH_CPU \
+  ARCH_ENDIAN \
+  ARCH_LIBC \
+  ARCH_OS \
+  GNU_CPU \
+  GNU_SYSTEM \
+  GNU_TYPE \
+  MULTIARCH \
+  ,DEB_$(machine)_$(var)))
+loop_targets := $(filter-out DEB_BUILD_ARCH,$(vars))
+
+test: $(loop_targets)
+	test '$(DEB_BUILD_ARCH)' = 'overridden'
+	test "$${DEB_BUILD_ARCH}" = 'overridden'
+
+$(loop_targets):
+  # Test the Make variable.
+	test '$($@)' = '$(TEST_$@)'
+  # Test the exported shell variable.
+	test "$${$@}" = '$(TEST_$@)'
diff --git a/scripts/t/mk/buildflags.mk b/scripts/t/mk/buildflags.mk
index 94d85a7e0..44d312adc 100644
--- a/scripts/t/mk/buildflags.mk
+++ b/scripts/t/mk/buildflags.mk
@@ -1,26 +1,36 @@
 DEB_CPPFLAGS_MAINT_APPEND = -DTEST_MK=test-host
 DEB_CPPFLAGS_FOR_BUILD_MAINT_APPEND = -DTEST_MK=test-build
+DEB_CXXFLAGS_MAINT_SET := set
+DPKG_EXPORT_BUILDFLAGS := 1
 
 include $(srcdir)/mk/buildflags.mk
 
-test:
-	test "$(ASFLAGS)" = "$(TEST_ASFLAGS)"
-	test "$(ASFLAGS_FOR_BUILD)" = "$(TEST_ASFLAGS_FOR_BUILD)"
-	test "$(CFLAGS)" = "$(TEST_CFLAGS)"
-	test "$(CFLAGS_FOR_BUILD)" = "$(TEST_CFLAGS_FOR_BUILD)"
-	test "$(CPPFLAGS)" = "$(TEST_CPPFLAGS) -DTEST_MK=test-host"
-	test "$(CPPFLAGS_FOR_BUILD)" = "$(TEST_CPPFLAGS_FOR_BUILD)-DTEST_MK=test-build"
-	test "$(CXXFLAGS)" = "$(TEST_CXXFLAGS)"
-	test "$(CXXFLAGS_FOR_BUILD)" = "$(TEST_CXXFLAGS_FOR_BUILD)"
-	test "$(DFLAGS)" = "$(TEST_DFLAGS)"
-	test "$(DFLAGS_FOR_BUILD)" = "$(TEST_DFLAGS_FOR_BUILD)"
-	test "$(FCFLAGS)" = "$(TEST_FCFLAGS)"
-	test "$(FCFLAGS_FOR_BUILD)" = "$(TEST_FCFLAGS_FOR_BUILD)"
-	test "$(FFLAGS)" = "$(TEST_FFLAGS)"
-	test "$(FFLAGS_FOR_BUILD)" = "$(TEST_FFLAGS_FOR_BUILD)"
-	test "$(LDFLAGS)" = "$(TEST_LDFLAGS)"
-	test "$(LDFLAGS_FOR_BUILD)" = "$(TEST_LDFLAGS_FOR_BUILD)"
-	test "$(OBJCFLAGS)" = "$(TEST_OBJCFLAGS)"
-	test "$(OBJCFLAGS_FOR_BUILD)" = "$(TEST_OBJCFLAGS_FOR_BUILD)"
-	test "$(OBJCXXFLAGS)" = "$(TEST_OBJCXXFLAGS)"
-	test "$(OBJCXXFLAGS_FOR_BUILD)" = "$(TEST_OBJCXXFLAGS_FOR_BUILD)"
+vars := \
+  ASFLAGS \
+  CFLAGS \
+  DFLAGS \
+  FCFLAGS \
+  FFLAGS \
+  GCJFLAGS \
+  LDFLAGS \
+  OBJCFLAGS \
+  OBJCXXFLAGS \
+  # EOL
+loop_targets := $(vars) $(vars:=_FOR_BUILD)
+
+test: $(loop_targets)
+	test '$(CXXFLAGS)' = 'set'
+	test "$${CXXFLAGS}" = 'set'
+	test '$(CXXFLAGS_FOR_BUILD)' = 'set'
+	test "$${CXXFLAGS_FOR_BUILD}" = 'set'
+
+	test '$(CPPFLAGS)' = '$(TEST_CPPFLAGS) -DTEST_MK=test-host'
+	test "$${CPPFLAGS}" = '$(TEST_CPPFLAGS) -DTEST_MK=test-host'
+	test '$(CPPFLAGS_FOR_BUILD)' = '$(TEST_CPPFLAGS_FOR_BUILD) -DTEST_MK=test-build'
+	test "$${CPPFLAGS_FOR_BUILD}" = '$(TEST_CPPFLAGS_FOR_BUILD) -DTEST_MK=test-build'
+
+$(loop_targets):
+  # Test the Make variable.
+	test '$($@)' = '$(TEST_$@)'
+  # Test the exported shell variable.
+	test "$${$@}" = '$(TEST_$@)'
diff --git a/scripts/t/mk/buildtools.mk b/scripts/t/mk/buildtools.mk
index 6c27c5cf2..1df8f8b61 100644
--- a/scripts/t/mk/buildtools.mk
+++ b/scripts/t/mk/buildtools.mk
@@ -1,33 +1,36 @@
+AR := overridden
+DPKG_EXPORT_BUILDTOOLS := 1
+
 include $(srcdir)/mk/buildtools.mk
 
-test:
-	test "$(AS)" = "$(TEST_AS)"
-	test "$(AS_FOR_BUILD)" = "$(TEST_AS_FOR_BUILD)"
-	test "$(CC)" = "$(TEST_CC)"
-	test "$(CC_FOR_BUILD)" = "$(TEST_CC_FOR_BUILD)"
-	test "$(CXX)" = "$(TEST_CXX)"
-	test "$(CXX_FOR_BUILD)" = "$(TEST_CXX_FOR_BUILD)"
-	test "$(OBJC)" = "$(TEST_OBJC)"
-	test "$(OBJC_FOR_BUILD)" = "$(TEST_OBJC_FOR_BUILD)"
-	test "$(OBJCXX)" = "$(TEST_OBJCXX)"
-	test "$(OBJCXX_FOR_BUILD)" = "$(TEST_OBJCXX_FOR_BUILD)"
-	test "$(F77)" = "$(TEST_F77)"
-	test "$(F77_FOR_BUILD)" = "$(TEST_F77_FOR_BUILD)"
-	test "$(FC)" = "$(TEST_FC)"
-	test "$(FC_FOR_BUILD)" = "$(TEST_FC_FOR_BUILD)"
-	test "$(LD)" = "$(TEST_LD)"
-	test "$(LD_FOR_BUILD)" = "$(TEST_LD_FOR_BUILD)"
-	test "$(STRIP)" = "$(TEST_STRIP)"
-	test "$(STRIP_FOR_BUILD)" = "$(TEST_STRIP_FOR_BUILD)"
-	test "$(OBJCOPY)" = "$(TEST_OBJCOPY)"
-	test "$(OBJCOPY_FOR_BUILD)" = "$(TEST_OBJCOPY_FOR_BUILD)"
-	test "$(OBJDUMP)" = "$(TEST_OBJDUMP)"
-	test "$(OBJDUMP_FOR_BUILD)" = "$(TEST_OBJDUMP_FOR_BUILD)"
-	test "$(NM)" = "$(TEST_NM)"
-	test "$(NM_FOR_BUILD)" = "$(TEST_NM_FOR_BUILD)"
-	test "$(AR)" = "$(TEST_AR)"
-	test "$(AR_FOR_BUILD)" = "$(TEST_AR_FOR_BUILD)"
-	test "$(RANLIB)" = "$(TEST_RANLIB)"
-	test "$(RANLIB_FOR_BUILD)" = "$(TEST_RANLIB_FOR_BUILD)"
-	test "$(PKG_CONFIG)" = "$(TEST_PKG_CONFIG)"
-	test "$(PKG_CONFIG_FOR_BUILD)" = "$(TEST_PKG_CONFIG_FOR_BUILD)"
+tools := \
+  AS \
+  CC \
+  CPP \
+  CXX \
+  F77 \
+  FC \
+  GCJ \
+  LD \
+  NM \
+  OBJC \
+  OBJCOPY \
+  OBJCXX \
+  OBJDUMP \
+  PKG_CONFIG \
+  RANLIB \
+  STRIP \
+  # EOL
+loop_targets := $(tools) $(tools:=_FOR_BUILD)
+
+test: $(loop_targets)
+	test '$(AR)' = 'overridden'
+	test "$${AR}" = 'overridden'
+	test '$(AR_FOR_BUILD)' = 'overridden'
+	test "$${AR_FOR_BUILD}" = 'overridden'
+
+$(loop_targets):
+  # Test the Make variable.
+	test '$($@)' = '$(TEST_$@)'
+  # Test the exported shell variable.
+	test "$${$@}" = '$(TEST_$@)'
-- 
2.39.2

>From 9fc3d8c283b2ae6d582e10057b8424135f38661b Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <nico...@debian.org>
Date: Mon, 1 Nov 2021 10:08:08 +0100
Subject: [PATCH 3/8] scripts/mk/buildopts.mk: parse DEB_BUILD_OPTIONS once

Assign DEB_BUILD_OPTION_PARALLEL with := so that DEB_BUILD_OPTIONS is
not parsed every time DEB_BUILD_OPTION_PARALLEL is expanded.
---
 scripts/mk/buildopts.mk | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/scripts/mk/buildopts.mk b/scripts/mk/buildopts.mk
index 6787da76f..dd0cef852 100644
--- a/scripts/mk/buildopts.mk
+++ b/scripts/mk/buildopts.mk
@@ -4,12 +4,16 @@
 # Defines the following variables:
 #
 #   DEB_BUILD_OPTION_PARALLEL: the argument for the parallel=N option.
+#     Examples (the expansion is empty if parralel=N is not given):
+#     # $(MAKE) $(addprefix -j,$(DEB_BUILD_OPTION_PARALLEL))
+#     # SPHINXDOC += $(addprefix -j,$(DEB_BUILD_OPTION_PARALLEL))
 
 ifndef dpkg_buildopts.mk_included
 dpkg_buildopts.mk_included :=
 
-ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
-  DEB_BUILD_OPTION_PARALLEL = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+dpkg_buildopts.mk_parallel := $(filter parallel=%,$(DEB_BUILD_OPTIONS))
+ifneq (,$(dpkg_buildopts.mk_parallel))
+  DEB_BUILD_OPTIONS_PARALLEL := $(dpkg_buildopts.mk_parallel:parallel=%,%)
 endif
 
 endif
-- 
2.39.2

>From bdbb4ecf6d91efbfd0b8a48ca517b7a2603b0915 Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <nico...@debian.org>
Date: Wed, 10 Jan 2024 20:24:18 +0100
Subject: [PATCH 4/8] scripts/architecture.mk: reduce the number of
 subprocesses

Ensure that dpkg-architecture is only called when a
DEB_{HOST,ARCH_TARGET}_* variable is is expanded.

If so, call it once and cache all results for future expansions.
---
 scripts/mk/architecture.mk | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/scripts/mk/architecture.mk b/scripts/mk/architecture.mk
index 2ffcee287..174c5b638 100644
--- a/scripts/mk/architecture.mk
+++ b/scripts/mk/architecture.mk
@@ -5,12 +5,20 @@
 ifndef dpkg_architecture.mk_included
 dpkg_architecture.mk_included :=
 
-dpkg_lazy_eval ?= $$(or $$(value DPKG_CACHE_$(1)),$$(eval DPKG_CACHE_$(1) := $$(shell $(2)))$$(value DPKG_CACHE_$(1)))
-
-dpkg_architecture_setvar = export $(1) ?= $(call dpkg_lazy_eval,$(1),dpkg-architecture -q$(1))
-
+dpkg-architecture_vars := \
 $(foreach machine,BUILD HOST TARGET,\
   $(foreach var,ARCH ARCH_ABI ARCH_LIBC ARCH_OS ARCH_CPU ARCH_BITS ARCH_ENDIAN GNU_CPU GNU_SYSTEM GNU_TYPE MULTIARCH,\
-    $(eval $(call dpkg_architecture_setvar,DEB_$(machine)_$(var)))))
+    DEB_$(machine)_$(var)))
+
+# Spare a subprocess in the frequent case where dpkg-buildpackage
+# has already exported all variables.
+ifneq (,$(filter undefined,$(foreach v,$(dpkg-architecture_vars),$(origin $(v)))))
+
+  # ?= preserves overriddes from debian/rules or its command line.
+  $(foreach v,$(subst =,?=,$(shell dpkg-architecture)),$(eval $(v)))
+
+endif
+
+export $(dpkg-architecture_vars)
 
 endif
-- 
2.39.2

>From 7cfcad79ef7492d785764cf7f9b5ecb2b08a38a4 Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <nico...@debian.org>
Date: Wed, 10 Jan 2024 20:30:47 +0100
Subject: [PATCH 5/8] scripts/buildflags.mk: reduce the number of subprocesses

Ensure that dpkg-buildflags is only called when a *FLAGS variable is
is expanded.

If so, call it once and cache all results for future expansions.
---
 scripts/mk/buildflags.mk | 45 +++++++++++++++++++++++-----------------
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/scripts/mk/buildflags.mk b/scripts/mk/buildflags.mk
index 02baa53f2..f0d32d78c 100644
--- a/scripts/mk/buildflags.mk
+++ b/scripts/mk/buildflags.mk
@@ -26,8 +26,13 @@
 #   LDFLAGS_FOR_BUILD: flags for the build linker.
 #
 # You can also export them in the environment by setting
-# DPKG_EXPORT_BUILDFLAGS to a non-empty value.
+# DPKG_EXPORT_BUILDFLAGS.
 #
+# These variables are computed by dpkg-buildflags(1) and should not be
+# directly overridden.  The following setting are exported to
+# dpkg-buildflags.
+#   DEB_BUILD_{OPTIONS,MAINT_OPTIONS,PATH}
+#   DEB_*_MAINT_{APPEND,PREPEND,SET,STRIP}
 
 ifndef dpkg_buildflags.mk_included
 dpkg_buildflags.mk_included :=
@@ -35,31 +40,24 @@ dpkg_buildflags.mk_included :=
 # This list is kept in sync with the default set of flags returned
 # by dpkg-buildflags.
 
-dpkg_lazy_eval ?= $$(or $$(value DPKG_CACHE_$(1)),$$(eval DPKG_CACHE_$(1) := $$(shell $(2)))$$(value DPKG_CACHE_$(1)))
-
-DPKG_BUILDFLAGS_LIST = \
+DPKG_BUILDFLAGS_LIST := $(foreach var,\
   ASFLAGS \
-  ASFLAGS_FOR_BUILD \
   CFLAGS \
-  CFLAGS_FOR_BUILD \
   CPPFLAGS \
-  CPPFLAGS_FOR_BUILD \
   CXXFLAGS \
-  CXXFLAGS_FOR_BUILD \
   OBJCFLAGS \
-  OBJCFLAGS_FOR_BUILD \
   OBJCXXFLAGS \
-  OBJCXXFLAGS_FOR_BUILD \
+  GCJFLAGS \
   DFLAGS \
-  DFLAGS_FOR_BUILD \
   FFLAGS \
-  FFLAGS_FOR_BUILD \
   FCFLAGS \
-  FCFLAGS_FOR_BUILD \
   LDFLAGS \
-  LDFLAGS_FOR_BUILD \
-  # EOL
+  ,$(var) $(var)_FOR_BUILD)
+
+# Accumulate the parameters for dpkg-buildflags, in case it is ever
+# called.
 
+DPKG_BUILDFLAGS_EXPORT_ENVVAR :=
 define dpkg_buildflags_export_envvar
   ifdef $(1)
     DPKG_BUILDFLAGS_EXPORT_ENVVAR += $(1)="$$(value $(1))"
@@ -73,13 +71,22 @@ $(foreach flag,$(DPKG_BUILDFLAGS_LIST),\
   $(foreach operation,SET STRIP APPEND PREPEND,\
     $(eval $(call dpkg_buildflags_export_envvar,DEB_$(flag)_MAINT_$(operation)))))
 
-dpkg_buildflags_setvar = $(1) = $(call dpkg_lazy_eval,$(1),$(DPKG_BUILDFLAGS_EXPORT_ENVVAR) dpkg-buildflags --get $(1))
-
-$(foreach flag,$(DPKG_BUILDFLAGS_LIST),\
-  $(eval $(call dpkg_buildflags_setvar,$(flag))))
+# This variable is only expanded on demand, and we ensure that it
+# happens at most once..
+dpkg-buildflags_run = $(eval $(shell \
+  $(DPKG_BUILDFLAGS_EXPORT_ENVVAR) dpkg-buildflags \
+  | sed 's/^\([^=]*\)\(.*\)/$$(eval \1:\2)/'))
 
 ifdef DPKG_EXPORT_BUILDFLAGS
+  # We must compute all values right now.
+  $(dpkg-buildflags_run)
   export $(DPKG_BUILDFLAGS_LIST)
+else
+  # Only run a subprocess when a variable is actually used,
+  # but then replace each recursive definition with a non-recursive one
+  # (and of course return the asked value).
+  $(foreach var,$(DPKG_BUILDFLAGS_LIST),\
+    $(eval $(var) = $$(dpkg-buildflags_run)$$(var)))
 endif
 
 endif
-- 
2.39.2

>From 16911dded75b09712e65ee77928a3baeca34c58b Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <nico...@debian.org>
Date: Wed, 10 Jan 2024 20:33:27 +0100
Subject: [PATCH 6/8] scripts/pkg-info.mk: reduce the number of subprocesses

Ensure that dpkg-parsechangelog is only called at most once.

If so, call it once and cache all results for future expansions.
---
 scripts/mk/pkg-info.mk | 46 ++++++++++++++++++++++++++++++++++--------
 1 file changed, 38 insertions(+), 8 deletions(-)

diff --git a/scripts/mk/pkg-info.mk b/scripts/mk/pkg-info.mk
index 5b38d84e9..5b3fd5d8f 100644
--- a/scripts/mk/pkg-info.mk
+++ b/scripts/mk/pkg-info.mk
@@ -12,20 +12,50 @@
 #   SOURCE_DATE_EPOCH: source release date as seconds since the epoch, as
 #     specified by <https://reproducible-builds.org/specs/source-date-epoch/>
 #     (since dpkg 1.18.8).
+#     If it is undefined, the date of the latest changelog entry is used.
+#     In both cases, the value is exported.
 
 ifndef dpkg_pkg-info.mk_included
 dpkg_pkg-info.mk_included :=
 
-dpkg_late_eval ?= $(or $(value DPKG_CACHE_$(1)),$(eval DPKG_CACHE_$(1) := $(shell $(2)))$(value DPKG_CACHE_$(1)))
+# This variable is only expanded on demand, and we ensure that it
+# happens at most once..
+dpkg-parsechangelog_run = $(eval $(shell dpkg-parsechangelog \
+                                   | sed -n '$(dpkg-parsechangelog_sed)'))
 
-DEB_SOURCE = $(call dpkg_late_eval,DEB_SOURCE,dpkg-parsechangelog -SSource)
-DEB_VERSION = $(call dpkg_late_eval,DEB_VERSION,dpkg-parsechangelog -SVersion)
-DEB_VERSION_EPOCH_UPSTREAM = $(call dpkg_late_eval,DEB_VERSION_EPOCH_UPSTREAM,echo '$(DEB_VERSION)' | sed -e 's/-[^-]*$$//')
-DEB_VERSION_UPSTREAM_REVISION = $(call dpkg_late_eval,DEB_VERSION_UPSTREAM_REVISION,echo '$(DEB_VERSION)' | sed -e 's/^[0-9]*://')
-DEB_VERSION_UPSTREAM = $(call dpkg_late_eval,DEB_VERSION_UPSTREAM,echo '$(DEB_VERSION_EPOCH_UPSTREAM)' | sed -e 's/^[0-9]*://')
-DEB_DISTRIBUTION = $(call dpkg_late_eval,DEB_DISTRIBUTION,dpkg-parsechangelog -SDistribution)
+dpkg-parsechangelog_sed := \
+  s/^Source: \(.*\)/\
+    $$(eval DEB_SOURCE                    := \1)/p;\
+  s/^Version: \([0-9]*:\)\?\(.*\)\(-[^-]*\)$$/\
+    $$(eval DEB_VERSION                   := \1\2\3)\
+    $$(eval DEB_VERSION_EPOCH_UPSTREAM    := \1\2)\
+    $$(eval DEB_VERSION_UPSTREAM_REVISION := \2\3)\
+    $$(eval DEB_VERSION_UPSTREAM          := \2)/p;\
+  s/^Distribution: \(.*\)/\
+    $$(eval DEB_DISTRIBUTION              := \1)/p
 
-SOURCE_DATE_EPOCH ?= $(call dpkg_late_eval,SOURCE_DATE_EPOCH,dpkg-parsechangelog -STimestamp)
+ifdef SOURCE_DATE_EPOCH
+  # dpkg-buildpackage exports SOURCE_DATE_EPOCH.
+
+  # Only parse the changelog if a variable is actually used,
+  # but then replace each recursive definition with a non-recursive one
+  # (and of course return the asked value).
+  DEB_SOURCE                    = $(dpkg-parsechangelog_run)$(DEB_SOURCE)
+  DEB_VERSION                   = $(dpkg-parsechangelog_run)$(DEB_VERSION)
+  DEB_VERSION_EPOCH_UPSTREAM    = \
+    $(dpkg-parsechangelog_run)$(DEB_VERSION_EPOCH_UPSTREAM)
+  DEB_VERSION_UPSTREAM_REVISION = \
+    $(dpkg-parsechangelog_run)$(DEB_VERSION_UPSTREAM_REVISION)
+  DEB_VERSION_UPSTREAM          = \
+    $(dpkg-parsechangelog_run)$(DEB_VERSION_UPSTREAM)
+  DEB_DISTRIBUTION              = $(dpkg-parsechangelog_run)$(DEB_DISTRIBUTION)
+else
+  # We must run a subshell in order to compute SOURCE_DATE_EPOCH,
+  # so we may as well set all variables.
+  dpkg-parsechangelog_sed += \
+    ;s/^Timestamp: \(.*\)/$$(eval SOURCE_DATE_EPOCH:=\1)/p
+  $(dpkg-parsechangelog_run)
+endif
 
 export SOURCE_DATE_EPOCH
 
-- 
2.39.2

>From 8a71a6be34334983c23ba5edf80ac611497311e7 Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <nico...@debian.org>
Date: Wed, 10 Jan 2024 20:10:10 +0100
Subject: [PATCH 7/8] scripts/buildapi.mk: reduce the number of subprocesses

Ensure that dpkg-buildapi is only called at most once.

If so, call it once and cache the result for future expansions.
---
 scripts/mk/buildapi.mk | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/scripts/mk/buildapi.mk b/scripts/mk/buildapi.mk
index ba6b43543..1462866c7 100644
--- a/scripts/mk/buildapi.mk
+++ b/scripts/mk/buildapi.mk
@@ -4,7 +4,13 @@ ifndef dpkg_buildapi.mk_included
 dpkg_buildapi.mk_included :=
 
 # Default API level when not set.
-DPKG_BUILD_API ?= $(shell dpkg-buildapi)
+ifndef DPKG_BUILD_API
+  # Run dpkg-buildapi if the variable is actually expanded,
+  # but then replace the recursive definition with a non-recursive one
+  # (and of course return the asked value).
+  DPKG_BUILD_API = \
+    $$(eval DPKG_BUILD_API := $$(shell dpkg-buildapi))$$(DPKG_BUILD_API)
+endif
 
 # We could use only built-in GNU make functions, but that seems too much
 # complexity given no integer operators, given that we currently have to
-- 
2.39.2

>From e1ea3f3e5752f304b36140019293092b0564b771 Mon Sep 17 00:00:00 2001
From: Nicolas Boulenguez <nico...@debian.org>
Date: Sun, 13 Feb 2022 13:41:26 +0100
Subject: [PATCH 8/8] scripts/mk: improve details in documentation

architecture.mk: give more details
Mention default.mk as an alternative in included scripts.
Improve consistency accross Makefile snippets.
---
 scripts/mk/architecture.mk | 15 ++++++++++++---
 scripts/mk/buildflags.mk   |  5 +++--
 scripts/mk/buildopts.mk    |  7 +++----
 scripts/mk/buildtools.mk   |  5 +++--
 scripts/mk/pkg-info.mk     |  5 +++--
 scripts/mk/vendor.mk       |  5 +++--
 6 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/scripts/mk/architecture.mk b/scripts/mk/architecture.mk
index 174c5b638..a7e31cf16 100644
--- a/scripts/mk/architecture.mk
+++ b/scripts/mk/architecture.mk
@@ -1,6 +1,15 @@
-# This Makefile fragment (since dpkg 1.16.1) defines all the DEB_HOST_* and
-# DEB_BUILD_* variables that dpkg-architecture can return. Existing values
-# of those variables are preserved as per policy.
+# debian/rules helper defining the dpkg-architecture(1) variables.
+# (since dpkg 1.16.1)
+# Include this (or default.mk) if using DEB_{HOST,BUILD,TARGET}_*.
+#
+# These variables are usually computed by dpkg-buildpackage and simply
+# inherited by debian/rules, but need a definition when debian/rules
+# is invoked directly.
+#
+# Each variable may be overridden by the end user (on the debian/rules
+# command line) or by the maintainer (within debian/rules).
+#
+# All values are unconditionally exported.
 
 ifndef dpkg_architecture.mk_included
 dpkg_architecture.mk_included :=
diff --git a/scripts/mk/buildflags.mk b/scripts/mk/buildflags.mk
index f0d32d78c..a186e88d8 100644
--- a/scripts/mk/buildflags.mk
+++ b/scripts/mk/buildflags.mk
@@ -1,5 +1,6 @@
-# This Makefile fragment (since dpkg 1.16.1) defines the following host
-# variables:
+# debian/rules helper defining the dpkg-buildflags(1) variables.
+# Include this (or default.mk) if using
+# these host variables (since dpkg 1.16.1):
 #
 #   ASFLAGS: flags for the host assembler (since 1.21.0).
 #   CFLAGS: flags for the host C compiler.
diff --git a/scripts/mk/buildopts.mk b/scripts/mk/buildopts.mk
index dd0cef852..f3496f46e 100644
--- a/scripts/mk/buildopts.mk
+++ b/scripts/mk/buildopts.mk
@@ -1,7 +1,6 @@
-# This Makefile fragment (since dpkg 1.20.1) parses option arguments from
-# DEB_BUILD_OPTIONS, and exposes these as variables.
-#
-# Defines the following variables:
+# debian/rules helper extracting some arguments from DEB_BUILD_OPTIONS.
+# (since dpkg 1.20.1)
+# Include this (or default.mk) if using:
 #
 #   DEB_BUILD_OPTION_PARALLEL: the argument for the parallel=N option.
 #     Examples (the expansion is empty if parralel=N is not given):
diff --git a/scripts/mk/buildtools.mk b/scripts/mk/buildtools.mk
index 90770a872..e3f335a6b 100644
--- a/scripts/mk/buildtools.mk
+++ b/scripts/mk/buildtools.mk
@@ -1,5 +1,6 @@
-# This Makefile fragment (since dpkg 1.19.0) defines the following variables
-# for host tools:
+# debian/rules helper defining some host and build tools
+# (since dpkg 1.19.0)
+# Include this if using:
 #
 #   AS: assembler (since dpkg 1.19.1).
 #   CPP: C preprocessor.
diff --git a/scripts/mk/pkg-info.mk b/scripts/mk/pkg-info.mk
index 5b3fd5d8f..d9a4b4466 100644
--- a/scripts/mk/pkg-info.mk
+++ b/scripts/mk/pkg-info.mk
@@ -1,5 +1,6 @@
-# This Makefile fragment (since dpkg 1.16.1) defines the following package
-# information variables:
+# debian/rules helper defining some dpkg-parsechangelog(1) variables.
+# (since 1.16.1)
+# Include this (or default.mk) if using:
 #
 #   DEB_SOURCE: source package name.
 #   DEB_VERSION: package's full version (epoch + upstream vers. + revision).
diff --git a/scripts/mk/vendor.mk b/scripts/mk/vendor.mk
index 0ef79dace..35c508474 100644
--- a/scripts/mk/vendor.mk
+++ b/scripts/mk/vendor.mk
@@ -1,5 +1,6 @@
-# This Makefile fragment (since dpkg 1.16.1) defines the following
-# vendor-related variables:
+# debian/rules helper defining some dpkg-vendor(1) variables.
+# (since dpkg 1.16.1)
+# Include this (or default.mk) if using:
 #
 #   DEB_VENDOR: output of «dpkg-vendor --query Vendor».
 #   DEB_PARENT_VENDOR: output of «dpkg-vendor --query Parent» (can be empty).
-- 
2.39.2

Reply via email to