Skip to content

Commit 11b6d40

Browse files
committed
make CLI linker features influence the linker flavor
While they're isomorphic, we can flip the lld component where applicable, so that downstream doesn't have to check both the flavor and the linker features.
1 parent 2398d8c commit 11b6d40

File tree

2 files changed

+49
-2
lines changed
  • compiler

2 files changed

+49
-2
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
1111
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
1212
use rustc_middle::middle::dependency_format::Linkage;
1313
use rustc_middle::middle::exported_symbols::SymbolExportKind;
14+
use rustc_session::config::LinkerFeaturesCli;
1415
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, OutFileName, Strip};
1516
use rustc_session::config::{OutputFilenames, OutputType, PrintKind, SplitDwarfKind};
1617
use rustc_session::cstore::DllImport;
@@ -22,10 +23,10 @@ use rustc_session::utils::NativeLibKind;
2223
use rustc_session::{filesearch, Session};
2324
use rustc_span::symbol::Symbol;
2425
use rustc_target::spec::crt_objects::CrtObjects;
25-
use rustc_target::spec::LinkSelfContainedComponents;
2626
use rustc_target::spec::LinkSelfContainedDefault;
2727
use rustc_target::spec::LinkerFlavorCli;
2828
use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld, PanicStrategy};
29+
use rustc_target::spec::{LinkSelfContainedComponents, LinkerFeatures};
2930
use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo};
3031

3132
use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
@@ -1333,7 +1334,9 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
13331334
sess: &Session,
13341335
linker: Option<PathBuf>,
13351336
flavor: Option<LinkerFlavor>,
1337+
features: LinkerFeaturesCli,
13361338
) -> Option<(PathBuf, LinkerFlavor)> {
1339+
let flavor = flavor.map(|flavor| adjust_flavor_to_features(flavor, features));
13371340
match (linker, flavor) {
13381341
(Some(linker), Some(flavor)) => Some((linker, flavor)),
13391342
// only the linker flavor is known; use the default linker for the selected flavor
@@ -1381,12 +1384,33 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
13811384
sess.dcx().emit_fatal(errors::LinkerFileStem);
13821385
});
13831386
let flavor = sess.target.linker_flavor.with_linker_hints(stem);
1387+
let flavor = adjust_flavor_to_features(flavor, features);
13841388
Some((linker, flavor))
13851389
}
13861390
(None, None) => None,
13871391
}
13881392
}
13891393

1394+
// While linker flavors and linker features are isomorphic (and thus targets don't need to
1395+
// define features separately), we use the flavor as the root piece of data and have the
1396+
// linker-features CLI flag influence *that*, so that downstream code does not have to check for
1397+
// both yet.
1398+
fn adjust_flavor_to_features(
1399+
flavor: LinkerFlavor,
1400+
features: LinkerFeaturesCli,
1401+
) -> LinkerFlavor {
1402+
// Note: a linker feature cannot be both enabled and disabled on the CLI.
1403+
if features.enabled.contains(LinkerFeatures::LLD) {
1404+
flavor.with_lld_enabled()
1405+
} else if features.disabled.contains(LinkerFeatures::LLD) {
1406+
flavor.with_lld_disabled()
1407+
} else {
1408+
flavor
1409+
}
1410+
}
1411+
1412+
let features = sess.opts.unstable_opts.linker_features;
1413+
13901414
// linker and linker flavor specified via command line have precedence over what the target
13911415
// specification specifies
13921416
let linker_flavor = match sess.opts.cg.linker_flavor {
@@ -1400,14 +1424,15 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
14001424
.linker_flavor
14011425
.map(|flavor| sess.target.linker_flavor.with_cli_hints(flavor)),
14021426
};
1403-
if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor) {
1427+
if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor, features) {
14041428
return ret;
14051429
}
14061430

14071431
if let Some(ret) = infer_from(
14081432
sess,
14091433
sess.target.linker.as_deref().map(PathBuf::from),
14101434
Some(sess.target.linker_flavor),
1435+
features,
14111436
) {
14121437
return ret;
14131438
}

compiler/rustc_target/src/spec/mod.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,28 @@ impl LinkerFlavor {
448448
| LinkerFlavor::Ptx => false,
449449
}
450450
}
451+
452+
/// For flavors with an `Lld` component, ensure it's enabled. Otherwise, returns the given
453+
/// flavor unmodified.
454+
pub fn with_lld_enabled(self) -> LinkerFlavor {
455+
match self {
456+
LinkerFlavor::Gnu(cc, Lld::No) => LinkerFlavor::Gnu(cc, Lld::Yes),
457+
LinkerFlavor::Darwin(cc, Lld::No) => LinkerFlavor::Darwin(cc, Lld::Yes),
458+
LinkerFlavor::Msvc(Lld::No) => LinkerFlavor::Msvc(Lld::Yes),
459+
_ => self,
460+
}
461+
}
462+
463+
/// For flavors with an `Lld` component, ensure it's disabled. Otherwise, returns the given
464+
/// flavor unmodified.
465+
pub fn with_lld_disabled(self) -> LinkerFlavor {
466+
match self {
467+
LinkerFlavor::Gnu(cc, Lld::Yes) => LinkerFlavor::Gnu(cc, Lld::No),
468+
LinkerFlavor::Darwin(cc, Lld::Yes) => LinkerFlavor::Darwin(cc, Lld::No),
469+
LinkerFlavor::Msvc(Lld::Yes) => LinkerFlavor::Msvc(Lld::No),
470+
_ => self,
471+
}
472+
}
451473
}
452474

453475
macro_rules! linker_flavor_cli_impls {

0 commit comments

Comments
 (0)