]> git.lizzy.rs Git - rust.git/blobdiff - src/bootstrap/lib.rs
Rollup merge of #105904 - MarcusCalhoun-Lopez:darwin_arch_i386, r=bjorn3
[rust.git] / src / bootstrap / lib.rs
index a3d1893afbb65d171eb8052773a757978e5f75c1..47fb4a38d05be381e074f199401b03c7b1de9db4 100644 (file)
 use std::env;
 use std::fs::{self, File};
 use std::io;
+use std::io::ErrorKind;
 use std::path::{Path, PathBuf};
 use std::process::Command;
 use std::str;
 
 use crate::builder::Kind;
 use crate::config::{LlvmLibunwind, TargetSelection};
-use crate::util::{exe, libdir, mtime, output, run, run_suppressed, try_run_suppressed, CiEnv};
+use crate::util::{
+    exe, libdir, mtime, output, run, run_suppressed, symlink_dir, try_run_suppressed, CiEnv,
+};
 
 mod bolt;
 mod builder;
@@ -542,16 +545,6 @@ pub fn new(mut config: Config) -> 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 =
@@ -567,16 +560,48 @@ pub fn new(mut config: Config) -> 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);
 
-        build.verbose("learning about cargo");
-        metadata::build(&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);
+        }
+
+        // Make a symbolic link so we can use a consistent directory in the documentation.
+        let build_triple = build.out.join(&build.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
+                );
+            }
+        }
 
         build
     }
@@ -647,15 +672,28 @@ fn dir_is_empty(dir: &Path) -> bool {
         if !update(true).status().map_or(false, |status| status.success()) {
             self.run(&mut update(false));
         }
-        self.run(Command::new("git").args(&["stash", "push"]).current_dir(&absolute_path));
+
+        // 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(&["stash", "pop"]).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()) {
             return;
@@ -684,8 +722,6 @@ pub fn build(&mut self) {
             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);
         }
@@ -694,10 +730,6 @@ pub fn build(&mut self) {
             return clean::clean(self, all);
         }
 
-        if let Subcommand::Setup { profile } = &self.config.cmd {
-            return setup::setup(&self.config, *profile);
-        }
-
         // Download rustfmt early so that it can be used in rust-analyzer configs.
         let _ = &builder::Builder::new(&self).initial_rustfmt();
 
@@ -1620,10 +1652,10 @@ fn chmod(_path: &Path, _perms: u32) {}
 /// If the test is running and code is an error code, it will cause a panic.
 fn detail_exit(code: i32) -> ! {
     // if in test and code is an error code, panic with status code provided
-    if cfg!(test) && code != 0 {
+    if cfg!(test) {
         panic!("status code: {}", code);
     } else {
-        //otherwise,exit with provided status code
+        // otherwise,exit with provided status code
         std::process::exit(code);
     }
 }