Skip to content

Commit

Permalink
Auto merge of #85961 - 1000teslas:issue-71519-fix, r=petrochenkov
Browse files Browse the repository at this point in the history
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::back::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.
  • Loading branch information
bors committed Jun 11, 2021
2 parents 46ad16b + 2a76762 commit 72868e0
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 1 deletion.
31 changes: 30 additions & 1 deletion compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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");
}
}
}
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -2497,6 +2498,7 @@ crate mod dep_tracking {
SymbolManglingVersion,
SourceFileHashAlgorithm,
TrimmedDefPaths,
Option<LdImpl>,
);

impl<T1, T2> DepTrackingHash for (T1, T2)
Expand Down
16 changes: 16 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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! {
Expand Down Expand Up @@ -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],
Expand Down Expand Up @@ -1321,3 +1332,8 @@ pub enum WasiExecModel {
Command,
Reactor,
}

#[derive(Clone, Copy, Hash)]
pub enum LdImpl {
Lld,
}
7 changes: 7 additions & 0 deletions src/bootstrap/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions src/test/run-make/issue-71519/Makefile
Original file line number Diff line number Diff line change
@@ -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 changes: 4 additions & 0 deletions src/test/run-make/issue-71519/main.rs
Original file line number Diff line number Diff line change
@@ -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() {}
13 changes: 13 additions & 0 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 72868e0

Please sign in to comment.