@@ -140,7 +140,12 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
140140// The third parameter is for env vars, used on windows to set up the
141141// path for MSVC to find its DLLs, and gcc to find its bundled
142142// toolchain
143- fn get_linker ( sess : & Session , linker : & Path , flavor : LinkerFlavor ) -> Command {
143+ fn get_linker (
144+ sess : & Session ,
145+ linker : & Path ,
146+ flavor : LinkerFlavor ,
147+ self_contained : bool ,
148+ ) -> Command {
144149 let msvc_tool = windows_registry:: find_tool ( & sess. opts . target_triple . triple ( ) , "link.exe" ) ;
145150
146151 // If our linker looks like a batch script on Windows then to execute this
@@ -199,7 +204,7 @@ fn get_linker(sess: &Session, linker: &Path, flavor: LinkerFlavor) -> Command {
199204
200205 // The compiler's sysroot often has some bundled tools, so add it to the
201206 // PATH for the child.
202- let mut new_path = sess. host_filesearch ( PathKind :: All ) . get_tools_search_paths ( ) ;
207+ let mut new_path = sess. host_filesearch ( PathKind :: All ) . get_tools_search_paths ( self_contained ) ;
203208 let mut msvc_changed_path = false ;
204209 if sess. target . target . options . is_like_msvc {
205210 if let Some ( ref tool) = msvc_tool {
@@ -563,7 +568,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
563568 . iter ( )
564569 . copied ( )
565570 . flatten ( )
566- . map ( |obj| get_object_file_path ( sess, obj) . into_os_string ( ) )
571+ . map ( |obj| get_object_file_path ( sess, obj, fallback ) . into_os_string ( ) )
567572 . collect :: < Vec < _ > > ( )
568573 } ;
569574 let pre_objects_static_pie = get_objects ( pre_objects, LinkOutputKind :: StaticPicExe ) ;
@@ -1066,9 +1071,11 @@ fn get_crt_libs_path(sess: &Session) -> Option<PathBuf> {
10661071 }
10671072}
10681073
1069- fn get_object_file_path ( sess : & Session , name : & str ) -> PathBuf {
1074+ fn get_object_file_path ( sess : & Session , name : & str , self_contained : bool ) -> PathBuf {
10701075 // prefer system {,dll}crt2.o libs, see get_crt_libs_path comment for more details
1071- if sess. target . target . llvm_target . contains ( "windows-gnu" ) {
1076+ if sess. opts . debugging_opts . link_self_contained . is_none ( )
1077+ && sess. target . target . llvm_target . contains ( "windows-gnu" )
1078+ {
10721079 if let Some ( compiler_libs_path) = get_crt_libs_path ( sess) {
10731080 let file_path = compiler_libs_path. join ( name) ;
10741081 if file_path. exists ( ) {
@@ -1081,9 +1088,12 @@ fn get_object_file_path(sess: &Session, name: &str) -> PathBuf {
10811088 if file_path. exists ( ) {
10821089 return file_path;
10831090 }
1084- let file_path = fs. get_selfcontained_lib_path ( ) . join ( name) ;
1085- if file_path. exists ( ) {
1086- return file_path;
1091+ // Special directory with objects used only in self-contained linkage mode
1092+ if self_contained {
1093+ let file_path = fs. get_selfcontained_lib_path ( ) . join ( name) ;
1094+ if file_path. exists ( ) {
1095+ return file_path;
1096+ }
10871097 }
10881098 for search_path in fs. search_paths ( ) {
10891099 let file_path = search_path. dir . join ( name) ;
@@ -1268,6 +1278,10 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
12681278/// Whether we link to our own CRT objects instead of relying on gcc to pull them.
12691279/// We only provide such support for a very limited number of targets.
12701280fn crt_objects_fallback ( sess : & Session , crate_type : CrateType ) -> bool {
1281+ if let Some ( self_contained) = sess. opts . debugging_opts . link_self_contained {
1282+ return self_contained;
1283+ }
1284+
12711285 match sess. target . target . options . crt_objects_fallback {
12721286 // FIXME: Find a better heuristic for "native musl toolchain is available",
12731287 // based on host and linker path, for example.
@@ -1292,7 +1306,7 @@ fn add_pre_link_objects(
12921306 let opts = & sess. target . target . options ;
12931307 let objects = if fallback { & opts. pre_link_objects_fallback } else { & opts. pre_link_objects } ;
12941308 for obj in objects. get ( & link_output_kind) . iter ( ) . copied ( ) . flatten ( ) {
1295- cmd. add_object ( & get_object_file_path ( sess, obj) ) ;
1309+ cmd. add_object ( & get_object_file_path ( sess, obj, fallback ) ) ;
12961310 }
12971311}
12981312
@@ -1306,7 +1320,7 @@ fn add_post_link_objects(
13061320 let opts = & sess. target . target . options ;
13071321 let objects = if fallback { & opts. post_link_objects_fallback } else { & opts. post_link_objects } ;
13081322 for obj in objects. get ( & link_output_kind) . iter ( ) . copied ( ) . flatten ( ) {
1309- cmd. add_object ( & get_object_file_path ( sess, obj) ) ;
1323+ cmd. add_object ( & get_object_file_path ( sess, obj, fallback ) ) ;
13101324 }
13111325}
13121326
@@ -1468,9 +1482,12 @@ fn link_local_crate_native_libs_and_dependent_crate_libs<'a, B: ArchiveBuilder<'
14681482}
14691483
14701484/// Add sysroot and other globally set directories to the directory search list.
1471- fn add_library_search_dirs ( cmd : & mut dyn Linker , sess : & Session ) {
1485+ fn add_library_search_dirs ( cmd : & mut dyn Linker , sess : & Session , self_contained : bool ) {
14721486 // Prefer system mingw-w64 libs, see get_crt_libs_path comment for more details.
1473- if cfg ! ( windows) && sess. target . target . llvm_target . contains ( "windows-gnu" ) {
1487+ if sess. opts . debugging_opts . link_self_contained . is_none ( )
1488+ && cfg ! ( windows)
1489+ && sess. target . target . llvm_target . contains ( "windows-gnu" )
1490+ {
14741491 if let Some ( compiler_libs_path) = get_crt_libs_path ( sess) {
14751492 cmd. include_path ( & compiler_libs_path) ;
14761493 }
@@ -1481,8 +1498,11 @@ fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session) {
14811498 let lib_path = sess. target_filesearch ( PathKind :: All ) . get_lib_path ( ) ;
14821499 cmd. include_path ( & fix_windows_verbatim_for_gcc ( & lib_path) ) ;
14831500
1484- let lib_path = sess. target_filesearch ( PathKind :: All ) . get_selfcontained_lib_path ( ) ;
1485- cmd. include_path ( & fix_windows_verbatim_for_gcc ( & lib_path) ) ;
1501+ // Special directory with libraries used only in self-contained linkage mode
1502+ if self_contained {
1503+ let lib_path = sess. target_filesearch ( PathKind :: All ) . get_selfcontained_lib_path ( ) ;
1504+ cmd. include_path ( & fix_windows_verbatim_for_gcc ( & lib_path) ) ;
1505+ }
14861506}
14871507
14881508/// Add options making relocation sections in the produced ELF files read-only
@@ -1545,13 +1565,13 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
15451565 codegen_results : & CodegenResults ,
15461566 target_cpu : & str ,
15471567) -> Command {
1548- let base_cmd = get_linker ( sess, path, flavor) ;
1568+ let crt_objects_fallback = crt_objects_fallback ( sess, crate_type) ;
1569+ let base_cmd = get_linker ( sess, path, flavor, crt_objects_fallback) ;
15491570 // FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction
15501571 // to the linker args construction.
15511572 assert ! ( base_cmd. get_args( ) . is_empty( ) || sess. target. target. target_vendor == "uwp" ) ;
15521573 let cmd = & mut * codegen_results. linker_info . to_linker ( base_cmd, & sess, flavor, target_cpu) ;
15531574 let link_output_kind = link_output_kind ( sess, crate_type) ;
1554- let crt_objects_fallback = crt_objects_fallback ( sess, crate_type) ;
15551575
15561576 // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
15571577 add_pre_link_args ( cmd, sess, flavor) ;
@@ -1597,7 +1617,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
15971617
15981618 // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
15991619 // FIXME: Order-dependent, at least relatively to other args adding searh directories.
1600- add_library_search_dirs ( cmd, sess) ;
1620+ add_library_search_dirs ( cmd, sess, crt_objects_fallback ) ;
16011621
16021622 // OBJECT-FILES-YES
16031623 add_local_crate_regular_objects ( cmd, codegen_results) ;
0 commit comments