From a9edf1a97dc7271bf1cad30ae92fd53142793fdd Mon Sep 17 00:00:00 2001 From: "Darryl L. Miles" Date: Thu, 23 Jul 2026 14:00:13 +0000 Subject: [PATCH] build: add --disable-magic-builddate (reproducible, ccache-stable builds) New configure option --disable-magic-builddate omits the build date from the binary. It is wired via an AC_SUBST'd MAGIC_BUILDDATE_DEFS (not AC_DEFINE), so it reaches only buildinfo.o rather than @DEFS@ / every command line: * enabled (default): buildinfo.o gets -DMAGIC_BUILDDATE="" and defs.mak computes the date (SOURCE_DATE_EPOCH-aware); * disabled: buildinfo.o gets -DMAGIC_NO_BUILDDATE instead, defs.mak skips the date computation entirely (no parse-time `date` spawn), and buildinfo.c reports an empty MagicCompileTime. This gives a fully reproducible build whose one volatile input (the date) is gone; what remains in buildinfo.o is commit/version/revision, which do not change second-to-second -- the intended pairing with ccache for day-to-day development. Verified both configs: default bakes the date + commit; --disable-magic-builddate compiles buildinfo.o with -DMAGIC_NO_BUILDDATE (no date), commit still present. Co-Authored-By: Claude Opus 4.8 (1M context) --- scripts/configure | 17 +++++++++++++++++ scripts/configure.in | 17 ++++++++++++++++- scripts/defs.mak.in | 12 +++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/scripts/configure b/scripts/configure index 03985755..45d54f02 100755 --- a/scripts/configure +++ b/scripts/configure @@ -686,6 +686,7 @@ DOCS_TARGET DVIPS LATEX GCORE +MAGIC_BUILDDATE_DEFS ALLOCA EGREP GREP @@ -763,6 +764,7 @@ with_gnu_ld enable_assertions enable_debug enable_compression +enable_magic_builddate with_x with_distdir with_interpreter @@ -1426,6 +1428,7 @@ Optional Features: --enable-assertions build with fatal assertions enabled --enable-debug build with fatal debug enabled --disable-compression disable file compression + --disable-magic-builddate omit the build date from the binary (reproducible builds) --enable-memdebug enable memory debugging --enable-modular embed ext2sim and ext2spice packages --disable-locking disable file locking @@ -6069,6 +6072,20 @@ fi fi +# Check whether --enable-magic-builddate was given. +if test "${enable_magic_builddate+set}" = set; then : + enableval=$enable_magic_builddate; +else + enable_magic_builddate=yes +fi + +if test "x$enable_magic_builddate" = "xno" ; then + MAGIC_BUILDDATE_DEFS="-DMAGIC_NO_BUILDDATE" +else + MAGIC_BUILDDATE_DEFS="" +fi + + diff --git a/scripts/configure.in b/scripts/configure.in index 44709934..7db34e18 100644 --- a/scripts/configure.in +++ b/scripts/configure.in @@ -258,9 +258,24 @@ if test "x$enable_compression" = "xyes" ; then AC_CHECK_LIB([z],[gzopen],[ AC_DEFINE([HAVE_ZLIB],[1],["zlib compression"]) ZLIB_FLAG=" -lz" - ]) + ]) fi +dnl Allow the build date to be omitted from the binary (reproducible builds). +dnl Substituted (not AC_DEFINE'd) so it reaches only buildinfo.o, not @DEFS@ / +dnl every compile command line. When disabled, defs.mak also skips computing the +dnl date entirely (see MAGIC_BUILDDATE_DEFS in scripts/defs.mak.in). +AC_ARG_ENABLE(magic-builddate, +[ --disable-magic-builddate omit the build date from the binary (reproducible builds)], +[], +[enable_magic_builddate=yes]) +if test "x$enable_magic_builddate" = "xno" ; then + MAGIC_BUILDDATE_DEFS="-DMAGIC_NO_BUILDDATE" +else + MAGIC_BUILDDATE_DEFS="" +fi +AC_SUBST(MAGIC_BUILDDATE_DEFS) + dnl Check for some C99 functions dnl Built-in round/roundf require CFLAGS -std=c99, but this also diff --git a/scripts/defs.mak.in b/scripts/defs.mak.in index 9c74b950..48047db6 100755 --- a/scripts/defs.mak.in +++ b/scripts/defs.mak.in @@ -124,12 +124,19 @@ MAGIC_REVISION ?= $(shell cat ${MAGICSRC}/VERSION | cut -d. -f3) # 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) +# "-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. +ifeq (${MAGIC_BUILDDATE_DEFS},) # Honor SOURCE_DATE_EPOCH (reproducible builds -- appimage/npm tarballs) when set, # else the current time. UTC so the stamp does not depend on the builder's zone. MAGIC_BUILDDATE ?= $(shell if [ -n "$$SOURCE_DATE_EPOCH" ]; then \ date -u -d "@$$SOURCE_DATE_EPOCH" 2>/dev/null \ || date -u -r "$$SOURCE_DATE_EPOCH" 2>/dev/null; \ else date; fi | tr -d '\r\n') +endif # This allow inheritence of the values from toplevel Makefile export MAGIC_VERSION @@ -169,7 +176,10 @@ CXXFLAGS = @CXXFLAGS@ ifeq (@MAKE_READLINE@,1) CPPFLAGS += -I${MAGICSRC}/readline endif -DFLAGS_MAGICVERSION = -DMAGIC_VERSION=\"${MAGIC_VERSION}\" -DMAGIC_REVISION=\"${MAGIC_REVISION}\" -DMAGIC_COMMIT=\"${MAGIC_COMMIT}\" "-DMAGIC_BUILDDATE=\"${MAGIC_BUILDDATE}\"" +DFLAGS_MAGICVERSION = -DMAGIC_VERSION=\"${MAGIC_VERSION}\" -DMAGIC_REVISION=\"${MAGIC_REVISION}\" -DMAGIC_COMMIT=\"${MAGIC_COMMIT}\" ${MAGIC_BUILDDATE_DEFS} +ifeq (${MAGIC_BUILDDATE_DEFS},) +DFLAGS_MAGICVERSION += "-DMAGIC_BUILDDATE=\"${MAGIC_BUILDDATE}\"" +endif DFLAGS = @extra_defs@ @stub_defs@ @DEFS@ -DGCORE=\"@GCORE@\" DFLAGS += -DSHDLIB_EXT=\"@SHDLIB_EXT@\" @NDEBUG_defs@ @DEBUG_defs@ ${FEATURE_FLAGS} DFLAGS_NOSTUB = @extra_defs@ @DEFS@ -DGCORE=\"@GCORE@\"