@@ -11,6 +11,7 @@ use rustc_metadata::fs::{copy_to_stdout, emit_wrapper_file, METADATA_FILENAME};
11
11
use rustc_middle:: middle:: debugger_visualizer:: DebuggerVisualizerFile ;
12
12
use rustc_middle:: middle:: dependency_format:: Linkage ;
13
13
use rustc_middle:: middle:: exported_symbols:: SymbolExportKind ;
14
+ use rustc_session:: config:: LinkerFeaturesCli ;
14
15
use rustc_session:: config:: { self , CFGuard , CrateType , DebugInfo , OutFileName , Strip } ;
15
16
use rustc_session:: config:: { OutputFilenames , OutputType , PrintKind , SplitDwarfKind } ;
16
17
use rustc_session:: cstore:: DllImport ;
@@ -22,10 +23,10 @@ use rustc_session::utils::NativeLibKind;
22
23
use rustc_session:: { filesearch, Session } ;
23
24
use rustc_span:: symbol:: Symbol ;
24
25
use rustc_target:: spec:: crt_objects:: CrtObjects ;
25
- use rustc_target:: spec:: LinkSelfContainedComponents ;
26
26
use rustc_target:: spec:: LinkSelfContainedDefault ;
27
27
use rustc_target:: spec:: LinkerFlavorCli ;
28
28
use rustc_target:: spec:: { Cc , LinkOutputKind , LinkerFlavor , Lld , PanicStrategy } ;
29
+ use rustc_target:: spec:: { LinkSelfContainedComponents , LinkerFeatures } ;
29
30
use rustc_target:: spec:: { RelocModel , RelroLevel , SanitizerSet , SplitDebuginfo } ;
30
31
31
32
use super :: archive:: { ArchiveBuilder , ArchiveBuilderBuilder } ;
@@ -1333,7 +1334,9 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
1333
1334
sess : & Session ,
1334
1335
linker : Option < PathBuf > ,
1335
1336
flavor : Option < LinkerFlavor > ,
1337
+ features : LinkerFeaturesCli ,
1336
1338
) -> Option < ( PathBuf , LinkerFlavor ) > {
1339
+ let flavor = flavor. map ( |flavor| adjust_flavor_to_features ( flavor, features) ) ;
1337
1340
match ( linker, flavor) {
1338
1341
( Some ( linker) , Some ( flavor) ) => Some ( ( linker, flavor) ) ,
1339
1342
// 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) {
1381
1384
sess. dcx ( ) . emit_fatal ( errors:: LinkerFileStem ) ;
1382
1385
} ) ;
1383
1386
let flavor = sess. target . linker_flavor . with_linker_hints ( stem) ;
1387
+ let flavor = adjust_flavor_to_features ( flavor, features) ;
1384
1388
Some ( ( linker, flavor) )
1385
1389
}
1386
1390
( None , None ) => None ,
1387
1391
}
1388
1392
}
1389
1393
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
+
1390
1414
// linker and linker flavor specified via command line have precedence over what the target
1391
1415
// specification specifies
1392
1416
let linker_flavor = match sess. opts . cg . linker_flavor {
@@ -1400,14 +1424,15 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
1400
1424
. linker_flavor
1401
1425
. map ( |flavor| sess. target . linker_flavor . with_cli_hints ( flavor) ) ,
1402
1426
} ;
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 ) {
1404
1428
return ret;
1405
1429
}
1406
1430
1407
1431
if let Some ( ret) = infer_from (
1408
1432
sess,
1409
1433
sess. target . linker . as_deref ( ) . map ( PathBuf :: from) ,
1410
1434
Some ( sess. target . linker_flavor ) ,
1435
+ features,
1411
1436
) {
1412
1437
return ret;
1413
1438
}
0 commit comments