about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/builder.rs9
-rw-r--r--src/bootstrap/compile.rs66
-rw-r--r--src/bootstrap/config.rs3
-rw-r--r--src/bootstrap/download.rs19
-rw-r--r--src/bootstrap/flags.rs13
-rw-r--r--src/bootstrap/format.rs4
-rw-r--r--src/bootstrap/lib.rs11
-rw-r--r--src/bootstrap/native.rs2
-rw-r--r--src/bootstrap/setup.rs120
-rw-r--r--src/bootstrap/tool.rs6
10 files changed, 143 insertions, 110 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 952c70cec1c..b33fc02f49c 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -792,7 +792,7 @@ impl<'a> Builder<'a> {
                 run::CollectLicenseMetadata,
                 run::GenerateCopyright,
             ),
-            Kind::Setup => describe!(setup::Profile),
+            Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::Vscode),
             Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std),
             // special-cased in Build::build()
             Kind::Format => vec![],
@@ -1915,6 +1915,13 @@ impl<'a> Builder<'a> {
             }
         }
 
+        if matches!(mode, Mode::Std) {
+            if let Some(mir_opt_level) = self.config.rust_validate_mir_opts {
+                rustflags.arg("-Zvalidate-mir");
+                rustflags.arg(&format!("-Zmir-opt-level={}", mir_opt_level));
+            }
+        }
+
         Cargo { command: cargo, rustflags, rustdocflags, allow_features }
     }
 
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index f0fcdf0d5a0..348d22a9ce6 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -459,72 +459,6 @@ impl Step for StdLink {
         let libdir = builder.sysroot_libdir(target_compiler, target);
         let hostdir = builder.sysroot_libdir(target_compiler, compiler.host);
         add_to_sysroot(builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target));
-
-        if compiler.stage == 0 {
-            // special handling for stage0, to make `rustup toolchain link` and `x dist --stage 0`
-            // work for stage0-sysroot
-            let sysroot = builder.out.join(&compiler.host.triple).join("stage0-sysroot");
-
-            let host_lib_dir = builder.initial_rustc.ancestors().nth(2).unwrap().join("lib");
-            let host_bin_dir = builder.out.join(&builder.initial_rustc.parent().unwrap());
-            let host_codegen_backends =
-                host_lib_dir.join("rustlib").join(&compiler.host.triple).join("codegen-backends");
-            let sysroot_bin_dir = sysroot.join("bin");
-            let sysroot_lib_dir = sysroot.join("lib");
-            let sysroot_codegen_backends = builder.sysroot_codegen_backends(compiler);
-
-            // Create the `bin` directory in stage0-sysroot
-            t!(fs::create_dir_all(&sysroot_bin_dir));
-
-            // copy bin files from `builder.initial_rustc/./` to `stage0-sysroot/bin`
-            if let Ok(files) = fs::read_dir(&host_bin_dir) {
-                for file in files {
-                    let file = t!(file);
-                    if file.file_name() == "rustfmt" {
-                        // This is when `rustc` and `cargo` are set in `config.toml`
-                        if !file.path().starts_with(&builder.out) {
-                            builder.copy(
-                                &file.path().into_boxed_path(),
-                                &sysroot_bin_dir.join(file.file_name()),
-                            );
-                        } else {
-                            builder.copy(
-                                &builder
-                                    .out
-                                    .join(&compiler.host.triple)
-                                    .join("rustfmt/bin/rustfmt"),
-                                &sysroot_bin_dir.join(file.file_name()),
-                            );
-                        }
-                    } else {
-                        builder.copy(
-                            &file.path().into_boxed_path(),
-                            &sysroot_bin_dir.join(file.file_name()),
-                        );
-                    }
-                }
-            }
-
-            // copy dylib files from `builder.initial_rustc/../lib/*` while excluding the `rustlib` directory to `stage0-sysroot/lib`
-            if let Ok(files) = fs::read_dir(&host_lib_dir) {
-                for file in files {
-                    let file = t!(file);
-                    let path = file.path();
-                    if path.is_file()
-                        && is_dylib(&file.file_name().into_string().unwrap())
-                        && !path.starts_with(sysroot_lib_dir.join("rustlib").into_boxed_path())
-                    {
-                        builder.copy(&path, &sysroot_lib_dir.join(path.file_name().unwrap()));
-                    }
-                }
-            }
-
-            t!(fs::create_dir_all(&sysroot_codegen_backends));
-            // copy `codegen-backends` from `host_lib_dir/rustlib/codegen_backends` to `stage0-sysroot/lib/rustlib/host-triple/codegen-backends` if it exists.
-            if host_codegen_backends.exists() {
-                builder.cp_r(&host_codegen_backends, &sysroot_codegen_backends);
-            }
-        }
     }
 }
 
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 56f96734bbb..4a563bc396d 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -173,6 +173,7 @@ pub struct Config {
     pub rust_profile_use: Option<String>,
     pub rust_profile_generate: Option<String>,
     pub rust_lto: RustcLto,
+    pub rust_validate_mir_opts: Option<u32>,
     pub llvm_profile_use: Option<String>,
     pub llvm_profile_generate: bool,
     pub llvm_libunwind_default: Option<LlvmLibunwind>,
@@ -770,6 +771,7 @@ define_config! {
         // ignored; this is set from an env var set by bootstrap.py
         download_rustc: Option<StringOrBool> = "download-rustc",
         lto: Option<String> = "lto",
+        validate_mir_opts: Option<u32> = "validate-mir-opts",
     }
 }
 
@@ -1149,6 +1151,7 @@ impl Config {
                 .as_deref()
                 .map(|value| RustcLto::from_str(value).unwrap())
                 .unwrap_or_default();
+            config.rust_validate_mir_opts = rust.validate_mir_opts;
         } else {
             config.rust_profile_use = flags.rust_profile_use;
             config.rust_profile_generate = flags.rust_profile_generate;
diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs
index d6592d2d771..d1e2149d3f9 100644
--- a/src/bootstrap/download.rs
+++ b/src/bootstrap/download.rs
@@ -2,7 +2,7 @@ use std::{
     env,
     ffi::{OsStr, OsString},
     fs::{self, File},
-    io::{self, BufRead, BufReader, ErrorKind},
+    io::{BufRead, BufReader, ErrorKind},
     path::{Path, PathBuf},
     process::{Command, Stdio},
 };
@@ -26,14 +26,6 @@ impl Config {
         self.verbose > 0
     }
 
-    pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(&self, src: P, link: Q) -> io::Result<()> {
-        #[cfg(unix)]
-        use std::os::unix::fs::symlink as symlink_file;
-        #[cfg(windows)]
-        use std::os::windows::fs::symlink_file;
-        if !self.dry_run() { symlink_file(src.as_ref(), link.as_ref()) } else { Ok(()) }
-    }
-
     pub(crate) fn create(&self, path: &Path, s: &str) {
         if self.dry_run() {
             return;
@@ -338,15 +330,6 @@ impl Config {
         let bin_root = self.out.join(host.triple).join("rustfmt");
         let rustfmt_path = bin_root.join("bin").join(exe("rustfmt", host));
         let rustfmt_stamp = bin_root.join(".rustfmt-stamp");
-
-        #[cfg(not(windows))]
-        {
-            let legacy_rustfmt = self.initial_rustc.with_file_name(exe("rustfmt", host));
-            if !legacy_rustfmt.exists() {
-                t!(self.symlink_file(&rustfmt_path, &legacy_rustfmt));
-            }
-        }
-
         if rustfmt_path.exists() && !program_out_of_date(&rustfmt_stamp, &channel) {
             return Some(rustfmt_path);
         }
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index f07e710a9e6..9d1504c34e8 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -554,7 +554,8 @@ Arguments:
             Kind::Setup => {
                 subcommand_help.push_str(&format!(
                     "\n
-x.py setup creates a `config.toml` which changes the defaults for x.py itself.
+x.py setup creates a `config.toml` which changes the defaults for x.py itself,
+as well as setting up a git pre-push hook, VS code config and toolchain link.
 
 Arguments:
     This subcommand accepts a 'profile' to use for builds. For example:
@@ -564,7 +565,13 @@ Arguments:
     The profile is optional and you will be prompted interactively if it is not given.
     The following profiles are available:
 
-{}",
+{}
+
+    To only set up the git hook, VS code or toolchain link, you may use
+        ./x.py setup hook
+        ./x.py setup vscode
+        ./x.py setup link
+",
                     Profile::all_for_help("        ").trim_end()
                 ));
             }
@@ -638,7 +645,7 @@ Arguments:
             }
             Kind::Setup => {
                 let profile = if paths.len() > 1 {
-                    eprintln!("\nerror: At most one profile can be passed to setup\n");
+                    eprintln!("\nerror: At most one option can be passed to setup\n");
                     usage(1, &opts, verbose, &subcommand_help)
                 } else if let Some(path) = paths.pop() {
                     let profile_string = t!(path.into_os_string().into_string().map_err(
diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs
index 615794958d0..ae72a42973c 100644
--- a/src/bootstrap/format.rs
+++ b/src/bootstrap/format.rs
@@ -218,7 +218,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
                     WalkBuilder::new(first)
                 }
             } else {
-                WalkBuilder::new(first)
+                WalkBuilder::new(src.join(first))
             };
 
             for path in &paths[1..] {
@@ -229,7 +229,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
                         walker.add(path);
                     }
                 } else {
-                    walker.add(path);
+                    walker.add(src.join(path));
                 }
             }
 
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index f753720b353..f4abdf1cc57 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -20,6 +20,7 @@ use std::cell::{Cell, RefCell};
 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};
@@ -1406,7 +1407,7 @@ impl Build {
                 src = t!(fs::canonicalize(src));
             } else {
                 let link = t!(fs::read_link(src));
-                t!(self.config.symlink_file(link, dst));
+                t!(self.symlink_file(link, dst));
                 return;
             }
         }
@@ -1524,6 +1525,14 @@ impl Build {
         iter.map(|e| t!(e)).collect::<Vec<_>>().into_iter()
     }
 
+    fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(&self, src: P, link: Q) -> io::Result<()> {
+        #[cfg(unix)]
+        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(()) }
+    }
+
     /// Returns if config.ninja is enabled, and checks for ninja existence,
     /// exiting with a nicer error message if not.
     fn ninja(&self) -> bool {
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index d6e63fb937e..21157b02a78 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -516,7 +516,7 @@ impl Step for Llvm {
 
             let lib_llvm = out_dir.join("build").join("lib").join(lib_name);
             if !lib_llvm.exists() {
-                t!(builder.build.config.symlink_file("libLLVM.dylib", &lib_llvm));
+                t!(builder.symlink_file("libLLVM.dylib", &lib_llvm));
             }
         }
 
diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs
index a027139df23..4480bce99d7 100644
--- a/src/bootstrap/setup.rs
+++ b/src/bootstrap/setup.rs
@@ -21,6 +21,7 @@ pub enum Profile {
     Library,
     Tools,
     User,
+    None,
 }
 
 /// A list of historical hashes of `src/etc/vscode_settings.json`.
@@ -41,7 +42,7 @@ impl Profile {
     pub fn all() -> impl Iterator<Item = Self> {
         use Profile::*;
         // N.B. these are ordered by how they are displayed, not alphabetically
-        [Library, Compiler, Codegen, Tools, User].iter().copied()
+        [Library, Compiler, Codegen, Tools, User, None].iter().copied()
     }
 
     pub fn purpose(&self) -> String {
@@ -52,6 +53,7 @@ impl Profile {
             Codegen => "Contribute to the compiler, and also modify LLVM or codegen",
             Tools => "Contribute to tools which depend on the compiler, but do not modify it directly (e.g. rustdoc, clippy, miri)",
             User => "Install Rust from source",
+            None => "Do not modify `config.toml`"
         }
         .to_string()
     }
@@ -71,6 +73,7 @@ impl Profile {
             Profile::Library => "library",
             Profile::Tools => "tools",
             Profile::User => "user",
+            Profile::None => "none",
         }
     }
 }
@@ -87,6 +90,7 @@ impl FromStr for Profile {
             "tools" | "tool" | "rustdoc" | "clippy" | "miri" | "rustfmt" | "rls" => {
                 Ok(Profile::Tools)
             }
+            "none" => Ok(Profile::None),
             _ => Err(format!("unknown profile: '{}'", s)),
         }
     }
@@ -144,17 +148,8 @@ impl Step for Profile {
 }
 
 pub fn setup(config: &Config, profile: Profile) {
-    let stage_path =
-        ["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
-
-    if !rustup_installed() && profile != Profile::User {
-        eprintln!("`rustup` is not installed; cannot link `stage1` toolchain");
-    } else if stage_dir_exists(&stage_path[..]) && !config.dry_run() {
-        attempt_toolchain_link(&stage_path[..]);
-    }
-
-    let suggestions = match profile {
-        Profile::Codegen | Profile::Compiler => &["check", "build", "test"][..],
+    let suggestions: &[&str] = match profile {
+        Profile::Codegen | Profile::Compiler | Profile::None => &["check", "build", "test"],
         Profile::Tools => &[
             "check",
             "build",
@@ -167,11 +162,6 @@ pub fn setup(config: &Config, profile: Profile) {
         Profile::User => &["dist", "build"],
     };
 
-    if !config.dry_run() {
-        t!(install_git_hook_maybe(&config));
-        t!(create_vscode_settings_maybe(&config));
-    }
-
     println!();
 
     println!("To get started, try one of the following commands:");
@@ -190,6 +180,9 @@ pub fn setup(config: &Config, profile: Profile) {
 }
 
 fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
+    if profile == Profile::None {
+        return;
+    }
     if path.exists() {
         eprintln!();
         eprintln!(
@@ -217,6 +210,41 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
     println!("`x.py` will now use the configuration at {}", include_path.display());
 }
 
+/// Creates a toolchain link for stage1 using `rustup`
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
+pub struct Link;
+impl Step for Link {
+    type Output = ();
+    const DEFAULT: bool = true;
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.alias("link")
+    }
+    fn make_run(run: RunConfig<'_>) {
+        if run.builder.config.dry_run() {
+            return;
+        }
+        if let [cmd] = &run.paths[..] {
+            if cmd.assert_single_path().path.as_path().as_os_str() == "link" {
+                run.builder.ensure(Link);
+            }
+        }
+    }
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        let config = &builder.config;
+        if config.dry_run() {
+            return;
+        }
+        let stage_path =
+            ["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
+
+        if !rustup_installed() {
+            eprintln!("`rustup` is not installed; cannot link `stage1` toolchain");
+        } else if stage_dir_exists(&stage_path[..]) && !config.dry_run() {
+            attempt_toolchain_link(&stage_path[..]);
+        }
+    }
+}
+
 fn rustup_installed() -> bool {
     Command::new("rustup")
         .arg("--version")
@@ -394,6 +422,35 @@ fn prompt_user(prompt: &str) -> io::Result<Option<PromptResult>> {
     }
 }
 
+/// Installs `src/etc/pre-push.sh` as a Git hook
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
+pub struct Hook;
+
+impl Step for Hook {
+    type Output = ();
+    const DEFAULT: bool = true;
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.alias("hook")
+    }
+    fn make_run(run: RunConfig<'_>) {
+        if run.builder.config.dry_run() {
+            return;
+        }
+        if let [cmd] = &run.paths[..] {
+            if cmd.assert_single_path().path.as_path().as_os_str() == "hook" {
+                run.builder.ensure(Hook);
+            }
+        }
+    }
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        let config = &builder.config;
+        if config.dry_run() {
+            return;
+        }
+        t!(install_git_hook_maybe(&config));
+    }
+}
+
 // install a git hook to automatically run tidy, if they want
 fn install_git_hook_maybe(config: &Config) -> io::Result<()> {
     let git = t!(config.git().args(&["rev-parse", "--git-common-dir"]).output().map(|output| {
@@ -432,6 +489,35 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
     Ok(())
 }
 
+/// Sets up or displays `src/etc/vscode_settings.json`
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
+pub struct Vscode;
+
+impl Step for Vscode {
+    type Output = ();
+    const DEFAULT: bool = true;
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.alias("vscode")
+    }
+    fn make_run(run: RunConfig<'_>) {
+        if run.builder.config.dry_run() {
+            return;
+        }
+        if let [cmd] = &run.paths[..] {
+            if cmd.assert_single_path().path.as_path().as_os_str() == "vscode" {
+                run.builder.ensure(Vscode);
+            }
+        }
+    }
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        let config = &builder.config;
+        if config.dry_run() {
+            return;
+        }
+        t!(create_vscode_settings_maybe(&config));
+    }
+}
+
 /// Create a `.vscode/settings.json` file for rustc development, or just print it
 fn create_vscode_settings_maybe(config: &Config) -> io::Result<()> {
     let (current_hash, historical_hashes) = SETTINGS_HASHES.split_last().unwrap();
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index d30532ef3c6..3c9a154da9a 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -595,7 +595,7 @@ impl Step for Rustdoc {
             features.push("jemalloc".to_string());
         }
 
-        let cargo = prepare_tool_cargo(
+        let mut cargo = prepare_tool_cargo(
             builder,
             build_compiler,
             Mode::ToolRustc,
@@ -606,6 +606,10 @@ impl Step for Rustdoc {
             features.as_slice(),
         );
 
+        if builder.config.rustc_parallel {
+            cargo.rustflag("--cfg=parallel_compiler");
+        }
+
         let msg = tooling_output(
             Mode::ToolRustc,
             "rustdoc",