@@ -9,7 +9,7 @@ use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun,
9
9
use crate :: core:: config:: TargetSelection ;
10
10
use crate :: utils:: channel:: GitInfo ;
11
11
use 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} ;
13
13
use crate :: Compiler ;
14
14
use crate :: Mode ;
15
15
use crate :: { gha, Kind } ;
@@ -553,6 +553,55 @@ impl Step for Rustdoc {
553
553
}
554
554
let target = target_compiler. host ;
555
555
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
+
582
+ let has_changes = !git ( Some ( & builder. config . src ) )
583
+ . args ( [ "diff-index" , "--quiet" , & commit] )
584
+ . arg ( "--" )
585
+ . arg ( librustdoc_src)
586
+ . arg ( rustdoc_src)
587
+ . run ( builder)
588
+ . status ( )
589
+ . unwrap ( )
590
+ . success ( ) ;
591
+
592
+ if !has_changes {
593
+ let precompiled_rustdoc = builder
594
+ . config
595
+ . ci_rustc_dir ( )
596
+ . join ( "bin" )
597
+ . join ( exe ( "rustdoc" , target_compiler. host ) ) ;
598
+
599
+ let bin_rustdoc = bin_rustdoc ( ) ;
600
+ builder. copy_link ( & precompiled_rustdoc, & bin_rustdoc) ;
601
+ return bin_rustdoc;
602
+ }
603
+ }
604
+
556
605
let build_compiler = if builder. download_rustc ( ) && target_compiler. stage == 1 {
557
606
// We already have the stage 1 compiler, we don't need to cut the stage.
558
607
builder. compiler ( target_compiler. stage , builder. config . build )
@@ -613,11 +662,7 @@ impl Step for Rustdoc {
613
662
614
663
// don't create a stage0-sysroot/bin directory.
615
664
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) ;
665
+ let bin_rustdoc = bin_rustdoc ( ) ;
621
666
builder. copy_link ( & tool_rustdoc, & bin_rustdoc) ;
622
667
bin_rustdoc
623
668
} else {
0 commit comments