@@ -22,10 +22,10 @@ use rustc_session::utils::NativeLibKind;
2222use rustc_session:: { filesearch, Session } ;
2323use rustc_span:: symbol:: Symbol ;
2424use rustc_target:: spec:: crt_objects:: CrtObjects ;
25- use rustc_target:: spec:: LinkSelfContainedComponents ;
2625use rustc_target:: spec:: LinkSelfContainedDefault ;
2726use rustc_target:: spec:: LinkerFlavorCli ;
2827use rustc_target:: spec:: { Cc , LinkOutputKind , LinkerFlavor , Lld , PanicStrategy } ;
28+ use rustc_target:: spec:: { LinkSelfContainedComponents , LinkerFeatures } ;
2929use rustc_target:: spec:: { RelocModel , RelroLevel , SanitizerSet , SplitDebuginfo } ;
3030
3131use super :: archive:: { ArchiveBuilder , ArchiveBuilderBuilder } ;
@@ -741,6 +741,8 @@ fn link_natively(
741741 info ! ( "preparing {:?} to {:?}" , crate_type, out_filename) ;
742742 let ( linker_path, flavor) = linker_and_flavor ( sess) ;
743743 let self_contained_components = self_contained_components ( sess, crate_type) ;
744+ let linker_features = linker_features ( sess, flavor) ;
745+
744746 let mut cmd = linker_with_args (
745747 & linker_path,
746748 flavor,
@@ -751,6 +753,7 @@ fn link_natively(
751753 out_filename,
752754 codegen_results,
753755 self_contained_components,
756+ linker_features,
754757 ) ?;
755758
756759 linker:: disable_localization ( & mut cmd) ;
@@ -1816,6 +1819,40 @@ fn self_contained_components(sess: &Session, crate_type: CrateType) -> LinkSelfC
18161819 }
18171820}
18181821
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+
18191856/// Add pre-link object files defined by the target spec.
18201857fn add_pre_link_objects (
18211858 cmd : & mut dyn Linker ,
@@ -2114,6 +2151,7 @@ fn linker_with_args(
21142151 out_filename : & Path ,
21152152 codegen_results : & CodegenResults ,
21162153 self_contained_components : LinkSelfContainedComponents ,
2154+ linker_features : LinkerFeatures ,
21172155) -> Result < Command , ErrorGuaranteed > {
21182156 let self_contained_crt_objects = self_contained_components. is_crt_objects_enabled ( ) ;
21192157 let cmd = & mut * super :: linker:: get_linker (
@@ -2301,6 +2339,7 @@ fn linker_with_args(
23012339 codegen_results,
23022340 out_filename,
23032341 tmpdir,
2342+ linker_features,
23042343 ) ;
23052344
23062345 // Can be used for arbitrary order-independent options.
@@ -2334,9 +2373,10 @@ fn add_order_independent_options(
23342373 codegen_results : & CodegenResults ,
23352374 out_filename : & Path ,
23362375 tmpdir : & Path ,
2376+ linker_features : LinkerFeatures ,
23372377) {
23382378 // 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 ) ;
23402380
23412381 add_apple_sdk ( cmd, sess, flavor) ;
23422382
@@ -3053,24 +3093,21 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootErro
30533093 }
30543094}
30553095
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:
30583098/// - when the self-contained linker flag is active: the build of `lld` distributed with rustc,
30593099/// - or any `lld` available to `cc`.
3100+ #[ instrument( level = "debug" , skip( cmd, sess) ) ]
30603101fn add_lld_args (
30613102 cmd : & mut dyn Linker ,
30623103 sess : & Session ,
30633104 flavor : LinkerFlavor ,
30643105 self_contained_components : LinkSelfContainedComponents ,
3106+ linker_features : LinkerFeatures ,
30653107) {
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 ( ) ) {
30743111 return ;
30753112 }
30763113
0 commit comments