From 0aacd546c9aabc87242d105fd18169db40dcc8c0 Mon Sep 17 00:00:00 2001 From: "Darryl L. Miles" Date: Thu, 23 Jul 2026 15:42:19 +0000 Subject: [PATCH] build: compute version/commit/date once, not per sub-make recursion MAGIC_VERSION/REVISION/COMMIT/BUILDDATE used `?=` with `$(shell ...)`, which makes them recursively-expanded. Because they are exported, make re-evaluated (re-spawned git/date/cat) every time it built a child's environment -- so a no-op recursive `make` spawned git and date ~624 times each. Guard each with `ifndef` and assign with `:=` (simply-expanded) so the value is computed once at the top and exported as a plain string; sub-makes inherit it and the ifndef skips recomputation. This was the last "fold in" item from the buildinfo/ccache plan. Verified: a no-op `make` now spawns git and date once each (was 624); a full clean build spawns 1 git / 2 date / 10 cat; the commit is still embedded correctly and builds are reproducible. Co-Authored-By: Claude Opus 4.8 (1M context) --- scripts/defs.mak.in | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/scripts/defs.mak.in b/scripts/defs.mak.in index e9563f63..aa738031 100755 --- a/scripts/defs.mak.in +++ b/scripts/defs.mak.in @@ -119,27 +119,40 @@ LIB_SPECS_GRNULL = @LIB_SPECS_GRNULL@ WISH_EXE = @WISH_EXE@ TCL_LIB_DIR = @TCL_LIB_DIR@ -MAGIC_VERSION ?= $(shell cat ${MAGICSRC}/VERSION | cut -d. -f1-2) -MAGIC_REVISION ?= $(shell cat ${MAGICSRC}/VERSION | cut -d. -f3) +# Computed once, simply-expanded (:=), and exported below. Sub-makes inherit the +# resulting strings and the `ifndef` guards skip recomputation -- so git/date/cat +# run once at the top instead of being re-spawned every time make rebuilds the +# recursively-expanded export for a child (a no-op recursive make otherwise spawns +# each of them hundreds of times). +ifndef MAGIC_VERSION +MAGIC_VERSION := $(shell cat ${MAGICSRC}/VERSION | cut -d. -f1-2) +endif +ifndef MAGIC_REVISION +MAGIC_REVISION := $(shell cat ${MAGICSRC}/VERSION | cut -d. -f3) +endif # git may be absent (source tarball) or ${MAGICSRC} not a work-tree: fall back to # empty rather than emitting an error. -MAGIC_COMMIT ?= $(shell git -C ${MAGICSRC} rev-parse HEAD 2>/dev/null) +ifndef MAGIC_COMMIT +MAGIC_COMMIT := $(shell git -C ${MAGICSRC} rev-parse HEAD 2>/dev/null) +endif # "-DMAGIC_NO_BUILDDATE" when configured with --disable-magic-builddate, else # empty. buildinfo.c reports an empty MagicCompileTime under that define. MAGIC_BUILDDATE_DEFS = @MAGIC_BUILDDATE_DEFS@ # Only compute the (volatile) build date when it will actually be baked in -- -# skipping it under --disable-magic-builddate avoids the parse-time date spawn. +# skipping it under --disable-magic-builddate avoids the date spawn entirely. ifeq (${MAGIC_BUILDDATE_DEFS},) +ifndef MAGIC_BUILDDATE # Honor SOURCE_DATE_EPOCH (reproducible builds -- appimage/npm tarballs) when set, # else the current time. @SOURCE_DATE_CMD@ is the platform's epoch->UTC-date # invocation, chosen by configure (GNU `date -u -d @` / `gdate` vs BSD # `date -u -r `); the epoch is appended here. The SOURCE_DATE_EPOCH branch is # UTC so a reproducible stamp does not depend on the builder's zone; the plain # `date` fallback is local. -MAGIC_BUILDDATE ?= $(shell if [ -n "$$SOURCE_DATE_EPOCH" ]; then \ +MAGIC_BUILDDATE := $(shell if [ -n "$$SOURCE_DATE_EPOCH" ]; then \ @SOURCE_DATE_CMD@$$SOURCE_DATE_EPOCH; \ else date; fi | tr -d '\r\n') endif +endif # This allow inheritence of the values from toplevel Makefile export MAGIC_VERSION