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/bootstrap.py4
-rw-r--r--src/bootstrap/bootstrap_test.py19
-rw-r--r--src/bootstrap/builder.rs10
-rw-r--r--src/bootstrap/builder/tests.rs6
-rw-r--r--src/bootstrap/compile.rs39
-rw-r--r--src/bootstrap/config.rs22
-rw-r--r--src/bootstrap/doc.rs2
-rw-r--r--src/bootstrap/flags.rs18
-rw-r--r--src/bootstrap/lib.rs2
-rw-r--r--src/bootstrap/llvm.rs20
-rw-r--r--src/bootstrap/mk/Makefile.in4
-rw-r--r--src/bootstrap/test.rs15
12 files changed, 112 insertions, 49 deletions
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index fe66b1d41bf..70079106689 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -472,7 +472,9 @@ class FakeArgs:
 
 class RustBuild(object):
     """Provide all the methods required to build Rust"""
-    def __init__(self, config_toml="", args=FakeArgs()):
+    def __init__(self, config_toml="", args=None):
+        if args is None:
+            args = FakeArgs()
         self.git_version = None
         self.nix_deps_dir = None
         self._should_fix_bins_and_dylibs = None
diff --git a/src/bootstrap/bootstrap_test.py b/src/bootstrap/bootstrap_test.py
index 3c91e403df3..dc06a4c9734 100644
--- a/src/bootstrap/bootstrap_test.py
+++ b/src/bootstrap/bootstrap_test.py
@@ -4,7 +4,6 @@ Run these with `x test bootstrap`, or `python -m unittest src/bootstrap/bootstra
 
 from __future__ import absolute_import, division, print_function
 import os
-import doctest
 import unittest
 import tempfile
 import hashlib
@@ -16,12 +15,15 @@ from shutil import rmtree
 bootstrap_dir = os.path.dirname(os.path.abspath(__file__))
 # For the import below, have Python search in src/bootstrap first.
 sys.path.insert(0, bootstrap_dir)
-import bootstrap
-import configure
+import bootstrap # noqa: E402
+import configure # noqa: E402
 
-def serialize_and_parse(configure_args, bootstrap_args=bootstrap.FakeArgs()):
+def serialize_and_parse(configure_args, bootstrap_args=None):
     from io import StringIO
 
+    if bootstrap_args is None:
+        bootstrap_args = bootstrap.FakeArgs()
+
     section_order, sections, targets = configure.parse_args(configure_args)
     buffer = StringIO()
     configure.write_config_toml(buffer, section_order, targets, sections)
@@ -129,7 +131,14 @@ class GenerateAndParseConfig(unittest.TestCase):
 class BuildBootstrap(unittest.TestCase):
     """Test that we generate the appropriate arguments when building bootstrap"""
 
-    def build_args(self, configure_args=[], args=[], env={}):
+    def build_args(self, configure_args=None, args=None, env=None):
+        if configure_args is None:
+            configure_args = []
+        if args is None:
+            args = []
+        if env is None:
+            env = {}
+
         env = env.copy()
         env["PATH"] = os.environ["PATH"]
 
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index d369e8eeda9..b3666192853 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -317,19 +317,17 @@ impl StepDescription {
     }
 
     fn is_excluded(&self, builder: &Builder<'_>, pathset: &PathSet) -> bool {
-        if builder.config.exclude.iter().any(|e| pathset.has(&e, builder.kind)) {
+        if builder.config.skip.iter().any(|e| pathset.has(&e, builder.kind)) {
             if !matches!(builder.config.dry_run, DryRun::SelfCheck) {
                 println!("Skipping {pathset:?} because it is excluded");
             }
             return true;
         }
 
-        if !builder.config.exclude.is_empty()
-            && !matches!(builder.config.dry_run, DryRun::SelfCheck)
-        {
+        if !builder.config.skip.is_empty() && !matches!(builder.config.dry_run, DryRun::SelfCheck) {
             builder.verbose(&format!(
                 "{:?} not skipped for {:?} -- not in {:?}",
-                pathset, self.name, builder.config.exclude
+                pathset, self.name, builder.config.skip
             ));
         }
         false
@@ -2129,7 +2127,7 @@ impl<'a> Builder<'a> {
         let desc = StepDescription::from::<S>(kind);
         let should_run = (desc.should_run)(ShouldRun::new(self, desc.kind));
 
-        // Avoid running steps contained in --exclude
+        // Avoid running steps contained in --skip
         for pathset in &should_run.paths {
             if desc.is_excluded(self, pathset) {
                 return None;
diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs
index 65b8f7fd3b7..43b4a34fe5b 100644
--- a/src/bootstrap/builder/tests.rs
+++ b/src/bootstrap/builder/tests.rs
@@ -119,7 +119,7 @@ fn test_intersection() {
 #[test]
 fn test_exclude() {
     let mut config = configure("test", &["A"], &["A"]);
-    config.exclude = vec!["src/tools/tidy".into()];
+    config.skip = vec!["src/tools/tidy".into()];
     let cache = run_build(&[], config);
 
     // Ensure we have really excluded tidy
@@ -137,7 +137,7 @@ fn test_exclude_kind() {
     // Ensure our test is valid, and `test::Rustc` would be run without the exclude.
     assert!(run_build(&[], config.clone()).contains::<test::CrateLibrustc>());
     // Ensure tests for rustc are skipped.
-    config.exclude = vec![path.clone()];
+    config.skip = vec![path.clone()];
     assert!(!run_build(&[], config.clone()).contains::<test::CrateLibrustc>());
     // Ensure builds for rustc are not skipped.
     assert!(run_build(&[], config).contains::<compile::Rustc>());
@@ -587,6 +587,7 @@ mod dist {
             run: None,
             only_modified: false,
             skip: vec![],
+            extra_checks: None,
         };
 
         let build = Build::new(config);
@@ -658,6 +659,7 @@ mod dist {
             pass: None,
             run: None,
             only_modified: false,
+            extra_checks: None,
         };
         // Make sure rustfmt binary not being found isn't an error.
         config.channel = "beta".to_string();
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 2c63ec80c3e..cad370ad756 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -31,6 +31,7 @@ use crate::util::get_clang_cl_resource_dir;
 use crate::util::{exe, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date};
 use crate::LLVM_TOOLS;
 use crate::{CLang, Compiler, DependencyType, GitRepo, Mode};
+use filetime::FileTime;
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct Std {
@@ -904,19 +905,12 @@ impl Step for Rustc {
         // our LLVM wrapper. Unless we're explicitly requesting `librustc_driver` to be built with
         // debuginfo (via the debuginfo level of the executables using it): strip this debuginfo
         // away after the fact.
-        // FIXME: to make things simpler for now, limit this to the host and target where we know
-        // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
-        // cross-compiling. Expand this to other appropriate targets in the future.
         if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None
             && builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None
-            && target == "x86_64-unknown-linux-gnu"
-            && target == builder.config.build
         {
             let target_root_dir = stamp.parent().unwrap();
             let rustc_driver = target_root_dir.join("librustc_driver.so");
-            if rustc_driver.exists() {
-                output(Command::new("strip").arg("--strip-debug").arg(rustc_driver));
-            }
+            strip_debug(builder, target, &rustc_driver);
         }
 
         builder.ensure(RustcLink::from_rustc(
@@ -1135,7 +1129,7 @@ fn needs_codegen_config(run: &RunConfig<'_>) -> bool {
     needs_codegen_cfg
 }
 
-const CODEGEN_BACKEND_PREFIX: &str = "rustc_codegen_";
+pub(crate) const CODEGEN_BACKEND_PREFIX: &str = "rustc_codegen_";
 
 fn is_codegen_cfg_needed(path: &TaskPath, run: &RunConfig<'_>) -> bool {
     if path.path.to_str().unwrap().contains(&CODEGEN_BACKEND_PREFIX) {
@@ -1974,3 +1968,30 @@ pub enum CargoMessage<'a> {
         success: bool,
     },
 }
+
+pub fn strip_debug(builder: &Builder<'_>, target: TargetSelection, path: &Path) {
+    // FIXME: to make things simpler for now, limit this to the host and target where we know
+    // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
+    // cross-compiling. Expand this to other appropriate targets in the future.
+    if target != "x86_64-unknown-linux-gnu" || target != builder.config.build || !path.exists() {
+        return;
+    }
+
+    let previous_mtime = FileTime::from_last_modification_time(&path.metadata().unwrap());
+    // Note: `output` will propagate any errors here.
+    output(Command::new("strip").arg("--strip-debug").arg(path));
+
+    // After running `strip`, we have to set the file modification time to what it was before,
+    // otherwise we risk Cargo invalidating its fingerprint and rebuilding the world next time
+    // bootstrap is invoked.
+    //
+    // An example of this is if we run this on librustc_driver.so. In the first invocation:
+    // - Cargo will build librustc_driver.so (mtime of 1)
+    // - Cargo will build rustc-main (mtime of 2)
+    // - Bootstrap will strip librustc_driver.so (changing the mtime to 3).
+    //
+    // In the second invocation of bootstrap, Cargo will see that the mtime of librustc_driver.so
+    // is greater than the mtime of rustc-main, and will rebuild rustc-main. That will then cause
+    // everything else (standard library, future stages...) to be rebuilt.
+    t!(filetime::set_file_mtime(path, previous_mtime));
+}
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index da60166b84d..830c1a3b846 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -20,6 +20,7 @@ use std::str::FromStr;
 use crate::cache::{Interned, INTERNER};
 use crate::cc_detect::{ndk_compiler, Language};
 use crate::channel::{self, GitInfo};
+use crate::compile::CODEGEN_BACKEND_PREFIX;
 pub use crate::flags::Subcommand;
 use crate::flags::{Color, Flags, Warnings};
 use crate::util::{exe, output, t};
@@ -130,7 +131,7 @@ pub struct Config {
     pub sanitizers: bool,
     pub profiler: bool,
     pub omit_git_hash: bool,
-    pub exclude: Vec<PathBuf>,
+    pub skip: Vec<PathBuf>,
     pub include_default_paths: bool,
     pub rustc_error_format: Option<String>,
     pub json_output: bool,
@@ -1112,7 +1113,7 @@ impl Config {
 
         // Set flags.
         config.paths = std::mem::take(&mut flags.paths);
-        config.exclude = flags.exclude;
+        config.skip = flags.skip.into_iter().chain(flags.exclude).collect();
         config.include_default_paths = flags.include_default_paths;
         config.rustc_error_format = flags.rustc_error_format;
         config.json_output = flags.json_output;
@@ -1443,8 +1444,21 @@ impl Config {
                 .map(|v| v.parse().expect("failed to parse rust.llvm-libunwind"));
 
             if let Some(ref backends) = rust.codegen_backends {
-                config.rust_codegen_backends =
-                    backends.iter().map(|s| INTERNER.intern_str(s)).collect();
+                let available_backends = vec!["llvm", "cranelift", "gcc"];
+
+                config.rust_codegen_backends = backends.iter().map(|s| {
+                    if let Some(backend) = s.strip_prefix(CODEGEN_BACKEND_PREFIX) {
+                        if available_backends.contains(&backend) {
+                            panic!("Invalid value '{s}' for 'rust.codegen-backends'. Instead, please use '{backend}'.");
+                        } else {
+                            println!("help: '{s}' for 'rust.codegen-backends' might fail. \
+                                Codegen backends are mostly defined without the '{CODEGEN_BACKEND_PREFIX}' prefix. \
+                                In this case, it would be referred to as '{backend}'.");
+                        }
+                    }
+
+                    INTERNER.intern_str(s)
+                }).collect();
             }
 
             config.rust_codegen_units = rust.codegen_units.map(threads_from_config);
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 9cb3546ba0a..505f06ed12d 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -570,7 +570,7 @@ fn doc_std(
     if builder.no_std(target) == Some(true) {
         panic!(
             "building std documentation for no_std target {target} is not supported\n\
-             Set `docs = false` in the config to disable documentation, or pass `--exclude doc::library`."
+             Set `docs = false` in the config to disable documentation, or pass `--skip library`."
         );
     }
 
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index a1e0a440729..e0291e407b3 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -68,7 +68,10 @@ pub struct Flags {
 
     #[arg(global(true), long, value_name = "PATH")]
     /// build paths to exclude
-    pub exclude: Vec<PathBuf>,
+    pub exclude: Vec<PathBuf>, // keeping for client backward compatibility
+    #[arg(global(true), long, value_name = "PATH")]
+    /// build paths to skip
+    pub skip: Vec<PathBuf>,
     #[arg(global(true), long)]
     /// include default paths in addition to the provided ones
     pub include_default_paths: bool,
@@ -318,7 +321,7 @@ pub enum Subcommand {
         no_fail_fast: bool,
         #[arg(long, value_name = "SUBSTRING")]
         /// skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times
-        skip: Vec<String>,
+        skip: Vec<PathBuf>,
         #[arg(long, value_name = "ARGS", allow_hyphen_values(true))]
         /// extra arguments to be passed for the test tool being used
         /// (e.g. libtest, compiletest or rustdoc)
@@ -336,6 +339,10 @@ pub enum Subcommand {
         /// whether to automatically update stderr/stdout files
         bless: bool,
         #[arg(long)]
+        /// comma-separated list of other files types to check (accepts py, py:lint,
+        /// py:fmt, shell)
+        extra_checks: Option<String>,
+        #[arg(long)]
         /// rerun tests even if the inputs are unchanged
         force_rerun: bool,
         #[arg(long)]
@@ -473,6 +480,13 @@ impl Subcommand {
         }
     }
 
+    pub fn extra_checks(&self) -> Option<&str> {
+        match *self {
+            Subcommand::Test { ref extra_checks, .. } => extra_checks.as_ref().map(String::as_str),
+            _ => None,
+        }
+    }
+
     pub fn only_modified(&self) -> bool {
         match *self {
             Subcommand::Test { only_modified, .. } => only_modified,
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 8c674d075b8..e3a9434a164 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -133,7 +133,7 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
     // #[cfg(bootstrap)]
     (Some(Mode::Std), "target_vendor", Some(&["unikraft"])),
     (Some(Mode::Std), "target_env", Some(&["libnx"])),
-    // (Some(Mode::Std), "target_os", Some(&[])),
+    (Some(Mode::Std), "target_os", Some(&["teeos"])),
     // #[cfg(bootstrap)] mips32r6, mips64r6
     (
         Some(Mode::Std),
diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs
index 14ee5659ed5..4943f93fa9a 100644
--- a/src/bootstrap/llvm.rs
+++ b/src/bootstrap/llvm.rs
@@ -512,27 +512,21 @@ impl Step for Llvm {
         // When building LLVM as a shared library on linux, it can contain unexpected debuginfo:
         // some can come from the C++ standard library. Unless we're explicitly requesting LLVM to
         // be built with debuginfo, strip it away after the fact, to make dist artifacts smaller.
-        // FIXME: to make things simpler for now, limit this to the host and target where we know
-        // `strip -g` is both available and will fix the issue, i.e. on a x64 linux host that is not
-        // cross-compiling. Expand this to other appropriate targets in the future.
         if builder.llvm_link_shared()
             && builder.config.llvm_optimize
             && !builder.config.llvm_release_debuginfo
-            && target == "x86_64-unknown-linux-gnu"
-            && target == builder.config.build
         {
             // Find the name of the LLVM shared library that we just built.
             let lib_name = find_llvm_lib_name("so");
 
             // If the shared library exists in LLVM's `/build/lib/` or `/lib/` folders, strip its
-            // debuginfo. Note: `output` will propagate any errors here.
-            let strip_if_possible = |path: PathBuf| {
-                if path.exists() {
-                    output(Command::new("strip").arg("--strip-debug").arg(path));
-                }
-            };
-            strip_if_possible(out_dir.join("lib").join(&lib_name));
-            strip_if_possible(out_dir.join("build").join("lib").join(&lib_name));
+            // debuginfo.
+            crate::compile::strip_debug(builder, target, &out_dir.join("lib").join(&lib_name));
+            crate::compile::strip_debug(
+                builder,
+                target,
+                &out_dir.join("build").join("lib").join(&lib_name),
+            );
         }
 
         t!(stamp.write());
diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index 9476137968b..a9865e262fe 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -63,7 +63,7 @@ prepare:
 ci-msvc-py:
 	$(Q)$(CFG_SRC_DIR)/x.py test --stage 2 tidy
 ci-msvc-ps1:
-	$(Q)$(CFG_SRC_DIR)/x.ps1 test --stage 2 --exclude tidy
+	$(Q)$(CFG_SRC_DIR)/x.ps1 test --stage 2 --skip tidy
 ci-msvc: ci-msvc-py ci-msvc-ps1
 
 ## MingW native builders
@@ -72,7 +72,7 @@ ci-msvc: ci-msvc-py ci-msvc-ps1
 ci-mingw-x:
 	$(Q)$(CFG_SRC_DIR)/x test --stage 2 tidy
 ci-mingw-bootstrap:
-	$(Q)$(BOOTSTRAP) test --stage 2 --exclude tidy
+	$(Q)$(BOOTSTRAP) test --stage 2 --skip tidy
 ci-mingw: ci-mingw-x ci-mingw-bootstrap
 
 .PHONY: dist
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 4bfb16928f1..d0d62db0807 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -4,6 +4,7 @@
 //! our CI.
 
 use std::env;
+use std::ffi::OsStr;
 use std::ffi::OsString;
 use std::fs;
 use std::iter;
@@ -122,7 +123,7 @@ impl Step for Linkcheck {
         if (hosts != targets) && !hosts.is_empty() && !targets.is_empty() {
             panic!(
                 "Linkcheck currently does not support builds with different hosts and targets.
-You can skip linkcheck with --exclude src/tools/linkchecker"
+You can skip linkcheck with --skip src/tools/linkchecker"
             );
         }
 
@@ -1094,6 +1095,14 @@ impl Step for Tidy {
         if builder.config.cmd.bless() {
             cmd.arg("--bless");
         }
+        if let Some(s) = builder.config.cmd.extra_checks() {
+            cmd.arg(format!("--extra-checks={s}"));
+        }
+        let mut args = std::env::args_os();
+        if let Some(_) = args.find(|arg| arg == OsStr::new("--")) {
+            cmd.arg("--");
+            cmd.args(args);
+        }
 
         if builder.config.channel == "dev" || builder.config.channel == "nightly" {
             builder.info("fmt check");
@@ -1104,7 +1113,7 @@ impl Step for Tidy {
 error: no `rustfmt` binary found in {PATH}
 info: `rust.channel` is currently set to \"{CHAN}\"
 help: if you are testing a beta branch, set `rust.channel` to \"beta\" in the `config.toml` file
-help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy` to `x.py test`",
+help: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to `x.py test`",
                     PATH = inferred_rustfmt_dir.display(),
                     CHAN = builder.config.channel,
                 );
@@ -1650,7 +1659,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the
             cmd.arg("--run-clang-based-tests-with").arg(clang_exe);
         }
 
-        for exclude in &builder.config.exclude {
+        for exclude in &builder.config.skip {
             cmd.arg("--skip");
             cmd.arg(&exclude);
         }