TLDR: I got a deterministic julia build
Hello everybody!
This is a followup from issue #25900.
Background: reproducible builds are important both for trusting that binary artifacts match a given source code, and from a scientific point of view. Two distributions that give a special attention to reproducible builds are Guix System and NixOS.
Currently, julia is not reproducible on neither systems.
After many failed tries, I successfully produced a deterministic result, with relatively few patches. Those patches are available on my fork, based on v1.4.0-rc1 release.
They cannot be applied as-is, basically because I'm not sure every corner case will work and because the last few patches disable some precompilation (work in progress on identifying why the current precompile_script breaks determinism), but I see this like a success, so I'll describe the patches so that we can discuss better solutions.
A few notes on the build environment: I'm building it with guix. Guix uses a clean chroot environment, with empty&isolated /tmp dir, among other things, the variable SOURCE_DATE_EPOCH set to 1, ASLR disabled.
Description of the commits (file name links to the commit):
To recap:
What do you think?
Thanks, Nicol貌
contrib/generate_precompile.jl: here, mktemp() and mktempdir() are called. The problem is that, the current directory get stored in the precompile cache (because of calls like
push!(DEPOT_PATH, prec_path)). Maybe we can check for an env variable and decide what to do (use a random name/static name based on that)?
But they get emptied later? Isn't that enough? https://github.com/nico202/julia/commit/ae2929a5d3d1f724b421a7f04b6c7b84c9987583#diff-5dfe4463e5341531d80109dacf106768R77-R78.
contrib/generate_precompile.jl: here, mktemp() and mktempdir() are called. The problem is that, the current directory get stored in the precompile cache (because of calls like
push!(DEPOT_PATH, prec_path)). Maybe we can check for an env variable and decide what to do (use a random name/static name based on that)?But they get emptied later? Isn't that enough? nico202@ae2929a#diff-5dfe4463e5341531d80109dacf106768R77-R78.
Nope! The code precompiled with the using keyword (using __PackagePrecompilationStatementModule) includes the package path.
strings /gnu/store/pv5xqa12x09v0dfx2zg7nmnqbhhgrkn1-julia-1.4.0/lib/julia/sys.so| grep "/tmp/jl"
/tmp/jl_precompile
/tmp/jl_precompile_file
/tmp/jl_precompile/__PackagePrecompilationStatementModule/src/__PackagePrecompilationStatementModule.jl
This is awesome! Sorry to hear that my patch to base/loading.jl was not perfect...
It seems to me that a few of these patches are simple and non-controversial, while others will take more discussion. What about opening individual PRs for the easy ones first? I'd love to see forward progress on this, since it would pave the way for Julia packages in Nix.
Hi @thomasjm!
Sure, I'll try to resume the work in the following days (rebase on master, check if the build is still deterministic & so on) and then I'll send one PR at a time.
Let us know how it goes and if you need help with anything. Very sympathetic to making deterministic builds possible!
Most helpful comment
Nope! The code precompiled with the
usingkeyword (using __PackagePrecompilationStatementModule) includes the package path.