Code change:
This is an issue extracted from which is caused by an issue that any OSX compilation with debuginfo ends up being nondeterministic. Specifically (currently known at least) the source of nondeterminism is that an mtime for an object file winds up in the final binary. It turns out this isn't really our fault (unfortunately that makes it harder to fix!). This can be reproduced with just C and a linker: Here we're using the exact same object file (with two timestamps) and we're seeing different linked artifacts. This is a source of bugs in programs that expect rustc to be deterministic (aka as was originally stated) and is something that we as rustc should probably fix. Unfortunately I don't really know of a fix for this myself. I'd be tempted to take a big hammer to the problem and deterministically set all mtime fields for objects going into the linker to a known fixed value, but that unfortunately doesn't fix the determinism for C code (whose objects we don't control) and also is probably too big of a hammer (if a build system uses the mtime of the object to control rebuilds it'd get mixed up). We could also use something like and reach in to the specific field and remove the actual data. I found it in a symbol section with the type (described in various documents online too apparently). We may be able to postprocess all output artifacts on OSX to maybe just zero out these fields unconditionally (or set them to something like May 15, 2015), although I'm not actually sure if this would be easy to do.
cc cc (you're probably interested in this for the sccache ramifications like is)
If we used LLD for linking (), it would be possible to fix this in the linker (by providing a flag to ignore mtime). This would also fix (this part of) deterministic compilation for other languages as well.
Source code for the darwin linker , but I have no idea whether they take patches. Maybe LLVM develpers know more. Most likely, Apple will switch to LLD eventually.
I wonder what experts on deterministic builds ( ) can say about this.
Hm. I wonder why we haven't noticed this for Firefox builds? Maybe the version of the linker we're using has a patch to work around this? We're using for our builds.
that is indeed surprising! The source code there , but that may be getting postprocessed somewhere else perhaps.
We discussed this on IRC, and I suspect the reason is that nobody has actually tried to do unstripped reproducible Firefox builds for macOS (although I'm not 100% sure). The info in question are STABS entries used by dsymutil to link the debug info from the object files into the dSYM. This isn't critical for sccache currently, since it doesn't cache linker outputs.
Related: noticed that static archives are not reproducible on macOS because Apple's tool puts timestamps in the archive ().
Right, I think the impact on sccache is similar to What I am seeing is that the .dylib non-determinism is causing unexpected cache misses in sccache since the dylibs end up being passed to rustc. Here is an example for :
Ah, right, proc macro crates!
This should be fixable by setting the in the env of the linker (libtool and ld64). For more context, see determinism blog post and commit for Chromium. I'm not sure of the first Xcode version that supports this though.
It should be harmless to set it even if it's not supported, you just won't get a deterministic binary. in the most recent ld64 source available, FWIW.

Related discussion:
text: has_elf_tls: version >= (10, 7), abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, <ins> // This environment variable is pretty magical but is intended for // producing deterministic builds. This was first discovered to be used // by the `ar` tool as a way to control whether or not mtime entries in // the archive headers were set to zero or not. It appears that // eventually the linker got updated to do the same thing and now reads // this environment variable too in recent versions. // // For some more info see the commentary on #47086 link_env: vec![("ZERO_AR_DATE".to_string(), "1".to_string())], </ins> ..Default::default() } }