@@ -22,10 +22,10 @@ use rustc_session::utils::NativeLibKind;
22
22
use rustc_session:: { filesearch, Session } ;
23
23
use rustc_span:: symbol:: Symbol ;
24
24
use rustc_target:: spec:: crt_objects:: CrtObjects ;
25
- use rustc_target:: spec:: LinkSelfContainedComponents ;
26
25
use rustc_target:: spec:: LinkSelfContainedDefault ;
27
26
use rustc_target:: spec:: LinkerFlavorCli ;
28
27
use rustc_target:: spec:: { Cc , LinkOutputKind , LinkerFlavor , Lld , PanicStrategy } ;
28
+ use rustc_target:: spec:: { LinkSelfContainedComponents , LinkerFeatures } ;
29
29
use rustc_target:: spec:: { RelocModel , RelroLevel , SanitizerSet , SplitDebuginfo } ;
30
30
31
31
use super :: archive:: { ArchiveBuilder , ArchiveBuilderBuilder } ;
@@ -741,6 +741,8 @@ fn link_natively(
741
741
info ! ( "preparing {:?} to {:?}" , crate_type, out_filename) ;
742
742
let ( linker_path, flavor) = linker_and_flavor ( sess) ;
743
743
let self_contained_components = self_contained_components ( sess, crate_type) ;
744
+ let linker_features = linker_features ( sess, flavor) ;
745
+
744
746
let mut cmd = linker_with_args (
745
747
& linker_path,
746
748
flavor,
@@ -751,6 +753,7 @@ fn link_natively(
751
753
out_filename,
752
754
codegen_results,
753
755
self_contained_components,
756
+ linker_features,
754
757
) ?;
755
758
756
759
linker:: disable_localization ( & mut cmd) ;
@@ -1816,6 +1819,40 @@ fn self_contained_components(sess: &Session, crate_type: CrateType) -> LinkSelfC
1816
1819
}
1817
1820
}
1818
1821
1822
+ /// Returns the set of linker features that are:
1823
+ /// - enabled on the CLI, or by the current target
1824
+ /// - and, are not disabled on the CLI
1825
+ fn linker_features ( sess : & Session , flavor : LinkerFlavor ) -> LinkerFeatures {
1826
+ // Note: currently, both the linker flavors and linker features model the same functionality:
1827
+ // they can only contain whether the linker is used via a C/C++ compiler, and whether the linker
1828
+ // used is lld.
1829
+ //
1830
+ // While linker features are unstable, and in order to reduce churn on the many target specs
1831
+ // (e.g. by adding linker features there, and removing the cc/lld components from the flavors)
1832
+ // we currently *infer* the target's linker features from the linker flavor itself.
1833
+ //
1834
+ // For stabilization, and/or when linker features gain additional components that are not
1835
+ // modeled by the current linker flavors, the refactoring mentioned above may need to be done.
1836
+ let mut linker_features_target = LinkerFeatures :: empty ( ) ;
1837
+ if flavor. uses_cc ( ) {
1838
+ linker_features_target. insert ( LinkerFeatures :: CC ) ;
1839
+ }
1840
+ if flavor. uses_lld ( ) {
1841
+ linker_features_target. insert ( LinkerFeatures :: LLD ) ;
1842
+ }
1843
+
1844
+ // Now we merge the features enabled on the CLI and the target, and remove the ones disabled on
1845
+ // the CLI.
1846
+ let linker_features_cli = & sess. opts . unstable_opts . linker_features ;
1847
+ debug ! (
1848
+ "linker features - target: {:?}, enabled on CLI: {:?}, disabled on CLI: {:?}" ,
1849
+ linker_features_target, linker_features_cli. enabled, linker_features_cli. disabled
1850
+ ) ;
1851
+ let linker_features =
1852
+ ( linker_features_cli. enabled | linker_features_target) - linker_features_cli. disabled ;
1853
+ linker_features
1854
+ }
1855
+
1819
1856
/// Add pre-link object files defined by the target spec.
1820
1857
fn add_pre_link_objects (
1821
1858
cmd : & mut dyn Linker ,
@@ -2114,6 +2151,7 @@ fn linker_with_args(
2114
2151
out_filename : & Path ,
2115
2152
codegen_results : & CodegenResults ,
2116
2153
self_contained_components : LinkSelfContainedComponents ,
2154
+ linker_features : LinkerFeatures ,
2117
2155
) -> Result < Command , ErrorGuaranteed > {
2118
2156
let self_contained_crt_objects = self_contained_components. is_crt_objects_enabled ( ) ;
2119
2157
let cmd = & mut * super :: linker:: get_linker (
@@ -2301,6 +2339,7 @@ fn linker_with_args(
2301
2339
codegen_results,
2302
2340
out_filename,
2303
2341
tmpdir,
2342
+ linker_features,
2304
2343
) ;
2305
2344
2306
2345
// Can be used for arbitrary order-independent options.
@@ -2334,9 +2373,10 @@ fn add_order_independent_options(
2334
2373
codegen_results : & CodegenResults ,
2335
2374
out_filename : & Path ,
2336
2375
tmpdir : & Path ,
2376
+ linker_features : LinkerFeatures ,
2337
2377
) {
2338
2378
// Take care of the flavors and CLI options requesting the `lld` linker.
2339
- add_lld_args ( cmd, sess, flavor, self_contained_components) ;
2379
+ add_lld_args ( cmd, sess, flavor, self_contained_components, linker_features ) ;
2340
2380
2341
2381
add_apple_sdk ( cmd, sess, flavor) ;
2342
2382
@@ -3053,24 +3093,21 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootErro
3053
3093
}
3054
3094
}
3055
3095
3056
- /// When using the linker flavors opting in to `lld`, add the necessary paths and arguments to
3057
- /// invoke it:
3096
+ /// When using the linker flavors (or linker feature) opting in to `lld`, add the necessary paths
3097
+ /// and arguments to invoke it:
3058
3098
/// - when the self-contained linker flag is active: the build of `lld` distributed with rustc,
3059
3099
/// - or any `lld` available to `cc`.
3100
+ #[ instrument( level = "debug" , skip( cmd, sess) ) ]
3060
3101
fn add_lld_args (
3061
3102
cmd : & mut dyn Linker ,
3062
3103
sess : & Session ,
3063
3104
flavor : LinkerFlavor ,
3064
3105
self_contained_components : LinkSelfContainedComponents ,
3106
+ linker_features : LinkerFeatures ,
3065
3107
) {
3066
- debug ! (
3067
- "add_lld_args requested, flavor: '{:?}', target self-contained components: {:?}" ,
3068
- flavor, self_contained_components,
3069
- ) ;
3070
-
3071
- // If the flavor doesn't use a C/C++ compiler to invoke the linker, or doesn't opt in to `lld`,
3072
- // we don't need to do anything.
3073
- if !( flavor. uses_cc ( ) && flavor. uses_lld ( ) ) {
3108
+ // If we're not using a C/C++ compiler to invoke the linker, or don't opt in to `lld`, we don't
3109
+ // need to do anything.
3110
+ if !( linker_features. is_cc_enabled ( ) && linker_features. is_lld_enabled ( ) ) {
3074
3111
return ;
3075
3112
}
3076
3113
0 commit comments