diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index ae200d51431..31efd89be07 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -242,6 +242,14 @@ pub fn library_search_path>(&mut self, path: P) -> &mut Self { self } + /// Add a directory to the library search path with a restriction. Equivalent to `-L KIND=PATH` in rustc. + pub fn specific_library_search_path>(&mut self, kind: &str, path: P) -> &mut Self { + assert!(["dependency", "native", "all", "framework", "crate"].contains(&kind)); + let path = path.as_ref().to_string_lossy(); + self.cmd.arg(format!("-L{kind}={path}")); + self + } + /// Override the system root. Equivalent to `--sysroot` in rustc. pub fn sysroot>(&mut self, path: P) -> &mut Self { self.cmd.arg("--sysroot"); diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index f7ec7d0b3f6..9faeb7df402 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -10,7 +10,6 @@ run-make/c-unwind-abi-catch-panic/Makefile run-make/cat-and-grep-sanity-check/Makefile run-make/cdylib-dylib-linkage/Makefile run-make/compiler-lookup-paths-2/Makefile -run-make/compiler-lookup-paths/Makefile run-make/compiler-rt-works-on-mingw/Makefile run-make/crate-hash-rustc-version/Makefile run-make/cross-lang-lto-clang/Makefile diff --git a/tests/run-make/compiler-lookup-paths/Makefile b/tests/run-make/compiler-lookup-paths/Makefile deleted file mode 100644 index fc0cbde4c35..00000000000 --- a/tests/run-make/compiler-lookup-paths/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -# rustc supports different types of lookup paths, such as dependency, native or crate. This test checks that these lookup paths are functional and result in functional compilation. -# See https://github.com/rust-lang/rust/pull/19941 - -include ../tools.mk - -# ignore-wasm32 (need a C compiler) -# ignore-wasm64 (need a C compiler) - -all: $(TMPDIR)/libnative.a - mkdir -p $(TMPDIR)/crate - mkdir -p $(TMPDIR)/native - mv $(TMPDIR)/libnative.a $(TMPDIR)/native - $(RUSTC) a.rs - mv $(TMPDIR)/liba.rlib $(TMPDIR)/crate - $(RUSTC) b.rs -L native=$(TMPDIR)/crate && exit 1 || exit 0 - $(RUSTC) b.rs -L dependency=$(TMPDIR)/crate && exit 1 || exit 0 - $(RUSTC) b.rs -L crate=$(TMPDIR)/crate - $(RUSTC) b.rs -L all=$(TMPDIR)/crate - $(RUSTC) c.rs -L native=$(TMPDIR)/crate && exit 1 || exit 0 - $(RUSTC) c.rs -L crate=$(TMPDIR)/crate && exit 1 || exit 0 - $(RUSTC) c.rs -L dependency=$(TMPDIR)/crate - $(RUSTC) c.rs -L all=$(TMPDIR)/crate - $(RUSTC) d.rs -L dependency=$(TMPDIR)/native && exit 1 || exit 0 - $(RUSTC) d.rs -L crate=$(TMPDIR)/native && exit 1 || exit 0 - $(RUSTC) d.rs -L native=$(TMPDIR)/native - $(RUSTC) d.rs -L all=$(TMPDIR)/native - # Deduplication tests: - # Same hash, no errors. - mkdir -p $(TMPDIR)/e1 - mkdir -p $(TMPDIR)/e2 - $(RUSTC) e.rs -o $(TMPDIR)/e1/libe.rlib - $(RUSTC) e.rs -o $(TMPDIR)/e2/libe.rlib - $(RUSTC) f.rs -L $(TMPDIR)/e1 -L $(TMPDIR)/e2 - $(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L $(TMPDIR)/e2 - $(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L crate=$(TMPDIR)/e2 - # Different hash, errors. - $(RUSTC) e2.rs -o $(TMPDIR)/e2/libe.rlib - $(RUSTC) f.rs -L $(TMPDIR)/e1 -L $(TMPDIR)/e2 && exit 1 || exit 0 - $(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L $(TMPDIR)/e2 && exit 1 || exit 0 - $(RUSTC) f.rs -L crate=$(TMPDIR)/e1 -L crate=$(TMPDIR)/e2 && exit 1 || exit 0 - # Native/dependency paths don't cause errors. - $(RUSTC) f.rs -L native=$(TMPDIR)/e1 -L $(TMPDIR)/e2 - $(RUSTC) f.rs -L dependency=$(TMPDIR)/e1 -L $(TMPDIR)/e2 - $(RUSTC) f.rs -L dependency=$(TMPDIR)/e1 -L crate=$(TMPDIR)/e2 diff --git a/tests/run-make/compiler-lookup-paths/rmake.rs b/tests/run-make/compiler-lookup-paths/rmake.rs new file mode 100644 index 00000000000..f33076c37c7 --- /dev/null +++ b/tests/run-make/compiler-lookup-paths/rmake.rs @@ -0,0 +1,103 @@ +// Since #19941, rustc can accept specifications on its library search paths. +// This test runs Rust programs with varied library dependencies, expecting them +// to succeed or fail depending on the situation. +// The second part of the tests also checks that libraries with an incorrect hash +// fail to be used by the compiler. +// See https://github.com/rust-lang/rust/pull/19941 + +use run_make_support::fs_wrapper; +use run_make_support::{rmake_out_path, rustc}; + +fn main() { + assert!(rmake_out_path("libnative.a").exists()); + fs_wrapper::create_dir_all(rmake_out_path("crate")); + fs_wrapper::create_dir_all(rmake_out_path("native")); + fs_wrapper::rename(rmake_out_path("libnative.a"), rmake_out_path("native")); + rustc().input("a.rs").run(); + fs_wrapper::rename(rmake_out_path("liba.a"), rmake_out_path("crate")); + rustc() + .input("b.rs") + .specific_library_search_path("native", rmake_out_path("crate")) + .run_fail(); + rustc() + .input("b.rs") + .specific_library_search_path("dependency", rmake_out_path("crate")) + .run_fail(); + rustc().input("b.rs").specific_library_search_path("crate", rmake_out_path("crate")).run(); + rustc().input("b.rs").specific_library_search_path("all", rmake_out_path("crate")).run(); + + rustc() + .input("c.rs") + .specific_library_search_path("native", rmake_out_path("crate")) + .run_fail(); + rustc().input("c.rs").specific_library_search_path("crate", rmake_out_path("crate")).run_fail(); + rustc().input("c.rs").specific_library_search_path("dependency", rmake_out_path("crate")).run(); + rustc().input("c.rs").specific_library_search_path("all", rmake_out_path("crate")).run(); + + rustc() + .input("d.rs") + .specific_library_search_path("dependency", rmake_out_path("native")) + .run_fail(); + rustc() + .input("d.rs") + .specific_library_search_path("crate", rmake_out_path("native")) + .run_fail(); + rustc().input("d.rs").specific_library_search_path("native", rmake_out_path("native")).run(); + rustc().input("d.rs").specific_library_search_path("all", rmake_out_path("native")).run(); + + // Deduplication tests. + fs_wrapper::create_dir_all(rmake_out_path("e1")); + fs_wrapper::create_dir_all(rmake_out_path("e2")); + + rustc().input("e.rs").output(rmake_out_path("e1/libe.rlib")).run(); + rustc().input("e.rs").output(rmake_out_path("e2/libe.rlib")).run(); + // If the library hash is correct, compilation should succeed. + rustc() + .input("f.rs") + .library_search_path(rmake_out_path("e1")) + .library_search_path(rmake_out_path("e2")) + .run(); + rustc() + .input("f.rs") + .specific_library_search_path("crate", rmake_out_path("e1")) + .library_search_path(rmake_out_path("e2")) + .run(); + rustc() + .input("f.rs") + .specific_library_search_path("crate", rmake_out_path("e1")) + .specific_library_search_path("crate", rmake_out_path("e2")) + .run(); + // If the library has a different hash, errors should occur. + rustc().input("e2.rs").output(rmake_out_path("e2/libe.rlib")).run(); + rustc() + .input("f.rs") + .library_search_path(rmake_out_path("e1")) + .library_search_path(rmake_out_path("e2")) + .run_fail(); + rustc() + .input("f.rs") + .specific_library_search_path("crate", rmake_out_path("e1")) + .library_search_path(rmake_out_path("e2")) + .run_fail(); + rustc() + .input("f.rs") + .specific_library_search_path("crate", rmake_out_path("e1")) + .specific_library_search_path("crate", rmake_out_path("e2")) + .run_fail(); + // Native and dependency paths do not cause errors. + rustc() + .input("f.rs") + .specific_library_search_path("native", rmake_out_path("e1")) + .library_search_path(rmake_out_path("e2")) + .run(); + rustc() + .input("f.rs") + .specific_library_search_path("dependency", rmake_out_path("e1")) + .library_search_path(rmake_out_path("e2")) + .run(); + rustc() + .input("f.rs") + .specific_library_search_path("dependency", rmake_out_path("e1")) + .specific_library_search_path("crate", rmake_out_path("e2")) + .run(); +}