Add a helper function for checking if LLD was used to run-make-support

This commit is contained in:
Jakub Beránek 2025-03-18 08:00:10 +01:00
parent e0883a2a6c
commit 6af96f873a
No known key found for this signature in database
GPG key ID: 909CD0D26483516B
6 changed files with 68 additions and 118 deletions

View file

@ -17,6 +17,7 @@ pub mod assertion_helpers;
pub mod diff;
pub mod env;
pub mod external_deps;
pub mod linker;
pub mod path_helpers;
pub mod run;
pub mod scoped_run;

View file

@ -0,0 +1,36 @@
use regex::Regex;
use crate::{Rustc, is_msvc};
/// Asserts that `rustc` uses LLD for linking when executed.
pub fn assert_rustc_uses_lld(rustc: &mut Rustc) {
let stderr = get_stderr_with_linker_messages(rustc);
assert!(
has_lld_version_in_logs(&stderr),
"LLD version should be present in rustc stderr:\n{stderr}"
);
}
/// Asserts that `rustc` doesn't use LLD for linking when executed.
pub fn assert_rustc_doesnt_use_lld(rustc: &mut Rustc) {
let stderr = get_stderr_with_linker_messages(rustc);
assert!(
!has_lld_version_in_logs(&stderr),
"LLD version should NOT be present in rustc stderr:\n{stderr}"
);
}
fn get_stderr_with_linker_messages(rustc: &mut Rustc) -> String {
// lld-link is used if msvc, otherwise a gnu-compatible lld is used.
let linker_version_flag = if is_msvc() { "--version" } else { "-Wl,-v" };
let output = rustc.arg("-Wlinker-messages").link_arg(linker_version_flag).run();
output.stderr_utf8()
}
fn has_lld_version_in_logs(stderr: &str) -> bool {
// Strip the `-Wlinker-messages` wrappers prefixing the linker output.
let stderr = Regex::new(r"warning: linker std(out|err):").unwrap().replace_all(&stderr, "");
let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
}

View file

@ -4,24 +4,11 @@
//@ ignore-nightly
//@ only-x86_64-unknown-linux-gnu
use std::process::Output;
use run_make_support::regex::Regex;
use run_make_support::linker::assert_rustc_doesnt_use_lld;
use run_make_support::rustc;
fn main() {
// A regular compilation should not use rust-lld by default. We'll check that by asking the
// linker to display its version number with a link-arg.
let output = rustc().arg("-Wlinker-messages").link_arg("-Wl,-v").input("main.rs").run();
assert!(
!find_lld_version_in_logs(output.stderr_utf8()),
"the LLD version string should not be present in the output logs:\n{}",
output.stderr_utf8()
);
}
fn find_lld_version_in_logs(stderr: String) -> bool {
let lld_version_re =
Regex::new(r"^warning: linker stdout: LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
assert_rustc_doesnt_use_lld(rustc().input("main.rs"));
}

View file

@ -6,35 +6,14 @@
//@ ignore-stable
//@ only-x86_64-unknown-linux-gnu
use run_make_support::regex::Regex;
use run_make_support::linker::{assert_rustc_doesnt_use_lld, assert_rustc_uses_lld};
use run_make_support::rustc;
fn main() {
// A regular compilation should use rust-lld by default. We'll check that by asking the linker
// to display its version number with a link-arg.
let output = rustc().arg("-Wlinker-messages").link_arg("-Wl,-v").input("main.rs").run();
assert!(
find_lld_version_in_logs(output.stderr_utf8()),
"the LLD version string should be present in the output logs:\n{}",
output.stderr_utf8()
);
assert_rustc_uses_lld(rustc().input("main.rs"));
// But it can still be disabled by turning the linker feature off.
let output = rustc()
.arg("-Wlinker-messages")
.link_arg("-Wl,-v")
.arg("-Zlinker-features=-lld")
.input("main.rs")
.run();
assert!(
!find_lld_version_in_logs(output.stderr_utf8()),
"the LLD version string should not be present in the output logs:\n{}",
output.stderr_utf8()
);
}
fn find_lld_version_in_logs(stderr: String) -> bool {
let lld_version_re =
Regex::new(r"^warning: linker stdout: LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs"));
}

View file

@ -8,43 +8,22 @@
//@ needs-rust-lld
//@ only-x86_64-unknown-linux-gnu
use run_make_support::regex::Regex;
use run_make_support::linker::{assert_rustc_doesnt_use_lld, assert_rustc_uses_lld};
use run_make_support::rustc;
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()
.crate_type("cdylib")
.arg("-Wlinker-messages")
.target("custom-target.json")
.link_arg("-Wl,-v")
.input("lib.rs")
.run();
assert!(
find_lld_version_in_logs(output.stderr_utf8()),
"the LLD version string should be present in the output logs:\n{}",
output.stderr_utf8()
assert_rustc_uses_lld(
rustc().crate_type("cdylib").target("custom-target.json").input("lib.rs"),
);
// But it can also be disabled via linker features.
let output = rustc()
assert_rustc_doesnt_use_lld(
rustc()
.crate_type("cdylib")
.arg("-Wlinker-messages")
.target("custom-target.json")
.arg("-Zlinker-features=-lld")
.link_arg("-Wl,-v")
.input("lib.rs")
.run();
assert!(
!find_lld_version_in_logs(output.stderr_utf8()),
"the LLD version string should not be present in the output logs:\n{}",
output.stderr_utf8()
.input("lib.rs"),
);
}
fn find_lld_version_in_logs(stderr: String) -> bool {
let lld_version_re =
Regex::new(r"^warning: linker stdout: LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
}

View file

@ -4,64 +4,32 @@
//@ needs-rust-lld
//@ ignore-s390x lld does not yet support s390x as target
use run_make_support::regex::Regex;
use run_make_support::{is_msvc, rustc};
use run_make_support::linker::{assert_rustc_doesnt_use_lld, assert_rustc_uses_lld};
use run_make_support::rustc;
fn main() {
// lld-link is used if msvc, otherwise a gnu-compatible lld is used.
let linker_version_flag = if is_msvc() { "--version" } else { "-Wl,-v" };
// 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()
assert_rustc_uses_lld(
rustc()
.arg("-Zlinker-features=+lld")
.arg("-Clink-self-contained=+linker")
.arg("-Zunstable-options")
.arg("-Wlinker-messages")
.link_arg(linker_version_flag)
.input("main.rs")
.run();
assert!(
find_lld_version_in_logs(output.stderr_utf8()),
"the LLD version string should be present in the output logs:\n{}",
output.stderr_utf8()
.input("main.rs"),
);
// It should not be used when we explicitly opt-out of lld.
let output = rustc()
.link_arg(linker_version_flag)
.arg("-Zlinker-features=-lld")
.arg("-Wlinker-messages")
.input("main.rs")
.run();
assert!(
!find_lld_version_in_logs(output.stderr_utf8()),
"the LLD version string should not be present in the output logs:\n{}",
output.stderr_utf8()
);
assert_rustc_doesnt_use_lld(rustc().arg("-Zlinker-features=-lld").input("main.rs"));
// While we're here, also check that the last linker feature flag "wins" when passed multiple
// times to rustc.
let output = rustc()
.link_arg(linker_version_flag)
assert_rustc_uses_lld(
rustc()
.arg("-Clink-self-contained=+linker")
.arg("-Zunstable-options")
.arg("-Zlinker-features=-lld")
.arg("-Zlinker-features=+lld")
.arg("-Zlinker-features=-lld,+lld")
.arg("-Wlinker-messages")
.input("main.rs")
.run();
assert!(
find_lld_version_in_logs(output.stderr_utf8()),
"the LLD version string should be present in the output logs:\n{}",
output.stderr_utf8()
.input("main.rs"),
);
}
fn find_lld_version_in_logs(stderr: String) -> bool {
// Strip the `-Wlinker-messages` wrappers prefixing the linker output.
let stderr = Regex::new(r"warning: linker std(out|err):").unwrap().replace_all(&stderr, "");
let lld_version_re = Regex::new(r"^LLD [0-9]+\.[0-9]+\.[0-9]+").unwrap();
stderr.lines().any(|line| lld_version_re.is_match(line.trim()))
}