@@ -11,7 +11,9 @@ use rustc_session::search_paths::PathKind;
1111/// need out of the shared crate context before we get rid of it.
1212use rustc_session:: { filesearch, Session } ;
1313use 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 } ;
1517
1618use super :: archive:: ArchiveBuilder ;
1719use super :: command:: Command ;
@@ -1130,33 +1132,70 @@ fn exec_linker(
11301132 }
11311133}
11321134
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 ,
11391143 } ;
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,
11421154 }
1155+ }
11431156
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 ,
11481171 }
11491172}
11501173
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 ( ) {
11541184 cmd. add_object ( & get_object_file_path ( sess, obj) ) ;
11551185 }
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) ) ;
11601199 }
11611200}
11621201
@@ -1320,38 +1359,6 @@ fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session) {
13201359 cmd. include_path ( & fix_windows_verbatim_for_gcc ( & lib_path) ) ;
13211360}
13221361
1323- /// Add options requesting executables to be position-independent or not position-independent.
1324- fn add_position_independent_executable_args (
1325- cmd : & mut dyn Linker ,
1326- sess : & Session ,
1327- flavor : LinkerFlavor ,
1328- crate_type : CrateType ,
1329- codegen_results : & CodegenResults ,
1330- ) {
1331- if crate_type != CrateType :: Executable {
1332- return ;
1333- }
1334-
1335- if sess. target . target . options . position_independent_executables {
1336- let attr_link_args = & * codegen_results. crate_info . link_args ;
1337- let mut user_defined_link_args = sess. opts . cg . link_args . iter ( ) . chain ( attr_link_args) ;
1338- if sess. relocation_model ( ) == RelocModel :: Pic
1339- && !sess. crt_static ( Some ( crate_type) )
1340- && !user_defined_link_args. any ( |x| x == "-static" )
1341- {
1342- cmd. position_independent_executable ( ) ;
1343- return ;
1344- }
1345- }
1346-
1347- // Recent versions of gcc can be configured to generate position
1348- // independent executables by default. We have to pass -no-pie to
1349- // explicitly turn that off. Not applicable to ld.
1350- if sess. target . target . options . linker_is_gnu && flavor != LinkerFlavor :: Ld {
1351- cmd. no_position_independent_executable ( ) ;
1352- }
1353- }
1354-
13551362/// Add options making relocation sections in the produced ELF files read-only
13561363/// and suppressing lazy binding.
13571364fn add_relro_args ( cmd : & mut dyn Linker , sess : & Session ) {
@@ -1417,6 +1424,8 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
14171424 // to the linker args construction.
14181425 assert ! ( base_cmd. get_args( ) . is_empty( ) || sess. target. target. target_vendor == "uwp" ) ;
14191426 let cmd = & mut * codegen_results. linker_info . to_linker ( base_cmd, & sess, flavor, target_cpu) ;
1427+ let link_output_kind = link_output_kind ( sess, crate_type) ;
1428+ let crt_objects_fallback = crt_objects_fallback ( sess, crate_type) ;
14201429
14211430 // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
14221431 add_pre_link_args ( cmd, sess, flavor, crate_type) ;
@@ -1430,8 +1439,13 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
14301439 cmd. arg ( format ! ( "--dynamic-linker={}ld.so.1" , prefix) ) ;
14311440 }
14321441
1442+ // NO-OPT-OUT, OBJECT-FILES-NO
1443+ if crt_objects_fallback {
1444+ cmd. no_crt_objects ( ) ;
1445+ }
1446+
14331447 // NO-OPT-OUT, OBJECT-FILES-YES
1434- add_pre_link_objects ( cmd, sess, crate_type ) ;
1448+ add_pre_link_objects ( cmd, sess, link_output_kind , crt_objects_fallback ) ;
14351449
14361450 // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
14371451 if sess. target . target . options . is_like_emscripten {
@@ -1490,7 +1504,16 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
14901504 }
14911505
14921506 // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1493- add_position_independent_executable_args ( cmd, sess, flavor, crate_type, codegen_results) ;
1507+ // FIXME: Support `StaticPicExe` correctly.
1508+ match link_output_kind {
1509+ LinkOutputKind :: DynamicPicExe | LinkOutputKind :: StaticPicExe => {
1510+ cmd. position_independent_executable ( )
1511+ }
1512+ LinkOutputKind :: DynamicNoPicExe | LinkOutputKind :: StaticNoPicExe => {
1513+ cmd. no_position_independent_executable ( )
1514+ }
1515+ _ => { }
1516+ }
14941517
14951518 // OBJECT-FILES-NO, AUDIT-ORDER
14961519 add_relro_args ( cmd, sess) ;
@@ -1520,12 +1543,14 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
15201543 ) ;
15211544
15221545 // NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1523- // Tell the linker what we're doing.
1524- if crate_type != CrateType :: Executable {
1525- cmd. build_dylib ( out_filename) ;
1526- }
1527- if crate_type == CrateType :: Executable && sess. crt_static ( Some ( crate_type) ) {
1528- cmd. build_static_executable ( ) ;
1546+ // FIXME: Merge with the previous `link_output_kind` match,
1547+ // and support `StaticPicExe` and `StaticDylib` correctly.
1548+ match link_output_kind {
1549+ LinkOutputKind :: StaticNoPicExe | LinkOutputKind :: StaticPicExe => {
1550+ cmd. build_static_executable ( )
1551+ }
1552+ LinkOutputKind :: DynamicDylib | LinkOutputKind :: StaticDylib => cmd. build_dylib ( out_filename) ,
1553+ _ => { }
15291554 }
15301555
15311556 // OBJECT-FILES-NO, AUDIT-ORDER
@@ -1551,7 +1576,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
15511576 add_late_link_args ( cmd, sess, flavor, crate_type, codegen_results) ;
15521577
15531578 // NO-OPT-OUT, OBJECT-FILES-YES
1554- add_post_link_objects ( cmd, sess, crate_type ) ;
1579+ add_post_link_objects ( cmd, sess, link_output_kind , crt_objects_fallback ) ;
15551580
15561581 // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
15571582 add_post_link_args ( cmd, sess, flavor) ;
0 commit comments