@@ -933,6 +933,15 @@ fn cp_rustc_component_to_ci_sysroot(builder: &Builder<'_>, sysroot: &Path, conte
933
933
}
934
934
}
935
935
936
+ /// Represents information about a built rustc.
937
+ #[ derive( Clone , Debug ) ]
938
+ pub struct BuiltRustc {
939
+ /// The compiler that actually built this *rustc*.
940
+ /// This can be different from the *build_compiler* passed to the `Rustc` step because of
941
+ /// uplifting.
942
+ pub build_compiler : Compiler ,
943
+ }
944
+
936
945
/// Build rustc using the passed `build_compiler`.
937
946
///
938
947
/// - Makes sure that `build_compiler` has a standard library prepared for its host target,
@@ -960,7 +969,7 @@ impl Rustc {
960
969
}
961
970
962
971
impl Step for Rustc {
963
- type Output = ( ) ;
972
+ type Output = BuiltRustc ;
964
973
965
974
const IS_HOST : bool = true ;
966
975
const DEFAULT : bool = false ;
@@ -1000,7 +1009,7 @@ impl Step for Rustc {
1000
1009
/// This will build the compiler for a particular stage of the build using
1001
1010
/// the `build_compiler` targeting the `target` architecture. The artifacts
1002
1011
/// created will also be linked into the sysroot directory.
1003
- fn run ( self , builder : & Builder < ' _ > ) {
1012
+ fn run ( self , builder : & Builder < ' _ > ) -> Self :: Output {
1004
1013
let build_compiler = self . build_compiler ;
1005
1014
let target = self . target ;
1006
1015
@@ -1016,7 +1025,7 @@ impl Step for Rustc {
1016
1025
& sysroot,
1017
1026
builder. config . ci_rustc_dev_contents ( ) ,
1018
1027
) ;
1019
- return ;
1028
+ return BuiltRustc { build_compiler } ;
1020
1029
}
1021
1030
1022
1031
// Build a standard library for `target` using the `build_compiler`.
@@ -1028,9 +1037,9 @@ impl Step for Rustc {
1028
1037
1029
1038
builder. info ( "WARNING: Using a potentially old librustc. This may not behave well." ) ;
1030
1039
builder. info ( "WARNING: Use `--keep-stage-std` if you want to rebuild the compiler when it changes" ) ;
1031
- builder. ensure ( RustcLink :: from_rustc ( self , build_compiler ) ) ;
1040
+ builder. ensure ( RustcLink :: from_rustc ( self ) ) ;
1032
1041
1033
- return ;
1042
+ return BuiltRustc { build_compiler } ;
1034
1043
}
1035
1044
1036
1045
// The stage of the compiler that we're building
@@ -1042,21 +1051,35 @@ impl Step for Rustc {
1042
1051
&& !builder. config . full_bootstrap
1043
1052
&& ( target == builder. host_target || builder. hosts . contains ( & target) )
1044
1053
{
1045
- // If we're cross-compiling, the earliest rustc that we could have is stage 2.
1046
- // If we're not cross-compiling, then we should have rustc stage 1.
1047
- let stage_to_uplift = if target == builder . host_target { 1 } else { 2 } ;
1048
- let rustc_to_uplift = builder. compiler ( stage_to_uplift , target ) ;
1049
- let msg = if rustc_to_uplift . host == target {
1050
- format ! ( "Uplifting rustc (stage{} -> stage{stage})" , rustc_to_uplift . stage , )
1054
+ // Here we need to determine the **build compiler** that built the stage that we will
1055
+ // be uplifting. We cannot uplift stage 1, as it has a different ABI than stage 2+,
1056
+ // so we always uplift the stage2 compiler (compiled with stage 1).
1057
+ let uplift_build_compiler = builder. compiler ( 1 , build_compiler . host ) ;
1058
+ let msg = if uplift_build_compiler . host == target {
1059
+ format ! ( "Uplifting rustc (stage2 -> stage{stage})" )
1051
1060
} else {
1052
1061
format ! (
1053
- "Uplifting rustc (stage{} :{} -> stage{stage}:{target})" ,
1054
- rustc_to_uplift . stage , rustc_to_uplift . host,
1062
+ "Uplifting rustc (stage2 :{} -> stage{stage}:{target})" ,
1063
+ uplift_build_compiler . host
1055
1064
)
1056
1065
} ;
1057
1066
builder. info ( & msg) ;
1058
- builder. ensure ( RustcLink :: from_rustc ( self , rustc_to_uplift) ) ;
1059
- return ;
1067
+
1068
+ // Here the compiler that built the rlibs (`uplift_build_compiler`) can be different
1069
+ // from the compiler whose sysroot should be modified in this step. So we need to copy
1070
+ // the (previously built) rlibs into the correct sysroot.
1071
+ builder. ensure ( RustcLink :: from_build_compiler_and_sysroot (
1072
+ // This is the compiler that actually built the rustc rlibs
1073
+ uplift_build_compiler,
1074
+ // We copy the rlibs into the sysroot of `build_compiler`
1075
+ build_compiler,
1076
+ target,
1077
+ self . crates ,
1078
+ ) ) ;
1079
+
1080
+ // Here we have performed an uplift, so we return the actual build compiler that "built"
1081
+ // this rustc.
1082
+ return BuiltRustc { build_compiler : uplift_build_compiler } ;
1060
1083
}
1061
1084
1062
1085
// Build a standard library for the current host target using the `build_compiler`.
@@ -1129,10 +1152,8 @@ impl Step for Rustc {
1129
1152
strip_debug ( builder, target, & target_root_dir. join ( "rustc-main" ) ) ;
1130
1153
}
1131
1154
1132
- builder. ensure ( RustcLink :: from_rustc (
1133
- self ,
1134
- builder. compiler ( build_compiler. stage , builder. config . host_target ) ,
1135
- ) ) ;
1155
+ builder. ensure ( RustcLink :: from_rustc ( self ) ) ;
1156
+ BuiltRustc { build_compiler }
1136
1157
}
1137
1158
1138
1159
fn metadata ( & self ) -> Option < StepMetadata > {
@@ -1441,31 +1462,51 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect
1441
1462
}
1442
1463
}
1443
1464
1444
- /// `RustcLink` copies all of the rlibs from the rustc build into the previous stage's sysroot.
1465
+ /// `RustcLink` copies compiler rlibs from a rustc build into a compiler sysroot.
1466
+ /// It works with (potentially up to) three compilers:
1467
+ /// - `build_compiler` is a compiler that built rustc rlibs
1468
+ /// - `sysroot_compiler` is a compiler into whose sysroot we will copy the rlibs
1469
+ /// - In most situations, `build_compiler` == `sysroot_compiler`
1470
+ /// - `target_compiler` is the compiler whose rlibs were built. It is not represented explicitly
1471
+ /// in this step, rather we just read the rlibs from a rustc build stamp of `build_compiler`.
1472
+ ///
1445
1473
/// This is necessary for tools using `rustc_private`, where the previous compiler will build
1446
1474
/// a tool against the next compiler.
1447
1475
/// To build a tool against a compiler, the rlibs of that compiler that it links against
1448
1476
/// must be in the sysroot of the compiler that's doing the compiling.
1449
1477
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
1450
1478
struct RustcLink {
1451
- /// The compiler whose rlibs we are copying around.
1452
- pub compiler : Compiler ,
1453
- /// This is the compiler into whose sysroot we want to copy the rlibs into.
1454
- pub previous_stage_compiler : Compiler ,
1455
- pub target : TargetSelection ,
1479
+ /// This compiler **built** some rustc, whose rlibs we will copy into a sysroot.
1480
+ build_compiler : Compiler ,
1481
+ /// This is the compiler into whose sysroot we want to copy the built rlibs.
1482
+ /// In most cases, it will correspond to `build_compiler`.
1483
+ sysroot_compiler : Compiler ,
1484
+ target : TargetSelection ,
1456
1485
/// Not actually used; only present to make sure the cache invalidation is correct.
1457
1486
crates : Vec < String > ,
1458
1487
}
1459
1488
1460
1489
impl RustcLink {
1461
- fn from_rustc ( rustc : Rustc , host_compiler : Compiler ) -> Self {
1490
+ /// Copy rlibs from the build compiler that build this `rustc` into the sysroot of that
1491
+ /// build compiler.
1492
+ fn from_rustc ( rustc : Rustc ) -> Self {
1462
1493
Self {
1463
- compiler : host_compiler ,
1464
- previous_stage_compiler : rustc. build_compiler ,
1494
+ build_compiler : rustc . build_compiler ,
1495
+ sysroot_compiler : rustc. build_compiler ,
1465
1496
target : rustc. target ,
1466
1497
crates : rustc. crates ,
1467
1498
}
1468
1499
}
1500
+
1501
+ /// Copy rlibs **built** by `build_compiler` into the sysroot of `sysroot_compiler`.
1502
+ fn from_build_compiler_and_sysroot (
1503
+ build_compiler : Compiler ,
1504
+ sysroot_compiler : Compiler ,
1505
+ target : TargetSelection ,
1506
+ crates : Vec < String > ,
1507
+ ) -> Self {
1508
+ Self { build_compiler, sysroot_compiler, target, crates }
1509
+ }
1469
1510
}
1470
1511
1471
1512
impl Step for RustcLink {
@@ -1477,14 +1518,14 @@ impl Step for RustcLink {
1477
1518
1478
1519
/// Same as `std_link`, only for librustc
1479
1520
fn run ( self , builder : & Builder < ' _ > ) {
1480
- let compiler = self . compiler ;
1481
- let previous_stage_compiler = self . previous_stage_compiler ;
1521
+ let build_compiler = self . build_compiler ;
1522
+ let sysroot_compiler = self . sysroot_compiler ;
1482
1523
let target = self . target ;
1483
1524
add_to_sysroot (
1484
1525
builder,
1485
- & builder. sysroot_target_libdir ( previous_stage_compiler , target) ,
1486
- & builder. sysroot_target_libdir ( previous_stage_compiler , compiler . host ) ,
1487
- & build_stamp:: librustc_stamp ( builder, compiler , target) ,
1526
+ & builder. sysroot_target_libdir ( sysroot_compiler , target) ,
1527
+ & builder. sysroot_target_libdir ( sysroot_compiler , sysroot_compiler . host ) ,
1528
+ & build_stamp:: librustc_stamp ( builder, build_compiler , target) ,
1488
1529
) ;
1489
1530
}
1490
1531
}
@@ -2099,7 +2140,10 @@ impl Step for Assemble {
2099
2140
"target_compiler.host" = ?target_compiler. host,
2100
2141
"building compiler libraries to link to"
2101
2142
) ;
2102
- builder. ensure ( Rustc :: new ( build_compiler, target_compiler. host ) ) ;
2143
+
2144
+ // It is possible that an uplift has happened, so we override build_compiler here.
2145
+ let BuiltRustc { build_compiler } =
2146
+ builder. ensure ( Rustc :: new ( build_compiler, target_compiler. host ) ) ;
2103
2147
2104
2148
let stage = target_compiler. stage ;
2105
2149
let host = target_compiler. host ;
0 commit comments