Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use precompiled rustdoc with CI rustc #127463

Merged
merged 2 commits into from
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 12 additions & 21 deletions src/bootstrap/src/core/build_steps/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use crate::{generate_smart_stamp_hash, CLang, GitRepo, Kind};

use crate::utils::exec::command;
use build_helper::ci::CiEnv;
use build_helper::git::get_git_merge_base;

#[derive(Clone)]
pub struct LlvmResult {
Expand Down Expand Up @@ -154,26 +153,18 @@ pub fn prebuilt_llvm_config(builder: &Builder<'_>, target: TargetSelection) -> L
/// This retrieves the LLVM sha we *want* to use, according to git history.
pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String {
let llvm_sha = if is_git {
// We proceed in 2 steps. First we get the closest commit that is actually upstream. Then we
// walk back further to the last bors merge commit that actually changed LLVM. The first
// step will fail on CI because only the `auto` branch exists; we just fall back to `HEAD`
// in that case.
let closest_upstream = get_git_merge_base(&config.git_config(), Some(&config.src))
.unwrap_or_else(|_| "HEAD".into());
let mut rev_list = helpers::git(Some(&config.src));
rev_list.args(&[
PathBuf::from("rev-list"),
format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(),
"-n1".into(),
"--first-parent".into(),
closest_upstream.into(),
"--".into(),
config.src.join("src/llvm-project"),
config.src.join("src/bootstrap/download-ci-llvm-stamp"),
// the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
config.src.join("src/version"),
]);
output(rev_list.as_command_mut()).trim().to_owned()
helpers::get_closest_merge_base_commit(
Some(&config.src),
&config.git_config(),
&config.stage0_metadata.config.git_merge_commit_email,
&[
config.src.join("src/llvm-project"),
config.src.join("src/bootstrap/download-ci-llvm-stamp"),
// the LLVM shared object file is named `LLVM-12-rust-{version}-nightly`
config.src.join("src/version"),
],
)
.unwrap()
} else if let Some(info) = channel::read_commit_info_file(&config.src) {
info.sha.trim().to_owned()
} else {
Expand Down
59 changes: 53 additions & 6 deletions src/bootstrap/src/core/build_steps/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun,
use crate::core::config::TargetSelection;
use crate::utils::channel::GitInfo;
use crate::utils::exec::{command, BootstrapCommand};
use crate::utils::helpers::{add_dylib_path, exe, t};
use crate::utils::helpers::{add_dylib_path, exe, get_closest_merge_base_commit, git, t};
use crate::Compiler;
use crate::Mode;
use crate::{gha, Kind};
Expand Down Expand Up @@ -554,6 +554,57 @@ impl Step for Rustdoc {
}
let target = target_compiler.host;

let bin_rustdoc = || {
let sysroot = builder.sysroot(target_compiler);
let bindir = sysroot.join("bin");
t!(fs::create_dir_all(&bindir));
let bin_rustdoc = bindir.join(exe("rustdoc", target_compiler.host));
let _ = fs::remove_file(&bin_rustdoc);
bin_rustdoc
};

// If CI rustc is enabled and we haven't modified the rustdoc sources,
// use the precompiled rustdoc from CI rustc's sysroot to speed up bootstrapping.
if builder.download_rustc()
&& target_compiler.stage > 0
&& builder.rust_info().is_managed_git_subrepository()
{
let commit = get_closest_merge_base_commit(
Some(&builder.config.src),
&builder.config.git_config(),
&builder.config.stage0_metadata.config.git_merge_commit_email,
&[],
)
.unwrap();

let librustdoc_src = builder.config.src.join("src/librustdoc");
let rustdoc_src = builder.config.src.join("src/tools/rustdoc");

// FIXME: The change detection logic here is quite similar to `Config::download_ci_rustc_commit`.
// It would be better to unify them.
let has_changes = !git(Some(&builder.config.src))
Kobzol marked this conversation as resolved.
Show resolved Hide resolved
.allow_failure()
.run_always()
.args(["diff-index", "--quiet", &commit])
.arg("--")
.arg(librustdoc_src)
.arg(rustdoc_src)
.run(builder)
.is_success();

if !has_changes {
onur-ozkan marked this conversation as resolved.
Show resolved Hide resolved
let precompiled_rustdoc = builder
.config
.ci_rustc_dir()
.join("bin")
.join(exe("rustdoc", target_compiler.host));

let bin_rustdoc = bin_rustdoc();
builder.copy_link(&precompiled_rustdoc, &bin_rustdoc);
return bin_rustdoc;
}
}

let build_compiler = if builder.download_rustc() && target_compiler.stage == 1 {
// We already have the stage 1 compiler, we don't need to cut the stage.
builder.compiler(target_compiler.stage, builder.config.build)
Expand Down Expand Up @@ -614,11 +665,7 @@ impl Step for Rustdoc {

// don't create a stage0-sysroot/bin directory.
if target_compiler.stage > 0 {
let sysroot = builder.sysroot(target_compiler);
let bindir = sysroot.join("bin");
t!(fs::create_dir_all(&bindir));
let bin_rustdoc = bindir.join(exe("rustdoc", target_compiler.host));
let _ = fs::remove_file(&bin_rustdoc);
let bin_rustdoc = bin_rustdoc();
builder.copy_link(&tool_rustdoc, &bin_rustdoc);
bin_rustdoc
} else {
Expand Down
36 changes: 17 additions & 19 deletions src/bootstrap/src/core/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use crate::core::build_steps::llvm;
use crate::core::config::flags::{Color, Flags, Warnings};
use crate::utils::cache::{Interned, INTERNER};
use crate::utils::channel::{self, GitInfo};
use crate::utils::helpers::{self, exe, output, t};
use crate::utils::helpers::{self, exe, get_closest_merge_base_commit, output, t};
use build_helper::exit;
use serde::{Deserialize, Deserializer};
use serde_derive::Deserialize;
Expand Down Expand Up @@ -2471,14 +2471,13 @@ impl Config {

// Look for a version to compare to based on the current commit.
// Only commits merged by bors will have CI artifacts.
let merge_base = output(
helpers::git(Some(&self.src))
.arg("rev-list")
.arg(format!("--author={}", self.stage0_metadata.config.git_merge_commit_email))
.args(["-n1", "--first-parent", "HEAD"])
.as_command_mut(),
);
let commit = merge_base.trim_end();
let commit = get_closest_merge_base_commit(
Some(&self.src),
&self.git_config(),
&self.stage0_metadata.config.git_merge_commit_email,
&[],
)
.unwrap();
if commit.is_empty() {
println!("ERROR: could not find commit hash for downloading rustc");
println!("HELP: maybe your repository history is too shallow?");
Expand All @@ -2489,7 +2488,7 @@ impl Config {

// Warn if there were changes to the compiler or standard library since the ancestor commit.
let has_changes = !t!(helpers::git(Some(&self.src))
.args(["diff-index", "--quiet", commit])
.args(["diff-index", "--quiet", &commit])
.arg("--")
.args([self.src.join("compiler"), self.src.join("library")])
.as_command_mut()
Expand Down Expand Up @@ -2565,14 +2564,13 @@ impl Config {
) -> Option<String> {
// Look for a version to compare to based on the current commit.
// Only commits merged by bors will have CI artifacts.
let merge_base = output(
helpers::git(Some(&self.src))
.arg("rev-list")
.arg(format!("--author={}", self.stage0_metadata.config.git_merge_commit_email))
.args(["-n1", "--first-parent", "HEAD"])
.as_command_mut(),
);
let commit = merge_base.trim_end();
let commit = get_closest_merge_base_commit(
Some(&self.src),
&self.git_config(),
&self.stage0_metadata.config.git_merge_commit_email,
&[],
)
.unwrap();
if commit.is_empty() {
println!("error: could not find commit hash for downloading components from CI");
println!("help: maybe your repository history is too shallow?");
Expand All @@ -2583,7 +2581,7 @@ impl Config {

// Warn if there were changes to the compiler or standard library since the ancestor commit.
let mut git = helpers::git(Some(&self.src));
git.args(["diff-index", "--quiet", commit, "--"]);
git.args(["diff-index", "--quiet", &commit, "--"]);

// Handle running from a directory other than the top level
let top_level = &self.src;
Expand Down
24 changes: 24 additions & 0 deletions src/bootstrap/src/utils/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
//! Simple things like testing the various filesystem operations here and there,
//! not a lot of interesting happenings here unfortunately.
use build_helper::git::{get_git_merge_base, output_result, GitConfig};
use build_helper::util::fail;
use std::env;
use std::ffi::OsStr;
Expand Down Expand Up @@ -521,3 +522,26 @@ pub fn git(source_dir: Option<&Path>) -> BootstrapCommand {

git
}

/// Returns the closest commit available from upstream for the given `author` and `target_paths`.
///
/// If it fails to find the commit from upstream using `git merge-base`, fallbacks to HEAD.
pub fn get_closest_merge_base_commit(
source_dir: Option<&Path>,
config: &GitConfig<'_>,
author: &str,
target_paths: &[PathBuf],
) -> Result<String, String> {
let mut git = git(source_dir).capture_stdout();

let merge_base = get_git_merge_base(config, source_dir).unwrap_or_else(|_| "HEAD".into());

git.arg(Path::new("rev-list"));
git.args([&format!("--author={author}"), "-n1", "--first-parent", &merge_base]);

if !target_paths.is_empty() {
git.arg("--").args(target_paths);
}

Ok(output_result(git.as_command_mut())?.trim().to_owned())
}
2 changes: 1 addition & 1 deletion src/tools/build_helper/src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub struct GitConfig<'a> {
}

/// Runs a command and returns the output
fn output_result(cmd: &mut Command) -> Result<String, String> {
pub fn output_result(cmd: &mut Command) -> Result<String, String> {
let output = match cmd.stderr(Stdio::inherit()).output() {
Ok(status) => status,
Err(e) => return Err(format!("failed to run command: {:?}: {}", cmd, e)),
Expand Down
Loading