diff options
Diffstat (limited to 'src/bootstrap')
| -rw-r--r-- | src/bootstrap/bootstrap.py | 4 | ||||
| -rw-r--r-- | src/bootstrap/bootstrap_test.py | 19 | ||||
| -rw-r--r-- | src/bootstrap/builder.rs | 10 | ||||
| -rw-r--r-- | src/bootstrap/builder/tests.rs | 6 | ||||
| -rw-r--r-- | src/bootstrap/compile.rs | 39 | ||||
| -rw-r--r-- | src/bootstrap/config.rs | 22 | ||||
| -rw-r--r-- | src/bootstrap/doc.rs | 2 | ||||
| -rw-r--r-- | src/bootstrap/flags.rs | 18 | ||||
| -rw-r--r-- | src/bootstrap/lib.rs | 2 | ||||
| -rw-r--r-- | src/bootstrap/llvm.rs | 20 | ||||
| -rw-r--r-- | src/bootstrap/mk/Makefile.in | 4 | ||||
| -rw-r--r-- | src/bootstrap/test.rs | 15 |
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); } |
