131 lines
4.2 KiB
Rust
131 lines
4.2 KiB
Rust
// This test ensures we are able to compile -Zbuild-std=core under a variety of profiles.
|
|
// Currently, it tests that we can compile to all Tier 1 targets, and it does this by checking what
|
|
// the tier metadata in target-spec JSON. This means that all in-tree targets must have a tier set.
|
|
|
|
#![deny(warnings)]
|
|
|
|
use std::collections::HashMap;
|
|
use std::sync::{Arc, Mutex};
|
|
use std::thread;
|
|
|
|
use run_make_support::serde_json::{self, Value};
|
|
use run_make_support::tempfile::TempDir;
|
|
use run_make_support::{cargo, rfs, rustc};
|
|
|
|
#[derive(Clone)]
|
|
struct Task {
|
|
target: String,
|
|
opt_level: u8,
|
|
debug: u8,
|
|
panic: &'static str,
|
|
}
|
|
|
|
fn manifest(task: &Task) -> String {
|
|
let Task { opt_level, debug, panic, target: _ } = task;
|
|
format!(
|
|
r#"[package]
|
|
name = "scratch"
|
|
version = "0.1.0"
|
|
edition = "2024"
|
|
|
|
[lib]
|
|
path = "lib.rs"
|
|
|
|
[profile.release]
|
|
opt-level = {opt_level}
|
|
debug = {debug}
|
|
panic = "{panic}"
|
|
"#
|
|
)
|
|
}
|
|
|
|
fn main() {
|
|
let mut targets = Vec::new();
|
|
let all_targets =
|
|
rustc().args(&["--print=all-target-specs-json", "-Zunstable-options"]).run().stdout_utf8();
|
|
let all_targets: HashMap<String, Value> = serde_json::from_str(&all_targets).unwrap();
|
|
for (target, spec) in all_targets {
|
|
let metadata = spec.as_object().unwrap()["metadata"].as_object().unwrap();
|
|
let tier = metadata["tier"]
|
|
.as_u64()
|
|
.expect(&format!("Target {} is missing tier metadata", target));
|
|
if tier == 1 {
|
|
targets.push(target);
|
|
}
|
|
}
|
|
|
|
let mut tasks = Vec::new();
|
|
|
|
// Testing every combination of compiler flags is infeasible. So we are making some attempt to
|
|
// choose combinations that will tend to run into problems.
|
|
//
|
|
// The particular combination of settings below is tuned to look for problems generating the
|
|
// code for compiler-builtins.
|
|
// We only exercise opt-level 0 and 3 to exercise mir-opt-level 1 and 2.
|
|
// We only exercise debug 0 and 2 because level 2 turns off some MIR optimizations.
|
|
// We only test abort and immediate-abort because abort vs unwind doesn't change MIR much at
|
|
// all. but immediate-abort does.
|
|
//
|
|
// Currently this only tests that we can compile the tier 1 targets. But since we are using
|
|
// -Zbuild-std=core, we could have any list of targets.
|
|
|
|
for opt_level in [0, 3] {
|
|
for debug in [0, 2] {
|
|
for panic in ["abort", "immediate-abort"] {
|
|
for target in &targets {
|
|
tasks.push(Task { target: target.clone(), opt_level, debug, panic });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let tasks = Arc::new(Mutex::new(tasks));
|
|
let mut threads = Vec::new();
|
|
|
|
// Try to obey the -j argument passed to bootstrap, otherwise fall back to using all the system
|
|
// resouces. This test can be rather memory-hungry (~1 GB/thread); if it causes trouble in
|
|
// practice do not hesitate to limit its parallelism.
|
|
for _ in 0..run_make_support::env::jobs() {
|
|
let tasks = Arc::clone(&tasks);
|
|
let handle = thread::spawn(move || {
|
|
loop {
|
|
let maybe_task = tasks.lock().unwrap().pop();
|
|
if let Some(task) = maybe_task {
|
|
test(task);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
threads.push(handle);
|
|
}
|
|
|
|
for t in threads {
|
|
t.join().unwrap();
|
|
}
|
|
}
|
|
|
|
fn test(task: Task) {
|
|
let dir = TempDir::new().unwrap();
|
|
|
|
let manifest = manifest(&task);
|
|
rfs::write(dir.path().join("Cargo.toml"), &manifest);
|
|
rfs::write(dir.path().join("lib.rs"), "#![no_std]");
|
|
|
|
let mut args = vec!["build", "--release", "-Zbuild-std=core", "--target", &task.target, "-j1"];
|
|
if task.panic == "immediate-abort" {
|
|
args.push("-Zpanic-immediate-abort");
|
|
}
|
|
cargo()
|
|
.current_dir(dir.path())
|
|
.args(&args)
|
|
.env("RUSTC_BOOTSTRAP", "1")
|
|
// Visual Studio 2022 requires that the LIB env var be set so it can
|
|
// find the Windows SDK.
|
|
.env("LIB", std::env::var("LIB").unwrap_or_default())
|
|
.context(&format!(
|
|
"build-std for target `{}` failed with the following Cargo.toml:\n\n{manifest}",
|
|
task.target
|
|
))
|
|
.run();
|
|
}
|