mirror of https://github.com/rust-lang/rust.git
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.
This commit is contained in:
parent
2398d8cf08
commit
11b6d40a98
|
@ -11,6 +11,7 @@ use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
|
|||
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
|
||||
use rustc_middle::middle::dependency_format::Linkage;
|
||||
use rustc_middle::middle::exported_symbols::SymbolExportKind;
|
||||
use rustc_session::config::LinkerFeaturesCli;
|
||||
use rustc_session::config::{self, CFGuard, CrateType, DebugInfo, OutFileName, Strip};
|
||||
use rustc_session::config::{OutputFilenames, OutputType, PrintKind, SplitDwarfKind};
|
||||
use rustc_session::cstore::DllImport;
|
||||
|
@ -22,10 +23,10 @@ use rustc_session::utils::NativeLibKind;
|
|||
use rustc_session::{filesearch, Session};
|
||||
use rustc_span::symbol::Symbol;
|
||||
use rustc_target::spec::crt_objects::CrtObjects;
|
||||
use rustc_target::spec::LinkSelfContainedComponents;
|
||||
use rustc_target::spec::LinkSelfContainedDefault;
|
||||
use rustc_target::spec::LinkerFlavorCli;
|
||||
use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld, PanicStrategy};
|
||||
use rustc_target::spec::{LinkSelfContainedComponents, LinkerFeatures};
|
||||
use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo};
|
||||
|
||||
use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
|
||||
|
@ -1333,7 +1334,9 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
|
|||
sess: &Session,
|
||||
linker: Option<PathBuf>,
|
||||
flavor: Option<LinkerFlavor>,
|
||||
features: LinkerFeaturesCli,
|
||||
) -> Option<(PathBuf, LinkerFlavor)> {
|
||||
let flavor = flavor.map(|flavor| adjust_flavor_to_features(flavor, features));
|
||||
match (linker, flavor) {
|
||||
(Some(linker), Some(flavor)) => Some((linker, flavor)),
|
||||
// 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) {
|
|||
sess.dcx().emit_fatal(errors::LinkerFileStem);
|
||||
});
|
||||
let flavor = sess.target.linker_flavor.with_linker_hints(stem);
|
||||
let flavor = adjust_flavor_to_features(flavor, features);
|
||||
Some((linker, flavor))
|
||||
}
|
||||
(None, None) => None,
|
||||
}
|
||||
}
|
||||
|
||||
// While linker flavors and linker features are isomorphic (and thus targets don't need to
|
||||
// define features separately), we use the flavor as the root piece of data and have the
|
||||
// linker-features CLI flag influence *that*, so that downstream code does not have to check for
|
||||
// both yet.
|
||||
fn adjust_flavor_to_features(
|
||||
flavor: LinkerFlavor,
|
||||
features: LinkerFeaturesCli,
|
||||
) -> LinkerFlavor {
|
||||
// Note: a linker feature cannot be both enabled and disabled on the CLI.
|
||||
if features.enabled.contains(LinkerFeatures::LLD) {
|
||||
flavor.with_lld_enabled()
|
||||
} else if features.disabled.contains(LinkerFeatures::LLD) {
|
||||
flavor.with_lld_disabled()
|
||||
} else {
|
||||
flavor
|
||||
}
|
||||
}
|
||||
|
||||
let features = sess.opts.unstable_opts.linker_features;
|
||||
|
||||
// linker and linker flavor specified via command line have precedence over what the target
|
||||
// specification specifies
|
||||
let linker_flavor = match sess.opts.cg.linker_flavor {
|
||||
|
@ -1400,7 +1424,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
|
|||
.linker_flavor
|
||||
.map(|flavor| sess.target.linker_flavor.with_cli_hints(flavor)),
|
||||
};
|
||||
if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor) {
|
||||
if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor, features) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1408,6 +1432,7 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
|
|||
sess,
|
||||
sess.target.linker.as_deref().map(PathBuf::from),
|
||||
Some(sess.target.linker_flavor),
|
||||
features,
|
||||
) {
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -448,6 +448,28 @@ impl LinkerFlavor {
|
|||
| LinkerFlavor::Ptx => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// For flavors with an `Lld` component, ensure it's enabled. Otherwise, returns the given
|
||||
/// flavor unmodified.
|
||||
pub fn with_lld_enabled(self) -> LinkerFlavor {
|
||||
match self {
|
||||
LinkerFlavor::Gnu(cc, Lld::No) => LinkerFlavor::Gnu(cc, Lld::Yes),
|
||||
LinkerFlavor::Darwin(cc, Lld::No) => LinkerFlavor::Darwin(cc, Lld::Yes),
|
||||
LinkerFlavor::Msvc(Lld::No) => LinkerFlavor::Msvc(Lld::Yes),
|
||||
_ => self,
|
||||
}
|
||||
}
|
||||
|
||||
/// For flavors with an `Lld` component, ensure it's disabled. Otherwise, returns the given
|
||||
/// flavor unmodified.
|
||||
pub fn with_lld_disabled(self) -> LinkerFlavor {
|
||||
match self {
|
||||
LinkerFlavor::Gnu(cc, Lld::Yes) => LinkerFlavor::Gnu(cc, Lld::No),
|
||||
LinkerFlavor::Darwin(cc, Lld::Yes) => LinkerFlavor::Darwin(cc, Lld::No),
|
||||
LinkerFlavor::Msvc(Lld::Yes) => LinkerFlavor::Msvc(Lld::No),
|
||||
_ => self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! linker_flavor_cli_impls {
|
||||
|
|
Loading…
Reference in New Issue