From afd88f2a332df214d0c3a2cfbe9cc05482955a98 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 5 May 2020 14:25:58 -0700 Subject: [PATCH] Export ZERO_AR_DATE for macos linker invocations This commit attempts to improve reproducibility of builds on macOS by exporting the `ZERO_AR_DATE=1` environment variable for all invocations of the linker. While it looks like this env var is targeted at just the `ar` command (which does actually read this) it appears that recent-ish versions of the linker *also* read this environment variable. This env var forces the linker to set a deterministic zero value for the mtime in the N_OSO field of the object file. Currently it's believe that older versions of the linker will simply ignore this env var, while newer versions will read it and produce a deterministic output for compilations with debuginfo. Closes #47086 Closes #66568 --- src/librustc_target/spec/apple_base.rs | 11 +++++++++++ .../run-make-fulldeps/reproducible-build-2/Makefile | 3 +-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs index 4ad65569e6a8a..bdd5a893d34e2 100644 --- a/src/librustc_target/spec/apple_base.rs +++ b/src/librustc_target/spec/apple_base.rs @@ -31,6 +31,17 @@ pub fn opts() -> TargetOptions { has_elf_tls: version >= (10, 7), abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, + + // 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())], + ..Default::default() } } diff --git a/src/test/run-make-fulldeps/reproducible-build-2/Makefile b/src/test/run-make-fulldeps/reproducible-build-2/Makefile index fc912efed5e3c..fd94516fbbaf6 100644 --- a/src/test/run-make-fulldeps/reproducible-build-2/Makefile +++ b/src/test/run-make-fulldeps/reproducible-build-2/Makefile @@ -2,7 +2,6 @@ # ignore-musl # ignore-windows -# ignore-macos (rust-lang/rust#66568) # Objects are reproducible but their path is not. all: \ @@ -21,7 +20,7 @@ sysroot: rm -rf $(TMPDIR) && mkdir $(TMPDIR) $(RUSTC) reproducible-build-aux.rs $(RUSTC) reproducible-build.rs --crate-type rlib --sysroot $(shell $(RUSTC) --print sysroot) --remap-path-prefix=$(shell $(RUSTC) --print sysroot)=/sysroot - cp -r $(shell $(RUSTC) --print sysroot) $(TMPDIR)/sysroot + cp -R $(shell $(RUSTC) --print sysroot) $(TMPDIR)/sysroot cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib $(RUSTC) reproducible-build.rs --crate-type rlib --sysroot $(TMPDIR)/sysroot --remap-path-prefix=$(TMPDIR)/sysroot=/sysroot cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1