From 3c68b113c06d6ebda8cc7d4bc331916eff0e89c8 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Wed, 31 Jul 2024 14:56:34 -0400 Subject: [PATCH 1/2] rewrite reproducible-build to rmake --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/reproducible-build/Makefile | 140 ----------- tests/run-make/reproducible-build/rmake.rs | 222 ++++++++++++++++++ 3 files changed, 222 insertions(+), 141 deletions(-) delete mode 100644 tests/run-make/reproducible-build/Makefile create mode 100644 tests/run-make/reproducible-build/rmake.rs diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 92405bdb876be..f55abb513b80d 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -8,7 +8,6 @@ run-make/jobserver-error/Makefile run-make/libs-through-symlinks/Makefile run-make/libtest-thread-limit/Makefile run-make/macos-deployment-target/Makefile -run-make/reproducible-build/Makefile run-make/split-debuginfo/Makefile run-make/symbol-mangling-hashed/Makefile run-make/translation/Makefile diff --git a/tests/run-make/reproducible-build/Makefile b/tests/run-make/reproducible-build/Makefile deleted file mode 100644 index f5d17a234c0ac..0000000000000 --- a/tests/run-make/reproducible-build/Makefile +++ /dev/null @@ -1,140 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# ignore-musl -# Objects are reproducible but their path is not. - -all: \ - smoke \ - debug \ - opt \ - link_paths \ - remap_paths \ - different_source_dirs_rlib \ - remap_cwd_rlib \ - remap_cwd_to_empty \ - extern_flags - -# TODO: Builds of `bin` crate types are not deterministic with debuginfo=2 on -# Windows. -# See: https://github.com/rust-lang/rust/pull/87320#issuecomment-920105533 -# Issue: https://github.com/rust-lang/rust/issues/88982 -# -# different_source_dirs_bin \ -# remap_cwd_bin \ - -smoke: - rm -rf $(TMPDIR) && mkdir $(TMPDIR) - $(RUSTC) linker.rs -O - $(RUSTC) reproducible-build-aux.rs - $(RUSTC) reproducible-build.rs -C linker=$(call RUN_BINFILE,linker) - $(RUSTC) reproducible-build.rs -C linker=$(call RUN_BINFILE,linker) - diff -u "$(TMPDIR)/linker-arguments1" "$(TMPDIR)/linker-arguments2" - -debug: - rm -rf $(TMPDIR) && mkdir $(TMPDIR) - $(RUSTC) linker.rs -O - $(RUSTC) reproducible-build-aux.rs -g - $(RUSTC) reproducible-build.rs -C linker=$(call RUN_BINFILE,linker) -g - $(RUSTC) reproducible-build.rs -C linker=$(call RUN_BINFILE,linker) -g - diff -u "$(TMPDIR)/linker-arguments1" "$(TMPDIR)/linker-arguments2" - -opt: - rm -rf $(TMPDIR) && mkdir $(TMPDIR) - $(RUSTC) linker.rs -O - $(RUSTC) reproducible-build-aux.rs -O - $(RUSTC) reproducible-build.rs -C linker=$(call RUN_BINFILE,linker) -O - $(RUSTC) reproducible-build.rs -C linker=$(call RUN_BINFILE,linker) -O - diff -u "$(TMPDIR)/linker-arguments1" "$(TMPDIR)/linker-arguments2" - -link_paths: - rm -rf $(TMPDIR) && mkdir $(TMPDIR) - $(RUSTC) reproducible-build-aux.rs - $(RUSTC) reproducible-build.rs --crate-type rlib -L /b - cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib - $(RUSTC) reproducible-build.rs --crate-type rlib -L /a - cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1 - -remap_paths: - rm -rf $(TMPDIR) && mkdir $(TMPDIR) - $(RUSTC) reproducible-build-aux.rs - $(RUSTC) reproducible-build.rs --crate-type rlib --remap-path-prefix=/a=/c - cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib - $(RUSTC) reproducible-build.rs --crate-type rlib --remap-path-prefix=/b=/c - cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1 - -different_source_dirs_bin: - rm -rf $(TMPDIR) && mkdir $(TMPDIR) - $(RUSTC) reproducible-build-aux.rs - mkdir $(TMPDIR)/test - cp reproducible-build.rs $(TMPDIR)/test - $(RUSTC) reproducible-build.rs --crate-type bin --remap-path-prefix=$$PWD=/b - cp $(TMPDIR)/reproducible-build $(TMPDIR)/foo - (cd $(TMPDIR)/test && $(RUSTC) reproducible-build.rs \ - --remap-path-prefix=$(TMPDIR)/test=/b \ - --crate-type bin) - cmp "$(TMPDIR)/reproducible-build" "$(TMPDIR)/foo" || exit 1 - -different_source_dirs_rlib: - rm -rf $(TMPDIR) && mkdir $(TMPDIR) - $(RUSTC) reproducible-build-aux.rs - mkdir $(TMPDIR)/test - cp reproducible-build.rs $(TMPDIR)/test - $(RUSTC) reproducible-build.rs --crate-type rlib --remap-path-prefix=$$PWD=/b - cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib - (cd $(TMPDIR)/test && $(RUSTC) reproducible-build.rs \ - --remap-path-prefix=$(TMPDIR)/test=/b \ - --crate-type rlib) - cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1 - -remap_cwd_bin: - rm -rf $(TMPDIR) && mkdir $(TMPDIR) - $(RUSTC) reproducible-build-aux.rs - mkdir $(TMPDIR)/test - cp reproducible-build.rs $(TMPDIR)/test - $(RUSTC) reproducible-build.rs --crate-type bin -C debuginfo=2 \ - -Z remap-cwd-prefix=. - cp $(TMPDIR)/reproducible-build $(TMPDIR)/first - (cd $(TMPDIR)/test && \ - $(RUSTC) reproducible-build.rs --crate-type bin -C debuginfo=2 \ - -Z remap-cwd-prefix=.) - cmp "$(TMPDIR)/first" "$(TMPDIR)/reproducible-build" || exit 1 - -remap_cwd_rlib: - rm -rf $(TMPDIR) && mkdir $(TMPDIR) - $(RUSTC) reproducible-build-aux.rs - mkdir $(TMPDIR)/test - cp reproducible-build.rs $(TMPDIR)/test - $(RUSTC) reproducible-build.rs --crate-type rlib -C debuginfo=2 \ - -Z remap-cwd-prefix=. - cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfirst.rlib - (cd $(TMPDIR)/test && \ - $(RUSTC) reproducible-build.rs --crate-type rlib -C debuginfo=2 \ - -Z remap-cwd-prefix=.) - cmp "$(TMPDIR)/libfirst.rlib" "$(TMPDIR)/libreproducible_build.rlib" || exit 1 - -remap_cwd_to_empty: - rm -rf $(TMPDIR) && mkdir $(TMPDIR) - $(RUSTC) reproducible-build-aux.rs - mkdir $(TMPDIR)/test - cp reproducible-build.rs $(TMPDIR)/test - $(RUSTC) reproducible-build.rs --crate-type rlib -C debuginfo=2 \ - -Z remap-cwd-prefix= - cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfirst.rlib - (cd $(TMPDIR)/test && \ - $(RUSTC) reproducible-build.rs --crate-type rlib -C debuginfo=2 \ - -Z remap-cwd-prefix=) - cmp "$(TMPDIR)/libfirst.rlib" "$(TMPDIR)/libreproducible_build.rlib" || exit 1 - -extern_flags: - rm -rf $(TMPDIR) && mkdir $(TMPDIR) - $(RUSTC) reproducible-build-aux.rs - $(RUSTC) reproducible-build.rs \ - --extern reproducible_build_aux=$(TMPDIR)/libreproducible_build_aux.rlib \ - --crate-type rlib - cp $(TMPDIR)/libreproducible_build_aux.rlib $(TMPDIR)/libbar.rlib - cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib - $(RUSTC) reproducible-build.rs \ - --extern reproducible_build_aux=$(TMPDIR)/libbar.rlib \ - --crate-type rlib - cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1 diff --git a/tests/run-make/reproducible-build/rmake.rs b/tests/run-make/reproducible-build/rmake.rs new file mode 100644 index 0000000000000..a5f27f34f4fcc --- /dev/null +++ b/tests/run-make/reproducible-build/rmake.rs @@ -0,0 +1,222 @@ +// This test case makes sure that two identical invocations of the compiler +// (i.e. same code base, same compile-flags, same compiler-versions, etc.) +// produce the same output. In the past, symbol names of monomorphized functions +// were not deterministic (which we want to avoid). +// +// The test tries to exercise as many different paths into symbol name +// generation as possible: +// +// - regular functions +// - generic functions +// - methods +// - statics +// - closures +// - enum variant constructors +// - tuple struct constructors +// - drop glue +// - FnOnce adapters +// - Trait object shims +// - Fn Pointer shims +// See https://github.com/rust-lang/rust/pull/32293 + +// FIXME(Oneirical): ignore-musl +// FIXME(Oneirical): two of these test blocks will apparently fail on windows +// FIXME(Oneirical): try it on test-various +// # FIXME: Builds of `bin` crate types are not deterministic with debuginfo=2 on +// # Windows. +// # See: https://github.com/rust-lang/rust/pull/87320#issuecomment-920105533 +// # Issue: https://github.com/rust-lang/rust/issues/88982 + +use run_make_support::{bin_name, cwd, diff, rfs, run_in_tmpdir, rust_lib_name, rustc}; + +fn main() { + run_in_tmpdir(|| { + rustc().input("linker.rs").opt().run(); + rustc().input("reproducible-build-aux.rs").run(); + rustc() + .input("reproducible-build.rs") + .linker(&cwd().join(bin_name("linker")).display().to_string()) + .run(); + rustc() + .input("reproducible-build.rs") + .linker(&cwd().join(bin_name("linker")).display().to_string()) + .run(); + diff().actual_file("linker-arguments1").expected_file("linker-arguments2").run(); + }); + + run_in_tmpdir(|| { + rustc().input("linker.rs").opt().run(); + rustc().arg("-g").input("reproducible-build-aux.rs").run(); + rustc() + .arg("-g") + .input("reproducible-build.rs") + .linker(&cwd().join(bin_name("linker")).display().to_string()) + .run(); + rustc() + .arg("-g") + .input("reproducible-build.rs") + .linker(&cwd().join(bin_name("linker")).display().to_string()) + .run(); + diff().actual_file("linker-arguments1").expected_file("linker-arguments2").run(); + }); + + run_in_tmpdir(|| { + rustc().input("linker.rs").opt().run(); + rustc().opt().input("reproducible-build-aux.rs").run(); + rustc() + .opt() + .input("reproducible-build.rs") + .linker(&cwd().join(bin_name("linker")).display().to_string()) + .run(); + rustc() + .opt() + .input("reproducible-build.rs") + .linker(&cwd().join(bin_name("linker")).display().to_string()) + .run(); + diff().actual_file("linker-arguments1").expected_file("linker-arguments2").run(); + }); + + run_in_tmpdir(|| { + rustc().input("reproducible-build-aux.rs").run(); + rustc().input("reproducible-build.rs").crate_type("rlib").library_search_path("b").run(); + rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo")); + rustc().input("reproducible-build.rs").crate_type("rlib").library_search_path("a").run(); + assert_eq!(rfs::read(rust_lib_name("reproducible_build")), rfs::read(rust_lib_name("foo"))); + }); + + run_in_tmpdir(|| { + rustc().input("reproducible-build-aux.rs").run(); + rustc() + .input("reproducible-build.rs") + .crate_type("rlib") + .arg("--remap-path-prefix=/a=/c") + .run(); + rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo")); + rustc() + .input("reproducible-build.rs") + .crate_type("rlib") + .arg("--remap-path-prefix=/b=/c") + .run(); + assert_eq!(rfs::read(rust_lib_name("reproducible_build")), rfs::read(rust_lib_name("foo"))); + }); + + run_in_tmpdir(|| { + rustc().input("reproducible-build-aux.rs").run(); + rfs::create_dir("test"); + rfs::copy("reproducible-build.rs", "test/reproducible-build.rs"); + rustc() + .input("reproducible-build.rs") + .crate_type("bin") + .arg(&format!("--remap-path-prefix={}=/b", cwd().display())) + .run(); + eprintln!("{:#?}", rfs::shallow_find_dir_entries(cwd())); + rfs::copy(bin_name("reproducible_build"), bin_name("foo")); + rustc() + .input("test/reproducible-build.rs") + .crate_type("bin") + .arg("--remap-path-prefix=/test=/b") + .run(); + assert_eq!(rfs::read(bin_name("reproducible_build")), rfs::read(bin_name("foo"))); + }); + + run_in_tmpdir(|| { + rustc().input("reproducible-build-aux.rs").run(); + rfs::create_dir("test"); + rfs::copy("reproducible-build.rs", "test/reproducible-build.rs"); + rustc() + .input("reproducible-build.rs") + .crate_type("rlib") + .arg(&format!("--remap-path-prefix={}=/b", cwd().display())) + .run(); + rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo")); + rustc() + .input("test/reproducible-build.rs") + .crate_type("rlib") + .arg("--remap-path-prefix=/test=/b") + .run(); + assert_eq!(rfs::read(rust_lib_name("reproducible_build")), rfs::read(rust_lib_name("foo"))); + }); + + run_in_tmpdir(|| { + rustc().input("reproducible-build-aux.rs").run(); + rfs::create_dir("test"); + rfs::copy("reproducible-build.rs", "test/reproducible-build.rs"); + rustc() + .input("reproducible-build.rs") + .crate_type("bin") + .arg("-Zremap-path-prefix=.") + .arg("-Cdebuginfo=2") + .run(); + rfs::copy(bin_name("reproducible_build"), bin_name("first")); + rustc() + .input("test/reproducible-build.rs") + .crate_type("bin") + .arg("-Zremap-path-prefix=.") + .arg("-Cdebuginfo=2") + .run(); + assert_eq!(rfs::read(bin_name("first")), rfs::read(bin_name("reproducible_build"))); + }); + + run_in_tmpdir(|| { + rustc().input("reproducible-build-aux.rs").run(); + rfs::create_dir("test"); + rfs::copy("reproducible-build.rs", "test/reproducible-build.rs"); + rustc() + .input("reproducible-build.rs") + .crate_type("rlib") + .arg("-Zremap-path-prefix=.") + .arg("-Cdebuginfo=2") + .run(); + rfs::copy("reproducible_build", "first"); + rustc() + .input("test/reproducible-build.rs") + .crate_type("rlib") + .arg("-Zremap-path-prefix=.") + .arg("-Cdebuginfo=2") + .run(); + assert_eq!( + rfs::read(rust_lib_name("first")), + rfs::read(rust_lib_name("reproducible_build")) + ); + }); + + run_in_tmpdir(|| { + rustc().input("reproducible-build-aux.rs").run(); + rfs::create_dir("test"); + rfs::copy("reproducible-build.rs", "test/reproducible-build.rs"); + rustc() + .input("reproducible-build.rs") + .crate_type("rlib") + .arg("-Zremap-path-prefix=") + .arg("-Cdebuginfo=2") + .run(); + rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("first")); + rustc() + .input("test/reproducible-build.rs") + .crate_type("rlib") + .arg("-Zremap-path-prefix=") + .arg("-Cdebuginfo=2") + .run(); + assert_eq!( + rfs::read(rust_lib_name("first")), + rfs::read(rust_lib_name("reproducible_build")) + ); + }); + + run_in_tmpdir(|| { + rustc().input("reproducible-build-aux.rs").run(); + rustc() + .input("reproducible-build.rs") + .crate_type("rlib") + .extern_("reproducible_build_aux", rust_lib_name("reproducible_build_aux")) + .run(); + rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo")); + rfs::copy(rust_lib_name("reproducible_build_aux"), rust_lib_name("bar")); + rustc() + .input("reproducible-build.rs") + .crate_type("rlib") + .extern_("reproducible_build_aux", rust_lib_name("bar")) + .run(); + assert_eq!(rfs::read(rust_lib_name("foo")), rfs::read(rust_lib_name("reproducible_build"))); + }); +} From e752410a43f2141ed592498219c808898b0cce61 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Tue, 6 Aug 2024 12:37:15 -0400 Subject: [PATCH 2/2] massive refactor of reproducible-build test --- tests/run-make/reproducible-build/rmake.rs | 340 +++++++++++---------- 1 file changed, 179 insertions(+), 161 deletions(-) diff --git a/tests/run-make/reproducible-build/rmake.rs b/tests/run-make/reproducible-build/rmake.rs index a5f27f34f4fcc..34410d224fbc4 100644 --- a/tests/run-make/reproducible-build/rmake.rs +++ b/tests/run-make/reproducible-build/rmake.rs @@ -18,205 +18,223 @@ // - Trait object shims // - Fn Pointer shims // See https://github.com/rust-lang/rust/pull/32293 +// Tracking Issue: https://github.com/rust-lang/rust/issues/129080 -// FIXME(Oneirical): ignore-musl -// FIXME(Oneirical): two of these test blocks will apparently fail on windows -// FIXME(Oneirical): try it on test-various -// # FIXME: Builds of `bin` crate types are not deterministic with debuginfo=2 on -// # Windows. -// # See: https://github.com/rust-lang/rust/pull/87320#issuecomment-920105533 -// # Issue: https://github.com/rust-lang/rust/issues/88982 - -use run_make_support::{bin_name, cwd, diff, rfs, run_in_tmpdir, rust_lib_name, rustc}; +use run_make_support::{ + bin_name, cwd, diff, is_darwin, is_windows, rfs, run_in_tmpdir, rust_lib_name, rustc, +}; fn main() { - run_in_tmpdir(|| { - rustc().input("linker.rs").opt().run(); - rustc().input("reproducible-build-aux.rs").run(); - rustc() - .input("reproducible-build.rs") - .linker(&cwd().join(bin_name("linker")).display().to_string()) - .run(); - rustc() - .input("reproducible-build.rs") - .linker(&cwd().join(bin_name("linker")).display().to_string()) - .run(); - diff().actual_file("linker-arguments1").expected_file("linker-arguments2").run(); - }); + // Smoke tests. Simple flags, build should be reproducible. + eprintln!("smoke_test => None"); + smoke_test(None); + eprintln!("smoke_test => SmokeFlag::Debug"); + smoke_test(Some(SmokeFlag::Debug)); + eprintln!("smoke_test => SmokeFlag::Opt"); + smoke_test(Some(SmokeFlag::Opt)); - run_in_tmpdir(|| { - rustc().input("linker.rs").opt().run(); - rustc().arg("-g").input("reproducible-build-aux.rs").run(); - rustc() - .arg("-g") - .input("reproducible-build.rs") - .linker(&cwd().join(bin_name("linker")).display().to_string()) - .run(); - rustc() - .arg("-g") - .input("reproducible-build.rs") - .linker(&cwd().join(bin_name("linker")).display().to_string()) - .run(); - diff().actual_file("linker-arguments1").expected_file("linker-arguments2").run(); - }); + // Builds should be reproducible even through custom library search paths + // or remap path prefixes. + eprintln!("paths_test => PathsFlag::Link"); + paths_test(PathsFlag::Link); + eprintln!("paths_test => PathsFlag::Remap"); + paths_test(PathsFlag::Remap); - run_in_tmpdir(|| { - rustc().input("linker.rs").opt().run(); - rustc().opt().input("reproducible-build-aux.rs").run(); - rustc() - .opt() - .input("reproducible-build.rs") - .linker(&cwd().join(bin_name("linker")).display().to_string()) - .run(); - rustc() - .opt() - .input("reproducible-build.rs") - .linker(&cwd().join(bin_name("linker")).display().to_string()) - .run(); - diff().actual_file("linker-arguments1").expected_file("linker-arguments2").run(); - }); + // Builds should be reproducible even if each build is done in a different directory, + // with both --remap-path-prefix and -Z remap-cwd-prefix. - run_in_tmpdir(|| { - rustc().input("reproducible-build-aux.rs").run(); - rustc().input("reproducible-build.rs").crate_type("rlib").library_search_path("b").run(); - rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo")); - rustc().input("reproducible-build.rs").crate_type("rlib").library_search_path("a").run(); - assert_eq!(rfs::read(rust_lib_name("reproducible_build")), rfs::read(rust_lib_name("foo"))); - }); + // FIXME(Oneirical): Building with crate type set to `bin` AND having -Cdebuginfo=2 + // (or `-g`, the shorthand form) enabled will cause reproducibility failures. + // See https://github.com/rust-lang/rust/issues/89911 + + if !is_darwin() && !is_windows() { + // FIXME(Oneirical): Bin builds are not reproducible on non-Linux targets. + eprintln!("diff_dir_test => Bin, Path"); + diff_dir_test(CrateType::Bin, RemapType::Path); + } + + eprintln!("diff_dir_test => Rlib, Path"); + diff_dir_test(CrateType::Rlib, RemapType::Path); + + // FIXME(Oneirical): This specific case would fail on Linux, should -Cdebuginfo=2 + // be added. + // FIXME(Oneirical): Bin builds are not reproducible on non-Linux targets. + // See https://github.com/rust-lang/rust/issues/89911 + if !is_darwin() && !is_windows() { + eprintln!("diff_dir_test => Bin, Cwd false"); + diff_dir_test(CrateType::Bin, RemapType::Cwd { is_empty: false }); + } + eprintln!("diff_dir_test => Rlib, Cwd false"); + diff_dir_test(CrateType::Rlib, RemapType::Cwd { is_empty: false }); + eprintln!("diff_dir_test => Rlib, Cwd true"); + diff_dir_test(CrateType::Rlib, RemapType::Cwd { is_empty: true }); + + eprintln!("final extern test"); + // Builds should be reproducible when using the --extern flag. run_in_tmpdir(|| { rustc().input("reproducible-build-aux.rs").run(); rustc() .input("reproducible-build.rs") .crate_type("rlib") - .arg("--remap-path-prefix=/a=/c") + .extern_("reproducible_build_aux", rust_lib_name("reproducible_build_aux")) .run(); rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo")); + rfs::copy(rust_lib_name("reproducible_build_aux"), rust_lib_name("bar")); rustc() .input("reproducible-build.rs") .crate_type("rlib") - .arg("--remap-path-prefix=/b=/c") + .extern_("reproducible_build_aux", rust_lib_name("bar")) .run(); - assert_eq!(rfs::read(rust_lib_name("reproducible_build")), rfs::read(rust_lib_name("foo"))); + assert!(rfs::read(rust_lib_name("foo")) == rfs::read(rust_lib_name("reproducible_build"))) }); +} +#[track_caller] +fn smoke_test(flag: Option) { run_in_tmpdir(|| { + rustc().input("linker.rs").opt().run(); rustc().input("reproducible-build-aux.rs").run(); - rfs::create_dir("test"); - rfs::copy("reproducible-build.rs", "test/reproducible-build.rs"); - rustc() + let mut compiler1 = rustc(); + let mut compiler2 = rustc(); + if let Some(flag) = flag { + match flag { + SmokeFlag::Debug => { + compiler1.arg("-g"); + compiler2.arg("-g"); + } + SmokeFlag::Opt => { + compiler1.opt(); + compiler2.opt(); + } + }; + }; + compiler1 .input("reproducible-build.rs") - .crate_type("bin") - .arg(&format!("--remap-path-prefix={}=/b", cwd().display())) - .run(); - eprintln!("{:#?}", rfs::shallow_find_dir_entries(cwd())); - rfs::copy(bin_name("reproducible_build"), bin_name("foo")); - rustc() - .input("test/reproducible-build.rs") - .crate_type("bin") - .arg("--remap-path-prefix=/test=/b") + .linker(&cwd().join(bin_name("linker")).display().to_string()) .run(); - assert_eq!(rfs::read(bin_name("reproducible_build")), rfs::read(bin_name("foo"))); - }); - - run_in_tmpdir(|| { - rustc().input("reproducible-build-aux.rs").run(); - rfs::create_dir("test"); - rfs::copy("reproducible-build.rs", "test/reproducible-build.rs"); - rustc() + compiler2 .input("reproducible-build.rs") - .crate_type("rlib") - .arg(&format!("--remap-path-prefix={}=/b", cwd().display())) - .run(); - rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo")); - rustc() - .input("test/reproducible-build.rs") - .crate_type("rlib") - .arg("--remap-path-prefix=/test=/b") + .linker(&cwd().join(bin_name("linker")).display().to_string()) .run(); - assert_eq!(rfs::read(rust_lib_name("reproducible_build")), rfs::read(rust_lib_name("foo"))); + diff().actual_file("linker-arguments1").expected_file("linker-arguments2").run(); }); +} +#[track_caller] +fn paths_test(flag: PathsFlag) { run_in_tmpdir(|| { rustc().input("reproducible-build-aux.rs").run(); - rfs::create_dir("test"); - rfs::copy("reproducible-build.rs", "test/reproducible-build.rs"); - rustc() - .input("reproducible-build.rs") - .crate_type("bin") - .arg("-Zremap-path-prefix=.") - .arg("-Cdebuginfo=2") - .run(); - rfs::copy(bin_name("reproducible_build"), bin_name("first")); - rustc() - .input("test/reproducible-build.rs") - .crate_type("bin") - .arg("-Zremap-path-prefix=.") - .arg("-Cdebuginfo=2") - .run(); - assert_eq!(rfs::read(bin_name("first")), rfs::read(bin_name("reproducible_build"))); + let mut compiler1 = rustc(); + let mut compiler2 = rustc(); + match flag { + PathsFlag::Link => { + compiler1.library_search_path("a"); + compiler2.library_search_path("b"); + } + PathsFlag::Remap => { + compiler1.arg("--remap-path-prefix=/a=/c"); + compiler2.arg("--remap-path-prefix=/b=/c"); + } + } + compiler1.input("reproducible-build.rs").crate_type("rlib").run(); + rfs::rename(rust_lib_name("reproducible_build"), rust_lib_name("foo")); + compiler2.input("reproducible-build.rs").crate_type("rlib").run(); + assert!(rfs::read(rust_lib_name("foo")) == rfs::read(rust_lib_name("reproducible_build"))) }); +} +#[track_caller] +fn diff_dir_test(crate_type: CrateType, remap_type: RemapType) { run_in_tmpdir(|| { + let base_dir = cwd(); rustc().input("reproducible-build-aux.rs").run(); rfs::create_dir("test"); rfs::copy("reproducible-build.rs", "test/reproducible-build.rs"); - rustc() + let mut compiler1 = rustc(); + let mut compiler2 = rustc(); + match crate_type { + CrateType::Bin => { + compiler1.crate_type("bin"); + compiler2.crate_type("bin"); + } + CrateType::Rlib => { + compiler1.crate_type("rlib"); + compiler2.crate_type("rlib"); + } + } + match remap_type { + RemapType::Path => { + compiler1.arg(&format!("--remap-path-prefix={}=/b", cwd().display())); + compiler2 + .arg(format!("--remap-path-prefix={}=/b", base_dir.join("test").display())); + } + RemapType::Cwd { is_empty } => { + // FIXME(Oneirical): Building with crate type set to `bin` AND having -Cdebuginfo=2 + // (or `-g`, the shorthand form) enabled will cause reproducibility failures + // for multiple platforms. + // See https://github.com/rust-lang/rust/issues/89911 + // FIXME(#129117): Windows rlib + `-Cdebuginfo=2` + `-Z remap-cwd-prefix=.` seems + // to be unreproducible. + if !matches!(crate_type, CrateType::Bin) && !is_windows() { + compiler1.arg("-Cdebuginfo=2"); + compiler2.arg("-Cdebuginfo=2"); + } + if is_empty { + compiler1.arg("-Zremap-cwd-prefix="); + compiler2.arg("-Zremap-cwd-prefix="); + } else { + compiler1.arg("-Zremap-cwd-prefix=."); + compiler2.arg("-Zremap-cwd-prefix=."); + } + } + } + compiler1.input("reproducible-build.rs").run(); + match crate_type { + CrateType::Bin => { + rfs::rename(bin_name("reproducible-build"), bin_name("foo")); + } + CrateType::Rlib => { + rfs::rename(rust_lib_name("reproducible_build"), rust_lib_name("foo")); + } + } + std::env::set_current_dir("test").unwrap(); + compiler2 .input("reproducible-build.rs") - .crate_type("rlib") - .arg("-Zremap-path-prefix=.") - .arg("-Cdebuginfo=2") - .run(); - rfs::copy("reproducible_build", "first"); - rustc() - .input("test/reproducible-build.rs") - .crate_type("rlib") - .arg("-Zremap-path-prefix=.") - .arg("-Cdebuginfo=2") - .run(); - assert_eq!( - rfs::read(rust_lib_name("first")), - rfs::read(rust_lib_name("reproducible_build")) - ); + .library_search_path(&base_dir) + .out_dir(&base_dir) + .run(); + std::env::set_current_dir(&base_dir).unwrap(); + match crate_type { + CrateType::Bin => { + assert!(rfs::read(bin_name("reproducible-build")) == rfs::read(bin_name("foo"))); + } + CrateType::Rlib => { + assert!( + rfs::read(rust_lib_name("foo")) + == rfs::read(rust_lib_name("reproducible_build")) + ); + } + } }); +} - run_in_tmpdir(|| { - rustc().input("reproducible-build-aux.rs").run(); - rfs::create_dir("test"); - rfs::copy("reproducible-build.rs", "test/reproducible-build.rs"); - rustc() - .input("reproducible-build.rs") - .crate_type("rlib") - .arg("-Zremap-path-prefix=") - .arg("-Cdebuginfo=2") - .run(); - rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("first")); - rustc() - .input("test/reproducible-build.rs") - .crate_type("rlib") - .arg("-Zremap-path-prefix=") - .arg("-Cdebuginfo=2") - .run(); - assert_eq!( - rfs::read(rust_lib_name("first")), - rfs::read(rust_lib_name("reproducible_build")) - ); - }); +enum SmokeFlag { + Debug, + Opt, +} - run_in_tmpdir(|| { - rustc().input("reproducible-build-aux.rs").run(); - rustc() - .input("reproducible-build.rs") - .crate_type("rlib") - .extern_("reproducible_build_aux", rust_lib_name("reproducible_build_aux")) - .run(); - rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo")); - rfs::copy(rust_lib_name("reproducible_build_aux"), rust_lib_name("bar")); - rustc() - .input("reproducible-build.rs") - .crate_type("rlib") - .extern_("reproducible_build_aux", rust_lib_name("bar")) - .run(); - assert_eq!(rfs::read(rust_lib_name("foo")), rfs::read(rust_lib_name("reproducible_build"))); - }); +enum PathsFlag { + Link, + Remap, +} + +enum CrateType { + Bin, + Rlib, +} + +enum RemapType { + Path, + Cwd { is_empty: bool }, }