use crate::builder::Kind;
use crate::config::{LlvmLibunwind, TargetSelection};
use crate::util::{
- exe, libdir, mtime, output, run, run_suppressed, t, try_run, try_run_suppressed, CiEnv,
+ check_run, exe, libdir, mtime, output, run, run_suppressed, t, try_run, try_run_suppressed,
+ CiEnv,
};
mod builder;
mod toolstate;
pub mod util;
+#[cfg(feature = "build-metrics")]
+mod metrics;
+
#[cfg(windows)]
mod job;
pub unsafe fn setup(_build: &mut crate::Build) {}
}
+pub use crate::builder::PathSet;
use crate::cache::{Interned, INTERNER};
pub use crate::config::Config;
pub use crate::flags::Subcommand;
hosts: Vec<TargetSelection>,
targets: Vec<TargetSelection>,
- // Stage 0 (downloaded) compiler, lld and cargo or their local rust equivalents
initial_rustc: PathBuf,
initial_cargo: PathBuf,
initial_lld: PathBuf,
prerelease_version: Cell<Option<u32>>,
tool_artifacts:
RefCell<HashMap<TargetSelection, HashMap<String, (&'static str, PathBuf, Vec<String>)>>>,
+
+ #[cfg(feature = "build-metrics")]
+ metrics: metrics::BuildMetrics,
}
#[derive(Debug)]
delayed_failures: RefCell::new(Vec::new()),
prerelease_version: Cell::new(None),
tool_artifacts: Default::default(),
+
+ #[cfg(feature = "build-metrics")]
+ metrics: metrics::BuildMetrics::init(),
};
build.verbose("finding compilers");
build.local_rebuild = true;
}
+ // Make sure we update these before gathering metadata so we don't get an error about missing
+ // Cargo.toml files.
+ let rust_submodules = [
+ "src/tools/rust-installer",
+ "src/tools/cargo",
+ "src/tools/rls",
+ "src/tools/miri",
+ "library/backtrace",
+ "library/stdarch",
+ ];
+ for s in rust_submodules {
+ build.update_submodule(Path::new(s));
+ }
+
build.verbose("learning about cargo");
metadata::build(&mut build);
}
// check_submodule
- if self.config.fast_submodules {
- let checked_out_hash = output(
- Command::new("git").args(&["rev-parse", "HEAD"]).current_dir(&absolute_path),
- );
- // update_submodules
- let recorded = output(
- Command::new("git")
- .args(&["ls-tree", "HEAD"])
- .arg(relative_path)
- .current_dir(&self.config.src),
- );
- let actual_hash = recorded
- .split_whitespace()
- .nth(2)
- .unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
-
- // update_submodule
- if actual_hash == checked_out_hash.trim_end() {
- // already checked out
- return;
- }
+ let checked_out_hash =
+ output(Command::new("git").args(&["rev-parse", "HEAD"]).current_dir(&absolute_path));
+ // update_submodules
+ let recorded = output(
+ Command::new("git")
+ .args(&["ls-tree", "HEAD"])
+ .arg(relative_path)
+ .current_dir(&self.config.src),
+ );
+ let actual_hash = recorded
+ .split_whitespace()
+ .nth(2)
+ .unwrap_or_else(|| panic!("unexpected output `{}`", recorded));
+
+ // update_submodule
+ if actual_hash == checked_out_hash.trim_end() {
+ // already checked out
+ return;
}
println!("Updating submodule {}", relative_path.display());
self.maybe_update_submodules();
if let Subcommand::Format { check, paths } = &self.config.cmd {
- return format::format(self, *check, &paths);
+ return format::format(&builder::Builder::new(&self), *check, &paths);
}
if let Subcommand::Clean { all } = self.config.cmd {
// Check for postponed failures from `test --no-fail-fast`.
let failures = self.delayed_failures.borrow();
if failures.len() > 0 {
- println!("\n{} command(s) did not execute successfully:\n", failures.len());
+ eprintln!("\n{} command(s) did not execute successfully:\n", failures.len());
for failure in failures.iter() {
- println!(" - {}\n", failure);
+ eprintln!(" - {}\n", failure);
}
process::exit(1);
}
+
+ #[cfg(feature = "build-metrics")]
+ self.metrics.persist(self);
}
/// Clear out `dir` if `input` is newer.
fn std_features(&self, target: TargetSelection) -> String {
let mut features = "panic-unwind".to_string();
- match self.config.llvm_libunwind {
+ match self.config.llvm_libunwind(target) {
LlvmLibunwind::InTree => features.push_str(" llvm-libunwind"),
LlvmLibunwind::System => features.push_str(" system-llvm-libunwind"),
LlvmLibunwind::No => {}
try_run_suppressed(cmd)
}
+ /// Runs a command, printing out nice contextual information if it fails.
+ /// Returns false if do not execute at all, otherwise returns its
+ /// `status.success()`.
+ fn check_run(&self, cmd: &mut Command) -> bool {
+ if self.config.dry_run {
+ return true;
+ }
+ self.verbose(&format!("running: {:?}", cmd));
+ check_run(cmd, self.is_verbose())
+ }
+
pub fn is_verbose(&self) -> bool {
self.verbosity > 0
}
/// Returns the number of parallel jobs that have been configured for this
/// build.
fn jobs(&self) -> u32 {
- self.config.jobs.unwrap_or_else(|| {
- std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32
- })
+ self.config.jobs.unwrap_or_else(|| num_cpus::get() as u32)
}
fn debuginfo_map_to(&self, which: GitRepo) -> Option<String> {