diff --git a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs index 9b7db11e2f29a..7b3a234cd9e8e 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_pc_windows_gnullvm.rs @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { metadata: TargetMetadata { description: Some("ARM64 MinGW (Windows 10+), LLVM ABI".into()), tier: Some(2), - host_tools: Some(false), + host_tools: Some(true), std: Some(true), }, pointer_width: 64, diff --git a/compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs index f04e3c2c2a5b0..508afd4793523 100644 --- a/compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i586_unknown_linux_gnu.rs @@ -5,5 +5,11 @@ pub(crate) fn target() -> Target { base.rustc_abi = None; // overwrite the SSE2 ABI set by the base target base.cpu = "pentium".into(); base.llvm_target = "i586-unknown-linux-gnu".into(); + base.metadata = crate::spec::TargetMetadata { + description: Some("32-bit Linux (kernel 3.2, glibc 2.17+)".into()), + tier: Some(2), + host_tools: Some(false), + std: Some(true), + }; base } diff --git a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs index 498d8182ad589..a6067f64c6860 100644 --- a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs @@ -18,7 +18,7 @@ pub(crate) fn target() -> Target { metadata: TargetMetadata { description: Some("SPARC Solaris 11.4".into()), tier: Some(2), - host_tools: Some(false), + host_tools: Some(true), std: Some(true), }, pointer_width: 64, diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs index e594d187e42bd..b53bf3b7bd52b 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip2.rs @@ -63,7 +63,7 @@ pub(crate) fn target() -> Target { llvm_target: "wasm32-wasip2".into(), metadata: TargetMetadata { description: Some("WebAssembly".into()), - tier: Some(3), + tier: Some(2), host_tools: Some(false), std: Some(true), }, diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs index d417f3d48a4be..3fb1d11ef60da 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip3.rs @@ -15,6 +15,12 @@ pub(crate) fn target() -> Target { // and this may grow over time as more features are supported. let mut target = super::wasm32_wasip2::target(); target.llvm_target = "wasm32-wasip3".into(); + target.metadata = crate::spec::TargetMetadata { + description: Some("WebAssembly".into()), + tier: Some(3), + host_tools: Some(false), + std: Some(true), + }; target.options.env = Env::P3; target } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs index 39ebe62430479..abcca352dfa33 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs @@ -20,7 +20,7 @@ pub(crate) fn target() -> Target { metadata: TargetMetadata { description: Some("64-bit Solaris 11.4".into()), tier: Some(2), - host_tools: Some(false), + host_tools: Some(true), std: Some(true), }, pointer_width: 64, diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs index 28c9e6251255c..0606d4508badc 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs @@ -14,7 +14,7 @@ pub(crate) fn target() -> Target { metadata: TargetMetadata { description: Some("64-bit x86 MinGW (Windows 10+), LLVM ABI".into()), tier: Some(2), - host_tools: Some(false), + host_tools: Some(true), std: Some(true), }, pointer_width: 64, diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 411d42962644d..b3f67d1b8ac53 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -22,7 +22,7 @@ use tracing::instrument; use crate::core::build_steps::compile::{get_codegen_backend_file, normalize_codegen_backend_name}; use crate::core::build_steps::doc::DocumentationFormat; use crate::core::build_steps::tool::{ - self, RustcPrivateCompilers, Tool, ToolTargetBuildMode, get_tool_target_compiler, + self, RustcPrivateCompilers, ToolTargetBuildMode, get_tool_target_compiler, }; use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor}; use crate::core::build_steps::{compile, llvm}; @@ -2695,10 +2695,14 @@ impl Step for BuildManifest { } fn run(self, builder: &Builder<'_>) -> GeneratedTarball { - let build_manifest = builder.tool_exe(Tool::BuildManifest); + // FIXME: Should BuildManifest actually be built for `self.target`? + // Today CI only builds this step where that matches the host_target so it doesn't matter + // today. + let build_manifest = + builder.ensure(tool::BuildManifest::new(builder, builder.config.host_target)); let tarball = Tarball::new(builder, "build-manifest", &self.target.triple); - tarball.add_file(&build_manifest, "bin", FileType::Executable); + tarball.add_file(&build_manifest.tool_path, "bin", FileType::Executable); tarball.generate() } diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index 6ab99ae799d70..5446ec085ffd0 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -37,7 +37,9 @@ impl Step for BuildManifest { fn run(self, builder: &Builder<'_>) { // This gets called by `promote-release` // (https://github.com/rust-lang/promote-release). - let mut cmd = builder.tool_cmd(Tool::BuildManifest); + let mut cmd = command( + builder.ensure(tool::BuildManifest::new(builder, builder.config.host_target)).tool_path, + ); let sign = builder.config.dist_sign_folder.as_ref().unwrap_or_else(|| { panic!("\n\nfailed to specify `dist.sign-folder` in `bootstrap.toml`\n\n") }); diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 79df9d3a49da2..0d765018d77bf 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -485,7 +485,6 @@ bootstrap_tool!( Linkchecker, "src/tools/linkchecker", "linkchecker"; CargoTest, "src/tools/cargotest", "cargotest"; Compiletest, "src/tools/compiletest", "compiletest"; - BuildManifest, "src/tools/build-manifest", "build-manifest"; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client"; RustInstaller, "src/tools/rust-installer", "rust-installer"; RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes"; @@ -1268,6 +1267,52 @@ impl Step for LibcxxVersionTool { } } +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub struct BuildManifest { + compiler: Compiler, + target: TargetSelection, +} + +impl BuildManifest { + pub fn new(builder: &Builder<'_>, target: TargetSelection) -> Self { + BuildManifest { compiler: builder.compiler(1, builder.config.host_target), target } + } +} + +impl Step for BuildManifest { + type Output = ToolBuildResult; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/build-manifest") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(BuildManifest::new(run.builder, run.target)); + } + + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { + // Building with the beta compiler will produce a broken build-manifest that doesn't support + // recently stabilized targets/hosts. + assert!(self.compiler.stage != 0); + builder.ensure(ToolBuild { + build_compiler: self.compiler, + target: self.target, + tool: "build-manifest", + mode: Mode::ToolStd, + path: "src/tools/build-manifest", + source_type: SourceType::InTree, + extra_features: vec![], + allow_features: "", + cargo_args: vec![], + artifact_kind: ToolArtifactKind::Binary, + }) + } + + fn metadata(&self) -> Option { + Some(StepMetadata::build("build-manifest", self.target).built_by(self.compiler)) + } +} + /// Represents which compilers are involved in the compilation of a tool /// that depends on compiler internals (`rustc_private`). /// Their compilation looks like this: diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index efa99f181b3a1..c0271bbc89b53 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -14,3 +14,7 @@ tar = "0.4.29" sha2 = "0.10.1" rayon = "1.5.1" hex = "0.4.2" + +[build-dependencies] +serde = "1" +serde_json = "1" diff --git a/src/tools/build-manifest/README.md b/src/tools/build-manifest/README.md index 2ea1bffb35f4d..bc1992ef80cc0 100644 --- a/src/tools/build-manifest/README.md +++ b/src/tools/build-manifest/README.md @@ -2,7 +2,13 @@ This tool generates the manifests uploaded to static.rust-lang.org and used by rustup. You can see a full list of all manifests at . -This listing is updated by every 7 days. + +We auto-generate the host targets (those with full compiler toolchains) and +target targets (a superset of hosts, some of which only support std) through +`build.rs`, which internally uses a stage 1 rustc to produce the target list +and uses the `TargetMetadata` to determine whether host tools are expected and +whether artifacts are expected. This list is not currently verified against the +actually produced artifacts by CI, though that may change in the future. This gets called by `promote-release` . `promote-release` downloads a pre-built binary of `build-manifest` which is generated in the dist-x86_64-linux builder and uploaded to s3. diff --git a/src/tools/build-manifest/build.rs b/src/tools/build-manifest/build.rs new file mode 100644 index 0000000000000..c804921408a93 --- /dev/null +++ b/src/tools/build-manifest/build.rs @@ -0,0 +1,76 @@ +use std::fmt::Write; +use std::path::PathBuf; +use std::process::{Command, Stdio}; + +#[derive(Default, Debug)] +pub(crate) struct RustcTargets { + /// Targets with host tool artifacts. + pub(crate) hosts: Vec, + + /// All targets we distribute some artifacts for (superset of `hosts`). + pub(crate) targets: Vec, +} + +fn collect_rustc_targets() -> RustcTargets { + let rustc_path = std::env::var("RUSTC").expect("RUSTC set"); + let output = Command::new(&rustc_path) + .arg("--print=all-target-specs-json") + .env("RUSTC_BOOTSTRAP", "1") + .arg("-Zunstable-options") + .stderr(Stdio::inherit()) + .output() + .unwrap(); + assert!(output.status.success()); + let json: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap(); + + let mut rustc_targets = RustcTargets::default(); + for (target, json) in json.as_object().unwrap().iter() { + let Some(tier) = json["metadata"]["tier"].as_u64() else { + eprintln!("skipping {target}: no tier in metadata"); + continue; + }; + let host_tools: Option = + serde_json::from_value(json["metadata"]["host_tools"].clone()).unwrap(); + + if !(tier == 1 || tier == 2) { + eprintln!("ignoring {target}: tier {tier} insufficient for target to be in manifest"); + continue; + } + + if host_tools == Some(true) { + rustc_targets.hosts.push(target.to_owned()); + rustc_targets.targets.push(target.to_owned()); + } else { + rustc_targets.targets.push(target.to_owned()); + } + } + + rustc_targets +} + +fn main() { + let targets = collect_rustc_targets(); + + // Verify we ended up with a reasonable target list. + assert!(targets.hosts.len() >= 10); + assert!(targets.targets.len() >= 30); + assert!(targets.hosts.iter().any(|e| e == "x86_64-unknown-linux-gnu")); + assert!(targets.targets.iter().any(|e| e == "x86_64-unknown-linux-gnu")); + + let mut output = String::new(); + + writeln!(output, "static HOSTS: &[&str] = &[").unwrap(); + for host in targets.hosts { + writeln!(output, " {:?},", host).unwrap(); + } + writeln!(output, "];").unwrap(); + + writeln!(output, "static TARGETS: &[&str] = &[").unwrap(); + for target in targets.targets { + writeln!(output, " {:?},", target).unwrap(); + } + writeln!(output, "];").unwrap(); + + std::fs::write(PathBuf::from(std::env::var_os("OUT_DIR").unwrap()).join("targets.rs"), output) + .unwrap(); +} diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 3f19e1128df9d..5d9d63093860f 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -12,194 +12,7 @@ use crate::checksum::Checksums; use crate::manifest::{Component, Manifest, Package, Rename, Target}; use crate::versions::{PkgType, Versions}; -static HOSTS: &[&str] = &[ - "aarch64-apple-darwin", - "aarch64-pc-windows-gnullvm", - "aarch64-pc-windows-msvc", - "aarch64-unknown-linux-gnu", - "aarch64-unknown-linux-musl", - "arm-unknown-linux-gnueabi", - "arm-unknown-linux-gnueabihf", - "armv7-unknown-linux-gnueabihf", - "i686-apple-darwin", - "i686-pc-windows-gnu", - "i686-pc-windows-msvc", - "i686-unknown-linux-gnu", - "loongarch64-unknown-linux-gnu", - "loongarch64-unknown-linux-musl", - "mips-unknown-linux-gnu", - "mips64-unknown-linux-gnuabi64", - "mips64el-unknown-linux-gnuabi64", - "mipsel-unknown-linux-gnu", - "mipsisa32r6-unknown-linux-gnu", - "mipsisa32r6el-unknown-linux-gnu", - "mipsisa64r6-unknown-linux-gnuabi64", - "mipsisa64r6el-unknown-linux-gnuabi64", - "powerpc-unknown-linux-gnu", - "powerpc64-unknown-linux-gnu", - "powerpc64le-unknown-linux-gnu", - "powerpc64le-unknown-linux-musl", - "riscv64gc-unknown-linux-gnu", - "s390x-unknown-linux-gnu", - "sparcv9-sun-solaris", - "x86_64-apple-darwin", - "x86_64-pc-solaris", - "x86_64-pc-windows-gnu", - "x86_64-pc-windows-gnullvm", - "x86_64-pc-windows-msvc", - "x86_64-unknown-freebsd", - "x86_64-unknown-illumos", - "x86_64-unknown-linux-gnu", - "x86_64-unknown-linux-musl", - "x86_64-unknown-netbsd", -]; - -static TARGETS: &[&str] = &[ - "aarch64-apple-darwin", - "aarch64-apple-ios", - "aarch64-apple-ios-macabi", - "aarch64-apple-ios-sim", - "aarch64-unknown-fuchsia", - "aarch64-linux-android", - "aarch64-pc-windows-gnullvm", - "aarch64-pc-windows-msvc", - "aarch64-unknown-hermit", - "aarch64-unknown-linux-gnu", - "aarch64-unknown-linux-musl", - "aarch64-unknown-linux-ohos", - "aarch64-unknown-none", - "aarch64-unknown-none-softfloat", - "aarch64-unknown-redox", - "aarch64-unknown-uefi", - "aarch64-unknown-managarm-mlibc", - "amdgcn-amd-amdhsa", - "arm64e-apple-darwin", - "arm64e-apple-ios", - "arm64e-apple-tvos", - "arm-linux-androideabi", - "arm-unknown-linux-gnueabi", - "arm-unknown-linux-gnueabihf", - "arm-unknown-linux-musleabi", - "arm-unknown-linux-musleabihf", - "arm64ec-pc-windows-msvc", - "armv5te-unknown-linux-gnueabi", - "armv5te-unknown-linux-musleabi", - "armv7-linux-androideabi", - "thumbv7neon-linux-androideabi", - "armv7-unknown-linux-gnueabi", - "armv7-unknown-linux-gnueabihf", - "armv7a-none-eabi", - "armv7a-none-eabihf", - "thumbv7neon-unknown-linux-gnueabihf", - "armv7-unknown-linux-musleabi", - "armv7-unknown-linux-musleabihf", - "armv7-unknown-linux-ohos", - "armebv7r-none-eabi", - "armebv7r-none-eabihf", - "armv7r-none-eabi", - "armv7r-none-eabihf", - "armv8r-none-eabihf", - "armv7s-apple-ios", - "bpfeb-unknown-none", - "bpfel-unknown-none", - "i386-apple-ios", - "i586-unknown-linux-gnu", - "i586-unknown-linux-musl", - "i586-unknown-redox", - "i686-apple-darwin", - "i686-linux-android", - "i686-pc-windows-gnu", - "i686-pc-windows-gnullvm", - "i686-pc-windows-msvc", - "i686-unknown-freebsd", - "i686-unknown-linux-gnu", - "i686-unknown-linux-musl", - "i686-unknown-uefi", - "loongarch64-unknown-linux-gnu", - "loongarch64-unknown-linux-musl", - "loongarch32-unknown-none", - "loongarch32-unknown-none-softfloat", - "loongarch64-unknown-none", - "loongarch64-unknown-none-softfloat", - "m68k-unknown-linux-gnu", - "m68k-unknown-none-elf", - "csky-unknown-linux-gnuabiv2", - "csky-unknown-linux-gnuabiv2hf", - "mips-unknown-linux-gnu", - "mips-unknown-linux-musl", - "mips64-unknown-linux-gnuabi64", - "mips64-unknown-linux-muslabi64", - "mips64el-unknown-linux-gnuabi64", - "mips64el-unknown-linux-muslabi64", - "mipsisa32r6-unknown-linux-gnu", - "mipsisa32r6el-unknown-linux-gnu", - "mipsisa64r6-unknown-linux-gnuabi64", - "mipsisa64r6el-unknown-linux-gnuabi64", - "mipsel-unknown-linux-gnu", - "mipsel-unknown-linux-musl", - "mips-mti-none-elf", - "mipsel-mti-none-elf", - "nvptx64-nvidia-cuda", - "powerpc-unknown-linux-gnu", - "powerpc64-unknown-linux-gnu", - "powerpc64le-unknown-linux-gnu", - "powerpc64le-unknown-linux-musl", - "riscv32i-unknown-none-elf", - "riscv32im-risc0-zkvm-elf", - "riscv32im-unknown-none-elf", - "riscv32ima-unknown-none-elf", - "riscv32imc-unknown-none-elf", - "riscv32imac-unknown-none-elf", - "riscv32imafc-unknown-none-elf", - "riscv32gc-unknown-linux-gnu", - "riscv64imac-unknown-none-elf", - "riscv64a23-unknown-linux-gnu", - "riscv64gc-unknown-hermit", - "riscv64gc-unknown-none-elf", - "riscv64gc-unknown-linux-gnu", - "riscv64gc-unknown-linux-musl", - "riscv64gc-unknown-managarm-mlibc", - "s390x-unknown-linux-gnu", - "sparc64-unknown-linux-gnu", - "sparcv9-sun-solaris", - "sparc-unknown-none-elf", - "thumbv6m-none-eabi", - "thumbv7em-none-eabi", - "thumbv7em-none-eabihf", - "thumbv7m-none-eabi", - "thumbv8m.base-none-eabi", - "thumbv8m.main-none-eabi", - "thumbv8m.main-none-eabihf", - "wasm32-unknown-emscripten", - "wasm32-unknown-unknown", - "wasm32-wasip1", - "wasm32-wasip1-threads", - "wasm32-wasip2", - "wasm32v1-none", - "x86_64-apple-darwin", - "x86_64-apple-ios", - "x86_64-apple-ios-macabi", - "x86_64-fortanix-unknown-sgx", - "x86_64-unknown-fuchsia", - "x86_64-linux-android", - "x86_64-pc-windows-gnu", - "x86_64-pc-windows-gnullvm", - "x86_64-pc-windows-msvc", - "x86_64-pc-solaris", - "x86_64-unikraft-linux-musl", - "x86_64-unknown-freebsd", - "x86_64-unknown-illumos", - "x86_64-unknown-linux-gnu", - "x86_64-unknown-linux-gnux32", - "x86_64-unknown-linux-musl", - "x86_64-unknown-linux-ohos", - "x86_64-unknown-netbsd", - "x86_64-unknown-none", - "x86_64-unknown-redox", - "x86_64-unknown-hermit", - "x86_64-unknown-uefi", - "x86_64-unknown-managarm-mlibc", -]; +include!(concat!(env!("OUT_DIR"), "/targets.rs")); /// This allows the manifest to contain rust-docs for hosts that don't build /// docs.