Source: erlang Version: 1:18.0-dfsg-1 Severity: wishlist Tags: patch User: reproducible-bui...@lists.alioth.debian.org Usertags: timestamps toolchain X-Debbugs-Cc: reproducible-bui...@lists.alioth.debian.org
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 `. `'` la...@debian.org / 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,