Fossil SCM

FOSSIL_BUILD_HASH varies across builds

Fixed

99038b83b489ddd… · opened 5 years, 10 months ago

Type
Feature_Request
Priority
Immediate
Severity
Minor
Resolution
Fixed
Subsystem
Created
June 11, 2020 1:37 p.m.

While working on reproducible builds for openSUSE, I found that when building the fossil package, there were slight differences between each build, because mkversion produced a different FOSSIL_BUILD_HASH value each time it was run.

Here is a patch that allows us to produce the same binary twice:

Author: Bernhard M. Wiedemann <bwiedemann suse.de>
Date: 2020-06-11 13:12

Allow to override build date with SOURCE_DATE_EPOCH
in order to make builds reproducible.
See https://reproducible-builds.org/ for why this is good
and https://reproducible-builds.org/specs/source-date-epoch/
for the definition of this variable.

Index: fossil-2.11/src/mkversion.c
===================================================================
--- fossil-2.11.orig/src/mkversion.c
+++ fossil-2.11/src/mkversion.c
@@ -81,7 +81,12 @@ int main(int argc, char *argv[]){
     printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b);
     n = strlen(b);
     if( n + 50 < sizeof(b) ){
-      sprintf(b+n, "%d", (int)time(0));
+      int t;
+      char *source_date_epoch;
+      if(NULL == (source_date_epoch = getenv("SOURCE_DATE_EPOCH")) ||
+        0 >= (t = (int)strtoll(source_date_epoch, NULL, 10)))
+          t = (int)time(0);
+      sprintf(b+n, "%d", t);
       hash(b,33,vx);
       printf("#define FOSSIL_BUILD_HASH \"%s\"\n", vx);
     }

Comments (4)

bmwiedemann 5 years, 10 months ago

While working on reproducible builds for openSUSE, I found that when building the fossil package, there were slight differences between each build, because mkversion produced a different FOSSIL_BUILD_HASH value each time it was run.

Here is a patch that allows us to produce the same binary twice:

Author: Bernhard M. Wiedemann <bwiedemann suse.de>
Date: 2020-06-11 13:12

Allow to override build date with SOURCE_DATE_EPOCH
in order to make builds reproducible.
See https://reproducible-builds.org/ for why this is good
and https://reproducible-builds.org/specs/source-date-epoch/
for the definition of this variable.

Index: fossil-2.11/src/mkversion.c
===================================================================
--- fossil-2.11.orig/src/mkversion.c
+++ fossil-2.11/src/mkversion.c
@@ -81,7 +81,12 @@ int main(int argc, char *argv[]){
     printf("#define MANIFEST_VERSION \"[%10.10s]\"\n",b);
     n = strlen(b);
     if( n + 50 < sizeof(b) ){
-      sprintf(b+n, "%d", (int)time(0));
+      int t;
+      char *source_date_epoch;
+      if(NULL == (source_date_epoch = getenv("SOURCE_DATE_EPOCH")) ||
+        0 >= (t = (int)strtoll(source_date_epoch, NULL, 10)))
+          t = (int)time(0);
+      sprintf(b+n, "%d", t);
       hash(b,33,vx);
       printf("#define FOSSIL_BUILD_HASH \"%s\"\n", vx);
     }
drh 5 years, 10 months ago

I added a compile-time option:

-DFOSSIL_BUILD_EPOCH=0

Any numeric value can be used as the argument. Whatever you use becomes a replacement for "time()". The FOSSIL_BUILD_HASH value is used to help know when ETags: values for HTTP request have expired (which should happen whenever the executable is rebuilt) so the specific value for -DFOSSIL_BUILD_EPOCH does not matter.

bmwiedemann 5 years, 9 months ago

Thanks for making it easier to get bit-reproducible results. I submitted it towards openSUSE in https://build.opensuse.org/request/show/813802

The downside compared to my patch is that now every distribution interested in reproducible build results needs to discover this new option and adjust their CFLAGS.

These distributions already set the SOURCE_DATE_EPOCH variable for all builds.

drh 5 years, 9 months ago

Further updated mkversion.c to respond to SOURCE_DATE_EPOCH.

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button