summaryrefslogtreecommitdiffstats
path: root/src/bootstrap/lib.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:18:32 +0000
commit4547b622d8d29df964fa2914213088b148c498fc (patch)
tree9fc6b25f3c3add6b745be9a2400a6e96140046e9 /src/bootstrap/lib.rs
parentReleasing progress-linux version 1.66.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-4547b622d8d29df964fa2914213088b148c498fc.tar.xz
rustc-4547b622d8d29df964fa2914213088b148c498fc.zip
Merging upstream version 1.67.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/bootstrap/lib.rs')
-rw-r--r--src/bootstrap/lib.rs215
1 files changed, 102 insertions, 113 deletions
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 7e70e99bb..3ed534523 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -112,15 +112,14 @@ use std::path::{Path, PathBuf};
use std::process::Command;
use std::str;
-use config::Target;
+use channel::GitInfo;
+use config::{DryRun, Target};
use filetime::FileTime;
use once_cell::sync::OnceCell;
use crate::builder::Kind;
use crate::config::{LlvmLibunwind, TargetSelection};
-use crate::util::{
- check_run, exe, libdir, mtime, output, run, run_suppressed, try_run, try_run_suppressed, CiEnv,
-};
+use crate::util::{exe, libdir, mtime, output, run, run_suppressed, try_run_suppressed, CiEnv};
mod bolt;
mod builder;
@@ -133,6 +132,7 @@ mod compile;
mod config;
mod dist;
mod doc;
+mod download;
mod flags;
mod format;
mod install;
@@ -281,7 +281,6 @@ pub struct Build {
src: PathBuf,
out: PathBuf,
bootstrap_out: PathBuf,
- rust_info: channel::GitInfo,
cargo_info: channel::GitInfo,
rust_analyzer_info: channel::GitInfo,
clippy_info: channel::GitInfo,
@@ -396,6 +395,28 @@ pub enum CLang {
Cxx,
}
+macro_rules! forward {
+ ( $( $fn:ident( $($param:ident: $ty:ty),* ) $( -> $ret:ty)? ),+ $(,)? ) => {
+ impl Build {
+ $( fn $fn(&self, $($param: $ty),* ) $( -> $ret)? {
+ self.config.$fn( $($param),* )
+ } )+
+ }
+ }
+}
+
+forward! {
+ verbose(msg: &str),
+ is_verbose() -> bool,
+ create(path: &Path, s: &str),
+ remove(f: &Path),
+ tempdir() -> PathBuf,
+ try_run(cmd: &mut Command) -> bool,
+ llvm_link_shared() -> bool,
+ download_rustc() -> bool,
+ initial_rustfmt() -> Option<PathBuf>,
+}
+
impl Build {
/// Creates a new set of build configuration from the `flags` on the command
/// line and the filesystem `config`.
@@ -430,7 +451,7 @@ impl Build {
// we always try to use git for LLVM builds
let in_tree_llvm_info = channel::GitInfo::new(false, &src.join("src/llvm-project"));
- let initial_target_libdir_str = if config.dry_run {
+ let initial_target_libdir_str = if config.dry_run() {
"/dummy/lib/path/to/lib/".to_string()
} else {
output(
@@ -444,7 +465,7 @@ impl Build {
let initial_target_dir = Path::new(&initial_target_libdir_str).parent().unwrap();
let initial_lld = initial_target_dir.join("bin").join("rust-lld");
- let initial_sysroot = if config.dry_run {
+ let initial_sysroot = if config.dry_run() {
"/dummy".to_string()
} else {
output(Command::new(&config.initial_rustc).arg("--print").arg("sysroot"))
@@ -499,7 +520,6 @@ impl Build {
out,
bootstrap_out,
- rust_info,
cargo_info,
rust_analyzer_info,
clippy_info,
@@ -522,16 +542,6 @@ impl Build {
metrics: metrics::BuildMetrics::init(),
};
- build.verbose("finding compilers");
- cc_detect::find(&mut build);
- // When running `setup`, the profile is about to change, so any requirements we have now may
- // be different on the next invocation. Don't check for them until the next time x.py is
- // run. This is ok because `setup` never runs any build commands, so it won't fail if commands are missing.
- if !matches!(build.config.cmd, Subcommand::Setup { .. }) {
- build.verbose("running sanity check");
- sanity::check(&mut build);
- }
-
// If local-rust is the same major.minor as the current version, then force a
// local-rebuild
let local_version_verbose =
@@ -547,16 +557,34 @@ impl Build {
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", "library/backtrace", "library/stdarch"];
- for s in rust_submodules {
- build.update_submodule(Path::new(s));
- }
+ build.verbose("finding compilers");
+ cc_detect::find(&mut build);
+ // When running `setup`, the profile is about to change, so any requirements we have now may
+ // be different on the next invocation. Don't check for them until the next time x.py is
+ // run. This is ok because `setup` never runs any build commands, so it won't fail if commands are missing.
+ //
+ // Similarly, for `setup` we don't actually need submodules or cargo metadata.
+ if !matches!(build.config.cmd, Subcommand::Setup { .. }) {
+ build.verbose("running sanity check");
+ sanity::check(&mut 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",
+ ];
+ for s in rust_submodules {
+ build.update_submodule(Path::new(s));
+ }
+ // Now, update all existing submodules.
+ build.update_existing_submodules();
- build.verbose("learning about cargo");
- metadata::build(&mut build);
+ build.verbose("learning about cargo");
+ metadata::build(&mut build);
+ }
build
}
@@ -570,7 +598,7 @@ impl Build {
t!(std::fs::read_dir(dir)).next().is_none()
}
- if !self.config.submodules(&self.rust_info) {
+ if !self.config.submodules(&self.rust_info()) {
return;
}
@@ -628,15 +656,29 @@ impl Build {
self.run(&mut update(false));
}
+ // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error).
+ let has_local_modifications = !self.try_run(
+ Command::new("git")
+ .args(&["diff-index", "--quiet", "HEAD"])
+ .current_dir(&absolute_path),
+ );
+ if has_local_modifications {
+ self.run(Command::new("git").args(&["stash", "push"]).current_dir(&absolute_path));
+ }
+
self.run(Command::new("git").args(&["reset", "-q", "--hard"]).current_dir(&absolute_path));
- self.run(Command::new("git").args(&["clean", "-qdfx"]).current_dir(absolute_path));
+ self.run(Command::new("git").args(&["clean", "-qdfx"]).current_dir(&absolute_path));
+
+ if has_local_modifications {
+ self.run(Command::new("git").args(&["stash", "pop"]).current_dir(absolute_path));
+ }
}
/// If any submodule has been initialized already, sync it unconditionally.
/// This avoids contributors checking in a submodule change by accident.
- pub fn maybe_update_submodules(&self) {
+ pub fn update_existing_submodules(&self) {
// Avoid running git when there isn't a git checkout.
- if !self.config.submodules(&self.rust_info) {
+ if !self.config.submodules(&self.rust_info()) {
return;
}
let output = output(
@@ -663,8 +705,6 @@ impl Build {
job::setup(self);
}
- self.maybe_update_submodules();
-
if let Subcommand::Format { check, paths } = &self.config.cmd {
return format::format(&builder::Builder::new(&self), *check, &paths);
}
@@ -689,13 +729,13 @@ impl Build {
}
}
- if !self.config.dry_run {
+ if !self.config.dry_run() {
{
- self.config.dry_run = true;
+ self.config.dry_run = DryRun::SelfCheck;
let builder = builder::Builder::new(&self);
builder.execute_cli();
}
- self.config.dry_run = false;
+ self.config.dry_run = DryRun::Disabled;
let builder = builder::Builder::new(&self);
builder.execute_cli();
} else {
@@ -735,6 +775,10 @@ impl Build {
cleared
}
+ fn rust_info(&self) -> &GitInfo {
+ &self.config.rust_info
+ }
+
/// Gets the space-separated set of activated features for the standard
/// library.
fn std_features(&self, target: TargetSelection) -> String {
@@ -947,7 +991,7 @@ impl Build {
/// Runs a command, printing out nice contextual information if it fails.
fn run(&self, cmd: &mut Command) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
self.verbose(&format!("running: {:?}", cmd));
@@ -956,7 +1000,7 @@ impl Build {
/// Runs a command, printing out nice contextual information if it fails.
fn run_quiet(&self, cmd: &mut Command) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
self.verbose(&format!("running: {:?}", cmd));
@@ -966,47 +1010,14 @@ impl Build {
/// 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(&self, cmd: &mut Command) -> bool {
- if self.config.dry_run {
- return true;
- }
- self.verbose(&format!("running: {:?}", cmd));
- try_run(cmd, self.is_verbose())
- }
-
- /// 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 {
- if self.config.dry_run {
+ if self.config.dry_run() {
return true;
}
self.verbose(&format!("running: {:?}", cmd));
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
- }
-
- /// Prints a message if this build is configured in verbose mode.
- fn verbose(&self, msg: &str) {
- if self.is_verbose() {
- println!("{}", msg);
- }
- }
-
pub fn is_verbose_than(&self, level: usize) -> bool {
self.verbosity > level
}
@@ -1019,10 +1030,12 @@ impl Build {
}
fn info(&self, msg: &str) {
- if self.config.dry_run {
- return;
+ match self.config.dry_run {
+ DryRun::SelfCheck => return,
+ DryRun::Disabled | DryRun::UserSelected => {
+ println!("{}", msg);
+ }
}
- println!("{}", msg);
}
/// Returns the number of parallel jobs that have been configured for this
@@ -1152,8 +1165,8 @@ impl Build {
options[0] = Some("-Clink-arg=-fuse-ld=lld".to_string());
}
- let threads = if target.contains("windows") { "/threads:1" } else { "--threads=1" };
- options[1] = Some(format!("-Clink-arg=-Wl,{}", threads));
+ let no_threads = util::lld_flag_no_threads(target.contains("windows"));
+ options[1] = Some(format!("-Clink-arg=-Wl,{}", no_threads));
}
IntoIterator::into_iter(options).flatten()
@@ -1267,7 +1280,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.ignore_git {
format!("{}-beta.{}", num, self.beta_prerelease_version())
} else {
format!("{}-beta", num)
@@ -1327,7 +1340,7 @@ impl Build {
/// Note that this is a descriptive string which includes the commit date,
/// sha, version, etc.
fn rust_version(&self) -> String {
- let mut version = self.rust_info.version(self, &self.version);
+ let mut version = self.rust_info().version(self, &self.version);
if let Some(ref s) = self.config.description {
version.push_str(" (");
version.push_str(s);
@@ -1338,7 +1351,7 @@ impl Build {
/// Returns the full commit hash.
fn rust_sha(&self) -> Option<&str> {
- self.rust_info.sha()
+ self.rust_info().sha()
}
/// Returns the `a.b.c` version that the given package is at.
@@ -1400,7 +1413,7 @@ impl Build {
}
fn read_stamp_file(&self, stamp: &Path) -> Vec<(PathBuf, DependencyType)> {
- if self.config.dry_run {
+ if self.config.dry_run() {
return Vec::new();
}
@@ -1424,23 +1437,13 @@ impl Build {
paths
}
- /// Create a temporary directory in `out` and return its path.
- ///
- /// NOTE: this temporary directory is shared between all steps;
- /// if you need an empty directory, create a new subdirectory inside it.
- fn tempdir(&self) -> PathBuf {
- let tmp = self.out.join("tmp");
- t!(fs::create_dir_all(&tmp));
- tmp
- }
-
/// Copies a file from `src` to `dst`
pub fn copy(&self, src: &Path, dst: &Path) {
self.copy_internal(src, dst, false);
}
fn copy_internal(&self, src: &Path, dst: &Path, dereference_symlinks: bool) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
self.verbose_than(1, &format!("Copy {:?} to {:?}", src, dst));
@@ -1477,7 +1480,7 @@ impl Build {
/// Copies the `src` directory recursively to `dst`. Both are assumed to exist
/// when this function is called.
pub fn cp_r(&self, src: &Path, dst: &Path) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
for f in self.read_dir(src) {
@@ -1530,7 +1533,7 @@ impl Build {
}
fn install(&self, src: &Path, dstdir: &Path, perms: u32) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
let dst = dstdir.join(src.file_name().unwrap());
@@ -1543,29 +1546,22 @@ impl Build {
chmod(&dst, perms);
}
- fn create(&self, path: &Path, s: &str) {
- if self.config.dry_run {
- return;
- }
- t!(fs::write(path, s));
- }
-
fn read(&self, path: &Path) -> String {
- if self.config.dry_run {
+ if self.config.dry_run() {
return String::new();
}
t!(fs::read_to_string(path))
}
fn create_dir(&self, dir: &Path) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
t!(fs::create_dir_all(dir))
}
fn remove_dir(&self, dir: &Path) {
- if self.config.dry_run {
+ if self.config.dry_run() {
return;
}
t!(fs::remove_dir_all(dir))
@@ -1574,7 +1570,7 @@ impl Build {
fn read_dir(&self, dir: &Path) -> impl Iterator<Item = fs::DirEntry> {
let iter = match fs::read_dir(dir) {
Ok(v) => v,
- Err(_) if self.config.dry_run => return vec![].into_iter(),
+ Err(_) if self.config.dry_run() => return vec![].into_iter(),
Err(err) => panic!("could not read dir {:?}: {:?}", dir, err),
};
iter.map(|e| t!(e)).collect::<Vec<_>>().into_iter()
@@ -1585,14 +1581,7 @@ impl Build {
use std::os::unix::fs::symlink as symlink_file;
#[cfg(windows)]
use std::os::windows::fs::symlink_file;
- if !self.config.dry_run { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) }
- }
-
- fn remove(&self, f: &Path) {
- if self.config.dry_run {
- return;
- }
- fs::remove_file(f).unwrap_or_else(|_| panic!("failed to remove {:?}", f));
+ if !self.config.dry_run() { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) }
}
/// Returns if config.ninja is enabled, and checks for ninja existence,