build system: use SOURCE_DATE_EPOCH for timestamp if available

The SOURCE_DATE_EPOCH is an effort of the Reproducible Builds
organization to make timestamps/build dates in compiled tools
deterministic over several repetitive builds.

Busybox shows by default the build date timestamp which changes whenever
compiled. To have a reasonable accurate build date while staying
reproducible, it's possible to use the *date of last source
modification* rather than the current time and date.

Further information on SOURCE_DATE_EPOCH are available online [1].

This patch modifies `confdata.c` so that the content of the
SOURCE_DATE_EPOCH env variable is used as timestamp.

To be independent of different timezones between builds, whenever
SOURCE_DATE_EPOCH is defined the GMT time is used.

[1]: https://reproducible-builds.org/docs/source-date-epoch/

Signed-off-by: Paul Spooren <mail@aparcar.org>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Paul Spooren 2021-05-13 23:39:05 +02:00 committed by Denys Vlasenko
parent 1b30c63dfd
commit 947a22b332

View File

@ -342,6 +342,8 @@ int conf_write(const char *name)
time_t now; time_t now;
int use_timestamp = 1; int use_timestamp = 1;
char *env; char *env;
char *source_date_epoch;
struct tm *build_time;
dirname[0] = 0; dirname[0] = 0;
if (name && name[0]) { if (name && name[0]) {
@ -378,7 +380,16 @@ int conf_write(const char *name)
} }
sym = sym_lookup("KERNELVERSION", 0); sym = sym_lookup("KERNELVERSION", 0);
sym_calc_value(sym); sym_calc_value(sym);
source_date_epoch = getenv("SOURCE_DATE_EPOCH");
if (source_date_epoch && *source_date_epoch) {
now = strtoull(source_date_epoch, NULL, 10);
build_time = gmtime(&now);
} else {
time(&now); time(&now);
build_time = localtime(&now);
}
env = getenv("KCONFIG_NOTIMESTAMP"); env = getenv("KCONFIG_NOTIMESTAMP");
if (env && *env) if (env && *env)
use_timestamp = 0; use_timestamp = 0;
@ -398,14 +409,14 @@ int conf_write(const char *name)
if (use_timestamp) { if (use_timestamp) {
size_t ret = \ size_t ret = \
strftime(buf, sizeof(buf), "#define AUTOCONF_TIMESTAMP " strftime(buf, sizeof(buf), "#define AUTOCONF_TIMESTAMP "
"\"%Y-%m-%d %H:%M:%S %Z\"\n", localtime(&now)); "\"%Y-%m-%d %H:%M:%S %Z\"\n", build_time);
/* if user has Factory timezone or some other odd install, the /* if user has Factory timezone or some other odd install, the
* %Z above will overflow the string leaving us with undefined * %Z above will overflow the string leaving us with undefined
* results ... so let's try again without the timezone. * results ... so let's try again without the timezone.
*/ */
if (ret == 0) if (ret == 0)
strftime(buf, sizeof(buf), "#define AUTOCONF_TIMESTAMP " strftime(buf, sizeof(buf), "#define AUTOCONF_TIMESTAMP "
"\"%Y-%m-%d %H:%M:%S\"\n", localtime(&now)); "\"%Y-%m-%d %H:%M:%S\"\n", build_time);
} else { /* bbox */ } else { /* bbox */
strcpy(buf, "#define AUTOCONF_TIMESTAMP \"\"\n"); strcpy(buf, "#define AUTOCONF_TIMESTAMP \"\"\n");
} }