@@ -11,6 +11,7 @@ use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
1111use rustc_middle:: middle:: debugger_visualizer:: DebuggerVisualizerFile ;
1212use rustc_middle:: middle:: dependency_format:: Linkage ;
1313use rustc_middle:: middle:: exported_symbols:: SymbolExportKind ;
14+ use rustc_session:: config:: LinkerFeaturesCli ;
1415use rustc_session:: config:: { self , CFGuard , CrateType , DebugInfo , OutFileName , Strip } ;
1516use rustc_session:: config:: { OutputFilenames , OutputType , PrintKind , SplitDwarfKind } ;
1617use rustc_session:: cstore:: DllImport ;
@@ -22,10 +23,10 @@ use rustc_session::utils::NativeLibKind;
2223use rustc_session:: { filesearch, Session } ;
2324use rustc_span:: symbol:: Symbol ;
2425use rustc_target:: spec:: crt_objects:: CrtObjects ;
25- use rustc_target:: spec:: LinkSelfContainedComponents ;
2626use rustc_target:: spec:: LinkSelfContainedDefault ;
2727use rustc_target:: spec:: LinkerFlavorCli ;
2828use rustc_target:: spec:: { Cc , LinkOutputKind , LinkerFlavor , Lld , PanicStrategy } ;
29+ use rustc_target:: spec:: { LinkSelfContainedComponents , LinkerFeatures } ;
2930use rustc_target:: spec:: { RelocModel , RelroLevel , SanitizerSet , SplitDebuginfo } ;
3031
3132use 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 }
0 commit comments