summaryrefslogtreecommitdiffstats
path: root/src/bootstrap/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootstrap/lib.rs')
-rw-r--r--src/bootstrap/lib.rs122
1 files changed, 78 insertions, 44 deletions
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 0a7aff622..4396bbc51 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -27,7 +27,7 @@ use std::process::{Command, Stdio};
use std::str;
use build_helper::ci::{gha, CiEnv};
-use build_helper::detail_exit_macro;
+use build_helper::exit;
use channel::GitInfo;
use config::{DryRun, Target};
use filetime::FileTime;
@@ -36,10 +36,9 @@ use once_cell::sync::OnceCell;
use crate::builder::Kind;
use crate::config::{LlvmLibunwind, TargetSelection};
use crate::util::{
- exe, libdir, mtime, output, run, run_suppressed, symlink_dir, try_run_suppressed,
+ dir_is_empty, exe, libdir, mtime, output, run, run_suppressed, symlink_dir, try_run_suppressed,
};
-mod bolt;
mod builder;
mod cache;
mod cc_detect;
@@ -131,9 +130,16 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
(Some(Mode::Std), "freebsd13", None),
(Some(Mode::Std), "backtrace_in_libstd", None),
/* Extra values not defined in the built-in targets yet, but used in std */
+ // #[cfg(bootstrap)]
+ (Some(Mode::Std), "target_vendor", Some(&["unikraft"])),
(Some(Mode::Std), "target_env", Some(&["libnx"])),
- // (Some(Mode::Std), "target_os", Some(&[])),
- (Some(Mode::Std), "target_arch", Some(&["asmjs", "spirv", "nvptx", "xtensa"])),
+ (Some(Mode::Std), "target_os", Some(&["teeos"])),
+ // #[cfg(bootstrap)] mips32r6, mips64r6
+ (
+ Some(Mode::Std),
+ "target_arch",
+ Some(&["asmjs", "spirv", "nvptx", "xtensa", "mips32r6", "mips64r6", "csky"]),
+ ),
/* Extra names used by dependencies */
// FIXME: Used by serde_json, but we should not be triggering on external dependencies.
(Some(Mode::Rustc), "no_btreemap_remove_entry", None),
@@ -191,7 +197,7 @@ pub enum GitRepo {
/// although most functions are implemented as free functions rather than
/// methods specifically on this structure itself (to make it easier to
/// organize).
-#[cfg_attr(not(feature = "build-metrics"), derive(Clone))]
+#[derive(Clone)]
pub struct Build {
/// User-specified configuration from `config.toml`.
config: Config,
@@ -333,7 +339,6 @@ forward! {
create(path: &Path, s: &str),
remove(f: &Path),
tempdir() -> PathBuf,
- try_run(cmd: &mut Command) -> Result<(), ()>,
llvm_link_shared() -> bool,
download_rustc() -> bool,
initial_rustfmt() -> Option<PathBuf>,
@@ -478,7 +483,7 @@ impl Build {
.unwrap()
.trim();
if local_release.split('.').take(2).eq(version.split('.').take(2)) {
- build.verbose(&format!("auto-detected local-rebuild {}", local_release));
+ build.verbose(&format!("auto-detected local-rebuild {local_release}"));
build.local_rebuild = true;
}
@@ -531,10 +536,6 @@ impl Build {
///
/// `relative_path` should be relative to the root of the git repository, not an absolute path.
pub(crate) fn update_submodule(&self, relative_path: &Path) {
- fn dir_is_empty(dir: &Path) -> bool {
- t!(std::fs::read_dir(dir)).next().is_none()
- }
-
if !self.config.submodules(&self.rust_info()) {
return;
}
@@ -617,7 +618,9 @@ impl Build {
}
// Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error).
+ #[allow(deprecated)] // diff-index reports the modifications through the exit status
let has_local_modifications = self
+ .config
.try_run(
Command::new("git")
.args(&["diff-index", "--quiet", "HEAD"])
@@ -709,9 +712,9 @@ impl Build {
if failures.len() > 0 {
eprintln!("\n{} command(s) did not execute successfully:\n", failures.len());
for failure in failures.iter() {
- eprintln!(" - {}\n", failure);
+ eprintln!(" - {failure}\n");
}
- detail_exit_macro!(1);
+ exit!(1);
}
#[cfg(feature = "build-metrics")]
@@ -822,11 +825,6 @@ impl Build {
self.stage_out(compiler, mode).join(&*target.triple).join(self.cargo_dir())
}
- /// Directory where the extracted `rustc-dev` component is stored.
- fn ci_rustc_dir(&self, target: TargetSelection) -> PathBuf {
- self.out.join(&*target.triple).join("ci-rustc")
- }
-
/// Root output directory for LLVM compiled for `target`
///
/// Note that if LLVM is configured externally then the directory returned
@@ -960,7 +958,7 @@ impl Build {
if self.config.dry_run() {
return;
}
- self.verbose(&format!("running: {:?}", cmd));
+ self.verbose(&format!("running: {cmd:?}"));
run(cmd, self.is_verbose())
}
@@ -969,19 +967,43 @@ impl Build {
if self.config.dry_run() {
return;
}
- self.verbose(&format!("running: {:?}", cmd));
+ self.verbose(&format!("running: {cmd:?}"));
run_suppressed(cmd)
}
/// Runs a command, printing out nice contextual information if it fails.
/// Exits if the command failed to execute at all, otherwise returns its
/// `status.success()`.
- fn try_run_quiet(&self, cmd: &mut Command) -> bool {
+ fn run_quiet_delaying_failure(&self, cmd: &mut Command) -> bool {
if self.config.dry_run() {
return true;
}
- self.verbose(&format!("running: {:?}", cmd));
- try_run_suppressed(cmd)
+ if !self.fail_fast {
+ self.verbose(&format!("running: {cmd:?}"));
+ if !try_run_suppressed(cmd) {
+ let mut failures = self.delayed_failures.borrow_mut();
+ failures.push(format!("{cmd:?}"));
+ return false;
+ }
+ } else {
+ self.run_quiet(cmd);
+ }
+ true
+ }
+
+ /// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes.
+ pub(crate) fn run_delaying_failure(&self, cmd: &mut Command) -> bool {
+ if !self.fail_fast {
+ #[allow(deprecated)] // can't use Build::try_run, that's us
+ if self.config.try_run(cmd).is_err() {
+ let mut failures = self.delayed_failures.borrow_mut();
+ failures.push(format!("{cmd:?}"));
+ return false;
+ }
+ } else {
+ self.run(cmd);
+ }
+ true
}
pub fn is_verbose_than(&self, level: usize) -> bool {
@@ -991,7 +1013,7 @@ impl Build {
/// Prints a message if this build is configured in more verbose mode than `level`.
fn verbose_than(&self, level: usize, msg: &str) {
if self.is_verbose_than(level) {
- println!("{}", msg);
+ println!("{msg}");
}
}
@@ -999,11 +1021,13 @@ impl Build {
match self.config.dry_run {
DryRun::SelfCheck => return,
DryRun::Disabled | DryRun::UserSelected => {
- println!("{}", msg);
+ println!("{msg}");
}
}
}
+ #[must_use = "Groups should not be dropped until the Step finishes running"]
+ #[track_caller]
fn msg_check(
&self,
what: impl Display,
@@ -1012,6 +1036,8 @@ impl Build {
self.msg(Kind::Check, self.config.stage, what, self.config.build, target)
}
+ #[must_use = "Groups should not be dropped until the Step finishes running"]
+ #[track_caller]
fn msg_doc(
&self,
compiler: Compiler,
@@ -1021,6 +1047,8 @@ impl Build {
self.msg(Kind::Doc, compiler.stage, what, compiler.host, target.into())
}
+ #[must_use = "Groups should not be dropped until the Step finishes running"]
+ #[track_caller]
fn msg_build(
&self,
compiler: Compiler,
@@ -1033,6 +1061,8 @@ impl Build {
/// Return a `Group` guard for a [`Step`] that is built for each `--stage`.
///
/// [`Step`]: crate::builder::Step
+ #[must_use = "Groups should not be dropped until the Step finishes running"]
+ #[track_caller]
fn msg(
&self,
action: impl Into<Kind>,
@@ -1059,6 +1089,8 @@ impl Build {
/// Return a `Group` guard for a [`Step`] that is only built once and isn't affected by `--stage`.
///
/// [`Step`]: crate::builder::Step
+ #[must_use = "Groups should not be dropped until the Step finishes running"]
+ #[track_caller]
fn msg_unstaged(
&self,
action: impl Into<Kind>,
@@ -1070,6 +1102,8 @@ impl Build {
self.group(&msg)
}
+ #[must_use = "Groups should not be dropped until the Step finishes running"]
+ #[track_caller]
fn msg_sysroot_tool(
&self,
action: impl Into<Kind>,
@@ -1088,6 +1122,7 @@ impl Build {
self.group(&msg)
}
+ #[track_caller]
fn group(&self, msg: &str) -> Option<gha::Group> {
match self.config.dry_run {
DryRun::SelfCheck => None,
@@ -1111,7 +1146,7 @@ impl Build {
match which {
GitRepo::Rustc => {
let sha = self.rust_sha().unwrap_or(&self.version);
- Some(format!("/rustc/{}", sha))
+ Some(format!("/rustc/{sha}"))
}
GitRepo::Llvm => Some(String::from("/rustc/llvm")),
}
@@ -1164,10 +1199,10 @@ impl Build {
let map = format!("{}={}", self.src.display(), map_to);
let cc = self.cc(target);
if cc.ends_with("clang") || cc.ends_with("gcc") {
- base.push(format!("-fdebug-prefix-map={}", map));
+ base.push(format!("-fdebug-prefix-map={map}"));
} else if cc.ends_with("clang-cl.exe") {
base.push("-Xclang".into());
- base.push(format!("-fdebug-prefix-map={}", map));
+ base.push(format!("-fdebug-prefix-map={map}"));
}
}
base
@@ -1196,9 +1231,7 @@ impl Build {
}
match self.cxx.borrow().get(&target) {
Some(p) => Ok(p.path().into()),
- None => {
- Err(format!("target `{}` is not configured as a host, only as a target", target))
- }
+ None => Err(format!("target `{target}` is not configured as a host, only as a target")),
}
}
@@ -1241,7 +1274,7 @@ impl Build {
}
let no_threads = util::lld_flag_no_threads(target.contains("windows"));
- options[1] = Some(format!("-Clink-arg=-Wl,{}", no_threads));
+ options[1] = Some(format!("-Clink-arg=-Wl,{no_threads}"));
}
IntoIterator::into_iter(options).flatten()
@@ -1368,11 +1401,11 @@ impl Build {
if !self.config.omit_git_hash {
format!("{}-beta.{}", num, self.beta_prerelease_version())
} else {
- format!("{}-beta", num)
+ format!("{num}-beta")
}
}
- "nightly" => format!("{}-nightly", num),
- _ => format!("{}-dev", num),
+ "nightly" => format!("{num}-nightly"),
+ _ => format!("{num}-dev"),
}
}
@@ -1420,7 +1453,7 @@ impl Build {
"stable" => num.to_string(),
"beta" => "beta".to_string(),
"nightly" => "nightly".to_string(),
- _ => format!("{}-dev", num),
+ _ => format!("{num}-dev"),
}
}
@@ -1451,7 +1484,7 @@ impl Build {
/// Returns the `a.b.c` version that the given package is at.
fn release_num(&self, package: &str) -> String {
- let toml_file_name = self.src.join(&format!("src/tools/{}/Cargo.toml", package));
+ let toml_file_name = self.src.join(&format!("src/tools/{package}/Cargo.toml"));
let toml = t!(fs::read_to_string(&toml_file_name));
for line in toml.lines() {
if let Some(stripped) =
@@ -1461,7 +1494,7 @@ impl Build {
}
}
- panic!("failed to find version in {}'s Cargo.toml", package)
+ panic!("failed to find version in {package}'s Cargo.toml")
}
/// Returns `true` if unstable features should be enabled for the compiler
@@ -1507,6 +1540,7 @@ impl Build {
}
}
}
+ ret.sort_unstable_by_key(|krate| krate.name); // reproducible order needed for tests
ret
}
@@ -1520,7 +1554,7 @@ impl Build {
"Error: Unable to find the stamp file {}, did you try to keep a nonexistent build stage?",
stamp.display()
);
- crate::detail_exit_macro!(1);
+ crate::exit!(1);
}
let mut paths = Vec::new();
@@ -1552,7 +1586,7 @@ impl Build {
if self.config.dry_run() {
return;
}
- self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst));
+ self.verbose_than(1, &format!("Copy {src:?} to {dst:?}"));
if src == dst {
return;
}
@@ -1643,7 +1677,7 @@ impl Build {
return;
}
let dst = dstdir.join(src.file_name().unwrap());
- self.verbose_than(1, &format!("Install {:?} to {:?}", src, dst));
+ self.verbose_than(1, &format!("Install {src:?} to {dst:?}"));
t!(fs::create_dir_all(dstdir));
if !src.exists() {
panic!("Error: File \"{}\" not found!", src.display());
@@ -1677,7 +1711,7 @@ impl Build {
let iter = match fs::read_dir(dir) {
Ok(v) => v,
Err(_) if self.config.dry_run() => return vec![].into_iter(),
- Err(err) => panic!("could not read dir {:?}: {:?}", dir, err),
+ Err(err) => panic!("could not read dir {dir:?}: {err:?}"),
};
iter.map(|e| t!(e)).collect::<Vec<_>>().into_iter()
}
@@ -1712,7 +1746,7 @@ Alternatively, set `download-ci-llvm = true` in that `[llvm]` section
to download LLVM rather than building it.
"
);
- detail_exit_macro!(1);
+ exit!(1);
}
}