Fossil SCM
FOSSIL_BUILD_HASH varies across builds
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)
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);
}
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.
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.
Further updated mkversion.c to respond to SOURCE_DATE_EPOCH.