Skip to content

Commit 1da271b

Browse files
committed
refactor add_gcc_ld_path into its final form
1 parent 0fb8071 commit 1da271b

File tree

2 files changed

+68
-51
lines changed

2 files changed

+68
-51
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 63 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
1212
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
1313
use rustc_middle::middle::dependency_format::Linkage;
1414
use rustc_middle::middle::exported_symbols::SymbolExportKind;
15-
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, LdImpl, Strip};
15+
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, Strip};
1616
use rustc_session::config::{OutputFilenames, OutputType, PrintRequest, SplitDwarfKind};
1717
use rustc_session::cstore::DllImport;
1818
use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
@@ -2246,7 +2246,8 @@ fn add_order_independent_options(
22462246
out_filename: &Path,
22472247
tmpdir: &Path,
22482248
) {
2249-
add_gcc_ld_path(cmd, sess, flavor);
2249+
// Take care of the flavors and CLI options requesting the `lld` linker.
2250+
add_lld_args(cmd, sess, flavor);
22502251

22512252
add_apple_sdk(cmd, sess, flavor);
22522253

@@ -2948,55 +2949,66 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootErro
29482949
}
29492950
}
29502951

2951-
fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
2952-
if let Some(ld_impl) = sess.opts.unstable_opts.gcc_ld {
2953-
if let LinkerFlavor::Gnu(Cc::Yes, _)
2954-
| LinkerFlavor::Darwin(Cc::Yes, _)
2955-
| LinkerFlavor::WasmLld(Cc::Yes) = flavor
2956-
{
2957-
match ld_impl {
2958-
LdImpl::Lld => {
2959-
// Implement the "self-contained" part of -Zgcc-ld
2960-
// by adding rustc distribution directories to the tool search path.
2961-
for path in sess.get_tools_search_paths(false) {
2962-
cmd.arg({
2963-
let mut arg = OsString::from("-B");
2964-
arg.push(path.join("gcc-ld"));
2965-
arg
2966-
});
2967-
}
2968-
// Implement the "linker flavor" part of -Zgcc-ld
2969-
// by asking cc to use some kind of lld.
2970-
cmd.arg("-fuse-ld=lld");
2971-
2972-
if !flavor.is_gnu() {
2973-
// Tell clang to use a non-default LLD flavor.
2974-
// Gcc doesn't understand the target option, but we currently assume
2975-
// that gcc is not used for Apple and Wasm targets (#97402).
2976-
//
2977-
// Note that we don't want to do that by default on macOS: e.g. passing a
2978-
// 10.7 target to LLVM works, but not to recent versions of clang/macOS, as
2979-
// shown in issue #101653 and the discussion in PR #101792.
2980-
//
2981-
// It could be required in some cases of cross-compiling with
2982-
// `-Zgcc-ld=lld`, but this is generally unspecified, and we don't know
2983-
// which specific versions of clang, macOS SDK, host and target OS
2984-
// combinations impact us here.
2985-
//
2986-
// So we do a simple first-approximation until we know more of what the
2987-
// Apple targets require (and which would be handled prior to hitting this
2988-
// `-Zgcc-ld=lld` codepath anyway), but the expectation is that until then
2989-
// this should be manually passed if needed. We specify the target when
2990-
// targeting a different linker flavor on macOS, and that's also always
2991-
// the case when targeting WASM.
2992-
if sess.target.linker_flavor != sess.host.linker_flavor {
2993-
cmd.arg(format!("--target={}", sess.target.llvm_target));
2994-
}
2995-
}
2996-
}
2997-
}
2998-
} else {
2999-
sess.emit_fatal(errors::OptionGccOnly);
2952+
/// When using the linker flavors opting in to `lld`, or the unstable `-Zgcc-ld=lld` flag, add the
2953+
/// necessary paths and arguments to invoke it:
2954+
/// - when the self-contained linker flag is active: the build of `lld` distributed with rustc,
2955+
/// - or any `lld` available to `cc`.
2956+
fn add_lld_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
2957+
let unstable_use_lld = sess.opts.unstable_opts.gcc_ld.is_some();
2958+
debug!("add_lld_args requested, flavor: '{flavor:?}', `-Zgcc-ld=lld`: {unstable_use_lld}");
2959+
2960+
// Sanity check: using the old unstable `-Zgcc-ld=lld` option requires a `cc`-using flavor.
2961+
let flavor_uses_cc = flavor.uses_cc();
2962+
if unstable_use_lld && !flavor_uses_cc {
2963+
sess.emit_fatal(errors::OptionGccOnly);
2964+
}
2965+
2966+
// If the flavor doesn't use a C/C++ compiler to invoke the linker, or doesn't opt in to `lld`,
2967+
// we don't need to do anything.
2968+
let use_lld = flavor.uses_lld() || unstable_use_lld;
2969+
if !flavor_uses_cc || !use_lld {
2970+
return;
2971+
}
2972+
2973+
// 1. Implement the "self-contained" part of this feature by adding rustc distribution
2974+
// directories to the tool's search path.
2975+
let self_contained_linker = sess.opts.cg.link_self_contained.linker() || unstable_use_lld;
2976+
if self_contained_linker {
2977+
for path in sess.get_tools_search_paths(false) {
2978+
cmd.arg({
2979+
let mut arg = OsString::from("-B");
2980+
arg.push(path.join("gcc-ld"));
2981+
arg
2982+
});
2983+
}
2984+
}
2985+
2986+
// 2. Implement the "linker flavor" part of this feature by asking `cc` to use some kind of
2987+
// `lld` as the linker.
2988+
cmd.arg("-fuse-ld=lld");
2989+
2990+
if !flavor.is_gnu() {
2991+
// Tell clang to use a non-default LLD flavor.
2992+
// Gcc doesn't understand the target option, but we currently assume
2993+
// that gcc is not used for Apple and Wasm targets (#97402).
2994+
//
2995+
// Note that we don't want to do that by default on macOS: e.g. passing a
2996+
// 10.7 target to LLVM works, but not to recent versions of clang/macOS, as
2997+
// shown in issue #101653 and the discussion in PR #101792.
2998+
//
2999+
// It could be required in some cases of cross-compiling with
3000+
// `-Zgcc-ld=lld`, but this is generally unspecified, and we don't know
3001+
// which specific versions of clang, macOS SDK, host and target OS
3002+
// combinations impact us here.
3003+
//
3004+
// So we do a simple first-approximation until we know more of what the
3005+
// Apple targets require (and which would be handled prior to hitting this
3006+
// `-Zgcc-ld=lld` codepath anyway), but the expectation is that until then
3007+
// this should be manually passed if needed. We specify the target when
3008+
// targeting a different linker flavor on macOS, and that's also always
3009+
// the case when targeting WASM.
3010+
if sess.target.linker_flavor != sess.host.linker_flavor {
3011+
cmd.arg(format!("--target={}", sess.target.llvm_target));
30003012
}
30013013
}
30023014
}

compiler/rustc_session/src/config.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,11 @@ impl LinkSelfContained {
307307
on.set_all_explicitly(true);
308308
on
309309
}
310+
311+
/// Returns whether the self-contained linker component is enabled.
312+
pub fn linker(&self) -> bool {
313+
self.components.contains(LinkSelfContainedComponents::LINKER)
314+
}
310315
}
311316

312317
/// Used with `-Z assert-incr-state`.

0 commit comments

Comments
 (0)