Auto merge of #85961 - 1000teslas:issue-71519-fix, r=petrochenkov
MVP for using rust-lld as part of cc Will fix #71519. I need to figure out how to write a test showing that lld is used instead of whatever linker cc normally uses. When I manually run rustc using `echo 'fn main() {}' | RUSTC_LOG=rustc_codegen_ssa:🔙:link=debug ./rustc -Clinker-flavor=gcc-lld --crate-type bin -Clink-arg=-Wl,-v` (thanks to bjorn3 on Zulip), I can see that lld is used, but I'm not sure how to inspect that output in a test.
This commit is contained in:
commit
72868e017b
@ -5,7 +5,7 @@ use rustc_fs_util::fix_windows_verbatim_for_gcc;
|
||||
use rustc_hir::def_id::CrateNum;
|
||||
use rustc_middle::middle::cstore::{DllImport, LibSource};
|
||||
use rustc_middle::middle::dependency_format::Linkage;
|
||||
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, Strip};
|
||||
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
|
||||
use rustc_session::config::{OutputFilenames, OutputType, PrintRequest};
|
||||
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
|
||||
use rustc_session::search_paths::PathKind;
|
||||
@ -1927,6 +1927,8 @@ fn add_order_independent_options(
|
||||
out_filename: &Path,
|
||||
tmpdir: &Path,
|
||||
) {
|
||||
add_gcc_ld_path(cmd, sess, flavor);
|
||||
|
||||
add_apple_sdk(cmd, sess, flavor);
|
||||
|
||||
add_link_script(cmd, sess, tmpdir, crate_type);
|
||||
@ -2528,3 +2530,30 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
|
||||
Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
|
||||
}
|
||||
}
|
||||
|
||||
fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
|
||||
if let Some(ld_impl) = sess.opts.debugging_opts.gcc_ld {
|
||||
if let LinkerFlavor::Gcc = flavor {
|
||||
match ld_impl {
|
||||
LdImpl::Lld => {
|
||||
let tools_path =
|
||||
sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
|
||||
let lld_path = tools_path
|
||||
.into_iter()
|
||||
.map(|p| p.join("gcc-ld"))
|
||||
.find(|p| {
|
||||
p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists()
|
||||
})
|
||||
.unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found"));
|
||||
cmd.cmd().arg({
|
||||
let mut arg = OsString::from("-B");
|
||||
arg.push(lld_path);
|
||||
arg
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sess.fatal("option `-Z gcc-ld` is used even though linker flavor is not gcc");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2417,6 +2417,7 @@ impl PpMode {
|
||||
/// we have an opt-in scheme here, so one is hopefully forced to think about
|
||||
/// how the hash should be calculated when adding a new command-line argument.
|
||||
crate mod dep_tracking {
|
||||
use super::LdImpl;
|
||||
use super::{
|
||||
CFGuard, CrateType, DebugInfo, ErrorOutputType, InstrumentCoverage, LinkerPluginLto,
|
||||
LtoCli, OptLevel, OutputTypes, Passes, SourceFileHashAlgorithm, SwitchWithOptPath,
|
||||
@ -2497,6 +2498,7 @@ crate mod dep_tracking {
|
||||
SymbolManglingVersion,
|
||||
SourceFileHashAlgorithm,
|
||||
TrimmedDefPaths,
|
||||
Option<LdImpl>,
|
||||
);
|
||||
|
||||
impl<T1, T2> DepTrackingHash for (T1, T2)
|
||||
|
@ -370,6 +370,7 @@ mod desc {
|
||||
pub const parse_wasi_exec_model: &str = "either `command` or `reactor`";
|
||||
pub const parse_split_debuginfo: &str =
|
||||
"one of supported split-debuginfo modes (`off`, `packed`, or `unpacked`)";
|
||||
pub const parse_gcc_ld: &str = "one of: no value, `lld`";
|
||||
}
|
||||
|
||||
mod parse {
|
||||
@ -864,6 +865,15 @@ mod parse {
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
crate fn parse_gcc_ld(slot: &mut Option<LdImpl>, v: Option<&str>) -> bool {
|
||||
match v {
|
||||
None => *slot = None,
|
||||
Some("lld") => *slot = Some(LdImpl::Lld),
|
||||
_ => return false,
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
options! {
|
||||
@ -1067,6 +1077,7 @@ options! {
|
||||
"set the optimization fuel quota for a crate"),
|
||||
function_sections: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
"whether each function should go in its own section"),
|
||||
gcc_ld: Option<LdImpl> = (None, parse_gcc_ld, [TRACKED], "implementation of ld used by cc"),
|
||||
graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED],
|
||||
"use dark-themed colors in graphviz output (default: no)"),
|
||||
graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED],
|
||||
@ -1321,3 +1332,8 @@ pub enum WasiExecModel {
|
||||
Command,
|
||||
Reactor,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Hash)]
|
||||
pub enum LdImpl {
|
||||
Lld,
|
||||
}
|
||||
|
@ -1108,6 +1108,13 @@ impl Step for Assemble {
|
||||
let src_exe = exe("lld", target_compiler.host);
|
||||
let dst_exe = exe("rust-lld", target_compiler.host);
|
||||
builder.copy(&lld_install.join("bin").join(&src_exe), &libdir_bin.join(&dst_exe));
|
||||
// for `-Z gcc-ld=lld`
|
||||
let gcc_ld_dir = libdir_bin.join("gcc-ld");
|
||||
t!(fs::create_dir(&gcc_ld_dir));
|
||||
builder.copy(
|
||||
&lld_install.join("bin").join(&src_exe),
|
||||
&gcc_ld_dir.join(exe("ld", target_compiler.host)),
|
||||
);
|
||||
}
|
||||
|
||||
// Similarly, copy `llvm-dwp` into libdir for Split DWARF. Only copy it when the LLVM
|
||||
|
@ -402,6 +402,10 @@ impl Step for Rustc {
|
||||
if builder.config.lld_enabled {
|
||||
let exe = exe("rust-lld", compiler.host);
|
||||
builder.copy(&src_dir.join(&exe), &dst_dir.join(&exe));
|
||||
// for `-Z gcc-ld=lld`
|
||||
let gcc_lld_dir = dst_dir.join("gcc-ld");
|
||||
t!(fs::create_dir(&gcc_lld_dir));
|
||||
builder.copy(&src_dir.join(&exe), &gcc_lld_dir.join(&exe));
|
||||
}
|
||||
|
||||
// Copy over llvm-dwp if it's there
|
||||
|
6
src/test/run-make/issue-71519/Makefile
Normal file
6
src/test/run-make/issue-71519/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
-include ../../run-make-fulldeps/tools.mk
|
||||
|
||||
# needs-rust-lld
|
||||
all:
|
||||
RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Z gcc-ld=lld -C link-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt
|
||||
$(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt
|
4
src/test/run-make/issue-71519/main.rs
Normal file
4
src/test/run-make/issue-71519/main.rs
Normal file
@ -0,0 +1,4 @@
|
||||
// test linking using cc with rust-lld injected into search path as ld
|
||||
// see rust-lang/rust#71519 for more info
|
||||
|
||||
fn main() {}
|
@ -50,6 +50,15 @@ impl EarlyProps {
|
||||
let has_msan = util::MSAN_SUPPORTED_TARGETS.contains(&&*config.target);
|
||||
let has_tsan = util::TSAN_SUPPORTED_TARGETS.contains(&&*config.target);
|
||||
let has_hwasan = util::HWASAN_SUPPORTED_TARGETS.contains(&&*config.target);
|
||||
// for `-Z gcc-ld=lld`
|
||||
let has_rust_lld = config
|
||||
.compile_lib_path
|
||||
.join("rustlib")
|
||||
.join(&config.target)
|
||||
.join("bin")
|
||||
.join("gcc-ld")
|
||||
.join(if config.host.contains("windows") { "ld.exe" } else { "ld" })
|
||||
.exists();
|
||||
|
||||
iter_header(testfile, None, rdr, &mut |ln| {
|
||||
// we should check if any only-<platform> exists and if it exists
|
||||
@ -136,6 +145,10 @@ impl EarlyProps {
|
||||
if config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln) {
|
||||
props.ignore = true;
|
||||
}
|
||||
|
||||
if !has_rust_lld && config.parse_name_directive(ln, "needs-rust-lld") {
|
||||
props.ignore = true;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(s) = config.parse_aux_build(ln) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user