Skip to content

Commit 0636293

Browse files
committed
use precompiled rustdoc with CI rustc
When CI rustc is enabled and rustdoc sources are unchanged, we can use the precompiled rustdoc from the CI rustc's sysroot. This speeds up bootstrapping quite a lot by avoiding unnecessary rustdoc compilation. Signed-off-by: onur-ozkan <work@onurozkan.dev>
1 parent 2b5a982 commit 0636293

File tree

1 file changed

+53
-6
lines changed
  • src/bootstrap/src/core/build_steps

1 file changed

+53
-6
lines changed

src/bootstrap/src/core/build_steps/tool.rs

+53-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun,
99
use crate::core::config::TargetSelection;
1010
use crate::utils::channel::GitInfo;
1111
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};
1313
use crate::Compiler;
1414
use crate::Mode;
1515
use crate::{gha, Kind};
@@ -554,6 +554,57 @@ impl Step for Rustdoc {
554554
}
555555
let target = target_compiler.host;
556556

557+
let bin_rustdoc = || {
558+
let sysroot = builder.sysroot(target_compiler);
559+
let bindir = sysroot.join("bin");
560+
t!(fs::create_dir_all(&bindir));
561+
let bin_rustdoc = bindir.join(exe("rustdoc", target_compiler.host));
562+
let _ = fs::remove_file(&bin_rustdoc);
563+
bin_rustdoc
564+
};
565+
566+
// If CI rustc is enabled and we haven't modified the rustdoc sources,
567+
// use the precompiled rustdoc from CI rustc's sysroot to speed up bootstrapping.
568+
if builder.download_rustc()
569+
&& target_compiler.stage > 0
570+
&& builder.rust_info().is_managed_git_subrepository()
571+
{
572+
let commit = get_closest_merge_base_commit(
573+
Some(&builder.config.src),
574+
&builder.config.git_config(),
575+
&builder.config.stage0_metadata.config.git_merge_commit_email,
576+
&[],
577+
)
578+
.unwrap();
579+
580+
let librustdoc_src = builder.config.src.join("src/librustdoc");
581+
let rustdoc_src = builder.config.src.join("src/tools/rustdoc");
582+
583+
// FIXME: The change detection logic here is quite similar to `Config::download_ci_rustc_commit`.
584+
// It would be better to unify them.
585+
let has_changes = !git(Some(&builder.config.src))
586+
.allow_failure()
587+
.run_always()
588+
.args(["diff-index", "--quiet", &commit])
589+
.arg("--")
590+
.arg(librustdoc_src)
591+
.arg(rustdoc_src)
592+
.run(builder)
593+
.is_success();
594+
595+
if !has_changes {
596+
let precompiled_rustdoc = builder
597+
.config
598+
.ci_rustc_dir()
599+
.join("bin")
600+
.join(exe("rustdoc", target_compiler.host));
601+
602+
let bin_rustdoc = bin_rustdoc();
603+
builder.copy_link(&precompiled_rustdoc, &bin_rustdoc);
604+
return bin_rustdoc;
605+
}
606+
}
607+
557608
let build_compiler = if builder.download_rustc() && target_compiler.stage == 1 {
558609
// We already have the stage 1 compiler, we don't need to cut the stage.
559610
builder.compiler(target_compiler.stage, builder.config.build)
@@ -614,11 +665,7 @@ impl Step for Rustdoc {
614665

615666
// don't create a stage0-sysroot/bin directory.
616667
if target_compiler.stage > 0 {
617-
let sysroot = builder.sysroot(target_compiler);
618-
let bindir = sysroot.join("bin");
619-
t!(fs::create_dir_all(&bindir));
620-
let bin_rustdoc = bindir.join(exe("rustdoc", target_compiler.host));
621-
let _ = fs::remove_file(&bin_rustdoc);
668+
let bin_rustdoc = bin_rustdoc();
622669
builder.copy_link(&tool_rustdoc, &bin_rustdoc);
623670
bin_rustdoc
624671
} else {

0 commit comments

Comments
 (0)