From 6e411084a29a7658f7bc88aa5a62ab9016c22c79 Mon Sep 17 00:00:00 2001 From: Phil Pennock Date: Wed, 12 Apr 2017 23:22:36 -0400 Subject: [PATCH] $SOURCE_DATE_EPOCH support for build date stamp If, and _only_ if, $SOURCE_DATE_EPOCH is found in environ during build, use it to set the timestamp embedded in the binary instead of using __DATE__ and __TIME__ cpp directives. This per spec. It's sane and sensible, without removing date stamping which matters. The examples encourage packagers to use timestamps which do change when they backport patches, so that the date remains useful for distinguishing builds instead of claiming one date forever across multiple patchlevels. This change written so that the old behaviour and code is used if the environment variable is not found, to better continue to support ancient platforms with other variants of date(1). Built with and without an override, on macOS. --- doc/doc-txt/ChangeLog | 3 +++ doc/doc-txt/NewStuff | 3 +++ src/scripts/reversion | 34 ++++++++++++++++++++++++++++++++++ src/src/version.c | 11 +++++++++++ 4 files changed, 51 insertions(+) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 5dfc9b5bb..b6c9e3986 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -46,6 +46,9 @@ JH/06 Default openssl_options to include +no_ticket, to reduce load on peers. by default on recent versions (3.1.3 +) unless the PFS priority string is used (3.2.4 +). +PP/03 Add $SOURCE_DATE_EPOCH support for reproducible builds, per spec at + . + Exim version 4.89 ----------------- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index c0d07b446..5f446f792 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -26,6 +26,9 @@ Version 4.90 5. An option for recipient verify callouts to hold the connection open for further recipients and for delivery. + 6. The reproducible build $SOURCE_DATE_EPOCH environment variable is now + supported. + Version 4.89 ------------ diff --git a/src/scripts/reversion b/src/scripts/reversion index 9707b9c1c..45755c084 100755 --- a/src/scripts/reversion +++ b/src/scripts/reversion @@ -71,10 +71,41 @@ EXIM_COMPILE_NUMBER=$(expr "${EXIM_COMPILE_NUMBER:-0}" + 1) echo "$EXIM_COMPILE_NUMBER" >cnumber.h +# Reproducible builds, accept a build timestamp override from environ per +# . +# We require a fairly modern date(1) command here, which is not portable +# to some of the systems Exim is built on. That's okay, because the scenarios +# are: +# 1) Local postmaster building, not using $SOURCE_DATE_EPOCH, doesn't matter +# 2) Packaging folks who don't care about reproducible builds +# 3) Packaging folks who care but are using systems where date Just Works +# 3) Packaging folks who care and can put a modern date(1) in $PATH +# 4) Packaging folks who care and can supply us with a clean patch to support +# their requirements +# 5) Packaging folks who care but won't do any work to support their strange +# old systems and want us to do the work for them. We don't care either, +# they're SOL and have to live without reproducible builds. +# +exim_build_date_override='' +if [ ".${SOURCE_DATE_EPOCH:-}" != "." ]; then + fmt='+%d-%b-%Y %H:%M:%S' + # Non-reproducible, we use __DATE__ and __TIME__ in C, which respect timezone + # (think localtime, not gmtime); for reproduction between systems, UTC makes + # more sense and the examples available use UTC without explicitly mandating + # it. I think that we can switch behavior and use UTC for reproducible + # builds without it causing any problems: nothing really cares about timezone. + # GNU date: "date -d @TS" + # BSD date: "date -r TS" + exim_build_date_override="$(date -u -d "@${SOURCE_DATE_EPOCH}" "$fmt" 2>/dev/null | date -u -r "${SOURCE_DATE_EPOCH}" "$fmt" 2>/dev/null)" +fi + ( echo '# automatically generated file - see ../scripts/reversion' echo EXIM_RELEASE_VERSION='"'"$EXIM_RELEASE_VERSION"'"' echo EXIM_VARIANT_VERSION='"'"$EXIM_VARIANT_VERSION"'"' echo EXIM_COMPILE_NUMBER='"'"$EXIM_COMPILE_NUMBER"'"' + if [ ".${exim_build_date_override:-}" != "." ]; then + echo EXIM_BUILD_DATE_OVERRIDE='"'"${exim_build_date_override}"'"' + fi ) >version.sh if [ ! -f version.h ] @@ -83,6 +114,9 @@ then echo '#define EXIM_RELEASE_VERSION "'"$EXIM_RELEASE_VERSION"'"' echo '#define EXIM_VARIANT_VERSION "'"$EXIM_VARIANT_VERSION"'"' echo '#define EXIM_VERSION_STR EXIM_RELEASE_VERSION EXIM_VARIANT_VERSION' + if [ ".${exim_build_date_override:-}" != "." ]; then + echo '#define EXIM_BUILD_DATE_OVERRIDE "'"${exim_build_date_override}"'"' + fi ) >version.h fi diff --git a/src/src/version.c b/src/src/version.c index 04a2d0733..f27cc3cde 100644 --- a/src/src/version.c +++ b/src/src/version.c @@ -40,6 +40,16 @@ version_cnumber_format = US"%d\0<>"; sprintf(CS version_cnumber, CS version_cnumber_format, cnumber); version_string = US EXIM_VERSION_STR "\0<>"; +#ifdef EXIM_BUILD_DATE_OVERRIDE +/* Reproducible build support; build tooling should have given us something looking like + * "25-Feb-2017 20:15:40" in EXIM_BUILD_DATE_OVERRIDE based on $SOURCE_DATE_EPOCH in environ + * per + */ +version_date = date_buffer; +version_date[0] = 0; +Ustrncat(version_date, EXIM_BUILD_DATE_OVERRIDE, sizeof(date_buffer)); + +#else Ustrcpy(today, __DATE__); if (today[4] == ' ') today[4] = '0'; today[3] = today[6] = '-'; @@ -51,6 +61,7 @@ Ustrncat(version_date, today, 4); Ustrncat(version_date, today+7, 4); Ustrcat(version_date, " "); Ustrcat(version_date, __TIME__); +#endif } /* End of version.c */ -- 2.25.1