diff options
Diffstat (limited to '')
-rw-r--r-- | src/bootstrap/Cargo.lock | 1 | ||||
-rw-r--r-- | src/bootstrap/Cargo.toml | 2 | ||||
-rw-r--r-- | src/bootstrap/bin/rustc.rs | 21 | ||||
-rw-r--r-- | src/bootstrap/bin/rustdoc.rs | 11 | ||||
-rw-r--r-- | src/bootstrap/bootstrap.py | 2 | ||||
-rw-r--r-- | src/bootstrap/builder.rs | 44 | ||||
-rw-r--r-- | src/bootstrap/builder/tests.rs | 2 | ||||
-rw-r--r-- | src/bootstrap/check.rs | 2 | ||||
-rw-r--r-- | src/bootstrap/compile.rs | 11 | ||||
-rw-r--r-- | src/bootstrap/config.rs | 72 | ||||
-rw-r--r-- | src/bootstrap/dist.rs | 59 | ||||
-rw-r--r-- | src/bootstrap/doc.rs | 2 | ||||
-rw-r--r-- | src/bootstrap/flags.rs | 15 | ||||
-rw-r--r-- | src/bootstrap/install.rs | 9 | ||||
-rw-r--r-- | src/bootstrap/lib.rs | 33 | ||||
-rw-r--r-- | src/bootstrap/mk/Makefile.in | 11 | ||||
-rw-r--r-- | src/bootstrap/native.rs | 107 | ||||
-rw-r--r-- | src/bootstrap/run.rs | 22 | ||||
-rw-r--r-- | src/bootstrap/setup.rs | 2 | ||||
-rw-r--r-- | src/bootstrap/tarball.rs | 8 | ||||
-rw-r--r-- | src/bootstrap/test.rs | 119 | ||||
-rw-r--r-- | src/bootstrap/tool.rs | 28 | ||||
-rw-r--r-- | src/bootstrap/toolstate.rs | 1 | ||||
-rw-r--r-- | src/bootstrap/util.rs | 14 |
24 files changed, 328 insertions, 270 deletions
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 664ffa1dd..84c06fdce 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -53,7 +53,6 @@ dependencies = [ "hex", "ignore", "libc", - "num_cpus", "once_cell", "opener", "pretty_assertions", diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 84f6aaf99..95e711737 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -38,7 +38,6 @@ test = false cmake = "0.1.38" fd-lock = "3.0.6" filetime = "0.2" -num_cpus = "1.0" getopts = "0.2.19" cc = "1.0.69" libc = "0.2" @@ -68,6 +67,7 @@ features = [ "psapi", "impl-default", "timezoneapi", + "winbase", ] [dev-dependencies] diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index 40a3cc6d1..e96f8b0d3 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -25,10 +25,11 @@ use std::time::Instant; fn main() { let args = env::args_os().skip(1).collect::<Vec<_>>(); + let arg = |name| args.windows(2).find(|args| args[0] == name).and_then(|args| args[1].to_str()); // Detect whether or not we're a build script depending on whether --target // is passed (a bit janky...) - let target = args.windows(2).find(|w| &*w[0] == "--target").and_then(|w| w[1].to_str()); + let target = arg("--target"); let version = args.iter().find(|w| &**w == "-vV"); let verbose = match env::var("RUSTC_VERBOSE") { @@ -59,8 +60,7 @@ fn main() { cmd.args(&args).env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); // Get the name of the crate we're compiling, if any. - let crate_name = - args.windows(2).find(|args| args[0] == "--crate-name").and_then(|args| args[1].to_str()); + let crate_name = arg("--crate-name"); if let Some(crate_name) = crate_name { if let Some(target) = env::var_os("RUSTC_TIME") { @@ -106,6 +106,15 @@ fn main() { { cmd.arg("-C").arg("panic=abort"); } + + // `-Ztls-model=initial-exec` must not be applied to proc-macros, see + // issue https://github.com/rust-lang/rust/issues/100530 + if env::var("RUSTC_TLS_MODEL_INITIAL_EXEC").is_ok() + && arg("--crate-type") != Some("proc-macro") + && !matches!(crate_name, Some("proc_macro2" | "quote" | "syn" | "synstructure")) + { + cmd.arg("-Ztls-model=initial-exec"); + } } else { // FIXME(rust-lang/cargo#5754) we shouldn't be using special env vars // here, but rather Cargo should know what flags to pass rustc itself. @@ -130,10 +139,8 @@ fn main() { // Cargo doesn't pass RUSTFLAGS to proc_macros: // https://github.com/rust-lang/cargo/issues/4423 // Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`. - // We also declare that the flag is expected, which is mainly needed for - // later stages so that they don't warn about #[cfg(bootstrap)], - // but enabling it for stage 0 too lets any warnings, if they occur, - // occur more early on, e.g. about #[cfg(bootstrap = "foo")]. + // We also declare that the flag is expected, which we need to do to not + // get warnings about it being unexpected. if stage == "0" { cmd.arg("--cfg=bootstrap"); } diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index 87c1d22e7..e69cab956 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -11,6 +11,7 @@ include!("../dylib_util.rs"); fn main() { let args = env::args_os().skip(1).collect::<Vec<_>>(); + let stage = env::var("RUSTC_STAGE").expect("RUSTC_STAGE was not set"); let rustdoc = env::var_os("RUSTDOC_REAL").expect("RUSTDOC_REAL was not set"); let libdir = env::var_os("RUSTDOC_LIBDIR").expect("RUSTDOC_LIBDIR was not set"); let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set"); @@ -62,6 +63,16 @@ fn main() { cmd.arg("-Clink-arg=-Wl,--threads=1"); } } + // Cargo doesn't pass RUSTDOCFLAGS to proc_macros: + // https://github.com/rust-lang/cargo/issues/4423 + // Thus, if we are on stage 0, we explicitly set `--cfg=bootstrap`. + // We also declare that the flag is expected, which we need to do to not + // get warnings about it being unexpected. + if stage == "0" { + cmd.arg("--cfg=bootstrap"); + } + cmd.arg("-Zunstable-options"); + cmd.arg("--check-cfg=values(bootstrap)"); if verbose > 1 { eprintln!( diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 03eec02a8..cc08ae5f9 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -85,7 +85,7 @@ def _download(path, url, probably_big, verbose, exception): option = "-#" else: option = "-s" - # If curl is not present on Win32, we shoud not sys.exit + # If curl is not present on Win32, we should not sys.exit # but raise `CalledProcessError` or `OSError` instead require(["curl", "--version"], exception=platform_is_win32) run(["curl", option, diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 0ab4824ac..14e8ebd68 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -647,9 +647,9 @@ impl<'a> Builder<'a> { test::CrateRustdocJsonTypes, test::Linkcheck, test::TierCheck, + test::ReplacePlaceholderTest, test::Cargotest, test::Cargo, - test::Rls, test::RustAnalyzer, test::ErrorIndex, test::Distcheck, @@ -736,7 +736,6 @@ impl<'a> Builder<'a> { install::Docs, install::Std, install::Cargo, - install::Rls, install::RustAnalyzer, install::Rustfmt, install::RustDemangler, @@ -746,7 +745,12 @@ impl<'a> Builder<'a> { install::Src, install::Rustc ), - Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest, run::BumpStage0), + Kind::Run => describe!( + run::ExpandYamlAnchors, + run::BuildManifest, + run::BumpStage0, + run::ReplaceVersionPlaceholder, + ), // These commands either don't use paths, or they're special-cased in Build::build() Kind::Clean | Kind::Format | Kind::Setup => vec![], } @@ -942,7 +946,7 @@ impl<'a> Builder<'a> { }; patchelf.args(&[OsString::from("--set-rpath"), rpath_entries]); if !fname.extension().map_or(false, |ext| ext == "so") { - // Finally, set the corret .interp for binaries + // Finally, set the correct .interp for binaries let dynamic_linker_path = nix_deps_dir.join("nix-support/dynamic-linker"); // FIXME: can we support utf8 here? `args` doesn't accept Vec<u8>, only OsString ... let dynamic_linker = t!(String::from_utf8(t!(fs::read(dynamic_linker_path)))); @@ -958,7 +962,7 @@ impl<'a> Builder<'a> { let tempfile = self.tempdir().join(dest_path.file_name().unwrap()); // While bootstrap itself only supports http and https downloads, downstream forks might // need to download components from other protocols. The match allows them adding more - // protocols without worrying about merge conficts if we change the HTTP implementation. + // protocols without worrying about merge conflicts if we change the HTTP implementation. match url.split_once("://").map(|(proto, _)| proto) { Some("http") | Some("https") => { self.download_http_with_retries(&tempfile, url, help_on_error) @@ -1759,23 +1763,21 @@ impl<'a> Builder<'a> { }, ); - if !target.contains("windows") { - let needs_unstable_opts = target.contains("linux") - || target.contains("solaris") - || target.contains("windows") - || target.contains("bsd") - || target.contains("dragonfly") - || target.contains("illumos"); + let split_debuginfo_is_stable = target.contains("linux") + || target.contains("apple") + || (target.contains("msvc") + && self.config.rust_split_debuginfo == SplitDebuginfo::Packed) + || (target.contains("windows") + && self.config.rust_split_debuginfo == SplitDebuginfo::Off); - if needs_unstable_opts { - rustflags.arg("-Zunstable-options"); - } - match self.config.rust_split_debuginfo { - SplitDebuginfo::Packed => rustflags.arg("-Csplit-debuginfo=packed"), - SplitDebuginfo::Unpacked => rustflags.arg("-Csplit-debuginfo=unpacked"), - SplitDebuginfo::Off => rustflags.arg("-Csplit-debuginfo=off"), - }; + if !split_debuginfo_is_stable { + rustflags.arg("-Zunstable-options"); } + match self.config.rust_split_debuginfo { + SplitDebuginfo::Packed => rustflags.arg("-Csplit-debuginfo=packed"), + SplitDebuginfo::Unpacked => rustflags.arg("-Csplit-debuginfo=unpacked"), + SplitDebuginfo::Off => rustflags.arg("-Csplit-debuginfo=off"), + }; if self.config.cmd.bless() { // Bless `expect!` tests. @@ -1850,7 +1852,7 @@ impl<'a> Builder<'a> { // so we can't use it by default in general, but we can use it for tools // and our own internal libraries. if !mode.must_support_dlopen() && !target.triple.starts_with("powerpc-") { - rustflags.arg("-Ztls-model=initial-exec"); + cargo.env("RUSTC_TLS_MODEL_INITIAL_EXEC", "1"); } if self.config.incremental { diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index c084e77d3..280eba75f 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -547,7 +547,6 @@ mod dist { config.stage = 0; config.cmd = Subcommand::Test { paths: vec!["library/std".into()], - skip: vec![], test_args: vec![], rustc_args: vec![], fail_fast: true, @@ -618,7 +617,6 @@ mod dist { let mut config = configure(&["A"], &["A"]); config.cmd = Subcommand::Test { paths: vec![], - skip: vec![], test_args: vec![], rustc_args: vec![], fail_fast: true, diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 4e1e8ef9d..5c085bedf 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -457,7 +457,7 @@ tool_check_step!(Rustdoc, "src/tools/rustdoc", "src/librustdoc", SourceType::InT // rejected. tool_check_step!(Clippy, "src/tools/clippy", SourceType::InTree); tool_check_step!(Miri, "src/tools/miri", SourceType::Submodule); -tool_check_step!(Rls, "src/tools/rls", SourceType::Submodule); +tool_check_step!(Rls, "src/tools/rls", SourceType::InTree); tool_check_step!(Rustfmt, "src/tools/rustfmt", SourceType::InTree); tool_check_step!(Bootstrap, "src/bootstrap", SourceType::InTree, false); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index dd2b9d593..c13e83f6c 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -658,7 +658,12 @@ impl Step for Rustc { // With LLD, we can use ICF (identical code folding) to reduce the executable size // of librustc_driver/rustc and to improve i-cache utilization. - if builder.config.use_lld { + // + // -Wl,[link options] doesn't work on MSVC. However, /OPT:ICF (technically /OPT:REF,ICF) + // is already on by default in MSVC optimized builds, which is interpreted as --icf=all: + // https://github.com/llvm/llvm-project/blob/3329cec2f79185bafd678f310fafadba2a8c76d2/lld/COFF/Driver.cpp#L1746 + // https://github.com/rust-lang/rust/blob/f22819bcce4abaff7d1246a56eec493418f9f4ee/compiler/rustc_codegen_ssa/src/back/linker.rs#L827 + if builder.config.use_lld && !compiler.host.contains("msvc") { cargo.rustflag("-Clink-args=-Wl,--icf=all"); } @@ -1276,7 +1281,9 @@ impl Step for Assemble { compiler: build_compiler, target: target_compiler.host, }); - builder.copy(&lld_wrapper_exe, &gcc_ld_dir.join(exe("ld", target_compiler.host))); + for name in crate::LLD_FILE_NAMES { + builder.copy(&lld_wrapper_exe, &gcc_ld_dir.join(exe(name, target_compiler.host))); + } } if builder.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) { diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 4325a237c..f1a150e0f 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -388,6 +388,7 @@ impl PartialEq<&str> for TargetSelection { pub struct Target { /// Some(path to llvm-config) if using an external LLVM. pub llvm_config: Option<PathBuf>, + pub llvm_has_rust_patches: Option<bool>, /// Some(path to FileCheck) if one was specified. pub llvm_filecheck: Option<PathBuf>, pub llvm_libunwind: Option<LlvmLibunwind>, @@ -733,6 +734,7 @@ define_config! { default_linker: Option<PathBuf> = "default-linker", linker: Option<String> = "linker", llvm_config: Option<String> = "llvm-config", + llvm_has_rust_patches: Option<bool> = "llvm-has-rust-patches", llvm_filecheck: Option<String> = "llvm-filecheck", llvm_libunwind: Option<String> = "llvm-libunwind", android_ndk: Option<String> = "android-ndk", @@ -990,42 +992,7 @@ impl Config { config.llvm_from_ci = match llvm.download_ci_llvm { Some(StringOrBool::String(s)) => { assert!(s == "if-available", "unknown option `{}` for download-ci-llvm", s); - // This is currently all tier 1 targets and tier 2 targets with host tools - // (since others may not have CI artifacts) - // https://doc.rust-lang.org/rustc/platform-support.html#tier-1 - // FIXME: this is duplicated in bootstrap.py - let supported_platforms = [ - // tier 1 - "aarch64-unknown-linux-gnu", - "i686-pc-windows-gnu", - "i686-pc-windows-msvc", - "i686-unknown-linux-gnu", - "x86_64-unknown-linux-gnu", - "x86_64-apple-darwin", - "x86_64-pc-windows-gnu", - "x86_64-pc-windows-msvc", - // tier 2 with host tools - "aarch64-apple-darwin", - "aarch64-pc-windows-msvc", - "aarch64-unknown-linux-musl", - "arm-unknown-linux-gnueabi", - "arm-unknown-linux-gnueabihf", - "armv7-unknown-linux-gnueabihf", - "mips-unknown-linux-gnu", - "mips64-unknown-linux-gnuabi64", - "mips64el-unknown-linux-gnuabi64", - "mipsel-unknown-linux-gnu", - "powerpc-unknown-linux-gnu", - "powerpc64-unknown-linux-gnu", - "powerpc64le-unknown-linux-gnu", - "riscv64gc-unknown-linux-gnu", - "s390x-unknown-linux-gnu", - "x86_64-unknown-freebsd", - "x86_64-unknown-illumos", - "x86_64-unknown-linux-musl", - "x86_64-unknown-netbsd", - ]; - supported_platforms.contains(&&*config.build.triple) + crate::native::is_ci_llvm_available(&config, llvm_assertions.unwrap_or(false)) } Some(StringOrBool::Bool(b)) => b, None => false, @@ -1144,6 +1111,7 @@ impl Config { if let Some(ref s) = cfg.llvm_config { target.llvm_config = Some(config.src.join(s)); } + target.llvm_has_rust_patches = cfg.llvm_has_rust_patches; if let Some(ref s) = cfg.llvm_filecheck { target.llvm_filecheck = Some(config.src.join(s)); } @@ -1176,6 +1144,7 @@ impl Config { if config.llvm_from_ci { let triple = &config.build.triple; + let ci_llvm_bin = config.ci_llvm_root().join("bin"); let mut build_target = config .target_config .entry(config.build) @@ -1183,7 +1152,6 @@ impl Config { check_ci_llvm!(build_target.llvm_config); check_ci_llvm!(build_target.llvm_filecheck); - let ci_llvm_bin = config.out.join(&*config.build.triple).join("ci-llvm/bin"); build_target.llvm_config = Some(ci_llvm_bin.join(exe("llvm-config", config.build))); build_target.llvm_filecheck = Some(ci_llvm_bin.join(exe("FileCheck", config.build))); } @@ -1312,11 +1280,21 @@ impl Config { git } - pub(crate) fn artifact_channel(&self, commit: &str) -> String { + pub(crate) fn artifact_version_part(&self, commit: &str) -> String { let mut channel = self.git(); channel.arg("show").arg(format!("{}:src/ci/channel", commit)); let channel = output(&mut channel); - channel.trim().to_owned() + + let mut version = self.git(); + version.arg("show").arg(format!("{}:src/version", commit)); + let version = output(&mut version); + + match channel.trim() { + "stable" => version.trim().to_owned(), + "beta" => channel.trim().to_owned(), + "nightly" => channel.trim().to_owned(), + other => unreachable!("{:?} is not recognized as a valid channel", other), + } } /// Try to find the relative path of `bindir`, otherwise return it in full. @@ -1445,7 +1423,11 @@ impl Config { .get(&target) .and_then(|t| t.llvm_libunwind) .or(self.llvm_libunwind_default) - .unwrap_or(LlvmLibunwind::No) + .unwrap_or(if target.contains("fuchsia") { + LlvmLibunwind::InTree + } else { + LlvmLibunwind::No + }) } pub fn submodules(&self, rust_info: &GitInfo) -> bool { @@ -1461,7 +1443,7 @@ fn set<T>(field: &mut T, val: Option<T>) { fn threads_from_config(v: u32) -> u32 { match v { - 0 => num_cpus::get() as u32, + 0 => std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32, n => n, } } @@ -1554,7 +1536,7 @@ fn maybe_download_rustfmt(builder: &Builder<'_>) -> Option<PathBuf> { fn download_ci_rustc(builder: &Builder<'_>, commit: &str) { builder.verbose(&format!("using downloaded stage2 artifacts from CI (commit {commit})")); - let channel = builder.config.artifact_channel(commit); + let version = builder.config.artifact_version_part(commit); let host = builder.config.build.triple; let bin_root = builder.out.join(host).join("ci-rustc"); let rustc_stamp = bin_root.join(".rustc-stamp"); @@ -1563,13 +1545,13 @@ fn download_ci_rustc(builder: &Builder<'_>, commit: &str) { if bin_root.exists() { t!(fs::remove_dir_all(&bin_root)); } - let filename = format!("rust-std-{channel}-{host}.tar.xz"); + let filename = format!("rust-std-{version}-{host}.tar.xz"); let pattern = format!("rust-std-{host}"); download_ci_component(builder, filename, &pattern, commit); - let filename = format!("rustc-{channel}-{host}.tar.xz"); + let filename = format!("rustc-{version}-{host}.tar.xz"); download_ci_component(builder, filename, "rustc", commit); // download-rustc doesn't need its own cargo, it can just use beta's. - let filename = format!("rustc-dev-{channel}-{host}.tar.xz"); + let filename = format!("rustc-dev-{version}-{host}.tar.xz"); download_ci_component(builder, filename, "rustc-dev", commit); builder.fix_bin_or_dylib(&bin_root.join("bin").join("rustc")); diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 6291b204e..1a59b3958 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -423,8 +423,11 @@ impl Step for Rustc { let gcc_lld_src_dir = src_dir.join("gcc-ld"); let gcc_lld_dst_dir = dst_dir.join("gcc-ld"); t!(fs::create_dir(&gcc_lld_dst_dir)); - let exe_name = exe("ld", compiler.host); - builder.copy(&gcc_lld_src_dir.join(&exe_name), &gcc_lld_dst_dir.join(&exe_name)); + for name in crate::LLD_FILE_NAMES { + let exe_name = exe(name, compiler.host); + builder + .copy(&gcc_lld_src_dir.join(&exe_name), &gcc_lld_dst_dir.join(&exe_name)); + } } // Man pages @@ -1018,10 +1021,7 @@ impl Step for Rls { let rls = builder .ensure(tool::Rls { compiler, target, extra_features: Vec::new() }) - .or_else(|| { - missing_tool("RLS", builder.build.config.missing_tools); - None - })?; + .expect("rls expected to build"); let mut tarball = Tarball::new(builder, "rls", &target.triple); tarball.set_overlay(OverlayKind::RLS); @@ -1226,17 +1226,10 @@ impl Step for Rustfmt { let rustfmt = builder .ensure(tool::Rustfmt { compiler, target, extra_features: Vec::new() }) - .or_else(|| { - missing_tool("Rustfmt", builder.build.config.missing_tools); - None - })?; + .expect("rustfmt expected to build - essential tool"); let cargofmt = builder .ensure(tool::Cargofmt { compiler, target, extra_features: Vec::new() }) - .or_else(|| { - missing_tool("Cargofmt", builder.build.config.missing_tools); - None - })?; - + .expect("cargo fmt expected to build - essential tool"); let mut tarball = Tarball::new(builder, "rustfmt", &target.triple); tarball.set_overlay(OverlayKind::Rustfmt); tarball.is_preview(true); @@ -1419,7 +1412,7 @@ impl Step for Extended { let xform = |p: &Path| { let mut contents = t!(fs::read_to_string(p)); - for tool in &["rust-demangler", "rls", "rust-analyzer", "miri", "rustfmt"] { + for tool in &["rust-demangler", "rust-analyzer", "miri", "rustfmt"] { if !built_tools.contains(tool) { contents = filter(&contents, tool); } @@ -1459,7 +1452,7 @@ impl Step for Extended { prepare("rust-std"); prepare("rust-analysis"); prepare("clippy"); - for tool in &["rust-docs", "rust-demangler", "rls", "rust-analyzer", "miri"] { + for tool in &["rust-docs", "rust-demangler", "rust-analyzer", "miri"] { if built_tools.contains(tool) { prepare(tool); } @@ -1495,8 +1488,6 @@ impl Step for Extended { builder.create_dir(&exe.join(name)); let dir = if name == "rust-std" || name == "rust-analysis" { format!("{}-{}", name, target.triple) - } else if name == "rls" { - "rls-preview".to_string() } else if name == "rust-analyzer" { "rust-analyzer-preview".to_string() } else if name == "clippy" { @@ -1520,7 +1511,7 @@ impl Step for Extended { prepare("rust-docs"); prepare("rust-std"); prepare("clippy"); - for tool in &["rust-demangler", "rls", "rust-analyzer", "miri"] { + for tool in &["rust-demangler", "rust-analyzer", "miri"] { if built_tools.contains(tool) { prepare(tool); } @@ -1604,25 +1595,6 @@ impl Step for Extended { .arg("-out") .arg(exe.join("StdGroup.wxs")), ); - if built_tools.contains("rls") { - builder.run( - Command::new(&heat) - .current_dir(&exe) - .arg("dir") - .arg("rls") - .args(&heat_flags) - .arg("-cg") - .arg("RlsGroup") - .arg("-dr") - .arg("Rls") - .arg("-var") - .arg("var.RlsDir") - .arg("-out") - .arg(exe.join("RlsGroup.wxs")) - .arg("-t") - .arg(etc.join("msi/remove-duplicates.xsl")), - ); - } if built_tools.contains("rust-analyzer") { builder.run( Command::new(&heat) @@ -1754,9 +1726,6 @@ impl Step for Extended { if built_tools.contains("rust-demangler") { cmd.arg("-dRustDemanglerDir=rust-demangler"); } - if built_tools.contains("rls") { - cmd.arg("-dRlsDir=rls"); - } if built_tools.contains("rust-analyzer") { cmd.arg("-dRustAnalyzerDir=rust-analyzer"); } @@ -1779,9 +1748,6 @@ impl Step for Extended { if built_tools.contains("rust-demangler") { candle("RustDemanglerGroup.wxs".as_ref()); } - if built_tools.contains("rls") { - candle("RlsGroup.wxs".as_ref()); - } if built_tools.contains("rust-analyzer") { candle("RustAnalyzerGroup.wxs".as_ref()); } @@ -1819,9 +1785,6 @@ impl Step for Extended { .arg("ClippyGroup.wixobj") .current_dir(&exe); - if built_tools.contains("rls") { - cmd.arg("RlsGroup.wixobj"); - } if built_tools.contains("rust-analyzer") { cmd.arg("RustAnalyzerGroup.wixobj"); } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 2852442d0..f909ecc0a 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -793,7 +793,7 @@ impl Step for ErrorIndex { t!(fs::create_dir_all(&out)); let mut index = tool::ErrorIndex::command(builder); index.arg("html"); - index.arg(out.join("error-index.html")); + index.arg(out); index.arg(&builder.version); builder.run(&mut index); diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 80b3bcce8..789da7481 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -80,6 +80,7 @@ pub struct Flags { pub llvm_profile_generate: bool, } +#[derive(Debug)] #[cfg_attr(test, derive(Clone))] pub enum Subcommand { Build { @@ -115,7 +116,6 @@ pub enum Subcommand { compare_mode: Option<String>, pass: Option<String>, run: Option<String>, - skip: Vec<String>, test_args: Vec<String>, rustc_args: Vec<String>, fail_fast: bool, @@ -220,7 +220,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`", let j_msg = format!( "number of jobs to run in parallel; \ defaults to {} (this host's logical CPU count)", - num_cpus::get() + std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) ); opts.optopt("j", "jobs", &j_msg, "JOBS"); opts.optflag("h", "help", "print this help message"); @@ -568,7 +568,6 @@ Arguments: compare_mode: matches.opt_str("compare-mode"), pass: matches.opt_str("pass"), run: matches.opt_str("run"), - skip: matches.opt_strs("skip"), test_args: matches.opt_strs("test-args"), rustc_args: matches.opt_strs("rustc-args"), fail_fast: !matches.opt_present("no-fail-fast"), @@ -708,16 +707,6 @@ impl Subcommand { let mut args = vec![]; match *self { - Subcommand::Test { ref skip, .. } => { - for s in skip { - args.push("--skip"); - args.push(s.as_str()); - } - } - _ => (), - }; - - match *self { Subcommand::Test { ref test_args, .. } | Subcommand::Bench { ref test_args, .. } => { args.extend(test_args.iter().flat_map(|s| s.split_whitespace())) } diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 6e49f39ff..d34aa15c5 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -182,15 +182,6 @@ install!((self, builder, _config), .expect("missing cargo"); install_sh(builder, "cargo", self.compiler.stage, Some(self.target), &tarball); }; - Rls, alias = "rls", Self::should_build(_config), only_hosts: true, { - if let Some(tarball) = builder.ensure(dist::Rls { compiler: self.compiler, target: self.target }) { - install_sh(builder, "rls", self.compiler.stage, Some(self.target), &tarball); - } else { - builder.info( - &format!("skipping Install RLS stage{} ({})", self.compiler.stage, self.target), - ); - } - }; RustAnalyzer, alias = "rust-analyzer", Self::should_build(_config), only_hosts: true, { if let Some(tarball) = builder.ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target }) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index d265277b4..cc0cf12bd 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -112,6 +112,7 @@ use std::path::{Path, PathBuf}; use std::process::Command; use std::str; +use config::Target; use filetime::FileTime; use once_cell::sync::OnceCell; @@ -186,6 +187,9 @@ const LLVM_TOOLS: &[&str] = &[ "opt", // used to optimize LLVM bytecode ]; +/// LLD file names for all flavors. +const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"]; + pub const VERSION: usize = 2; /// Extra --check-cfg to add when building @@ -273,7 +277,6 @@ pub struct Build { bootstrap_out: PathBuf, rust_info: channel::GitInfo, cargo_info: channel::GitInfo, - rls_info: channel::GitInfo, rust_analyzer_info: channel::GitInfo, clippy_info: channel::GitInfo, miri_info: channel::GitInfo, @@ -412,7 +415,6 @@ impl Build { let ignore_git = config.ignore_git; let rust_info = channel::GitInfo::new(ignore_git, &src); let cargo_info = channel::GitInfo::new(ignore_git, &src.join("src/tools/cargo")); - let rls_info = channel::GitInfo::new(ignore_git, &src.join("src/tools/rls")); let rust_analyzer_info = channel::GitInfo::new(ignore_git, &src.join("src/tools/rust-analyzer")); let clippy_info = channel::GitInfo::new(ignore_git, &src.join("src/tools/clippy")); @@ -490,7 +492,6 @@ impl Build { rust_info, cargo_info, - rls_info, rust_analyzer_info, clippy_info, miri_info, @@ -542,7 +543,6 @@ impl Build { let rust_submodules = [ "src/tools/rust-installer", "src/tools/cargo", - "src/tools/rls", "src/tools/miri", "library/backtrace", "library/stdarch", @@ -843,12 +843,13 @@ impl Build { /// /// If no custom `llvm-config` was specified then Rust's llvm will be used. fn is_rust_llvm(&self, target: TargetSelection) -> bool { - if self.config.llvm_from_ci && target == self.config.build { - return true; - } - match self.config.target_config.get(&target) { - Some(ref c) => c.llvm_config.is_none(), + Some(Target { llvm_has_rust_patches: Some(patched), .. }) => *patched, + Some(Target { llvm_config, .. }) => { + // If the user set llvm-config we assume Rust is not patched, + // but first check to see if it was configured by llvm-from-ci. + (self.config.llvm_from_ci && target == self.config.build) || llvm_config.is_none() + } None => true, } } @@ -1013,7 +1014,9 @@ impl Build { /// Returns the number of parallel jobs that have been configured for this /// build. fn jobs(&self) -> u32 { - self.config.jobs.unwrap_or_else(|| num_cpus::get() as u32) + self.config.jobs.unwrap_or_else(|| { + std::thread::available_parallelism().map_or(1, std::num::NonZeroUsize::get) as u32 + }) } fn debuginfo_map_to(&self, which: GitRepo) -> Option<String> { @@ -1636,14 +1639,12 @@ fn chmod(_path: &Path, _perms: u32) {} /// If code is not 0 (successful exit status), exit status is 101 (rust's default error code.) /// If the test is running and code is an error code, it will cause a panic. fn detail_exit(code: i32) -> ! { - // Successful exit - if code == 0 { - std::process::exit(0); - } - if cfg!(test) { + // if in test and code is an error code, panic with status code provided + if cfg!(test) && code != 0 { panic!("status code: {}", code); } else { - std::panic::resume_unwind(Box::new(code)); + //otherwise,exit with provided status code + std::process::exit(code); } } diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index 5a1f2e704..9a08a7be0 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -66,16 +66,21 @@ TESTS_IN_2 := \ src/test/ui \ src/tools/linkchecker +## MSVC native builders + +# these intentionally don't use `$(BOOTSTRAP)` so we can test the shebang on Windows ci-subset-1: - $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_2:%=--exclude %) + $(Q)$(CFG_SRC_DIR)/x.py test --stage 2 $(TESTS_IN_2:%=--exclude %) ci-subset-2: - $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_2) + $(Q)$(CFG_SRC_DIR)/x.ps1 test --stage 2 $(TESTS_IN_2) + +## MingW native builders TESTS_IN_MINGW_2 := \ src/test/ui ci-mingw-subset-1: - $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_MINGW_2:%=--exclude %) + $(Q)$(CFG_SRC_DIR)/x test --stage 2 $(TESTS_IN_MINGW_2:%=--exclude %) ci-mingw-subset-2: $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_MINGW_2) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 4d548dbb6..fc3bfaf1b 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -114,23 +114,20 @@ pub fn prebuilt_llvm_config( Err(Meta { stamp, build_llvm_config, out_dir, root: root.into() }) } -pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) { - let config = &builder.config; - if !config.llvm_from_ci { - return; - } +/// This retrieves the LLVM sha we *want* to use, according to git history. +pub(crate) fn detect_llvm_sha(config: &crate::config::Config) -> String { let mut rev_list = config.git(); rev_list.args(&[ PathBuf::from("rev-list"), - format!("--author={}", builder.config.stage0_metadata.config.git_merge_commit_email).into(), + format!("--author={}", config.stage0_metadata.config.git_merge_commit_email).into(), "-n1".into(), "--first-parent".into(), "HEAD".into(), "--".into(), - builder.src.join("src/llvm-project"), - builder.src.join("src/bootstrap/download-ci-llvm-stamp"), + config.src.join("src/llvm-project"), + config.src.join("src/bootstrap/download-ci-llvm-stamp"), // the LLVM shared object file is named `LLVM-12-rust-{version}-nightly` - builder.src.join("src/version"), + config.src.join("src/version"), ]); let llvm_sha = output(&mut rev_list); let llvm_sha = llvm_sha.trim(); @@ -143,8 +140,82 @@ pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) { panic!(); } + llvm_sha.to_owned() +} + +/// Returns whether the CI-found LLVM is currently usable. +/// +/// This checks both the build triple platform to confirm we're usable at all, +/// and then verifies if the current HEAD matches the detected LLVM SHA head, +/// in which case LLVM is indicated as not available. +pub(crate) fn is_ci_llvm_available(config: &crate::config::Config, asserts: bool) -> bool { + // This is currently all tier 1 targets and tier 2 targets with host tools + // (since others may not have CI artifacts) + // https://doc.rust-lang.org/rustc/platform-support.html#tier-1 + let supported_platforms = [ + // tier 1 + "aarch64-unknown-linux-gnu", + "i686-pc-windows-gnu", + "i686-pc-windows-msvc", + "i686-unknown-linux-gnu", + "x86_64-unknown-linux-gnu", + "x86_64-apple-darwin", + "x86_64-pc-windows-gnu", + "x86_64-pc-windows-msvc", + // tier 2 with host tools + "aarch64-apple-darwin", + "aarch64-pc-windows-msvc", + "aarch64-unknown-linux-musl", + "arm-unknown-linux-gnueabi", + "arm-unknown-linux-gnueabihf", + "armv7-unknown-linux-gnueabihf", + "mips-unknown-linux-gnu", + "mips64-unknown-linux-gnuabi64", + "mips64el-unknown-linux-gnuabi64", + "mipsel-unknown-linux-gnu", + "powerpc-unknown-linux-gnu", + "powerpc64-unknown-linux-gnu", + "powerpc64le-unknown-linux-gnu", + "riscv64gc-unknown-linux-gnu", + "s390x-unknown-linux-gnu", + "x86_64-unknown-freebsd", + "x86_64-unknown-illumos", + "x86_64-unknown-linux-musl", + "x86_64-unknown-netbsd", + ]; + if !supported_platforms.contains(&&*config.build.triple) { + return false; + } + + let triple = &*config.build.triple; + if (triple == "aarch64-unknown-linux-gnu" || triple.contains("i686")) && asserts { + // No alt builder for aarch64-unknown-linux-gnu today. + return false; + } + + if crate::util::CiEnv::is_ci() { + let llvm_sha = detect_llvm_sha(config); + let head_sha = output(config.git().arg("rev-parse").arg("HEAD")); + let head_sha = head_sha.trim(); + if llvm_sha == head_sha { + eprintln!( + "Detected LLVM as non-available: running in CI and modified LLVM in this change" + ); + return false; + } + } + + true +} + +pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) { + let config = &builder.config; + if !config.llvm_from_ci { + return; + } let llvm_root = config.ci_llvm_root(); let llvm_stamp = llvm_root.join(".llvm-stamp"); + let llvm_sha = detect_llvm_sha(&config); let key = format!("{}{}", llvm_sha, config.llvm_assertions); if program_out_of_date(&llvm_stamp, &key) && !config.dry_run { download_ci_llvm(builder, &llvm_sha); @@ -189,8 +260,8 @@ fn download_ci_llvm(builder: &Builder<'_>, llvm_sha: &str) { } else { &builder.config.stage0_metadata.config.artifacts_server }; - let channel = builder.config.artifact_channel(llvm_sha); - let filename = format!("rust-dev-{}-{}.tar.xz", channel, builder.build.build.triple); + let version = builder.config.artifact_version_part(llvm_sha); + let filename = format!("rust-dev-{}-{}.tar.xz", version, builder.build.build.triple); let tarball = rustc_cache.join(&filename); if !tarball.exists() { let help_on_error = "error: failed to download llvm from ci @@ -325,6 +396,9 @@ impl Step for Llvm { cfg.define("LLVM_PROFDATA_FILE", &path); } + // Disable zstd to avoid a dependency on libzstd.so. + cfg.define("LLVM_ENABLE_ZSTD", "OFF"); + if target != "aarch64-apple-darwin" && !target.contains("windows") { cfg.define("LLVM_ENABLE_ZLIB", "ON"); } else { @@ -358,12 +432,13 @@ impl Step for Llvm { cfg.define("LLVM_LINK_LLVM_DYLIB", "ON"); } - if target.starts_with("riscv") && !target.contains("freebsd") { + if target.starts_with("riscv") && !target.contains("freebsd") && !target.contains("openbsd") + { // RISC-V GCC erroneously requires linking against // `libatomic` when using 1-byte and 2-byte C++ // atomics but the LLVM build system check cannot // detect this. Therefore it is set manually here. - // FreeBSD uses Clang as its system compiler and + // Some BSD uses Clang as its system compiler and // provides no libatomic in its base system so does // not want this. ldflags.exe.push(" -latomic"); @@ -512,11 +587,11 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { let version = output(cmd.arg("--version")); let mut parts = version.split('.').take(2).filter_map(|s| s.parse::<u32>().ok()); if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) { - if major >= 12 { + if major >= 13 { return; } } - panic!("\n\nbad LLVM version: {}, need >=12.0\n\n", version) + panic!("\n\nbad LLVM version: {}, need >=13.0\n\n", version) } fn configure_cmake( @@ -563,7 +638,7 @@ fn configure_cmake( if target.contains("darwin") { // Make sure that CMake does not build universal binaries on macOS. - // Explicitly specifiy the one single target architecture. + // Explicitly specify the one single target architecture. if target.starts_with("aarch64") { // macOS uses a different name for building arm64 cfg.define("CMAKE_OSX_ARCHITECTURES", "arm64"); diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index 25abe7a72..511872903 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -103,3 +103,25 @@ impl Step for BumpStage0 { builder.run(&mut cmd); } } + +#[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] +pub struct ReplaceVersionPlaceholder; + +impl Step for ReplaceVersionPlaceholder { + type Output = (); + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/replace-version-placeholder") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(ReplaceVersionPlaceholder); + } + + fn run(self, builder: &Builder<'_>) -> Self::Output { + let mut cmd = builder.tool_cmd(Tool::ReplaceVersionPlaceholder); + cmd.arg(&builder.src); + builder.run(&mut cmd); + } +} diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index a5a39a5a3..eb7da1bda 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -11,7 +11,7 @@ use std::{ io::{self, Write}, }; -#[derive(Clone, Copy, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Profile { Compiler, Codegen, diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index 7b0c029c1..e30067a5c 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -50,11 +50,7 @@ impl OverlayKind { OverlayKind::RustDemangler => { &["src/tools/rust-demangler/README.md", "LICENSE-APACHE", "LICENSE-MIT"] } - OverlayKind::RLS => &[ - "src/tools/rls/README.md", - "src/tools/rls/LICENSE-APACHE", - "src/tools/rls/LICENSE-MIT", - ], + OverlayKind::RLS => &["src/tools/rls/README.md", "LICENSE-APACHE", "LICENSE-MIT"], OverlayKind::RustAnalyzer => &[ "src/tools/rust-analyzer/README.md", "src/tools/rust-analyzer/LICENSE-APACHE", @@ -78,7 +74,7 @@ impl OverlayKind { OverlayKind::Rustfmt => { builder.rustfmt_info.version(builder, &builder.release_num("rustfmt")) } - OverlayKind::RLS => builder.rls_info.version(builder, &builder.release_num("rls")), + OverlayKind::RLS => builder.release(&builder.release_num("rls")), OverlayKind::RustAnalyzer => builder .rust_analyzer_info .version(builder, &builder.release_num("rust-analyzer/crates/rust-analyzer")), diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index c0fa8c9ac..dd41f8453 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -300,57 +300,6 @@ impl Step for Cargo { } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct Rls { - stage: u32, - host: TargetSelection, -} - -impl Step for Rls { - type Output = (); - const ONLY_HOSTS: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/rls") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rls { stage: run.builder.top_stage, host: run.target }); - } - - /// Runs `cargo test` for the rls. - fn run(self, builder: &Builder<'_>) { - let stage = self.stage; - let host = self.host; - let compiler = builder.compiler(stage, host); - - let build_result = - builder.ensure(tool::Rls { compiler, target: self.host, extra_features: Vec::new() }); - if build_result.is_none() { - eprintln!("failed to test rls: could not build"); - return; - } - - let mut cargo = tool::prepare_tool_cargo( - builder, - compiler, - Mode::ToolRustc, - host, - "test", - "src/tools/rls", - SourceType::Submodule, - &[], - ); - - cargo.add_rustc_lib_path(builder, compiler); - cargo.arg("--").args(builder.config.cmd.test_args()); - - if try_run(builder, &mut cargo.into()) { - builder.save_toolstate("rls", ToolState::TestPass); - } - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct RustAnalyzer { stage: u32, host: TargetSelection, @@ -628,6 +577,10 @@ impl Step for Miri { cargo.env("MIRI_HOST_SYSROOT", sysroot); cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler)); cargo.env("MIRI", miri); + // propagate --bless + if builder.config.cmd.bless() { + cargo.env("MIRI_BLESS", "Gesundheit"); + } cargo.arg("--").args(builder.config.cmd.test_args()); @@ -901,7 +854,10 @@ fn get_browser_ui_test_version_inner(npm: &Path, global: bool) -> Option<String> .output() .map(|output| String::from_utf8_lossy(&output.stdout).into_owned()) .unwrap_or(String::new()); - lines.lines().find_map(|l| l.split(":browser-ui-test@").skip(1).next()).map(|v| v.to_owned()) + lines + .lines() + .find_map(|l| l.split(':').nth(1)?.strip_prefix("browser-ui-test@")) + .map(|v| v.to_owned()) } fn get_browser_ui_test_version(npm: &Path) -> Option<String> { @@ -920,6 +876,11 @@ fn compare_browser_ui_test_version(installed_version: &str, src: &Path) { one used in the CI (`{}`)", installed_version, v ); + eprintln!( + "You can install this version using `npm update browser-ui-test` or by using \ + `npm install browser-ui-test@{}`", + v, + ); } } Err(e) => eprintln!("Couldn't find the CI browser-ui-test version: {:?}", e), @@ -1381,6 +1342,8 @@ note: if you're sure you want to do this, please open an issue as to why. In the let json_compiler = compiler.with_stage(0); cmd.arg("--jsondocck-path") .arg(builder.ensure(tool::JsonDocCk { compiler: json_compiler, target })); + cmd.arg("--jsondoclint-path") + .arg(builder.ensure(tool::JsonDocLint { compiler: json_compiler, target })); } if mode == "run-make" { @@ -1487,6 +1450,11 @@ 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 { + cmd.arg("--skip"); + cmd.arg(&exclude.path); + } + // Get paths from cmd args let paths = match &builder.config.cmd { Subcommand::Test { ref paths, .. } => &paths[..], @@ -1501,7 +1469,15 @@ note: if you're sure you want to do this, please open an issue as to why. In the test_args.append(&mut builder.config.cmd.test_args()); - cmd.args(&test_args); + // On Windows, replace forward slashes in test-args by backslashes + // so the correct filters are passed to libtest + if cfg!(windows) { + let test_args_win: Vec<String> = + test_args.iter().map(|s| s.replace("/", "\\")).collect(); + cmd.args(&test_args_win); + } else { + cmd.args(&test_args); + } if builder.is_verbose() { cmd.arg("--verbose"); @@ -2509,6 +2485,43 @@ impl Step for TierCheck { } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct ReplacePlaceholderTest; + +impl Step for ReplacePlaceholderTest { + type Output = (); + const ONLY_HOSTS: bool = true; + const DEFAULT: bool = true; + + /// Ensure the version placeholder replacement tool builds + fn run(self, builder: &Builder<'_>) { + builder.info("build check for version replacement placeholder"); + + // Test the version placeholder replacement tool itself. + let bootstrap_host = builder.config.build; + let compiler = builder.compiler(0, bootstrap_host); + let cargo = tool::prepare_tool_cargo( + builder, + compiler, + Mode::ToolBootstrap, + bootstrap_host, + "test", + "src/tools/replace-version-placeholder", + SourceType::InTree, + &[], + ); + try_run(builder, &mut cargo.into()); + } + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/replace-version-placeholder") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(Self); + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct LintDocs { pub compiler: Compiler, pub target: TargetSelection, diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 06fa5039f..7d4ed24b6 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -376,8 +376,10 @@ bootstrap_tool!( ExpandYamlAnchors, "src/tools/expand-yaml-anchors", "expand-yaml-anchors"; LintDocs, "src/tools/lint-docs", "lint-docs"; JsonDocCk, "src/tools/jsondocck", "jsondocck"; + JsonDocLint, "src/tools/jsondoclint", "jsondoclint"; HtmlChecker, "src/tools/html-checker", "html-checker"; BumpStage0, "src/tools/bump-stage0", "bump-stage0"; + ReplaceVersionPlaceholder, "src/tools/replace-version-placeholder", "replace-version-placeholder"; ); #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)] @@ -778,12 +780,10 @@ impl Step for RustAnalyzerProcMacroSrv { macro_rules! tool_extended { (($sel:ident, $builder:ident), $($name:ident, - $toolstate:ident, $path:expr, $tool_name:expr, stable = $stable:expr, $(in_tree = $in_tree:expr,)? - $(submodule = $submodule:literal,)? $(tool_std = $tool_std:literal,)? $extra_deps:block;)+) => { $( @@ -828,7 +828,6 @@ macro_rules! tool_extended { #[allow(unused_mut)] fn run(mut $sel, $builder: &Builder<'_>) -> Option<PathBuf> { $extra_deps - $( $builder.update_submodule(&Path::new("src").join("tools").join($submodule)); )? $builder.ensure(ToolBuild { compiler: $sel.compiler, target: $sel.target, @@ -854,24 +853,17 @@ macro_rules! tool_extended { // Note: Most submodule updates for tools are handled by bootstrap.py, since they're needed just to // invoke Cargo to build bootstrap. See the comment there for more details. tool_extended!((self, builder), - Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {}; - CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {}; - Clippy, clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {}; - Miri, miri, "src/tools/miri", "miri", stable=false, {}; - CargoMiri, miri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, {}; - Rls, rls, "src/tools/rls", "rls", stable=true, { - builder.ensure(Clippy { - compiler: self.compiler, - target: self.target, - extra_features: Vec::new(), - }); - self.extra_features.push("clippy".to_owned()); - }; + Cargofmt, "src/tools/rustfmt", "cargo-fmt", stable=true, in_tree=true, {}; + CargoClippy, "src/tools/clippy", "cargo-clippy", stable=true, in_tree=true, {}; + Clippy, "src/tools/clippy", "clippy-driver", stable=true, in_tree=true, {}; + Miri, "src/tools/miri", "miri", stable=false, {}; + CargoMiri, "src/tools/miri/cargo-miri", "cargo-miri", stable=false, {}; + Rls, "src/tools/rls", "rls", stable=true, {}; // FIXME: tool_std is not quite right, we shouldn't allow nightly features. // But `builder.cargo` doesn't know how to handle ToolBootstrap in stages other than 0, // and this is close enough for now. - RustDemangler, rust_demangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {}; - Rustfmt, rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {}; + RustDemangler, "src/tools/rust-demangler", "rust-demangler", stable=false, in_tree=true, tool_std=true, {}; + Rustfmt, "src/tools/rustfmt", "rustfmt", stable=true, in_tree=true, {}; ); impl<'a> Builder<'a> { diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index 2cfeae7dc..f3a6759ab 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -69,7 +69,6 @@ static STABLE_TOOLS: &[(&str, &str)] = &[ ("reference", "src/doc/reference"), ("rust-by-example", "src/doc/rust-by-example"), ("edition-guide", "src/doc/edition-guide"), - ("rls", "src/tools/rls"), ]; // These tools are permitted to not build on the beta/stable channels. diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 1895e2901..0ebabbd5c 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -197,9 +197,11 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { ptr::null_mut(), ); - let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]; - let db = data.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER; - let buf = &mut (*db).ReparseTarget as *mut u16; + #[repr(C, align(8))] + struct Align8<T>(T); + let mut data = Align8([0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]); + let db = data.0.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER; + let buf = core::ptr::addr_of_mut!((*db).ReparseTarget) as *mut u16; let mut i = 0; // FIXME: this conversion is very hacky let v = br"\??\"; @@ -219,7 +221,7 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { let res = DeviceIoControl( h as *mut _, FSCTL_SET_REPARSE_POINT, - data.as_ptr() as *mut _, + db.cast(), (*db).ReparseDataLength + 8, ptr::null_mut(), 0, @@ -258,6 +260,10 @@ impl CiEnv { } } + pub fn is_ci() -> bool { + Self::current() != CiEnv::None + } + /// If in a CI environment, forces the command to run with colors. pub fn force_coloring_in_ci(self, cmd: &mut Command) { if self != CiEnv::None { |