Skip to content

Commit 2a76762

Browse files
gcc-lld mvp
ignore test if rust-lld not found create ld -> rust-lld symlink at build time instead of run time for testing in ci copy instead of symlinking remove linux check test for linker, suggestions from bjorn3 fix overly restrictive lld matcher use -Zgcc-ld flag instead of -Clinker-flavor refactor code adding lld to gcc path revert ci changes suggestions from petrochenkov rename gcc_ld to gcc-ld in dirs
1 parent c5fbcd3 commit 2a76762

File tree

8 files changed

+82
-1
lines changed

8 files changed

+82
-1
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_fs_util::fix_windows_verbatim_for_gcc;
55
use rustc_hir::def_id::CrateNum;
66
use rustc_middle::middle::cstore::{DllImport, LibSource};
77
use rustc_middle::middle::dependency_format::Linkage;
8-
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, Strip};
8+
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
99
use rustc_session::config::{OutputFilenames, OutputType, PrintRequest};
1010
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
1111
use rustc_session::search_paths::PathKind;
@@ -1927,6 +1927,8 @@ fn add_order_independent_options(
19271927
out_filename: &Path,
19281928
tmpdir: &Path,
19291929
) {
1930+
add_gcc_ld_path(cmd, sess, flavor);
1931+
19301932
add_apple_sdk(cmd, sess, flavor);
19311933

19321934
add_link_script(cmd, sess, tmpdir, crate_type);
@@ -2528,3 +2530,30 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
25282530
Err(e) => Err(format!("failed to get {} SDK path: {}", sdk_name, e)),
25292531
}
25302532
}
2533+
2534+
fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
2535+
if let Some(ld_impl) = sess.opts.debugging_opts.gcc_ld {
2536+
if let LinkerFlavor::Gcc = flavor {
2537+
match ld_impl {
2538+
LdImpl::Lld => {
2539+
let tools_path =
2540+
sess.host_filesearch(PathKind::All).get_tools_search_paths(false);
2541+
let lld_path = tools_path
2542+
.into_iter()
2543+
.map(|p| p.join("gcc-ld"))
2544+
.find(|p| {
2545+
p.join(if sess.host.is_like_windows { "ld.exe" } else { "ld" }).exists()
2546+
})
2547+
.unwrap_or_else(|| sess.fatal("rust-lld (as ld) not found"));
2548+
cmd.cmd().arg({
2549+
let mut arg = OsString::from("-B");
2550+
arg.push(lld_path);
2551+
arg
2552+
});
2553+
}
2554+
}
2555+
} else {
2556+
sess.fatal("option `-Z gcc-ld` is used even though linker flavor is not gcc");
2557+
}
2558+
}
2559+
}

compiler/rustc_session/src/config.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2417,6 +2417,7 @@ impl PpMode {
24172417
/// we have an opt-in scheme here, so one is hopefully forced to think about
24182418
/// how the hash should be calculated when adding a new command-line argument.
24192419
crate mod dep_tracking {
2420+
use super::LdImpl;
24202421
use super::{
24212422
CFGuard, CrateType, DebugInfo, ErrorOutputType, InstrumentCoverage, LinkerPluginLto,
24222423
LtoCli, OptLevel, OutputTypes, Passes, SourceFileHashAlgorithm, SwitchWithOptPath,
@@ -2497,6 +2498,7 @@ crate mod dep_tracking {
24972498
SymbolManglingVersion,
24982499
SourceFileHashAlgorithm,
24992500
TrimmedDefPaths,
2501+
Option<LdImpl>,
25002502
);
25012503

25022504
impl<T1, T2> DepTrackingHash for (T1, T2)

compiler/rustc_session/src/options.rs

+16
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ mod desc {
370370
pub const parse_wasi_exec_model: &str = "either `command` or `reactor`";
371371
pub const parse_split_debuginfo: &str =
372372
"one of supported split-debuginfo modes (`off`, `packed`, or `unpacked`)";
373+
pub const parse_gcc_ld: &str = "one of: no value, `lld`";
373374
}
374375

375376
mod parse {
@@ -864,6 +865,15 @@ mod parse {
864865
}
865866
true
866867
}
868+
869+
crate fn parse_gcc_ld(slot: &mut Option<LdImpl>, v: Option<&str>) -> bool {
870+
match v {
871+
None => *slot = None,
872+
Some("lld") => *slot = Some(LdImpl::Lld),
873+
_ => return false,
874+
}
875+
true
876+
}
867877
}
868878

869879
options! {
@@ -1067,6 +1077,7 @@ options! {
10671077
"set the optimization fuel quota for a crate"),
10681078
function_sections: Option<bool> = (None, parse_opt_bool, [TRACKED],
10691079
"whether each function should go in its own section"),
1080+
gcc_ld: Option<LdImpl> = (None, parse_gcc_ld, [TRACKED], "implementation of ld used by cc"),
10701081
graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED],
10711082
"use dark-themed colors in graphviz output (default: no)"),
10721083
graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED],
@@ -1321,3 +1332,8 @@ pub enum WasiExecModel {
13211332
Command,
13221333
Reactor,
13231334
}
1335+
1336+
#[derive(Clone, Copy, Hash)]
1337+
pub enum LdImpl {
1338+
Lld,
1339+
}

src/bootstrap/compile.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,13 @@ impl Step for Assemble {
11081108
let src_exe = exe("lld", target_compiler.host);
11091109
let dst_exe = exe("rust-lld", target_compiler.host);
11101110
builder.copy(&lld_install.join("bin").join(&src_exe), &libdir_bin.join(&dst_exe));
1111+
// for `-Z gcc-ld=lld`
1112+
let gcc_ld_dir = libdir_bin.join("gcc-ld");
1113+
t!(fs::create_dir(&gcc_ld_dir));
1114+
builder.copy(
1115+
&lld_install.join("bin").join(&src_exe),
1116+
&gcc_ld_dir.join(exe("ld", target_compiler.host)),
1117+
);
11111118
}
11121119

11131120
// Similarly, copy `llvm-dwp` into libdir for Split DWARF. Only copy it when the LLVM

src/bootstrap/dist.rs

+4
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,10 @@ impl Step for Rustc {
402402
if builder.config.lld_enabled {
403403
let exe = exe("rust-lld", compiler.host);
404404
builder.copy(&src_dir.join(&exe), &dst_dir.join(&exe));
405+
// for `-Z gcc-ld=lld`
406+
let gcc_lld_dir = dst_dir.join("gcc-ld");
407+
t!(fs::create_dir(&gcc_lld_dir));
408+
builder.copy(&src_dir.join(&exe), &gcc_lld_dir.join(&exe));
405409
}
406410

407411
// Copy over llvm-dwp if it's there
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-include ../../run-make-fulldeps/tools.mk
2+
3+
# needs-rust-lld
4+
all:
5+
RUSTC_LOG=rustc_codegen_ssa::back::link=info $(RUSTC) -Z gcc-ld=lld -C link-args=-Wl,-v main.rs 2> $(TMPDIR)/output.txt
6+
$(CGREP) -e "^LLD [0-9]+\.[0-9]+\.[0-9]+" < $(TMPDIR)/output.txt

src/test/run-make/issue-71519/main.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// test linking using cc with rust-lld injected into search path as ld
2+
// see rust-lang/rust#71519 for more info
3+
4+
fn main() {}

src/tools/compiletest/src/header.rs

+13
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ impl EarlyProps {
5050
let has_msan = util::MSAN_SUPPORTED_TARGETS.contains(&&*config.target);
5151
let has_tsan = util::TSAN_SUPPORTED_TARGETS.contains(&&*config.target);
5252
let has_hwasan = util::HWASAN_SUPPORTED_TARGETS.contains(&&*config.target);
53+
// for `-Z gcc-ld=lld`
54+
let has_rust_lld = config
55+
.compile_lib_path
56+
.join("rustlib")
57+
.join(&config.target)
58+
.join("bin")
59+
.join("gcc-ld")
60+
.join(if config.host.contains("windows") { "ld.exe" } else { "ld" })
61+
.exists();
5362

5463
iter_header(testfile, None, rdr, &mut |ln| {
5564
// we should check if any only-<platform> exists and if it exists
@@ -136,6 +145,10 @@ impl EarlyProps {
136145
if config.debugger == Some(Debugger::Lldb) && ignore_lldb(config, ln) {
137146
props.ignore = true;
138147
}
148+
149+
if !has_rust_lld && config.parse_name_directive(ln, "needs-rust-lld") {
150+
props.ignore = true;
151+
}
139152
}
140153

141154
if let Some(s) = config.parse_aux_build(ln) {

0 commit comments

Comments
 (0)