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, 88 insertions, 34 deletions
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 950f3b151..419bcbc63 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -21,7 +21,6 @@ use std::collections::{HashMap, HashSet};
use std::env;
use std::fs::{self, File};
use std::io;
-use std::io::ErrorKind;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::str;
@@ -53,11 +52,13 @@ mod download;
mod flags;
mod format;
mod install;
+mod llvm;
mod metadata;
-mod native;
+mod render_tests;
mod run;
mod sanity;
mod setup;
+mod suggest;
mod tarball;
mod test;
mod tool;
@@ -88,6 +89,7 @@ pub use crate::builder::PathSet;
use crate::cache::{Interned, INTERNER};
pub use crate::config::Config;
pub use crate::flags::Subcommand;
+use termcolor::{ColorChoice, StandardStream, WriteColor};
const LLVM_TOOLS: &[&str] = &[
"llvm-cov", // used to generate coverage report
@@ -123,11 +125,13 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
(Some(Mode::Std), "no_rc", None),
(Some(Mode::Std), "no_sync", None),
(Some(Mode::Std), "freebsd12", None),
+ (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 */
(Some(Mode::Std), "target_env", Some(&["libnx"])),
// (Some(Mode::Std), "target_os", Some(&[])),
- (Some(Mode::Std), "target_arch", Some(&["asmjs", "spirv", "nvptx", "xtensa"])),
+ // #[cfg(bootstrap)] loongarch64
+ (Some(Mode::Std), "target_arch", Some(&["asmjs", "spirv", "nvptx", "xtensa", "loongarch64"])),
/* 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),
@@ -144,6 +148,11 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
// FIXME: Used by filetime, but we should not be triggering on external dependencies.
(Some(Mode::Rustc), "emulate_second_only_system", None),
(Some(Mode::ToolRustc), "emulate_second_only_system", None),
+ // Needed to avoid the need to copy windows.lib into the sysroot.
+ (Some(Mode::Rustc), "windows_raw_dylib", None),
+ (Some(Mode::ToolRustc), "windows_raw_dylib", None),
+ // #[cfg(bootstrap)] ohos
+ (Some(Mode::Std), "target_env", Some(&["ohos"])),
];
/// A structure representing a Rust compiler.
@@ -182,6 +191,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))]
pub struct Build {
/// User-specified configuration from `config.toml`.
config: Config,
@@ -235,7 +245,7 @@ pub struct Build {
metrics: metrics::BuildMetrics,
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
struct Crate {
name: Interned<String>,
deps: HashSet<Interned<String>>,
@@ -351,14 +361,14 @@ impl Build {
#[cfg(not(unix))]
let is_sudo = false;
- let ignore_git = config.ignore_git;
- let rust_info = channel::GitInfo::new(ignore_git, &src);
- let cargo_info = channel::GitInfo::new(ignore_git, &src.join("src/tools/cargo"));
+ let omit_git_hash = config.omit_git_hash;
+ let rust_info = channel::GitInfo::new(omit_git_hash, &src);
+ let cargo_info = channel::GitInfo::new(omit_git_hash, &src.join("src/tools/cargo"));
let rust_analyzer_info =
- channel::GitInfo::new(ignore_git, &src.join("src/tools/rust-analyzer"));
- let clippy_info = channel::GitInfo::new(ignore_git, &src.join("src/tools/clippy"));
- let miri_info = channel::GitInfo::new(ignore_git, &src.join("src/tools/miri"));
- let rustfmt_info = channel::GitInfo::new(ignore_git, &src.join("src/tools/rustfmt"));
+ channel::GitInfo::new(omit_git_hash, &src.join("src/tools/rust-analyzer"));
+ let clippy_info = channel::GitInfo::new(omit_git_hash, &src.join("src/tools/clippy"));
+ let miri_info = channel::GitInfo::new(omit_git_hash, &src.join("src/tools/miri"));
+ let rustfmt_info = channel::GitInfo::new(omit_git_hash, &src.join("src/tools/rustfmt"));
// we always try to use git for LLVM builds
let in_tree_llvm_info = channel::GitInfo::new(false, &src.join("src/llvm-project"));
@@ -482,12 +492,7 @@ impl Build {
// 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",
- "library/backtrace",
- "library/stdarch",
- ];
+ let rust_submodules = ["src/tools/cargo", "library/backtrace", "library/stdarch"];
for s in rust_submodules {
build.update_submodule(Path::new(s));
}
@@ -502,16 +507,18 @@ impl Build {
let build_triple = build.out.join(&build.build.triple);
t!(fs::create_dir_all(&build_triple));
let host = build.out.join("host");
- if let Err(e) = symlink_dir(&build.config, &build_triple, &host) {
- if e.kind() != ErrorKind::AlreadyExists {
- panic!(
- "symlink_dir({} => {}) failed with {}",
- host.display(),
- build_triple.display(),
- e
- );
- }
- }
+ if host.is_symlink() {
+ // Left over from a previous build; overwrite it.
+ // This matters if `build.build` has changed between invocations.
+ #[cfg(windows)]
+ t!(fs::remove_dir(&host));
+ #[cfg(not(windows))]
+ t!(fs::remove_file(&host));
+ }
+ t!(
+ symlink_dir(&build.config, &build_triple, &host),
+ format!("symlink_dir({} => {}) failed", host.display(), build_triple.display())
+ );
build
}
@@ -652,13 +659,20 @@ impl Build {
job::setup(self);
}
- if let Subcommand::Format { check, paths } = &self.config.cmd {
- return format::format(&builder::Builder::new(&self), *check, &paths);
- }
-
// Download rustfmt early so that it can be used in rust-analyzer configs.
let _ = &builder::Builder::new(&self).initial_rustfmt();
+ // hardcoded subcommands
+ match &self.config.cmd {
+ Subcommand::Format { check, paths } => {
+ return format::format(&builder::Builder::new(&self), *check, &paths);
+ }
+ Subcommand::Suggest { run } => {
+ return suggest::suggest(&builder::Builder::new(&self), *run);
+ }
+ _ => (),
+ }
+
{
let builder = builder::Builder::new(&self);
if let Some(path) = builder.paths.get(0) {
@@ -800,6 +814,11 @@ 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
@@ -1204,12 +1223,22 @@ impl Build {
///
/// When all of these conditions are met the build will lift artifacts from
/// the previous stage forward.
- fn force_use_stage1(&self, compiler: Compiler, target: TargetSelection) -> bool {
+ fn force_use_stage1(&self, stage: u32, target: TargetSelection) -> bool {
!self.config.full_bootstrap
- && compiler.stage >= 2
+ && !self.config.download_rustc()
+ && stage >= 2
&& (self.hosts.iter().any(|h| *h == target) || target == self.build)
}
+ /// Checks whether the `compiler` compiling for `target` should be forced to
+ /// use a stage2 compiler instead.
+ ///
+ /// When we download the pre-compiled version of rustc and compiler stage is >= 2,
+ /// it should be forced to use a stage2 compiler.
+ fn force_use_stage2(&self, stage: u32) -> bool {
+ self.config.download_rustc() && stage >= 2
+ }
+
/// Given `num` in the form "a.b.c" return a "release string" which
/// describes the release version number.
///
@@ -1219,7 +1248,7 @@ impl Build {
match &self.config.channel[..] {
"stable" => num.to_string(),
"beta" => {
- if self.rust_info().is_managed_git_subrepository() && !self.config.ignore_git {
+ if self.rust_info().is_managed_git_subrepository() && !self.config.omit_git_hash {
format!("{}-beta.{}", num, self.beta_prerelease_version())
} else {
format!("{}-beta", num)
@@ -1575,6 +1604,31 @@ to download LLVM rather than building it.
self.config.ninja_in_file
}
+
+ pub fn colored_stdout<R, F: FnOnce(&mut dyn WriteColor) -> R>(&self, f: F) -> R {
+ self.colored_stream_inner(StandardStream::stdout, self.config.stdout_is_tty, f)
+ }
+
+ pub fn colored_stderr<R, F: FnOnce(&mut dyn WriteColor) -> R>(&self, f: F) -> R {
+ self.colored_stream_inner(StandardStream::stderr, self.config.stderr_is_tty, f)
+ }
+
+ fn colored_stream_inner<R, F, C>(&self, constructor: C, is_tty: bool, f: F) -> R
+ where
+ C: Fn(ColorChoice) -> StandardStream,
+ F: FnOnce(&mut dyn WriteColor) -> R,
+ {
+ let choice = match self.config.color {
+ flags::Color::Always => ColorChoice::Always,
+ flags::Color::Never => ColorChoice::Never,
+ flags::Color::Auto if !is_tty => ColorChoice::Never,
+ flags::Color::Auto => ColorChoice::Auto,
+ };
+ let mut stream = constructor(choice);
+ let result = f(&mut stream);
+ stream.reset().unwrap();
+ result
+ }
}
#[cfg(unix)]