@@ -34,7 +34,7 @@ use filetime::FileTime;
34
34
use once_cell:: sync:: OnceCell ;
35
35
36
36
use crate :: builder:: Kind ;
37
- use crate :: config:: { LlvmLibunwind , TargetSelection } ;
37
+ use crate :: config:: { LldMode , LlvmLibunwind , TargetSelection } ;
38
38
use crate :: util:: {
39
39
dir_is_empty, exe, libdir, mtime, output, run, run_suppressed, symlink_dir, try_run_suppressed,
40
40
} ;
@@ -1250,6 +1250,7 @@ impl Build {
1250
1250
if self . config . dry_run ( ) {
1251
1251
return Some ( PathBuf :: new ( ) ) ;
1252
1252
}
1253
+
1253
1254
if let Some ( linker) = self . config . target_config . get ( & target) . and_then ( |c| c. linker . clone ( ) )
1254
1255
{
1255
1256
Some ( linker)
@@ -1260,32 +1261,72 @@ impl Build {
1260
1261
} else if target != self . config . build && util:: use_host_linker ( target) && !target. is_msvc ( )
1261
1262
{
1262
1263
Some ( self . cc ( target) )
1263
- } else if self . config . use_lld && !self . is_fuse_ld_lld ( target) && self . build == target {
1264
- Some ( self . initial_lld . clone ( ) )
1264
+ } else if self . config . lld_mode . is_used ( )
1265
+ && self . is_lld_direct_linker ( target)
1266
+ && self . build == target
1267
+ {
1268
+ match self . config . lld_mode {
1269
+ LldMode :: SelfContained => Some ( self . initial_lld . clone ( ) ) ,
1270
+ LldMode :: External => Some ( "lld" . into ( ) ) ,
1271
+ LldMode :: Unused => None ,
1272
+ }
1265
1273
} else {
1266
1274
None
1267
1275
}
1268
1276
}
1269
1277
1270
- // LLD is used through `-fuse-ld=lld` rather than directly.
1278
+ // Is LLD configured directly through `-Clinker`?
1271
1279
// Only MSVC targets use LLD directly at the moment.
1272
- fn is_fuse_ld_lld ( & self , target : TargetSelection ) -> bool {
1273
- self . config . use_lld && ! target. is_msvc ( )
1280
+ fn is_lld_direct_linker ( & self , target : TargetSelection ) -> bool {
1281
+ target. is_msvc ( )
1274
1282
}
1275
1283
1276
- fn lld_flags ( & self , target : TargetSelection ) -> impl Iterator < Item = String > {
1277
- let mut options = [ None , None ] ;
1284
+ // Returns the gcc-ld directory of the snapshot compiler's rust-lld.
1285
+ fn initial_lld_root ( & self ) -> PathBuf {
1286
+ let mut rust_lld_path = self . initial_lld . clone ( ) ;
1287
+ rust_lld_path. pop ( ) ;
1288
+ rust_lld_path. join ( "gcc-ld" )
1289
+ }
1278
1290
1279
- if self . config . use_lld {
1280
- if self . is_fuse_ld_lld ( target) {
1281
- options[ 0 ] = Some ( "-Clink-arg=-fuse-ld=lld" . to_string ( ) ) ;
1282
- }
1291
+ fn lld_flags ( & self , target : TargetSelection , test : bool ) -> Vec < String > {
1292
+ let mut flags = vec ! [ ] ;
1293
+
1294
+ if !self . is_lld_direct_linker ( target) {
1295
+ match self . config . lld_mode {
1296
+ LldMode :: SelfContained => {
1297
+ // FIXME: replace with MCP510 (-Clinker-flavor + -Clink-self-contained)
1298
+ // once gcc-ld is available in stage0-sysroot.
1299
+ flags. push ( "-Clink-arg=-fuse-ld=lld" . to_string ( ) ) ;
1300
+ flags. push ( format ! ( "-Clink-arg=-B{}" , self . initial_lld_root( ) . display( ) ) ) ;
1301
+ }
1302
+ LldMode :: External => {
1303
+ flags. push ( "-Clink-arg=-fuse-ld=lld" . to_string ( ) ) ;
1304
+ }
1305
+ LldMode :: Unused => { }
1306
+ } ;
1307
+ }
1283
1308
1284
- let no_threads = util:: lld_flag_no_threads ( target. contains ( "windows" ) ) ;
1285
- options[ 1 ] = Some ( format ! ( "-Clink-arg=-Wl,{no_threads}" ) ) ;
1309
+ // For tests we want to use only a single thread.
1310
+ // If we use an external LLD, we don't know if it's new enough to support the required
1311
+ // threads flag. Therefore we invoke it to find it out.
1312
+ // The self-contained lld should always be new enough.
1313
+ if test {
1314
+ let new_flags = if let LldMode :: External = self . config . lld_mode {
1315
+ util:: is_lld_newer_than_10 ( )
1316
+ } else {
1317
+ true
1318
+ } ;
1319
+
1320
+ let flag = match ( new_flags, target. contains ( "windows" ) ) {
1321
+ ( true , true ) => "/threads:1" ,
1322
+ ( true , false ) => "--threads=1" ,
1323
+ ( false , true ) => "/no-threads" ,
1324
+ ( false , false ) => "--no-threads" ,
1325
+ } ;
1326
+ flags. push ( format ! ( "-Clink-arg=-Wl,{flag}" ) ) ;
1286
1327
}
1287
1328
1288
- IntoIterator :: into_iter ( options ) . flatten ( )
1329
+ flags
1289
1330
}
1290
1331
1291
1332
/// Returns if this target should statically link the C runtime, if specified
0 commit comments