From 2a76762695325e6f189bcd865b57e7154dbf3574 Mon Sep 17 00:00:00 2001 From: 1000teslas <47207223+1000teslas@users.noreply.github.com> Date: Wed, 2 Jun 2021 19:48:33 +1000 Subject: [PATCH] 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 --- compiler/rustc_codegen_ssa/src/back/link.rs | 31 ++++++++++++++++++++- compiler/rustc_session/src/config.rs | 2 ++ compiler/rustc_session/src/options.rs | 16 +++++++++++ src/bootstrap/compile.rs | 7 +++++ src/bootstrap/dist.rs | 4 +++ src/test/run-make/issue-71519/Makefile | 6 ++++ src/test/run-make/issue-71519/main.rs | 4 +++ src/tools/compiletest/src/header.rs | 13 +++++++++ 8 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 src/test/run-make/issue-71519/Makefile create mode 100644 src/test/run-make/issue-71519/main.rs diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index cb56e3f9e8a19..6c9ec9e7b0dae 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -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 { 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"); + } + } +} diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 5752258268384..2b547f8be9228 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -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, ); impl DepTrackingHash for (T1, T2) diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 58a53b3de6eb0..1946bfd78cc38 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -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, 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 = (None, parse_opt_bool, [TRACKED], "whether each function should go in its own section"), + gcc_ld: Option = (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, +} diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index ed311e273b19c..112a6ea939869 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -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 diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index aee3c8324bc11..71ed0af4a7c04 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -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 diff --git a/src/test/run-make/issue-71519/Makefile b/src/test/run-make/issue-71519/Makefile new file mode 100644 index 0000000000000..636665ec1d0c2 --- /dev/null +++ b/src/test/run-make/issue-71519/Makefile @@ -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 diff --git a/src/test/run-make/issue-71519/main.rs b/src/test/run-make/issue-71519/main.rs new file mode 100644 index 0000000000000..f8d09e8975330 --- /dev/null +++ b/src/test/run-make/issue-71519/main.rs @@ -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() {} diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 983934d129a2e..3b620ab65ab94 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -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- 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) {