Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MVP for using rust-lld as part of cc #85961

Merged
merged 1 commit into from
Jun 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)),
);
petrochenkov marked this conversation as resolved.
Show resolved Hide resolved
}

// 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