@@ -23,6 +23,7 @@ use rustc_session::utils::NativeLibKind;
2323use rustc_session:: { filesearch, Session } ;
2424use rustc_span:: symbol:: Symbol ;
2525use rustc_target:: spec:: crt_objects:: CrtObjects ;
26+ use rustc_target:: spec:: LinkSelfContainedComponents ;
2627use rustc_target:: spec:: LinkSelfContainedDefault ;
2728use rustc_target:: spec:: { Cc , LinkOutputKind , LinkerFlavor , Lld , PanicStrategy } ;
2829use rustc_target:: spec:: { RelocModel , RelroLevel , SanitizerSet , SplitDebuginfo } ;
@@ -721,6 +722,7 @@ fn link_natively<'a>(
721722) -> Result < ( ) , ErrorGuaranteed > {
722723 info ! ( "preparing {:?} to {:?}" , crate_type, out_filename) ;
723724 let ( linker_path, flavor) = linker_and_flavor ( sess) ;
725+ let self_contained_components = self_contained_components ( sess, crate_type) ;
724726 let mut cmd = linker_with_args (
725727 & linker_path,
726728 flavor,
@@ -730,6 +732,7 @@ fn link_natively<'a>(
730732 tmpdir,
731733 out_filename,
732734 codegen_results,
735+ self_contained_components,
733736 ) ?;
734737
735738 linker:: disable_localization ( & mut cmd) ;
@@ -805,14 +808,14 @@ fn link_natively<'a>(
805808 "Linker does not support -static-pie command line option. Retrying with -static instead."
806809 ) ;
807810 // Mirror `add_(pre,post)_link_objects` to replace CRT objects.
808- let self_contained = self_contained ( sess , crate_type ) ;
811+ let self_contained_crt_objects = self_contained_components . is_crt_objects_enabled ( ) ;
809812 let opts = & sess. target ;
810- let pre_objects = if self_contained {
813+ let pre_objects = if self_contained_crt_objects {
811814 & opts. pre_link_objects_self_contained
812815 } else {
813816 & opts. pre_link_objects
814817 } ;
815- let post_objects = if self_contained {
818+ let post_objects = if self_contained_crt_objects {
816819 & opts. post_link_objects_self_contained
817820 } else {
818821 & opts. post_link_objects
@@ -823,7 +826,9 @@ fn link_natively<'a>(
823826 . iter ( )
824827 . copied ( )
825828 . flatten ( )
826- . map ( |obj| get_object_file_path ( sess, obj, self_contained) . into_os_string ( ) )
829+ . map ( |obj| {
830+ get_object_file_path ( sess, obj, self_contained_crt_objects) . into_os_string ( )
831+ } )
827832 . collect :: < Vec < _ > > ( )
828833 } ;
829834 let pre_objects_static_pie = get_objects ( pre_objects, LinkOutputKind :: StaticPicExe ) ;
@@ -1703,42 +1708,43 @@ fn detect_self_contained_mingw(sess: &Session) -> bool {
17031708/// Various toolchain components used during linking are used from rustc distribution
17041709/// instead of being found somewhere on the host system.
17051710/// We only provide such support for a very limited number of targets.
1706- fn self_contained ( sess : & Session , crate_type : CrateType ) -> bool {
1707- // Emit an error if the user requested self-contained mode on the CLI but the target explicitly
1708- // refuses it.
1709- if let Some ( self_contained) = sess. opts . cg . link_self_contained . explicitly_set {
1710- if sess. target . link_self_contained . is_disabled ( ) {
1711- sess. emit_err ( errors:: UnsupportedLinkSelfContained ) ;
1712- }
1713- return self_contained;
1714- }
1715-
1716- match sess. target . link_self_contained {
1717- LinkSelfContainedDefault :: False => false ,
1718- LinkSelfContainedDefault :: True => true ,
1719- LinkSelfContainedDefault :: WithComponents ( components) => {
1720- if components. is_all ( ) {
1721- true
1722- } else if components. is_empty ( ) {
1723- false
1724- } else {
1725- // FIXME: Currently no target makes use of individual components to mean
1726- // self-contained linking is fully enabled, in the sense of what the code downstream
1727- // from here expects. Until components are handled a bit more deeply, we can
1728- // consider that it's disabled and remain backwards compatible.
1729- false
1711+ fn self_contained_components ( sess : & Session , crate_type : CrateType ) -> LinkSelfContainedComponents {
1712+ // Turn the backwards compatible bool values for `self_contained` into fully inferred
1713+ // `LinkSelfContainedComponents`.
1714+ let self_contained =
1715+ if let Some ( self_contained) = sess. opts . cg . link_self_contained . explicitly_set {
1716+ // Emit an error if the user requested self-contained mode on the CLI but the target
1717+ // explicitly refuses it.
1718+ if sess. target . link_self_contained . is_disabled ( ) {
1719+ sess. emit_err ( errors:: UnsupportedLinkSelfContained ) ;
17301720 }
1731- }
1721+ self_contained
1722+ } else {
1723+ match sess. target . link_self_contained {
1724+ LinkSelfContainedDefault :: False => false ,
1725+ LinkSelfContainedDefault :: True => true ,
1726+
1727+ LinkSelfContainedDefault :: WithComponents ( components) => {
1728+ // For target specs with explicitly enabled components, we can return them
1729+ // directly.
1730+ return components;
1731+ }
17321732
1733- // FIXME: Find a better heuristic for "native musl toolchain is available",
1734- // based on host and linker path, for example.
1735- // (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237).
1736- LinkSelfContainedDefault :: InferredForMusl => sess. crt_static ( Some ( crate_type) ) ,
1737- LinkSelfContainedDefault :: InferredForMingw => {
1738- sess. host == sess. target
1739- && sess. target . vendor != "uwp"
1740- && detect_self_contained_mingw ( & sess)
1741- }
1733+ // FIXME: Find a better heuristic for "native musl toolchain is available",
1734+ // based on host and linker path, for example.
1735+ // (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237).
1736+ LinkSelfContainedDefault :: InferredForMusl => sess. crt_static ( Some ( crate_type) ) ,
1737+ LinkSelfContainedDefault :: InferredForMingw => {
1738+ sess. host == sess. target
1739+ && sess. target . vendor != "uwp"
1740+ && detect_self_contained_mingw ( & sess)
1741+ }
1742+ }
1743+ } ;
1744+ if self_contained {
1745+ LinkSelfContainedComponents :: all ( )
1746+ } else {
1747+ LinkSelfContainedComponents :: empty ( )
17421748 }
17431749}
17441750
@@ -2062,13 +2068,14 @@ fn linker_with_args<'a>(
20622068 tmpdir : & Path ,
20632069 out_filename : & Path ,
20642070 codegen_results : & CodegenResults ,
2071+ self_contained_components : LinkSelfContainedComponents ,
20652072) -> Result < Command , ErrorGuaranteed > {
2066- let self_contained = self_contained ( sess , crate_type ) ;
2073+ let self_contained_crt_objects = self_contained_components . is_crt_objects_enabled ( ) ;
20672074 let cmd = & mut * super :: linker:: get_linker (
20682075 sess,
20692076 path,
20702077 flavor,
2071- self_contained ,
2078+ self_contained_components . are_any_components_enabled ( ) ,
20722079 & codegen_results. crate_info . target_cpu ,
20732080 ) ;
20742081 let link_output_kind = link_output_kind ( sess, crate_type) ;
@@ -2095,7 +2102,7 @@ fn linker_with_args<'a>(
20952102 // ------------ Object code and libraries, order-dependent ------------
20962103
20972104 // Pre-link CRT objects.
2098- add_pre_link_objects ( cmd, sess, flavor, link_output_kind, self_contained ) ;
2105+ add_pre_link_objects ( cmd, sess, flavor, link_output_kind, self_contained_crt_objects ) ;
20992106
21002107 add_linked_symbol_object (
21012108 cmd,
@@ -2238,7 +2245,7 @@ fn linker_with_args<'a>(
22382245 cmd,
22392246 sess,
22402247 link_output_kind,
2241- self_contained ,
2248+ self_contained_components ,
22422249 flavor,
22432250 crate_type,
22442251 codegen_results,
@@ -2254,7 +2261,7 @@ fn linker_with_args<'a>(
22542261 // ------------ Object code and libraries, order-dependent ------------
22552262
22562263 // Post-link CRT objects.
2257- add_post_link_objects ( cmd, sess, link_output_kind, self_contained ) ;
2264+ add_post_link_objects ( cmd, sess, link_output_kind, self_contained_crt_objects ) ;
22582265
22592266 // ------------ Late order-dependent options ------------
22602267
@@ -2271,15 +2278,15 @@ fn add_order_independent_options(
22712278 cmd : & mut dyn Linker ,
22722279 sess : & Session ,
22732280 link_output_kind : LinkOutputKind ,
2274- self_contained : bool ,
2281+ self_contained_components : LinkSelfContainedComponents ,
22752282 flavor : LinkerFlavor ,
22762283 crate_type : CrateType ,
22772284 codegen_results : & CodegenResults ,
22782285 out_filename : & Path ,
22792286 tmpdir : & Path ,
22802287) {
22812288 // Take care of the flavors and CLI options requesting the `lld` linker.
2282- add_lld_args ( cmd, sess, flavor) ;
2289+ add_lld_args ( cmd, sess, flavor, self_contained_components ) ;
22832290
22842291 add_apple_sdk ( cmd, sess, flavor) ;
22852292
@@ -2304,7 +2311,7 @@ fn add_order_independent_options(
23042311 // Make the binary compatible with data execution prevention schemes.
23052312 cmd. add_no_exec ( ) ;
23062313
2307- if self_contained {
2314+ if self_contained_components . is_crt_objects_enabled ( ) {
23082315 cmd. no_crt_objects ( ) ;
23092316 }
23102317
@@ -2335,7 +2342,7 @@ fn add_order_independent_options(
23352342
23362343 cmd. linker_plugin_lto ( ) ;
23372344
2338- add_library_search_dirs ( cmd, sess, self_contained ) ;
2345+ add_library_search_dirs ( cmd, sess, self_contained_components . are_any_components_enabled ( ) ) ;
23392346
23402347 cmd. output_filename ( out_filename) ;
23412348
@@ -2985,8 +2992,16 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootErro
29852992/// invoke it:
29862993/// - when the self-contained linker flag is active: the build of `lld` distributed with rustc,
29872994/// - or any `lld` available to `cc`.
2988- fn add_lld_args ( cmd : & mut dyn Linker , sess : & Session , flavor : LinkerFlavor ) {
2989- debug ! ( "add_lld_args requested, flavor: '{flavor:?}'" ) ;
2995+ fn add_lld_args (
2996+ cmd : & mut dyn Linker ,
2997+ sess : & Session ,
2998+ flavor : LinkerFlavor ,
2999+ self_contained_components : LinkSelfContainedComponents ,
3000+ ) {
3001+ debug ! (
3002+ "add_lld_args requested, flavor: '{:?}', target self-contained components: {:?}" ,
3003+ flavor, self_contained_components,
3004+ ) ;
29903005
29913006 // If the flavor doesn't use a C/C++ compiler to invoke the linker, or doesn't opt in to `lld`,
29923007 // we don't need to do anything.
@@ -3000,7 +3015,7 @@ fn add_lld_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
30003015 // - if the self-contained linker is enabled on the CLI or by the target spec,
30013016 // - and if the self-contained linker is not disabled on the CLI.
30023017 let self_contained_cli = sess. opts . cg . link_self_contained . is_linker_enabled ( ) ;
3003- let self_contained_target = sess . target . options . link_self_contained . is_linker_enabled ( ) ;
3018+ let self_contained_target = self_contained_components . is_linker_enabled ( ) ;
30043019
30053020 // FIXME: in the future, codegen backends may need to have more control over this process: they
30063021 // don't always support all the features the linker expects here, and vice versa. For example,
0 commit comments