@@ -9,6 +9,7 @@ use rustc_hir::def_id::CrateNum;
9
9
use rustc_middle:: middle:: dependency_format:: Linkage ;
10
10
use rustc_middle:: middle:: exported_symbols:: SymbolExportKind ;
11
11
use rustc_session:: config:: { self , CFGuard , CrateType , DebugInfo , LdImpl , Strip } ;
12
+ use rustc_session:: config:: { LegacyLinkerFlavor , LldFlavor } ;
12
13
use rustc_session:: config:: { OutputFilenames , OutputType , PrintRequest , SplitDwarfKind } ;
13
14
use rustc_session:: cstore:: DllImport ;
14
15
use rustc_session:: output:: { check_file_is_writeable, invalid_output_for_target, out_filename} ;
@@ -20,7 +21,8 @@ use rustc_session::{filesearch, Session};
20
21
use rustc_span:: symbol:: Symbol ;
21
22
use rustc_span:: DebuggerVisualizerFile ;
22
23
use rustc_target:: spec:: crt_objects:: { CrtObjects , CrtObjectsFallback } ;
23
- use rustc_target:: spec:: { LinkOutputKind , LinkerFlavor , LldFlavor , SplitDebuginfo } ;
24
+ use rustc_target:: spec:: CoarseGrainedLinkerFlavor ;
25
+ use rustc_target:: spec:: { LinkOutputKind , SplitDebuginfo } ;
24
26
use rustc_target:: spec:: { PanicStrategy , RelocModel , RelroLevel , SanitizerSet , Target } ;
25
27
26
28
use super :: archive:: { find_library, ArchiveBuilder } ;
@@ -665,10 +667,11 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
665
667
tmpdir : & Path ,
666
668
) {
667
669
info ! ( "preparing {:?} to {:?}" , crate_type, out_filename) ;
668
- let ( linker_path, flavor) = linker_and_flavor ( sess) ;
670
+ let ( linker_path, full_flavor) = linker_and_flavor ( sess) ;
671
+ let flavor = * full_flavor;
669
672
let mut cmd = linker_with_args :: < B > (
670
673
& linker_path,
671
- flavor ,
674
+ full_flavor ,
672
675
sess,
673
676
crate_type,
674
677
tmpdir,
@@ -719,7 +722,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
719
722
// versions of gcc seem to use different quotes in the error message so
720
723
// don't check for them.
721
724
if sess. target . linker_is_gnu
722
- && flavor != LinkerFlavor :: Ld
725
+ && flavor == CoarseGrainedLinkerFlavor :: TargetLinkerCalledThroughCCompiler
723
726
&& unknown_arg_regex. is_match ( & out)
724
727
&& out. contains ( "-no-pie" )
725
728
&& cmd. get_args ( ) . iter ( ) . any ( |e| e. to_string_lossy ( ) == "-no-pie" )
@@ -738,7 +741,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
738
741
// Detect '-static-pie' used with an older version of gcc or clang not supporting it.
739
742
// Fallback from '-static-pie' to '-static' in that case.
740
743
if sess. target . linker_is_gnu
741
- && flavor != LinkerFlavor :: Ld
744
+ && flavor == CoarseGrainedLinkerFlavor :: TargetLinkerCalledThroughCCompiler
742
745
&& unknown_arg_regex. is_match ( & out)
743
746
&& ( out. contains ( "-static-pie" ) || out. contains ( "--no-dynamic-linker" ) )
744
747
&& cmd. get_args ( ) . iter ( ) . any ( |e| e. to_string_lossy ( ) == "-static-pie" )
@@ -873,7 +876,6 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(
873
876
// install the Visual Studio build tools.
874
877
if let Some ( code) = prog. status . code ( ) {
875
878
if sess. target . is_like_msvc
876
- && flavor == LinkerFlavor :: Msvc
877
879
// Respect the command line override
878
880
&& sess. opts . cg . linker . is_none ( )
879
881
// Match exactly "link.exe"
@@ -1139,94 +1141,103 @@ pub fn ignored_for_lto(sess: &Session, info: &CrateInfo, cnum: CrateNum) -> bool
1139
1141
&& ( info. compiler_builtins == Some ( cnum) || info. is_no_builtins . contains ( & cnum) )
1140
1142
}
1141
1143
1142
- // This functions tries to determine the appropriate linker (and corresponding LinkerFlavor) to use
1143
- pub fn linker_and_flavor ( sess : & Session ) -> ( PathBuf , LinkerFlavor ) {
1144
- fn infer_from (
1145
- sess : & Session ,
1146
- linker : Option < PathBuf > ,
1147
- flavor : Option < LinkerFlavor > ,
1148
- ) -> Option < ( PathBuf , LinkerFlavor ) > {
1149
- match ( linker, flavor) {
1150
- ( Some ( linker) , Some ( flavor) ) => Some ( ( linker, flavor) ) ,
1151
- // only the linker flavor is known; use the default linker for the selected flavor
1152
- ( None , Some ( flavor) ) => Some ( (
1153
- PathBuf :: from ( match flavor {
1154
- LinkerFlavor :: Em => {
1155
- if cfg ! ( windows) {
1156
- "emcc.bat"
1157
- } else {
1158
- "emcc"
1159
- }
1160
- }
1161
- LinkerFlavor :: Gcc => {
1162
- if cfg ! ( any( target_os = "solaris" , target_os = "illumos" ) ) {
1163
- // On historical Solaris systems, "cc" may have
1164
- // been Sun Studio, which is not flag-compatible
1165
- // with "gcc". This history casts a long shadow,
1166
- // and many modern illumos distributions today
1167
- // ship GCC as "gcc" without also making it
1168
- // available as "cc".
1169
- "gcc"
1170
- } else {
1171
- "cc"
1172
- }
1173
- }
1174
- LinkerFlavor :: Ld => "ld" ,
1175
- LinkerFlavor :: Msvc => "link.exe" ,
1176
- LinkerFlavor :: Lld ( _) => "lld" ,
1177
- LinkerFlavor :: PtxLinker => "rust-ptx-linker" ,
1178
- LinkerFlavor :: BpfLinker => "bpf-linker" ,
1179
- LinkerFlavor :: L4Bender => "l4-bender" ,
1180
- } ) ,
1181
- flavor,
1182
- ) ) ,
1183
- ( Some ( linker) , None ) => {
1184
- let stem = linker. file_stem ( ) . and_then ( |stem| stem. to_str ( ) ) . unwrap_or_else ( || {
1185
- sess. fatal ( "couldn't extract file stem from specified linker" )
1186
- } ) ;
1187
-
1188
- let flavor = if stem == "emcc" {
1189
- LinkerFlavor :: Em
1190
- } else if stem == "gcc"
1191
- || stem. ends_with ( "-gcc" )
1192
- || stem == "clang"
1193
- || stem. ends_with ( "-clang" )
1194
- {
1195
- LinkerFlavor :: Gcc
1196
- } else if stem == "wasm-ld" || stem. ends_with ( "-wasm-ld" ) {
1197
- LinkerFlavor :: Lld ( LldFlavor :: Wasm )
1198
- } else if stem == "ld" || stem == "ld.lld" || stem. ends_with ( "-ld" ) {
1199
- LinkerFlavor :: Ld
1200
- } else if stem == "link" || stem == "lld-link" {
1201
- LinkerFlavor :: Msvc
1202
- } else if stem == "lld" || stem == "rust-lld" {
1203
- LinkerFlavor :: Lld ( sess. target . lld_flavor )
1204
- } else {
1205
- // fall back to the value in the target spec
1206
- sess. target . linker_flavor
1207
- } ;
1144
+ fn flavor_from_linker_str ( linker : & Path , sess : & Session ) -> Option < LegacyLinkerFlavor > {
1145
+ let stem = linker
1146
+ . file_stem ( )
1147
+ . and_then ( |stem| stem. to_str ( ) )
1148
+ . unwrap_or_else ( || sess. fatal ( "couldn't extract file stem from specified linker" ) ) ;
1149
+
1150
+ Some ( if stem == "emcc" {
1151
+ LegacyLinkerFlavor :: Em
1152
+ } else if stem == "gcc"
1153
+ || stem. ends_with ( "-gcc" )
1154
+ || stem == "clang"
1155
+ || stem. ends_with ( "-clang" )
1156
+ || stem == "cc"
1157
+ || stem. ends_with ( "-cc" )
1158
+ || stem == "c++"
1159
+ || stem. ends_with ( "-c++" )
1160
+ {
1161
+ LegacyLinkerFlavor :: Gcc
1162
+ } else if stem == "wasm-ld" || stem. ends_with ( "-wasm-ld" ) {
1163
+ LegacyLinkerFlavor :: Lld ( LldFlavor :: Wasm )
1164
+ } else if stem == "ld" || stem == "ld.lld" || stem. ends_with ( "-ld" ) {
1165
+ LegacyLinkerFlavor :: Ld
1166
+ } else if stem == "link" || stem == "lld-link" {
1167
+ LegacyLinkerFlavor :: Msvc
1168
+ } else if stem == "lld" || stem == "rust-lld" {
1169
+ LegacyLinkerFlavor :: Lld ( LldFlavor :: from_sess ( sess) )
1170
+ } else if stem == "l4-bender" {
1171
+ LegacyLinkerFlavor :: L4Bender
1172
+ } else if stem == "rust-ptx-linker" {
1173
+ LegacyLinkerFlavor :: PtxLinker
1174
+ } else if stem == "bpf-linker" {
1175
+ LegacyLinkerFlavor :: BpfLinker
1176
+ } else {
1177
+ return None ;
1178
+ } )
1179
+ }
1208
1180
1209
- Some ( ( linker, flavor) )
1181
+ fn flavor_to_linker_str ( flavor : LegacyLinkerFlavor ) -> PathBuf {
1182
+ PathBuf :: from ( match flavor {
1183
+ LegacyLinkerFlavor :: Em => {
1184
+ if cfg ! ( windows) {
1185
+ "emcc.bat"
1186
+ } else {
1187
+ "emcc"
1210
1188
}
1211
- ( None , None ) => None ,
1212
1189
}
1213
- }
1190
+ LegacyLinkerFlavor :: Gcc => {
1191
+ if cfg ! ( any( target_os = "solaris" , target_os = "illumos" ) ) {
1192
+ // On historical Solaris systems, "cc" may have
1193
+ // been Sun Studio, which is not flag-compatible
1194
+ // with "gcc". This history casts a long shadow,
1195
+ // and many modern illumos distributions today
1196
+ // ship GCC as "gcc" without also making it
1197
+ // available as "cc".
1198
+ "gcc"
1199
+ } else {
1200
+ "cc"
1201
+ }
1202
+ }
1203
+ LegacyLinkerFlavor :: Ld => "ld" ,
1204
+ LegacyLinkerFlavor :: Msvc => "link.exe" ,
1205
+ LegacyLinkerFlavor :: Lld ( _) => "lld" ,
1206
+ LegacyLinkerFlavor :: PtxLinker => "rust-ptx-linker" ,
1207
+ LegacyLinkerFlavor :: BpfLinker => "bpf-linker" ,
1208
+ LegacyLinkerFlavor :: L4Bender => "l4-bender" ,
1209
+ } )
1210
+ }
1214
1211
1215
- // linker and linker flavor specified via command line have precedence over what the target
1216
- // specification specifies
1217
- if let Some ( ret ) = infer_from ( sess, sess . opts . cg . linker . clone ( ) , sess. opts . cg . linker_flavor ) {
1218
- return ret ;
1212
+ // This functions tries to determine the appropriate linker (and corresponding LegacyLinkerFlavor) to use
1213
+ pub fn linker_and_flavor ( sess : & Session ) -> ( PathBuf , LegacyLinkerFlavor ) {
1214
+ if let ( Some ( linker ) , Some ( flavor ) ) = ( & sess. opts . cg . linker , sess. opts . cg . linker_flavor ) {
1215
+ return ( linker . to_owned ( ) , flavor ) ;
1219
1216
}
1220
-
1221
- if let Some ( ret) = infer_from (
1222
- sess,
1223
- sess. target . linker . as_deref ( ) . map ( PathBuf :: from) ,
1224
- Some ( sess. target . linker_flavor ) ,
1225
- ) {
1226
- return ret;
1217
+ if let ( None , Some ( flavor) ) = ( & sess. opts . cg . linker , sess. opts . cg . linker_flavor ) {
1218
+ return ( flavor_to_linker_str ( flavor) , flavor) ;
1227
1219
}
1228
-
1229
- bug ! ( "Not enough information provided to determine how to invoke the linker" ) ;
1220
+ if let ( Some ( linker) , None ) = ( & sess. opts . cg . linker , sess. opts . cg . linker_flavor ) {
1221
+ if let Some ( flavor) = flavor_from_linker_str ( linker, sess) {
1222
+ return ( linker. to_owned ( ) , flavor) ;
1223
+ }
1224
+ if let Some ( default_linker) = & sess. target . linker {
1225
+ if let Some ( flavor) = flavor_from_linker_str ( Path :: new ( default_linker. as_ref ( ) ) , sess) {
1226
+ return ( linker. to_owned ( ) , flavor) ;
1227
+ }
1228
+ }
1229
+ // FIXME: From system
1230
+ return ( linker. to_owned ( ) , LegacyLinkerFlavor :: Gcc ) ;
1231
+ }
1232
+ if let Some ( default_linker) = & sess. target . linker {
1233
+ if let Some ( flavor) = flavor_from_linker_str ( Path :: new ( default_linker. as_ref ( ) ) , sess) {
1234
+ return ( PathBuf :: from ( default_linker. clone ( ) . into_owned ( ) ) , flavor) ;
1235
+ }
1236
+ // FIXME: From system
1237
+ return ( PathBuf :: from ( default_linker. clone ( ) . into_owned ( ) ) , LegacyLinkerFlavor :: Gcc ) ;
1238
+ }
1239
+ // FIXME: From system
1240
+ return ( PathBuf :: from ( "cc" ) , LegacyLinkerFlavor :: Gcc ) ;
1230
1241
}
1231
1242
1232
1243
/// Returns a pair of boolean indicating whether we should preserve the object and
@@ -1588,7 +1599,7 @@ fn add_post_link_objects(
1588
1599
1589
1600
/// Add arbitrary "pre-link" args defined by the target spec or from command line.
1590
1601
/// FIXME: Determine where exactly these args need to be inserted.
1591
- fn add_pre_link_args ( cmd : & mut dyn Linker , sess : & Session , flavor : LinkerFlavor ) {
1602
+ fn add_pre_link_args ( cmd : & mut dyn Linker , sess : & Session , flavor : CoarseGrainedLinkerFlavor ) {
1592
1603
if let Some ( args) = sess. target . pre_link_args . get ( & flavor) {
1593
1604
cmd. args ( args. iter ( ) . map ( Deref :: deref) ) ;
1594
1605
}
@@ -1628,7 +1639,7 @@ fn add_user_defined_link_args(cmd: &mut dyn Linker, sess: &Session) {
1628
1639
fn add_late_link_args (
1629
1640
cmd : & mut dyn Linker ,
1630
1641
sess : & Session ,
1631
- flavor : LinkerFlavor ,
1642
+ flavor : CoarseGrainedLinkerFlavor ,
1632
1643
crate_type : CrateType ,
1633
1644
codegen_results : & CodegenResults ,
1634
1645
) {
@@ -1652,7 +1663,7 @@ fn add_late_link_args(
1652
1663
1653
1664
/// Add arbitrary "post-link" args defined by the target spec.
1654
1665
/// FIXME: Determine where exactly these args need to be inserted.
1655
- fn add_post_link_args ( cmd : & mut dyn Linker , sess : & Session , flavor : LinkerFlavor ) {
1666
+ fn add_post_link_args ( cmd : & mut dyn Linker , sess : & Session , flavor : CoarseGrainedLinkerFlavor ) {
1656
1667
if let Some ( args) = sess. target . post_link_args . get ( & flavor) {
1657
1668
cmd. args ( args. iter ( ) . map ( Deref :: deref) ) ;
1658
1669
}
@@ -1851,18 +1862,19 @@ fn add_rpath_args(
1851
1862
/// e.g `--foo=yes --foo=no` may be equivalent to `--foo=no`.
1852
1863
fn linker_with_args < ' a , B : ArchiveBuilder < ' a > > (
1853
1864
path : & Path ,
1854
- flavor : LinkerFlavor ,
1865
+ full_flavor : LegacyLinkerFlavor ,
1855
1866
sess : & ' a Session ,
1856
1867
crate_type : CrateType ,
1857
1868
tmpdir : & Path ,
1858
1869
out_filename : & Path ,
1859
1870
codegen_results : & CodegenResults ,
1860
1871
) -> Command {
1872
+ let flavor = * full_flavor;
1861
1873
let crt_objects_fallback = crt_objects_fallback ( sess, crate_type) ;
1862
1874
let cmd = & mut * super :: linker:: get_linker (
1863
1875
sess,
1864
1876
path,
1865
- flavor ,
1877
+ full_flavor ,
1866
1878
crt_objects_fallback,
1867
1879
& codegen_results. crate_info . target_cpu ,
1868
1880
) ;
@@ -2015,7 +2027,7 @@ fn add_order_independent_options(
2015
2027
sess : & Session ,
2016
2028
link_output_kind : LinkOutputKind ,
2017
2029
crt_objects_fallback : bool ,
2018
- flavor : LinkerFlavor ,
2030
+ flavor : CoarseGrainedLinkerFlavor ,
2019
2031
crate_type : CrateType ,
2020
2032
codegen_results : & CodegenResults ,
2021
2033
out_filename : & Path ,
@@ -2056,11 +2068,11 @@ fn add_order_independent_options(
2056
2068
} ) ;
2057
2069
}
2058
2070
2059
- if flavor == LinkerFlavor :: PtxLinker {
2071
+ if sess . target . arch == "nvptx64" {
2060
2072
// Provide the linker with fallback to internal `target-cpu`.
2061
2073
cmd. arg ( "--fallback-arch" ) ;
2062
2074
cmd. arg ( & codegen_results. crate_info . target_cpu ) ;
2063
- } else if flavor == LinkerFlavor :: BpfLinker {
2075
+ } else if sess . target . arch == "bpf" {
2064
2076
cmd. arg ( "--cpu" ) ;
2065
2077
cmd. arg ( & codegen_results. crate_info . target_cpu ) ;
2066
2078
cmd. arg ( "--cpu-features" ) ;
@@ -2597,13 +2609,13 @@ fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
2597
2609
}
2598
2610
}
2599
2611
2600
- fn add_apple_sdk ( cmd : & mut dyn Linker , sess : & Session , flavor : LinkerFlavor ) {
2612
+ fn add_apple_sdk ( cmd : & mut dyn Linker , sess : & Session , flavor : CoarseGrainedLinkerFlavor ) {
2601
2613
let arch = & sess. target . arch ;
2602
2614
let os = & sess. target . os ;
2603
2615
let llvm_target = & sess. target . llvm_target ;
2604
2616
if sess. target . vendor != "apple"
2605
2617
|| !matches ! ( os. as_ref( ) , "ios" | "tvos" )
2606
- || flavor != LinkerFlavor :: Gcc
2618
+ || flavor == CoarseGrainedLinkerFlavor :: TargetLinker
2607
2619
{
2608
2620
return ;
2609
2621
}
@@ -2687,9 +2699,9 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
2687
2699
}
2688
2700
}
2689
2701
2690
- fn add_gcc_ld_path ( cmd : & mut dyn Linker , sess : & Session , flavor : LinkerFlavor ) {
2702
+ fn add_gcc_ld_path ( cmd : & mut dyn Linker , sess : & Session , flavor : CoarseGrainedLinkerFlavor ) {
2691
2703
if let Some ( ld_impl) = sess. opts . debugging_opts . gcc_ld {
2692
- if let LinkerFlavor :: Gcc = flavor {
2704
+ if flavor == CoarseGrainedLinkerFlavor :: TargetLinkerCalledThroughCCompiler {
2693
2705
match ld_impl {
2694
2706
LdImpl :: Lld => {
2695
2707
let tools_path = sess. get_tools_search_paths ( false ) ;
@@ -2705,7 +2717,9 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
2705
2717
arg. push ( gcc_ld_dir) ;
2706
2718
arg
2707
2719
} ) ;
2708
- cmd. arg ( format ! ( "-Wl,-rustc-lld-flavor={}" , sess. target. lld_flavor. as_str( ) ) ) ;
2720
+
2721
+ let lld_flavor = LldFlavor :: from_sess ( sess) ;
2722
+ cmd. arg ( format ! ( "-Wl,-rustc-lld-flavor={}" , lld_flavor. as_str( ) ) ) ;
2709
2723
}
2710
2724
}
2711
2725
} else {
0 commit comments