@@ -140,7 +140,12 @@ pub fn link_binary<'a, B: ArchiveBuilder<'a>>(
140
140
// The third parameter is for env vars, used on windows to set up the
141
141
// path for MSVC to find its DLLs, and gcc to find its bundled
142
142
// 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 {
144
149
let msvc_tool = windows_registry:: find_tool ( & sess. opts . target_triple . triple ( ) , "link.exe" ) ;
145
150
146
151
// 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 {
199
204
200
205
// The compiler's sysroot often has some bundled tools, so add it to the
201
206
// 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 ) ;
203
208
let mut msvc_changed_path = false ;
204
209
if sess. target . target . options . is_like_msvc {
205
210
if let Some ( ref tool) = msvc_tool {
@@ -563,7 +568,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
563
568
. iter ( )
564
569
. copied ( )
565
570
. 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 ( ) )
567
572
. collect :: < Vec < _ > > ( )
568
573
} ;
569
574
let pre_objects_static_pie = get_objects ( pre_objects, LinkOutputKind :: StaticPicExe ) ;
@@ -1066,9 +1071,11 @@ fn get_crt_libs_path(sess: &Session) -> Option<PathBuf> {
1066
1071
}
1067
1072
}
1068
1073
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 {
1070
1075
// 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
+ {
1072
1079
if let Some ( compiler_libs_path) = get_crt_libs_path ( sess) {
1073
1080
let file_path = compiler_libs_path. join ( name) ;
1074
1081
if file_path. exists ( ) {
@@ -1081,9 +1088,12 @@ fn get_object_file_path(sess: &Session, name: &str) -> PathBuf {
1081
1088
if file_path. exists ( ) {
1082
1089
return file_path;
1083
1090
}
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
+ }
1087
1097
}
1088
1098
for search_path in fs. search_paths ( ) {
1089
1099
let file_path = search_path. dir . join ( name) ;
@@ -1268,6 +1278,10 @@ fn link_output_kind(sess: &Session, crate_type: CrateType) -> LinkOutputKind {
1268
1278
/// Whether we link to our own CRT objects instead of relying on gcc to pull them.
1269
1279
/// We only provide such support for a very limited number of targets.
1270
1280
fn 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
+
1271
1285
match sess. target . target . options . crt_objects_fallback {
1272
1286
// FIXME: Find a better heuristic for "native musl toolchain is available",
1273
1287
// based on host and linker path, for example.
@@ -1292,7 +1306,7 @@ fn add_pre_link_objects(
1292
1306
let opts = & sess. target . target . options ;
1293
1307
let objects = if fallback { & opts. pre_link_objects_fallback } else { & opts. pre_link_objects } ;
1294
1308
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 ) ) ;
1296
1310
}
1297
1311
}
1298
1312
@@ -1306,7 +1320,7 @@ fn add_post_link_objects(
1306
1320
let opts = & sess. target . target . options ;
1307
1321
let objects = if fallback { & opts. post_link_objects_fallback } else { & opts. post_link_objects } ;
1308
1322
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 ) ) ;
1310
1324
}
1311
1325
}
1312
1326
@@ -1468,9 +1482,12 @@ fn link_local_crate_native_libs_and_dependent_crate_libs<'a, B: ArchiveBuilder<'
1468
1482
}
1469
1483
1470
1484
/// 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 ) {
1472
1486
// 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
+ {
1474
1491
if let Some ( compiler_libs_path) = get_crt_libs_path ( sess) {
1475
1492
cmd. include_path ( & compiler_libs_path) ;
1476
1493
}
@@ -1481,8 +1498,11 @@ fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session) {
1481
1498
let lib_path = sess. target_filesearch ( PathKind :: All ) . get_lib_path ( ) ;
1482
1499
cmd. include_path ( & fix_windows_verbatim_for_gcc ( & lib_path) ) ;
1483
1500
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
+ }
1486
1506
}
1487
1507
1488
1508
/// Add options making relocation sections in the produced ELF files read-only
@@ -1545,13 +1565,13 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
1545
1565
codegen_results : & CodegenResults ,
1546
1566
target_cpu : & str ,
1547
1567
) -> 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) ;
1549
1570
// FIXME: Move `/LIBPATH` addition for uwp targets from the linker construction
1550
1571
// to the linker args construction.
1551
1572
assert ! ( base_cmd. get_args( ) . is_empty( ) || sess. target. target. target_vendor == "uwp" ) ;
1552
1573
let cmd = & mut * codegen_results. linker_info . to_linker ( base_cmd, & sess, flavor, target_cpu) ;
1553
1574
let link_output_kind = link_output_kind ( sess, crate_type) ;
1554
- let crt_objects_fallback = crt_objects_fallback ( sess, crate_type) ;
1555
1575
1556
1576
// NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1557
1577
add_pre_link_args ( cmd, sess, flavor) ;
@@ -1597,7 +1617,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
1597
1617
1598
1618
// NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1599
1619
// 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 ) ;
1601
1621
1602
1622
// OBJECT-FILES-YES
1603
1623
add_local_crate_regular_objects ( cmd, codegen_results) ;
0 commit comments