Source: erlang
Version: 1:18.0-dfsg-1
Severity: wishlist
Tags: patch
User: [email protected]
Usertags: timestamps toolchain
X-Debbugs-Cc: [email protected]
Hi,
While working on the "reproducible builds" effort [1], we have noticed
that erlc generates .beam files that include the current timestamp:
$ echo '-module(test).' > test.erl
$ while sleep 1; do erlc test.erl && sha1sum test.beam; done
c82bb744a4665e34bb5cdc320bcc584ed25740b4 test.beam
7214b49ebc395c5c14df6fc59ac124fa0098fb5e test.beam
7353ca62788e505ba5565d4d90daceda1883cc84 test.beam
^C
The attached patch modifies erlc to optionally use the
SOURCE_DATE_EPOCH environment variable (which we set to the latest entry
from debian/changelog). If the variable is not set or is invalid we
fall back to the original behaviour of using the current UNIX timestamp:
$ export SOURCE_DATE_EPOCH=1234
$ while sleep 1; do erlc test.erl && sha1sum test.beam; done
23da6b9ffae248392455dfa629ab5f3a12846fd0 test.beam
23da6b9ffae248392455dfa629ab5f3a12846fd0 test.beam
23da6b9ffae248392455dfa629ab5f3a12846fd0 test.beam
^C
$ export SOURCE_DATE_EPOCH=1234_WHOOPS_BROKEN
$ while sleep 1; do erlc test.erl && sha1sum test.beam; done
58f9aec98a3ae9827743ce8ff0785337e4369cf7 test.beam
11f20e425e546b184fc545961c7d791a218d4df9 test.beam
63577de11becbcd048a6cd5954e9294b7a3bdaf7 test.beam
^C
The patch is based on an original version by Chris West (Faux).
Once applied, erlang packages that ship .beam files can be built
reproducibly in our reproducible toolchain.
[1]: https://wiki.debian.org/ReproducibleBuilds
Regards,
--
,''`.
: :' : Chris Lamb
`. `'` [email protected] / chris-lamb.co.uk
`-
diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl
index a3201b0..bbcac90 100644
--- a/lib/compiler/src/beam_asm.erl
+++ b/lib/compiler/src/beam_asm.erl
@@ -226,7 +226,11 @@ flatten_imports(Imps) ->
build_attributes(Opts, SourceFile, Attr, MD5) ->
Misc = case member(slim, Opts) of
false ->
- {{Y,Mo,D},{H,Mi,S}} = erlang:universaltime(),
+ {{Y,Mo,D},{H,Mi,S}} = case
string:to_integer(os:getenv("SOURCE_DATE_EPOCH")) of
+ {N,[]} ->calendar:gregorian_seconds_to_datetime(N +
+
calendar:datetime_to_gregorian_seconds({{1970,1,1},{0,0,0}}));
+ {_,_} -> erlang:universaltime()
+ end,
[{time,{Y,Mo,D,H,Mi,S}},{source,SourceFile}];
true -> []
end,