From 9ce62297fafc4640351164be8b335ab6b6fb2880 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Thu, 6 Jun 2024 16:25:08 -0400 Subject: [PATCH 1/4] rewrite compiler-lookup-paths to rmake --- src/tools/run-make-support/src/rustc.rs | 8 ++ .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/compiler-lookup-paths/Makefile | 44 -------- tests/run-make/compiler-lookup-paths/rmake.rs | 103 ++++++++++++++++++ 4 files changed, 111 insertions(+), 45 deletions(-) delete mode 100644 tests/run-make/compiler-lookup-paths/Makefile create mode 100644 tests/run-make/compiler-lookup-paths/rmake.rs 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(); +} From b55fa8f7575602b9e629903d6146e9504a977933 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Sun, 9 Jun 2024 16:18:12 -0400 Subject: [PATCH 2/4] rewrite dump-mono-stats to rmake format --- src/tools/run-make-support/src/rustc.rs | 9 +++++---- src/tools/tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/dump-mono-stats/Makefile | 5 ----- tests/run-make/dump-mono-stats/rmake.rs | 12 ++++++++++++ 4 files changed, 17 insertions(+), 10 deletions(-) delete mode 100644 tests/run-make/dump-mono-stats/Makefile create mode 100644 tests/run-make/dump-mono-stats/rmake.rs diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 31efd89be07..21cde437771 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -135,9 +135,6 @@ pub fn remap_path_prefix, P2: AsRef>( self.cmd.arg("--remap-path-prefix"); self.cmd.arg(format!("{from}={to}")); - self - } - /// Specify path to the input file. pub fn input>(&mut self, path: P) -> &mut Self { self.cmd.arg(path.as_ref()); @@ -243,7 +240,11 @@ pub fn library_search_path>(&mut self, path: P) -> &mut 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 { + 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}")); diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 9faeb7df402..b8b0fc23e53 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -20,7 +20,6 @@ run-make/dep-info-doesnt-run-much/Makefile run-make/dep-info-spaces/Makefile run-make/dep-info/Makefile run-make/dump-ice-to-disk/Makefile -run-make/dump-mono-stats/Makefile run-make/emit-to-stdout/Makefile run-make/export-executable-symbols/Makefile run-make/extern-diff-internal-name/Makefile diff --git a/tests/run-make/dump-mono-stats/Makefile b/tests/run-make/dump-mono-stats/Makefile deleted file mode 100644 index 196f84be6ec..00000000000 --- a/tests/run-make/dump-mono-stats/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -include ../tools.mk - -all: - $(RUSTC) --crate-type lib foo.rs -Z dump-mono-stats=$(TMPDIR) -Zdump-mono-stats-format=json - cat $(TMPDIR)/foo.mono_items.json | $(CGREP) '"name":"bar"' diff --git a/tests/run-make/dump-mono-stats/rmake.rs b/tests/run-make/dump-mono-stats/rmake.rs new file mode 100644 index 00000000000..67915959e6d --- /dev/null +++ b/tests/run-make/dump-mono-stats/rmake.rs @@ -0,0 +1,12 @@ +// A flag named dump-mono-stats was added to the compiler in 2022, which +// collects stats on instantiation of items and their associated costs. +// This test checks that the output stat file exists, and that it contains +// a specific expected string. +// See https://github.com/rust-lang/rust/pull/105481 + +use run_make_support::{cwd, fs_wrapper, rustc}; + +fn main() { + rustc().crate_type("lib").input("foo.rs").dump_mono_stats(cwd()).arg("-Zdump-mono-stats-format=json").run(); + assert!(fs_wrapper::read_to_string("foo.mono_items.json").contains("\"name\":\"bar\""); +} From 3b495bb60b4363ff365d044f7f60ddd565fe42f5 Mon Sep 17 00:00:00 2001 From: Oneirical Date: Sun, 9 Jun 2024 16:37:31 -0400 Subject: [PATCH 3/4] rewrite prune-link-args to rmake format --- src/tools/run-make-support/src/cc.rs | 11 +- src/tools/run-make-support/src/lib.rs | 20 ++++ src/tools/run-make-support/src/rustc.rs | 6 +- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/compiler-lookup-paths/rmake.rs | 107 +++++++----------- tests/run-make/dump-mono-stats/rmake.rs | 9 +- tests/run-make/prune-link-args/Makefile | 10 -- tests/run-make/prune-link-args/rmake.rs | 15 +++ 8 files changed, 99 insertions(+), 80 deletions(-) delete mode 100644 tests/run-make/prune-link-args/Makefile create mode 100644 tests/run-make/prune-link-args/rmake.rs diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs index 31b9e8a23b8..75a20a21a31 100644 --- a/src/tools/run-make-support/src/cc.rs +++ b/src/tools/run-make-support/src/cc.rs @@ -1,7 +1,7 @@ use std::path::Path; use crate::command::Command; -use crate::{bin_name, cygpath_windows, env_var, is_msvc, is_windows, uname}; +use crate::{cygpath_windows, env_var, is_msvc, is_windows, uname}; /// Construct a new platform-specific C compiler invocation. /// @@ -68,9 +68,14 @@ pub fn out_exe(&mut self, name: &str) -> &mut Self { // endif // ``` + let mut path = std::path::PathBuf::from(name); + if is_msvc() { - let fe_path = cygpath_windows(bin_name(name)); - let fo_path = cygpath_windows(format!("{name}.obj")); + path.set_extension("exe"); + let fe_path = cygpath_windows(&path); + path.set_extension(""); + path.set_extension("obj"); + let fo_path = cygpath_windows(path); self.cmd.arg(format!("-Fe:{fe_path}")); self.cmd.arg(format!("-Fo:{fo_path}")); } else { diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index e5f1ce1bf34..fc7802130bf 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -294,6 +294,26 @@ pub fn not_contains>(path: P, expected: &str) -> bool { !path.as_ref().file_name().is_some_and(|name| name.to_str().unwrap().contains(expected)) } +/// Builds a static lib (`.lib` on Windows MSVC and `.a` for the rest) with the given name. +#[track_caller] +pub fn build_native_static_lib(lib_name: &str) -> PathBuf { + let obj_file = if is_msvc() { format!("{lib_name}") } else { format!("{lib_name}.o") }; + let src = format!("{lib_name}.c"); + let lib_path = static_lib_name(lib_name); + if is_msvc() { + cc().arg("-c").out_exe(&obj_file).input(src).run(); + } else { + cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run(); + }; + let mut obj_file = PathBuf::from(format!("{lib_name}.o")); + if is_msvc() { + obj_file.set_extension(""); + obj_file.set_extension("obj"); + } + ar(&[obj_file], &lib_path); + path(lib_path) +} + /// Returns true if the filename at `path` is not in `expected`. pub fn filename_not_in_denylist, V: AsRef<[String]>>(path: P, expected: V) -> bool { let expected = expected.as_ref(); diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 21cde437771..6b08608cc62 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -135,6 +135,9 @@ pub fn remap_path_prefix, P2: AsRef>( self.cmd.arg("--remap-path-prefix"); self.cmd.arg(format!("{from}={to}")); + self + } + /// Specify path to the input file. pub fn input>(&mut self, path: P) -> &mut Self { self.cmd.arg(path.as_ref()); @@ -239,7 +242,8 @@ 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. + /// Add a directory to the library search path with a restriction, where `kind` is a dependency + /// type. Equivalent to `-L KIND=PATH` in rustc. pub fn specific_library_search_path>( &mut self, kind: &str, diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index b8b0fc23e53..8fd0ba244eb 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -94,7 +94,6 @@ run-make/pgo-indirect-call-promotion/Makefile run-make/pointer-auth-link-with-c/Makefile run-make/print-calling-conventions/Makefile run-make/print-target-list/Makefile -run-make/prune-link-args/Makefile run-make/raw-dylib-alt-calling-convention/Makefile run-make/raw-dylib-c/Makefile run-make/raw-dylib-custom-dlltool/Makefile diff --git a/tests/run-make/compiler-lookup-paths/rmake.rs b/tests/run-make/compiler-lookup-paths/rmake.rs index f33076c37c7..0f791852821 100644 --- a/tests/run-make/compiler-lookup-paths/rmake.rs +++ b/tests/run-make/compiler-lookup-paths/rmake.rs @@ -5,99 +5,80 @@ // 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}; +//@ ignore-wasm32 +//@ ignore-wasm64 +// Reason: a C compiler is required for build_native_static_lib + +use run_make_support::{build_native_static_lib, fs_wrapper, rustc, static_lib_name}; 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")); + build_native_static_lib("native"); + let lib_native = static_lib_name("native"); + fs_wrapper::create_dir_all("crate"); + fs_wrapper::create_dir_all("native"); + fs_wrapper::rename(&lib_native, format!("native/{}", &lib_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(); + fs_wrapper::rename("liba.rlib", "crate/liba.rlib"); + rustc().input("b.rs").specific_library_search_path("native", "crate").run_fail(); + rustc().input("b.rs").specific_library_search_path("dependency", "crate").run_fail(); + rustc().input("b.rs").specific_library_search_path("crate", "crate").run(); + rustc().input("b.rs").specific_library_search_path("all", "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("c.rs").specific_library_search_path("native", "crate").run_fail(); + rustc().input("c.rs").specific_library_search_path("crate", "crate").run_fail(); + rustc().input("c.rs").specific_library_search_path("dependency", "crate").run(); + rustc().input("c.rs").specific_library_search_path("all", "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(); + rustc().input("d.rs").specific_library_search_path("dependency", "native").run_fail(); + rustc().input("d.rs").specific_library_search_path("crate", "native").run_fail(); + rustc().input("d.rs").specific_library_search_path("native", "native").run(); + rustc().input("d.rs").specific_library_search_path("all", "native").run(); // Deduplication tests. - fs_wrapper::create_dir_all(rmake_out_path("e1")); - fs_wrapper::create_dir_all(rmake_out_path("e2")); + fs_wrapper::create_dir_all("e1"); + fs_wrapper::create_dir_all("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(); + rustc().input("e.rs").output("e1/libe.rlib").run(); + rustc().input("e.rs").output("e2/libe.rlib").run(); // If the library hash is correct, compilation should succeed. + rustc().input("f.rs").library_search_path("e1").library_search_path("e2").run(); rustc() .input("f.rs") - .library_search_path(rmake_out_path("e1")) - .library_search_path(rmake_out_path("e2")) + .specific_library_search_path("crate", "e1") + .library_search_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")) + .specific_library_search_path("crate", "e1") + .specific_library_search_path("crate", "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("e2.rs").output("e2/libe.rlib").run(); + rustc().input("f.rs").library_search_path("e1").library_search_path("e2").run_fail(); rustc() .input("f.rs") - .library_search_path(rmake_out_path("e1")) - .library_search_path(rmake_out_path("e2")) + .specific_library_search_path("crate", "e1") + .library_search_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")) + .specific_library_search_path("crate", "e1") + .specific_library_search_path("crate", "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")) + .specific_library_search_path("native", "e1") + .library_search_path("e2") .run(); rustc() .input("f.rs") - .specific_library_search_path("dependency", rmake_out_path("e1")) - .library_search_path(rmake_out_path("e2")) + .specific_library_search_path("dependency", "e1") + .library_search_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")) + .specific_library_search_path("dependency", "e1") + .specific_library_search_path("crate", "e2") .run(); } diff --git a/tests/run-make/dump-mono-stats/rmake.rs b/tests/run-make/dump-mono-stats/rmake.rs index 67915959e6d..05ba2e6b8ff 100644 --- a/tests/run-make/dump-mono-stats/rmake.rs +++ b/tests/run-make/dump-mono-stats/rmake.rs @@ -7,6 +7,11 @@ use run_make_support::{cwd, fs_wrapper, rustc}; fn main() { - rustc().crate_type("lib").input("foo.rs").dump_mono_stats(cwd()).arg("-Zdump-mono-stats-format=json").run(); - assert!(fs_wrapper::read_to_string("foo.mono_items.json").contains("\"name\":\"bar\""); + rustc() + .crate_type("lib") + .input("foo.rs") + .arg(format!("-Zdump-mono-stats={}", cwd().display())) + .arg("-Zdump-mono-stats-format=json") + .run(); + assert!(fs_wrapper::read_to_string("foo.mono_items.json").contains(r#""name":"bar""#)); } diff --git a/tests/run-make/prune-link-args/Makefile b/tests/run-make/prune-link-args/Makefile deleted file mode 100644 index c21ba6ace38..00000000000 --- a/tests/run-make/prune-link-args/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# ignore-cross-compile -include ../tools.mk - -# ignore-windows - -# Notice the space in the end, this emulates the output of pkg-config -RUSTC_FLAGS = -C link-args="-lc " - -all: - $(RUSTC) $(RUSTC_FLAGS) empty.rs diff --git a/tests/run-make/prune-link-args/rmake.rs b/tests/run-make/prune-link-args/rmake.rs new file mode 100644 index 00000000000..41c85a614cd --- /dev/null +++ b/tests/run-make/prune-link-args/rmake.rs @@ -0,0 +1,15 @@ +// Passing link-args with an unexpected space +// could result in the flag being parsed and receiving +// an unexpected, empty linker argument. This test +// ensures successful compilation even when a space is +// present. +// See https://github.com/rust-lang/rust/pull/10749 + +//@ ignore-cross-compile + +use run_make_support::rustc; + +fn main() { + // Notice the space at the end of -lc, which emulates the output of pkg-config. + rustc().arg("-Clink-args=-lc ").input("empty.rs").run(); +} From ea2b699b943b269287c5722c74a900a8720b3bdd Mon Sep 17 00:00:00 2001 From: Oneirical Date: Fri, 12 Jul 2024 13:42:39 -0400 Subject: [PATCH 4/4] build_native_static_lib with llvm_ar for run_make_support --- Cargo.lock | 7 ----- src/tools/run-make-support/Cargo.toml | 2 -- src/tools/run-make-support/src/lib.rs | 29 ++++++------------- src/tools/run-make-support/src/llvm.rs | 37 +++++++++++++++++++++++++ tests/run-make/invalid-library/rmake.rs | 10 +++++-- tests/run-make/prune-link-args/rmake.rs | 2 ++ 6 files changed, 55 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68478d55e23..764073ff24e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -228,12 +228,6 @@ dependencies = [ "backtrace", ] -[[package]] -name = "ar" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69" - [[package]] name = "ar_archive_writer" version = "0.2.0" @@ -3429,7 +3423,6 @@ dependencies = [ name = "run_make_support" version = "0.2.0" dependencies = [ - "ar", "bstr", "build_helper", "gimli 0.31.0", diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index 681284b1a48..b3913732839 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -10,6 +10,4 @@ similar = "2.5.0" wasmparser = "0.118.2" regex = "1.8" # 1.8 to avoid memchr 2.6.0, as 2.5.0 is pinned in the workspace gimli = "0.31.0" -ar = "0.9.0" - build_helper = { path = "../build_helper" } diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index fc7802130bf..cec2cedd15c 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -30,8 +30,8 @@ pub use clang::{clang, Clang}; pub use diff::{diff, Diff}; pub use llvm::{ - llvm_filecheck, llvm_objdump, llvm_profdata, llvm_readobj, LlvmFilecheck, LlvmObjdump, - LlvmProfdata, LlvmReadobj, + llvm_ar, llvm_filecheck, llvm_objdump, llvm_profdata, llvm_readobj, LlvmAr, LlvmFilecheck, + LlvmObjdump, LlvmProfdata, LlvmReadobj, }; pub use run::{cmd, run, run_fail, run_with_args}; pub use rustc::{aux_build, bare_rustc, rustc, Rustc}; @@ -61,19 +61,6 @@ pub fn target() -> String { env_var("TARGET") } -/// `AR` -#[track_caller] -pub fn ar(inputs: &[impl AsRef], output_path: impl AsRef) { - let output = fs::File::create(&output_path).expect(&format!( - "the file in path \"{}\" could not be created", - output_path.as_ref().display() - )); - let mut builder = ar::Builder::new(output); - for input in inputs { - builder.append_path(input).unwrap(); - } -} - /// Check if target is windows-like. #[must_use] pub fn is_windows() -> bool { @@ -305,12 +292,12 @@ pub fn build_native_static_lib(lib_name: &str) -> PathBuf { } else { cc().arg("-v").arg("-c").out_exe(&obj_file).input(src).run(); }; - let mut obj_file = PathBuf::from(format!("{lib_name}.o")); - if is_msvc() { - obj_file.set_extension(""); - obj_file.set_extension("obj"); - } - ar(&[obj_file], &lib_path); + let obj_file = if is_msvc() { + PathBuf::from(format!("{lib_name}.obj")) + } else { + PathBuf::from(format!("{lib_name}.o")) + }; + llvm_ar().obj_to_ar().output_input(&lib_path, &obj_file).run(); path(lib_path) } diff --git a/src/tools/run-make-support/src/llvm.rs b/src/tools/run-make-support/src/llvm.rs index 4c9e9a53230..064dc62a4af 100644 --- a/src/tools/run-make-support/src/llvm.rs +++ b/src/tools/run-make-support/src/llvm.rs @@ -29,6 +29,12 @@ pub fn llvm_objdump() -> LlvmObjdump { LlvmObjdump::new() } +/// Construct a new `llvm-ar` invocation. This assumes that `llvm-ar` is available +/// at `$LLVM_BIN_DIR/llvm-ar`. +pub fn llvm_ar() -> LlvmAr { + LlvmAr::new() +} + /// A `llvm-readobj` invocation builder. #[derive(Debug)] #[must_use] @@ -57,10 +63,18 @@ pub struct LlvmObjdump { cmd: Command, } +/// A `llvm-ar` invocation builder. +#[derive(Debug)] +#[must_use] +pub struct LlvmAr { + cmd: Command, +} + crate::impl_common_helpers!(LlvmReadobj); crate::impl_common_helpers!(LlvmProfdata); crate::impl_common_helpers!(LlvmFilecheck); crate::impl_common_helpers!(LlvmObjdump); +crate::impl_common_helpers!(LlvmAr); /// Generate the path to the bin directory of LLVM. #[must_use] @@ -204,3 +218,26 @@ pub fn input>(&mut self, path: P) -> &mut Self { self } } + +impl LlvmAr { + /// Construct a new `llvm-ar` invocation. This assumes that `llvm-ar` is available + /// at `$LLVM_BIN_DIR/llvm-ar`. + pub fn new() -> Self { + let llvm_ar = llvm_bin_dir().join("llvm-ar"); + let cmd = Command::new(llvm_ar); + Self { cmd } + } + + pub fn obj_to_ar(&mut self) -> &mut Self { + self.cmd.arg("rcus"); + self + } + + /// Provide an output, then an input file. Bundled in one function, as llvm-ar has + /// no "--output"-style flag. + pub fn output_input(&mut self, out: impl AsRef, input: impl AsRef) -> &mut Self { + self.cmd.arg(out.as_ref()); + self.cmd.arg(input.as_ref()); + self + } +} diff --git a/tests/run-make/invalid-library/rmake.rs b/tests/run-make/invalid-library/rmake.rs index 750fcd05c8a..9ebab1c8b0f 100644 --- a/tests/run-make/invalid-library/rmake.rs +++ b/tests/run-make/invalid-library/rmake.rs @@ -1,8 +1,14 @@ +// When the metadata format changes, old libraries used to cause librustc to abort +// when reading their metadata. The error message for this scenario was unhelpful at best. +// A better error message was implemented in #12645, and this test checks that it is the +// one appearing in stderr in this scenario. +// See https://github.com/rust-lang/rust/pull/12645 + use run_make_support::fs_wrapper::create_file; -use run_make_support::{ar, rustc}; +use run_make_support::{llvm_ar, rustc}; fn main() { create_file("lib.rmeta"); - ar(&["lib.rmeta"], "libfoo-ffffffff-1.0.rlib"); + llvm_ar().obj_to_ar().output_input("libfoo-ffffffff-1.0.rlib", "lib.rmeta").run(); rustc().input("foo.rs").run_fail().assert_stderr_contains("found invalid metadata"); } diff --git a/tests/run-make/prune-link-args/rmake.rs b/tests/run-make/prune-link-args/rmake.rs index 41c85a614cd..ea4ffa732bf 100644 --- a/tests/run-make/prune-link-args/rmake.rs +++ b/tests/run-make/prune-link-args/rmake.rs @@ -6,6 +6,8 @@ // See https://github.com/rust-lang/rust/pull/10749 //@ ignore-cross-compile +//@ ignore-windows-gnu +// Reason: The space is parsed as an empty linker argument on windows-gnu. use run_make_support::rustc;