@@ -9,7 +9,7 @@ use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun,
99use crate :: core:: config:: TargetSelection ;
1010use crate :: utils:: channel:: GitInfo ;
1111use crate :: utils:: exec:: { command, BootstrapCommand } ;
12- use crate :: utils:: helpers:: { add_dylib_path, exe, t} ;
12+ use crate :: utils:: helpers:: { add_dylib_path, exe, get_closest_merge_base_commit , git , t} ;
1313use crate :: Compiler ;
1414use crate :: Mode ;
1515use crate :: { gha, Kind } ;
@@ -553,6 +553,53 @@ impl Step for Rustdoc {
553553 }
554554 let target = target_compiler. host ;
555555
556+ let bin_rustdoc = || {
557+ let sysroot = builder. sysroot ( target_compiler) ;
558+ let bindir = sysroot. join ( "bin" ) ;
559+ t ! ( fs:: create_dir_all( & bindir) ) ;
560+ let bin_rustdoc = bindir. join ( exe ( "rustdoc" , target_compiler. host ) ) ;
561+ let _ = fs:: remove_file ( & bin_rustdoc) ;
562+ bin_rustdoc
563+ } ;
564+
565+ // If CI rustc is enabled and we haven't modified the rustdoc sources,
566+ // use the precompiled rustdoc from CI rustc's sysroot to speed up bootstrapping.
567+ if builder. download_rustc ( )
568+ && target_compiler. stage > 0
569+ && builder. rust_info ( ) . is_managed_git_subrepository ( )
570+ {
571+ let commit = get_closest_merge_base_commit (
572+ Some ( & builder. config . src ) ,
573+ & builder. config . git_config ( ) ,
574+ & builder. config . stage0_metadata . config . git_merge_commit_email ,
575+ & [ ] ,
576+ )
577+ . unwrap ( ) ;
578+
579+ let librustdoc_src = builder. config . src . join ( "src/librustdoc" ) ;
580+ let rustdoc_src = builder. config . src . join ( "src/tools/rustdoc" ) ;
581+ let has_changes = !t ! ( git( Some ( & builder. config. src) )
582+ . args( [ "diff-index" , "--quiet" , & commit] )
583+ . arg( "--" )
584+ . arg( librustdoc_src)
585+ . arg( rustdoc_src)
586+ . command
587+ . status( ) )
588+ . success ( ) ;
589+
590+ if !has_changes {
591+ let precompiled_rustdoc = builder
592+ . config
593+ . ci_rustc_dir ( )
594+ . join ( "bin" )
595+ . join ( exe ( "rustdoc" , target_compiler. host ) ) ;
596+
597+ let bin_rustdoc = bin_rustdoc ( ) ;
598+ builder. copy_link ( & precompiled_rustdoc, & bin_rustdoc) ;
599+ return bin_rustdoc;
600+ }
601+ }
602+
556603 let build_compiler = if builder. download_rustc ( ) && target_compiler. stage == 1 {
557604 // We already have the stage 1 compiler, we don't need to cut the stage.
558605 builder. compiler ( target_compiler. stage , builder. config . build )
@@ -613,11 +660,7 @@ impl Step for Rustdoc {
613660
614661 // don't create a stage0-sysroot/bin directory.
615662 if target_compiler. stage > 0 {
616- let sysroot = builder. sysroot ( target_compiler) ;
617- let bindir = sysroot. join ( "bin" ) ;
618- t ! ( fs:: create_dir_all( & bindir) ) ;
619- let bin_rustdoc = bindir. join ( exe ( "rustdoc" , target_compiler. host ) ) ;
620- let _ = fs:: remove_file ( & bin_rustdoc) ;
663+ let bin_rustdoc = bin_rustdoc ( ) ;
621664 builder. copy_link ( & tool_rustdoc, & bin_rustdoc) ;
622665 bin_rustdoc
623666 } else {
0 commit comments