diff --git a/Cargo.lock b/Cargo.lock index 3f8bf0ac8e890..97020034efcdc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4623,6 +4623,10 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tier-check" +version = "0.1.0" + [[package]] name = "time" version = "0.1.42" diff --git a/Cargo.toml b/Cargo.toml index 1936e35aa4c5d..87e958a1bafe6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,7 @@ members = [ "src/tools/rustbook", "src/tools/unstable-book-gen", "src/tools/tidy", + "src/tools/tier-check", "src/tools/build-manifest", "src/tools/remote-test-client", "src/tools/remote-test-server", diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index e13a5f2465336..4b0905bd6c16c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -404,6 +404,7 @@ impl<'a> Builder<'a> { test::CrateLibrustc, test::CrateRustdoc, test::Linkcheck, + test::TierCheck, test::Cargotest, test::Cargo, test::Rls, diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index bb5b9296c0aa7..11e2564305f0d 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -2043,3 +2043,47 @@ impl Step for Bootstrap { run.builder.ensure(Bootstrap); } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct TierCheck { + pub compiler: Compiler, + target: TargetSelection, +} + +impl Step for TierCheck { + type Output = (); + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("src/tools/tier-check") + } + + fn make_run(run: RunConfig<'_>) { + let compiler = run.builder.compiler_for(run.builder.top_stage, run.host, run.host); + run.builder.ensure(TierCheck { compiler, target: run.host }); + } + + /// Tests the Platform Support page in the rustc book. + fn run(self, builder: &Builder<'_>) { + builder.ensure(compile::Std { compiler: self.compiler, target: self.target }); + let mut cargo = tool::prepare_tool_cargo( + builder, + self.compiler, + Mode::ToolRustc, + self.target, + "run", + "src/tools/tier-check", + SourceType::InTree, + &[], + ); + cargo.arg(builder.src.join("src/doc/rustc/src/platform-support.md")); + cargo.arg(&builder.rustc(self.compiler)); + if builder.is_verbose() { + cargo.arg("--verbose"); + } + + builder.info("platform support check"); + try_run(builder, &mut cargo.into()); + } +} diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 683d402930614..b8d3c985cb5b6 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -57,7 +57,7 @@ Specifically, these platforms are required to have each of the following: target | std | host | notes -------|-----|------|------- -`aarch64-apple-ios` | ✓ | | ARM64 iOS +`aarch64-apple-ios` | ✓[^apple] | | ARM64 iOS `aarch64-fuchsia` | ✓ | | ARM64 Fuchsia `aarch64-linux-android` | ✓ | | ARM64 Android `aarch64-pc-windows-msvc` | ✓ | | ARM64 Windows MSVC @@ -122,7 +122,7 @@ target | std | host | notes `wasm32-unknown-emscripten` | ✓ | | WebAssembly via Emscripten `wasm32-unknown-unknown` | ✓ | | WebAssembly `wasm32-wasi` | ✓ | | WebAssembly with WASI -`x86_64-apple-ios` | ✓ | | 64-bit x86 iOS +`x86_64-apple-ios` | ✓[^apple] | | 64-bit x86 iOS `x86_64-fortanix-unknown-sgx` | ✓ | | [Fortanix ABI] for 64-bit Intel SGX `x86_64-fuchsia` | ✓ | | 64-bit Fuchsia `x86_64-linux-android` | ✓ | | 64-bit x86 Android @@ -147,7 +147,7 @@ not available. target | std | host | notes -------|-----|------|------- `aarch64-apple-darwin` | ? | | ARM64 macOS -`aarch64-apple-tvos` | * | | ARM64 tvOS +`aarch64-apple-tvos` | *[^apple] | | ARM64 tvOS `aarch64-unknown-cloudabi` | ✓ | | ARM64 CloudABI `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD `aarch64-unknown-hermit` | ? | | @@ -159,16 +159,16 @@ target | std | host | notes `armv4t-unknown-linux-gnueabi` | ? | | `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD `armv6-unknown-netbsd-eabihf` | ? | | -`armv7-apple-ios` | ✓ | | RMv7 iOS, Cortex- +`armv7-apple-ios` | ✓[^apple] | | ARMv7 iOS, Cortex-a8 `armv7-unknown-cloudabi-eabihf` | ✓ | | ARMv7 CloudABI, hardfloat `armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD `armv7-unknown-netbsd-eabihf` | ? | | `armv7-wrs-vxworks-eabihf` | ? | | `armv7a-none-eabihf` | * | | ARM Cortex-A, hardfloat -`armv7s-apple-ios` | ✓ | | +`armv7s-apple-ios` | ✓[^apple] | | `avr-unknown-unknown` | ? | | AVR `hexagon-unknown-linux-musl` | ? | | -`i386-apple-ios` | ✓ | | 32-bit x86 iOS +`i386-apple-ios` | ✓[^apple] | | 32-bit x86 iOS `i686-apple-darwin` | ✓ | ✓ | 32-bit OSX (10.7+, Lion+) `i686-pc-windows-msvc` | ✓ | | 32-bit Windows XP support `i686-unknown-cloudabi` | ✓ | | 32-bit CloudABI @@ -203,8 +203,8 @@ target | std | host | notes `thumbv7a-uwp-windows-msvc` | ✓ | | `thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode ARMv7a Linux with NEON, MUSL `thumbv4t-none-eabi` | * | | ARMv4T T32 -`x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst -`x86_64-apple-tvos` | * | | x86 64-bit tvOS +`x86_64-apple-ios-macabi` | ✓[^apple] | | Apple Catalyst +`x86_64-apple-tvos` | *[^apple] | | x86 64-bit tvOS `x86_64-linux-kernel` | ? | | Linux kernel modules `x86_64-pc-solaris` | ? | | `x86_64-pc-windows-msvc` | ✓ | | 64-bit Windows XP support @@ -220,3 +220,4 @@ target | std | host | notes `x86_64-wrs-vxworks` | ? | | [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets +[^apple]: These targets are only available on macOS. diff --git a/src/tools/tier-check/Cargo.toml b/src/tools/tier-check/Cargo.toml new file mode 100644 index 0000000000000..9917b383aab37 --- /dev/null +++ b/src/tools/tier-check/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "tier-check" +version = "0.1.0" +authors = ["Eric Huss"] +edition = "2018" +license = "MIT OR Apache-2.0" + +[dependencies] diff --git a/src/tools/tier-check/src/main.rs b/src/tools/tier-check/src/main.rs new file mode 100644 index 0000000000000..b8d60a5e2fef9 --- /dev/null +++ b/src/tools/tier-check/src/main.rs @@ -0,0 +1,52 @@ +//! This is a script for validating the platform support page in the rustc book. +//! +//! The script takes two arguments, the path to the Platform Support source +//! page, and the second argument is the path to `rustc`. + +use std::collections::HashSet; + +fn main() { + let mut args = std::env::args().skip(1); + let src = args.next().expect("expected source file as first argument"); + let filename = std::path::Path::new(&src).file_name().unwrap().to_str().unwrap(); + let rustc = args.next().expect("expected rustc as second argument"); + let output = std::process::Command::new(rustc) + .arg("--print=target-list") + .output() + .expect("rustc should run"); + if !output.status.success() { + eprintln!("rustc failed to run"); + std::process::exit(0); + } + let stdout = std::str::from_utf8(&output.stdout).expect("utf8"); + let target_list: HashSet<_> = stdout.lines().collect(); + + let doc_targets_md = std::fs::read_to_string(&src).expect("failed to read input source"); + let doc_targets: HashSet<_> = doc_targets_md + .lines() + .filter(|line| line.starts_with('`') && line.contains('|')) + // These platforms only exist on macos. + .filter(|line| !line.contains("[^apple]") || cfg!(target_os = "macos")) + .map(|line| line.split('`').skip(1).next().expect("expected target code span")) + .collect(); + + let missing: Vec<_> = target_list.difference(&doc_targets).collect(); + let extra: Vec<_> = doc_targets.difference(&target_list).collect(); + for target in &missing { + eprintln!( + "error: target `{}` is missing from {}\n\ + If this is a new target, please add it to {}.", + target, filename, src + ); + } + for target in &extra { + eprintln!( + "error: target `{}` is in {}, but does not appear in the rustc target list\n\ + If the target has been removed, please edit {} and remove the target.", + target, filename, src + ); + } + if !missing.is_empty() || !extra.is_empty() { + std::process::exit(1); + } +}