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="<date>" 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) <noreply@anthropic.com>
This commit is contained in:
Darryl L. Miles 2026-07-23 14:00:13 +00:00 committed by R. Timothy Edwards
parent 20911acc49
commit a9edf1a97d
3 changed files with 44 additions and 2 deletions

17
scripts/configure vendored
View File

@ -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

View File

@ -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

View File

@ -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@\"