@@ -11,7 +11,9 @@ use rustc_session::search_paths::PathKind;
11
11
/// need out of the shared crate context before we get rid of it.
12
12
use rustc_session:: { filesearch, Session } ;
13
13
use rustc_span:: symbol:: Symbol ;
14
- use rustc_target:: spec:: { LinkerFlavor , LldFlavor , PanicStrategy , RelocModel , RelroLevel } ;
14
+ use rustc_target:: spec:: crt_objects:: CrtObjectsFallback ;
15
+ use rustc_target:: spec:: { LinkOutputKind , LinkerFlavor , LldFlavor } ;
16
+ use rustc_target:: spec:: { PanicStrategy , RelocModel , RelroLevel } ;
15
17
16
18
use super :: archive:: ArchiveBuilder ;
17
19
use super :: command:: Command ;
@@ -1130,33 +1132,70 @@ fn exec_linker(
1130
1132
}
1131
1133
}
1132
1134
1133
- /// Add begin object files defined by the target spec.
1134
- fn add_pre_link_objects ( cmd : & mut dyn Linker , sess : & Session , crate_type : CrateType ) {
1135
- let pre_link_objects = if crate_type == CrateType :: Executable {
1136
- & sess. target . target . options . pre_link_objects_exe
1137
- } else {
1138
- & sess. target . target . options . pre_link_objects_dll
1135
+ fn link_output_kind ( sess : & Session , crate_type : CrateType ) -> LinkOutputKind {
1136
+ let kind = match ( crate_type, sess. crt_static ( Some ( crate_type) ) , sess. relocation_model ( ) ) {
1137
+ ( CrateType :: Executable , false , RelocModel :: Pic ) => LinkOutputKind :: DynamicPicExe ,
1138
+ ( CrateType :: Executable , false , _) => LinkOutputKind :: DynamicNoPicExe ,
1139
+ ( CrateType :: Executable , true , RelocModel :: Pic ) => LinkOutputKind :: StaticPicExe ,
1140
+ ( CrateType :: Executable , true , _) => LinkOutputKind :: StaticNoPicExe ,
1141
+ ( _, true , _) => LinkOutputKind :: StaticDylib ,
1142
+ ( _, false , _) => LinkOutputKind :: DynamicDylib ,
1139
1143
} ;
1140
- for obj in pre_link_objects {
1141
- cmd. add_object ( & get_object_file_path ( sess, obj) ) ;
1144
+
1145
+ // Adjust the output kind to target capabilities.
1146
+ let pic_exe_supported = sess. target . target . options . position_independent_executables ;
1147
+ let static_pic_exe_supported = false ; // FIXME: Add this option to target specs.
1148
+ let static_dylib_supported = sess. target . target . options . crt_static_allows_dylibs ;
1149
+ match kind {
1150
+ LinkOutputKind :: DynamicPicExe if !pic_exe_supported => LinkOutputKind :: DynamicNoPicExe ,
1151
+ LinkOutputKind :: StaticPicExe if !static_pic_exe_supported => LinkOutputKind :: StaticNoPicExe ,
1152
+ LinkOutputKind :: StaticDylib if !static_dylib_supported => LinkOutputKind :: DynamicDylib ,
1153
+ _ => kind,
1142
1154
}
1155
+ }
1143
1156
1144
- if crate_type == CrateType :: Executable && sess. crt_static ( Some ( crate_type) ) {
1145
- for obj in & sess. target . target . options . pre_link_objects_exe_crt {
1146
- cmd. add_object ( & get_object_file_path ( sess, obj) ) ;
1147
- }
1157
+ /// Whether we link to our own CRT objects instead of relying on gcc to pull them.
1158
+ /// We only provide such support for a very limited number of targets.
1159
+ fn crt_objects_fallback ( sess : & Session , crate_type : CrateType ) -> bool {
1160
+ match sess. target . target . options . crt_objects_fallback {
1161
+ // FIXME: Find a better heuristic for "native musl toolchain is available",
1162
+ // based on host and linker path, for example.
1163
+ // (https://github.com/rust-lang/rust/pull/71769#issuecomment-626330237).
1164
+ Some ( CrtObjectsFallback :: Musl ) => sess. crt_static ( Some ( crate_type) ) ,
1165
+ // FIXME: Find some heuristic for "native mingw toolchain is available",
1166
+ // likely based on `get_crt_libs_path` (https://github.com/rust-lang/rust/pull/67429).
1167
+ Some ( CrtObjectsFallback :: Mingw ) => sess. target . target . target_vendor != "uwp" ,
1168
+ // FIXME: Figure out cases in which WASM needs to link with a native toolchain.
1169
+ Some ( CrtObjectsFallback :: Wasm ) => true ,
1170
+ None => false ,
1148
1171
}
1149
1172
}
1150
1173
1151
- /// Add end object files defined by the target spec.
1152
- fn add_post_link_objects ( cmd : & mut dyn Linker , sess : & Session , crate_type : CrateType ) {
1153
- for obj in & sess. target . target . options . post_link_objects {
1174
+ /// Add pre-link object files defined by the target spec.
1175
+ fn add_pre_link_objects (
1176
+ cmd : & mut dyn Linker ,
1177
+ sess : & Session ,
1178
+ link_output_kind : LinkOutputKind ,
1179
+ fallback : bool ,
1180
+ ) {
1181
+ let opts = & sess. target . target . options ;
1182
+ let objects = if fallback { & opts. pre_link_objects_fallback } else { & opts. pre_link_objects } ;
1183
+ for obj in objects. get ( & link_output_kind) . iter ( ) . copied ( ) . flatten ( ) {
1154
1184
cmd. add_object ( & get_object_file_path ( sess, obj) ) ;
1155
1185
}
1156
- if sess. crt_static ( Some ( crate_type) ) {
1157
- for obj in & sess. target . target . options . post_link_objects_crt {
1158
- cmd. add_object ( & get_object_file_path ( sess, obj) ) ;
1159
- }
1186
+ }
1187
+
1188
+ /// Add post-link object files defined by the target spec.
1189
+ fn add_post_link_objects (
1190
+ cmd : & mut dyn Linker ,
1191
+ sess : & Session ,
1192
+ link_output_kind : LinkOutputKind ,
1193
+ fallback : bool ,
1194
+ ) {
1195
+ let opts = & sess. target . target . options ;
1196
+ let objects = if fallback { & opts. post_link_objects_fallback } else { & opts. post_link_objects } ;
1197
+ for obj in objects. get ( & link_output_kind) . iter ( ) . copied ( ) . flatten ( ) {
1198
+ cmd. add_object ( & get_object_file_path ( sess, obj) ) ;
1160
1199
}
1161
1200
}
1162
1201
@@ -1342,38 +1381,6 @@ fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session) {
1342
1381
cmd. include_path ( & fix_windows_verbatim_for_gcc ( & lib_path) ) ;
1343
1382
}
1344
1383
1345
- /// Add options requesting executables to be position-independent or not position-independent.
1346
- fn add_position_independent_executable_args (
1347
- cmd : & mut dyn Linker ,
1348
- sess : & Session ,
1349
- flavor : LinkerFlavor ,
1350
- crate_type : CrateType ,
1351
- codegen_results : & CodegenResults ,
1352
- ) {
1353
- if crate_type != CrateType :: Executable {
1354
- return ;
1355
- }
1356
-
1357
- if sess. target . target . options . position_independent_executables {
1358
- let attr_link_args = & * codegen_results. crate_info . link_args ;
1359
- let mut user_defined_link_args = sess. opts . cg . link_args . iter ( ) . chain ( attr_link_args) ;
1360
- if sess. relocation_model ( ) == RelocModel :: Pic
1361
- && !sess. crt_static ( Some ( crate_type) )
1362
- && !user_defined_link_args. any ( |x| x == "-static" )
1363
- {
1364
- cmd. position_independent_executable ( ) ;
1365
- return ;
1366
- }
1367
- }
1368
-
1369
- // Recent versions of gcc can be configured to generate position
1370
- // independent executables by default. We have to pass -no-pie to
1371
- // explicitly turn that off. Not applicable to ld.
1372
- if sess. target . target . options . linker_is_gnu && flavor != LinkerFlavor :: Ld {
1373
- cmd. no_position_independent_executable ( ) ;
1374
- }
1375
- }
1376
-
1377
1384
/// Add options making relocation sections in the produced ELF files read-only
1378
1385
/// and suppressing lazy binding.
1379
1386
fn add_relro_args ( cmd : & mut dyn Linker , sess : & Session ) {
@@ -1439,6 +1446,8 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
1439
1446
// to the linker args construction.
1440
1447
assert ! ( base_cmd. get_args( ) . is_empty( ) || sess. target. target. target_vendor == "uwp" ) ;
1441
1448
let cmd = & mut * codegen_results. linker_info . to_linker ( base_cmd, & sess, flavor, target_cpu) ;
1449
+ let link_output_kind = link_output_kind ( sess, crate_type) ;
1450
+ let crt_objects_fallback = crt_objects_fallback ( sess, crate_type) ;
1442
1451
1443
1452
// NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1444
1453
add_pre_link_args ( cmd, sess, flavor, crate_type) ;
@@ -1455,8 +1464,13 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
1455
1464
cmd. arg ( format ! ( "--dynamic-linker={}ld.so.1" , prefix) ) ;
1456
1465
}
1457
1466
1467
+ // NO-OPT-OUT, OBJECT-FILES-NO
1468
+ if crt_objects_fallback {
1469
+ cmd. no_crt_objects ( ) ;
1470
+ }
1471
+
1458
1472
// NO-OPT-OUT, OBJECT-FILES-YES
1459
- add_pre_link_objects ( cmd, sess, crate_type ) ;
1473
+ add_pre_link_objects ( cmd, sess, link_output_kind , crt_objects_fallback ) ;
1460
1474
1461
1475
// NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1462
1476
if sess. target . target . options . is_like_emscripten {
@@ -1515,7 +1529,16 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
1515
1529
}
1516
1530
1517
1531
// NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1518
- add_position_independent_executable_args ( cmd, sess, flavor, crate_type, codegen_results) ;
1532
+ // FIXME: Support `StaticPicExe` correctly.
1533
+ match link_output_kind {
1534
+ LinkOutputKind :: DynamicPicExe | LinkOutputKind :: StaticPicExe => {
1535
+ cmd. position_independent_executable ( )
1536
+ }
1537
+ LinkOutputKind :: DynamicNoPicExe | LinkOutputKind :: StaticNoPicExe => {
1538
+ cmd. no_position_independent_executable ( )
1539
+ }
1540
+ _ => { }
1541
+ }
1519
1542
1520
1543
// OBJECT-FILES-NO, AUDIT-ORDER
1521
1544
add_relro_args ( cmd, sess) ;
@@ -1545,12 +1568,14 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
1545
1568
) ;
1546
1569
1547
1570
// NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1548
- // Tell the linker what we're doing.
1549
- if crate_type != CrateType :: Executable {
1550
- cmd. build_dylib ( out_filename) ;
1551
- }
1552
- if crate_type == CrateType :: Executable && sess. crt_static ( Some ( crate_type) ) {
1553
- cmd. build_static_executable ( ) ;
1571
+ // FIXME: Merge with the previous `link_output_kind` match,
1572
+ // and support `StaticPicExe` and `StaticDylib` correctly.
1573
+ match link_output_kind {
1574
+ LinkOutputKind :: StaticNoPicExe | LinkOutputKind :: StaticPicExe => {
1575
+ cmd. build_static_executable ( )
1576
+ }
1577
+ LinkOutputKind :: DynamicDylib | LinkOutputKind :: StaticDylib => cmd. build_dylib ( out_filename) ,
1578
+ _ => { }
1554
1579
}
1555
1580
1556
1581
// OBJECT-FILES-NO, AUDIT-ORDER
@@ -1576,7 +1601,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
1576
1601
add_late_link_args ( cmd, sess, flavor, crate_type, codegen_results) ;
1577
1602
1578
1603
// NO-OPT-OUT, OBJECT-FILES-YES
1579
- add_post_link_objects ( cmd, sess, crate_type ) ;
1604
+ add_post_link_objects ( cmd, sess, link_output_kind , crt_objects_fallback ) ;
1580
1605
1581
1606
// NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1582
1607
add_post_link_args ( cmd, sess, flavor) ;
0 commit comments