From c00707d44941b2a8fed9802a91dd443e58d78f5d Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 30 Jun 2016 10:05:40 +0100 Subject: [PATCH] Override __DATE__ from SOURCE_DATE_EPOCH if set For deterministic/reproducible builds (where the same source and toolchain can be verified to produce the same binary, allowing maliciously substituted binaries to be detected) it is desirable to take the software's idea of the build date from the build system; otherwise, the real-time clock at the time of building affects the result, making it non-reproducible. SOURCE_DATE_EPOCH is a distribution-neutral specification for how to do that. It is meant to be set by meta-build systems such as dpkg or RPM, using a date/time that is already part of the source code, for example the date of the latest git commit, the date in the package's debian/changelog, or the date in the RPM spec file. See https://reproducible-builds.org/specs/source-date-epoch/ for the specification of SOURCE_DATE_EPOCH, or https://reproducible-builds.org/ for more information on reproducible builds in general. --- Makefile | 7 +++++++ src/common/header/common.h | 4 ++++ src/common/misc.c | 2 +- src/game/savegame/savegame.c | 4 ++-- 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 05c06ad7..a8e814c3 100755 --- a/Makefile +++ b/Makefile @@ -165,6 +165,13 @@ CFLAGS += -DOSTYPE=\"$(OSTYPE)\" -DARCH=\"$(ARCH)\" # ---------- +# https://reproducible-builds.org/specs/source-date-epoch/ +ifdef SOURCE_DATE_EPOCH +CFLAGS += -DBUILD_DATE=\"$(shell date --utc --date="@${SOURCE_DATE_EPOCH}" +"%b %_d %Y" | sed -e 's/ /\\ /g')\" +endif + +# ---------- + # Systemwide installation ifeq ($(WITH_SYSTEMWIDE),yes) CFLAGS += -DSYSTEMWIDE diff --git a/src/common/header/common.h b/src/common/header/common.h index 8a518863..ea84285e 100644 --- a/src/common/header/common.h +++ b/src/common/header/common.h @@ -44,6 +44,10 @@ #error ARCH should be defined by the build system #endif +#ifndef BUILD_DATE +#define BUILD_DATE __DATE__ +#endif + #ifdef _WIN32 #define CFGDIR "YamagiQ2" #else diff --git a/src/common/misc.c b/src/common/misc.c index 98a90e51..7589b159 100644 --- a/src/common/misc.c +++ b/src/common/misc.c @@ -241,7 +241,7 @@ Qcommon_Init(int argc, char **argv) dedicated = Cvar_Get("dedicated", "0", CVAR_NOSET); #endif - s = va("%s %s %s %s", YQ2VERSION, ARCH, __DATE__, OSTYPE); + s = va("%s %s %s %s", YQ2VERSION, ARCH, BUILD_DATE, OSTYPE); Cvar_Get("version", s, CVAR_SERVERINFO | CVAR_NOSET); if (dedicated->value) diff --git a/src/game/savegame/savegame.c b/src/game/savegame/savegame.c index 9dc08784..e60427f0 100644 --- a/src/game/savegame/savegame.c +++ b/src/game/savegame/savegame.c @@ -207,7 +207,7 @@ void InitGame(void) { gi.dprintf("Game is starting up.\n"); - gi.dprintf("Game is %s built on %s.\n", GAMEVERSION, __DATE__); + gi.dprintf("Game is %s built on %s.\n", GAMEVERSION, BUILD_DATE); gun_x = gi.cvar("gun_x", "0", 0); gun_y = gi.cvar("gun_y", "0", 0); @@ -223,7 +223,7 @@ InitGame(void) /* latched vars */ sv_cheats = gi.cvar("cheats", "0", CVAR_SERVERINFO | CVAR_LATCH); gi.cvar("gamename", GAMEVERSION, CVAR_SERVERINFO | CVAR_LATCH); - gi.cvar("gamedate", __DATE__, CVAR_SERVERINFO | CVAR_LATCH); + gi.cvar("gamedate", BUILD_DATE, CVAR_SERVERINFO | CVAR_LATCH); maxclients = gi.cvar("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH); maxspectators = gi.cvar("maxspectators", "4", CVAR_SERVERINFO); deathmatch = gi.cvar("deathmatch", "0", CVAR_LATCH);