@@ -203,51 +203,50 @@ impl Step for Std {
203203
204204 let mut target_deps = builder. ensure ( StartupObjects { compiler : build_compiler, target } ) ;
205205
206- let compiler_to_use =
207- builder. compiler_for ( build_compiler. stage , build_compiler. host , target) ;
208- trace ! ( ?compiler_to_use) ;
209-
210- if compiler_to_use != build_compiler
211- // Never uplift std unless we have compiled stage 1; if stage 1 is compiled,
212- // uplift it from there.
213- //
214- // FIXME: improve `fn compiler_for` to avoid adding stage condition here.
215- && build_compiler. stage > 1
206+ // Stage of the stdlib that we're building
207+ let stage = build_compiler. stage ;
208+
209+ // If we're building a stage2+ libstd, full bootstrap is
210+ // disabled and we have a stage1 libstd already compiled for the given target,
211+ // then simply uplift a previously built stage1 library.
212+ if build_compiler. stage > 1
213+ && !builder. config . full_bootstrap
214+ // This estimates if a stage1 libstd exists for the given target. If we're not
215+ // cross-compiling, it should definitely exist by the time we're building a stage2
216+ // libstd.
217+ // Or if we are cross-compiling, and we are building a cross-compiled rustc, then that
218+ // rustc needs to link to a cross-compiled libstd, so again we should have a stage1
219+ // libstd for the given target prepared.
220+ // Even if we guess wrong in the cross-compiled case, the worst that should happen is
221+ // that we build a fresh stage1 libstd below, and then we immediately uplift it, so we
222+ // don't pay the libstd build cost twice.
223+ && ( target == builder. host_target || builder. config . hosts . contains ( & target) )
216224 {
217- trace ! (
218- ?compiler_to_use,
219- ?build_compiler,
220- "build_compiler != compiler_to_use, uplifting library"
221- ) ;
225+ let build_compiler_for_std_to_uplift = builder. compiler ( 1 , builder. host_target ) ;
226+ builder. std ( build_compiler_for_std_to_uplift, target) ;
222227
223- builder. std ( compiler_to_use, target) ;
224- let msg = if compiler_to_use. host == target {
228+ let msg = if build_compiler_for_std_to_uplift. host == target {
225229 format ! (
226- "Uplifting library (stage{} -> stage{})" ,
227- compiler_to_use . stage , build_compiler . stage
230+ "Uplifting library (stage{} -> stage{stage })" ,
231+ build_compiler_for_std_to_uplift . stage
228232 )
229233 } else {
230234 format ! (
231- "Uplifting library (stage{}:{} -> stage{}:{})" ,
232- compiler_to_use . stage, compiler_to_use . host, build_compiler . stage , target
235+ "Uplifting library (stage{}:{} -> stage{stage }:{target })" ,
236+ build_compiler_for_std_to_uplift . stage, build_compiler_for_std_to_uplift . host,
233237 )
234238 } ;
239+
235240 builder. info ( & msg) ;
236241
237242 // Even if we're not building std this stage, the new sysroot must
238243 // still contain the third party objects needed by various targets.
239244 self . copy_extra_objects ( builder, & build_compiler, target) ;
240245
241- builder. ensure ( StdLink :: from_std ( self , compiler_to_use ) ) ;
246+ builder. ensure ( StdLink :: from_std ( self , build_compiler_for_std_to_uplift ) ) ;
242247 return ;
243248 }
244249
245- trace ! (
246- ?compiler_to_use,
247- ?build_compiler,
248- "compiler == compiler_to_use, handling not-cross-compile scenario"
249- ) ;
250-
251250 target_deps. extend ( self . copy_extra_objects ( builder, & build_compiler, target) ) ;
252251
253252 // We build a sysroot for mir-opt tests using the same trick that Miri does: A check build
0 commit comments