From 96e7d25891fbac3fb693a6c041b93a98712aba15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 14 Apr 2024 16:35:14 +0000 Subject: [PATCH 1/6] add missing lld directive to compiletest --- src/tools/compiletest/src/header.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index f78e0363f55..99597875d0f 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -839,6 +839,7 @@ pub fn line_directive<'line>( "needs-profiler-support", "needs-relocation-model-pic", "needs-run-enabled", + "needs-rust-lld", "needs-rust-lldb", "needs-sanitizer-address", "needs-sanitizer-cfi", From 682535e7775efb2f2e4934b2cf5bc5edc3253968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 14 Apr 2024 16:36:09 +0000 Subject: [PATCH 2/6] add regex to run_make_support note: version more recent than 1.8 depend on memchr 2.6, which creates conflicts as memchr 2.5.0 is pinned elsewhere in the workspace --- Cargo.lock | 1 + src/tools/run-make-support/Cargo.toml | 1 + src/tools/run-make-support/src/lib.rs | 1 + 3 files changed, 3 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 1f26dd7c43c..faf2c473ee1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3342,6 +3342,7 @@ name = "run_make_support" version = "0.0.0" dependencies = [ "object 0.34.0", + "regex", "wasmparser", ] diff --git a/src/tools/run-make-support/Cargo.toml b/src/tools/run-make-support/Cargo.toml index d8bb8c643d1..3ea35c7940c 100644 --- a/src/tools/run-make-support/Cargo.toml +++ b/src/tools/run-make-support/Cargo.toml @@ -6,3 +6,4 @@ edition = "2021" [dependencies] object = "0.34.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 diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs index 47b46a0a699..9a4fdff5d15 100644 --- a/src/tools/run-make-support/src/lib.rs +++ b/src/tools/run-make-support/src/lib.rs @@ -13,6 +13,7 @@ use std::process::{Command, Output}; pub use object; +pub use regex; pub use wasmparser; pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc}; From 97795923fc06fa3a944337cd5c4461b2c4833cb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 14 Apr 2024 17:00:32 +0000 Subject: [PATCH 3/6] port `rust-lld` test to rmake also check that turning off the linker feature does not use lld --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - tests/run-make/rust-lld/Makefile | 12 ---- tests/run-make/rust-lld/rmake.rs | 64 +++++++++++++++++++ 3 files changed, 64 insertions(+), 13 deletions(-) delete mode 100644 tests/run-make/rust-lld/Makefile create mode 100644 tests/run-make/rust-lld/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 3914feb3499..45d3acd8fd4 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -250,7 +250,6 @@ run-make/rlib-format-packed-bundled-libs-3/Makefile run-make/rlib-format-packed-bundled-libs/Makefile run-make/rmeta-preferred/Makefile run-make/rust-lld-custom-target/Makefile -run-make/rust-lld/Makefile run-make/rustc-macro-dep-files/Makefile run-make/rustdoc-determinism/Makefile run-make/rustdoc-error-lines/Makefile diff --git a/tests/run-make/rust-lld/Makefile b/tests/run-make/rust-lld/Makefile deleted file mode 100644 index 1ecac479f41..00000000000 --- a/tests/run-make/rust-lld/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -include ../tools.mk - -# ignore-msvc -# needs-rust-lld -# ignore-s390x lld does not yet support s390x as target -all: - RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Clink-self-contained=+linker -Zlinker-features=+lld -Zunstable-options -Clink-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt - $(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt - - # while we're here, also check that the last linker feature flag "wins" - RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Clink-self-contained=+linker -Zlinker-features=-lld -Zlinker-features=+lld -Zunstable-options -Clink-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt - $(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs new file mode 100644 index 00000000000..053b580ebd1 --- /dev/null +++ b/tests/run-make/rust-lld/rmake.rs @@ -0,0 +1,64 @@ +// Test linking using `cc` with `rust-lld`, using the unstable CLI described in MCP 510 +// see https://github.com/rust-lang/compiler-team/issues/510 for more info + +//@ needs-rust-lld +//@ ignore-msvc +//@ ignore-s390x lld does not yet support s390x as target + +extern crate run_make_support; + +use run_make_support::regex::Regex; +use run_make_support::rustc; +use std::process::Output; + +fn main() { + // Opt-in to lld and the self-contained linker, to link with rust-lld. We'll check that by + // asking the linker to display its version number with a link-arg. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .arg("-Zlinker-features=+lld") + .arg("-Clink-self-contained=+linker") + .arg("-Zunstable-options") + .arg("-Clink-args=-Wl,-v") + .input("main.rs") + .run(); + assert!( + find_lld_version_in_logs(output), + "the LLD version string should be present in the output logs" + ); + + // It should not be used when we explictly opt-out of lld. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .arg("-Clink-args=-Wl,-v") + .arg("-Zlinker-features=-lld") + .input("main.rs") + .run(); + assert!( + !find_lld_version_in_logs(output), + "the LLD version string should not be present in the output logs" + ); + + // While we're here, also check that the last linker feature flag "wins" when passed multiple + // times to rustc. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .arg("-Clink-args=-Wl,-v") + .arg("-Clink-self-contained=+linker") + .arg("-Zunstable-options") + .arg("-Zlinker-features=-lld") + .arg("-Zlinker-features=+lld") + .arg("-Zlinker-features=-lld,+lld") + .input("main.rs") + .run(); + assert!( + find_lld_version_in_logs(output), + "the LLD version string should be present in the output logs" + ); +} + +fn find_lld_version_in_logs(output: Output) -> bool { + let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); + let stderr = std::str::from_utf8(&output.stderr).unwrap(); + stderr.lines().any(|line| lld_version_re.is_match(line)) +} From 8fa6984e8edda921d34620f4eca657dc164c0f6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Sun, 14 Apr 2024 17:15:48 +0000 Subject: [PATCH 4/6] port `rust-lld-custom-target` test to rmake also make sure that rust-lld can be disabled via linker features, even when enabled by default by the target spec --- .../tidy/src/allowed_run_make_makefiles.txt | 1 - .../run-make/rust-lld-custom-target/Makefile | 7 --- .../run-make/rust-lld-custom-target/rmake.rs | 51 +++++++++++++++++++ 3 files changed, 51 insertions(+), 8 deletions(-) delete mode 100644 tests/run-make/rust-lld-custom-target/Makefile create mode 100644 tests/run-make/rust-lld-custom-target/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 45d3acd8fd4..f0ed0ae806f 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -249,7 +249,6 @@ run-make/rlib-format-packed-bundled-libs-2/Makefile run-make/rlib-format-packed-bundled-libs-3/Makefile run-make/rlib-format-packed-bundled-libs/Makefile run-make/rmeta-preferred/Makefile -run-make/rust-lld-custom-target/Makefile run-make/rustc-macro-dep-files/Makefile run-make/rustdoc-determinism/Makefile run-make/rustdoc-error-lines/Makefile diff --git a/tests/run-make/rust-lld-custom-target/Makefile b/tests/run-make/rust-lld-custom-target/Makefile deleted file mode 100644 index 007493ab0b9..00000000000 --- a/tests/run-make/rust-lld-custom-target/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -include ../tools.mk - -# needs-rust-lld -# only-x86_64-unknown-linux-gnu -all: - RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) --crate-type cdylib --target custom-target.json -Clink-args=-Wl,-v lib.rs 2> $(TMPDIR)/output.txt - $(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs new file mode 100644 index 00000000000..1b6e7c65b47 --- /dev/null +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -0,0 +1,51 @@ +// Test linking using `cc` with `rust-lld`, using a custom target with features described in MCP 510 +// see https://github.com/rust-lang/compiler-team/issues/510 for more info: +// +// Starting from the `x86_64-unknown-linux-gnu` target spec, we add the following options: +// - a linker-flavor using lld via a C compiler +// - the self-contained linker component is enabled + +//@ needs-rust-lld +//@ only-x86_64-unknown-linux-gnu + +extern crate run_make_support; + +use run_make_support::regex::Regex; +use run_make_support::rustc; +use std::process::Output; + +fn main() { + // Compile to a custom target spec with rust-lld enabled by default. We'll check that by asking + // the linker to display its version number with a link-arg. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .crate_type("cdylib") + .target("custom-target.json") + .arg("-Clink-args=-Wl,-v") + .input("lib.rs") + .run(); + assert!( + find_lld_version_in_logs(output), + "the LLD version string should be present in the output logs" + ); + + // But it can also be disabled via linker features. + let output = rustc() + .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") + .crate_type("cdylib") + .target("custom-target.json") + .arg("-Zlinker-features=-lld") + .arg("-Clink-args=-Wl,-v") + .input("lib.rs") + .run(); + assert!( + !find_lld_version_in_logs(output), + "the LLD version string should not be present in the output logs" + ); +} + +fn find_lld_version_in_logs(output: Output) -> bool { + let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap(); + let stderr = std::str::from_utf8(&output.stderr).unwrap(); + stderr.lines().any(|line| lld_version_re.is_match(line)) +} From 8acfe9a1380f73fade8dfe35aa054b3b6870faee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 15 Apr 2024 18:08:55 +0000 Subject: [PATCH 5/6] add `link_arg` helper to `run_make_support` and use it in the `rust-lld` tests --- src/tools/run-make-support/src/rustc.rs | 6 ++++++ tests/run-make/rust-lld-custom-target/rmake.rs | 4 ++-- tests/run-make/rust-lld/rmake.rs | 6 +++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index ebda151b908..88e409a588a 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -149,6 +149,12 @@ pub fn edition(&mut self, edition: &str) -> &mut Self { self } + /// Add an extra argument to the linker invocation, via `-Clink-arg`. + pub fn link_arg(&mut self, link_arg: &str) -> &mut Self { + self.cmd.arg(format!("-Clink-arg={link_arg}")); + self + } + #[track_caller] pub fn run_fail_assert_exit_code(&mut self, code: i32) -> Output { let caller_location = std::panic::Location::caller(); diff --git a/tests/run-make/rust-lld-custom-target/rmake.rs b/tests/run-make/rust-lld-custom-target/rmake.rs index 1b6e7c65b47..b5341725e36 100644 --- a/tests/run-make/rust-lld-custom-target/rmake.rs +++ b/tests/run-make/rust-lld-custom-target/rmake.rs @@ -21,7 +21,7 @@ fn main() { .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") .crate_type("cdylib") .target("custom-target.json") - .arg("-Clink-args=-Wl,-v") + .link_arg("-Wl,-v") .input("lib.rs") .run(); assert!( @@ -35,7 +35,7 @@ fn main() { .crate_type("cdylib") .target("custom-target.json") .arg("-Zlinker-features=-lld") - .arg("-Clink-args=-Wl,-v") + .link_arg("-Wl,-v") .input("lib.rs") .run(); assert!( diff --git a/tests/run-make/rust-lld/rmake.rs b/tests/run-make/rust-lld/rmake.rs index 053b580ebd1..acb6d74aaa8 100644 --- a/tests/run-make/rust-lld/rmake.rs +++ b/tests/run-make/rust-lld/rmake.rs @@ -19,7 +19,7 @@ fn main() { .arg("-Zlinker-features=+lld") .arg("-Clink-self-contained=+linker") .arg("-Zunstable-options") - .arg("-Clink-args=-Wl,-v") + .link_arg("-Wl,-v") .input("main.rs") .run(); assert!( @@ -30,7 +30,7 @@ fn main() { // It should not be used when we explictly opt-out of lld. let output = rustc() .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") - .arg("-Clink-args=-Wl,-v") + .link_arg("-Wl,-v") .arg("-Zlinker-features=-lld") .input("main.rs") .run(); @@ -43,7 +43,7 @@ fn main() { // times to rustc. let output = rustc() .env("RUSTC_LOG", "rustc_codegen_ssa::back::link=info") - .arg("-Clink-args=-Wl,-v") + .link_arg("-Wl,-v") .arg("-Clink-self-contained=+linker") .arg("-Zunstable-options") .arg("-Zlinker-features=-lld") From af887d3c42e6d2a2885f846ba0a67c052743fa7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 15 Apr 2024 19:45:01 +0000 Subject: [PATCH 6/6] mention json target specs in `run_make_support` --- src/tools/run-make-support/src/rustc.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tools/run-make-support/src/rustc.rs b/src/tools/run-make-support/src/rustc.rs index 88e409a588a..9bf41c6e2e9 100644 --- a/src/tools/run-make-support/src/rustc.rs +++ b/src/tools/run-make-support/src/rustc.rs @@ -128,9 +128,8 @@ pub fn json(&mut self, items: &str) -> &mut Self { self } - /// Specify target triple. + /// Specify the target triple, or a path to a custom target json spec file. pub fn target(&mut self, target: &str) -> &mut Self { - assert!(!target.contains(char::is_whitespace), "target triple cannot contain spaces"); self.cmd.arg(format!("--target={target}")); self }