@@ -933,6 +933,15 @@ fn cp_rustc_component_to_ci_sysroot(builder: &Builder<'_>, sysroot: &Path, conte
933933 }
934934}
935935
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+
936945/// Build rustc using the passed `build_compiler`.
937946///
938947/// - Makes sure that `build_compiler` has a standard library prepared for its host target,
@@ -960,7 +969,7 @@ impl Rustc {
960969}
961970
962971impl Step for Rustc {
963- type Output = ( ) ;
972+ type Output = BuiltRustc ;
964973
965974 const IS_HOST : bool = true ;
966975 const DEFAULT : bool = false ;
@@ -1000,7 +1009,7 @@ impl Step for Rustc {
10001009 /// This will build the compiler for a particular stage of the build using
10011010 /// the `build_compiler` targeting the `target` architecture. The artifacts
10021011 /// created will also be linked into the sysroot directory.
1003- fn run ( self , builder : & Builder < ' _ > ) {
1012+ fn run ( self , builder : & Builder < ' _ > ) -> Self :: Output {
10041013 let build_compiler = self . build_compiler ;
10051014 let target = self . target ;
10061015
@@ -1016,7 +1025,7 @@ impl Step for Rustc {
10161025 & sysroot,
10171026 builder. config . ci_rustc_dev_contents ( ) ,
10181027 ) ;
1019- return ;
1028+ return BuiltRustc { build_compiler } ;
10201029 }
10211030
10221031 // Build a standard library for `target` using the `build_compiler`.
@@ -1028,9 +1037,9 @@ impl Step for Rustc {
10281037
10291038 builder. info ( "WARNING: Using a potentially old librustc. This may not behave well." ) ;
10301039 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 ) ) ;
10321041
1033- return ;
1042+ return BuiltRustc { build_compiler } ;
10341043 }
10351044
10361045 // The stage of the compiler that we're building
@@ -1042,21 +1051,35 @@ impl Step for Rustc {
10421051 && !builder. config . full_bootstrap
10431052 && ( target == builder. host_target || builder. hosts . contains ( & target) )
10441053 {
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})" )
10511060 } else {
10521061 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
10551064 )
10561065 } ;
10571066 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 } ;
10601083 }
10611084
10621085 // Build a standard library for the current host target using the `build_compiler`.
@@ -1129,10 +1152,8 @@ impl Step for Rustc {
11291152 strip_debug ( builder, target, & target_root_dir. join ( "rustc-main" ) ) ;
11301153 }
11311154
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 }
11361157 }
11371158
11381159 fn metadata ( & self ) -> Option < StepMetadata > {
@@ -1441,31 +1462,51 @@ fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelect
14411462 }
14421463}
14431464
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+ ///
14451473/// This is necessary for tools using `rustc_private`, where the previous compiler will build
14461474/// a tool against the next compiler.
14471475/// To build a tool against a compiler, the rlibs of that compiler that it links against
14481476/// must be in the sysroot of the compiler that's doing the compiling.
14491477#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
14501478struct 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 ,
14561485 /// Not actually used; only present to make sure the cache invalidation is correct.
14571486 crates : Vec < String > ,
14581487}
14591488
14601489impl 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 {
14621493 Self {
1463- compiler : host_compiler ,
1464- previous_stage_compiler : rustc. build_compiler ,
1494+ build_compiler : rustc . build_compiler ,
1495+ sysroot_compiler : rustc. build_compiler ,
14651496 target : rustc. target ,
14661497 crates : rustc. crates ,
14671498 }
14681499 }
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+ }
14691510}
14701511
14711512impl Step for RustcLink {
@@ -1477,14 +1518,14 @@ impl Step for RustcLink {
14771518
14781519 /// Same as `std_link`, only for librustc
14791520 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 ;
14821523 let target = self . target ;
14831524 add_to_sysroot (
14841525 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) ,
14881529 ) ;
14891530 }
14901531}
@@ -2099,7 +2140,10 @@ impl Step for Assemble {
20992140 "target_compiler.host" = ?target_compiler. host,
21002141 "building compiler libraries to link to"
21012142 ) ;
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 ) ) ;
21032147
21042148 let stage = target_compiler. stage ;
21052149 let host = target_compiler. host ;
0 commit comments