Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3334,6 +3334,7 @@ dependencies = [
"rustdoc-json-types",
"serde_json",
"similar",
"tempfile",
"wasmparser 0.236.1",
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target {

Target {
llvm_target: "i586-unknown-redox".into(),
metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None },
metadata: TargetMetadata { description: None, tier: Some(3), host_tools: None, std: None },
pointer_width: 32,
data_layout:
"e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-i128:128-f64:32:64-f80:32-n8:16:32-S128"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub(crate) fn target() -> Target {
llvm_target: "x86_64-unknown-linux-none".into(),
metadata: TargetMetadata {
description: None,
tier: None,
tier: Some(3),
host_tools: None,
std: Some(false),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub(crate) fn target() -> Target {
pointer_width: 32,
data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(),
arch: Arch::Xtensa,
metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None },
metadata: TargetMetadata { description: None, tier: Some(3), host_tools: None, std: None },

options: TargetOptions {
endian: Endian::Little,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub(crate) fn target() -> Target {
pointer_width: 32,
data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(),
arch: Arch::Xtensa,
metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None },
metadata: TargetMetadata { description: None, tier: Some(3), host_tools: None, std: None },

options: TargetOptions {
endian: Endian::Little,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub(crate) fn target() -> Target {
pointer_width: 32,
data_layout: "e-m:e-p:32:32-v1:8:8-i64:64-i128:128-n32".into(),
arch: Arch::Xtensa,
metadata: TargetMetadata { description: None, tier: None, host_tools: None, std: None },
metadata: TargetMetadata { description: None, tier: Some(3), host_tools: None, std: None },

options: TargetOptions {
endian: Endian::Little,
Expand Down
5 changes: 5 additions & 0 deletions src/bootstrap/mk/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ check-aux:
src/tools/cargotest \
src/tools/test-float-parse \
$(BOOTSTRAP_ARGS)
# The build-std suite is off by default because it is uncommonly slow
# and memory-hungry.
$(Q)$(BOOTSTRAP) test --stage 2 \
build-std \
$(BOOTSTRAP_ARGS)
# Run standard library tests in Miri.
$(Q)MIRIFLAGS="-Zmiri-strict-provenance" \
$(BOOTSTRAP) miri --stage 2 \
Expand Down
8 changes: 7 additions & 1 deletion src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1625,6 +1625,12 @@ test!(RunMakeCargo {
suite: "run-make-cargo",
default: true
});
test!(BuildStd {
path: "tests/build-std",
mode: CompiletestMode::RunMake,
suite: "build-std",
default: false
});

test!(AssemblyLlvm {
path: "tests/assembly-llvm",
Expand Down Expand Up @@ -1948,7 +1954,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
let stage0_rustc_path = builder.compiler(0, test_compiler.host);
cmd.arg("--stage0-rustc-path").arg(builder.rustc(stage0_rustc_path));

if suite == "run-make-cargo" {
if matches!(suite, "run-make-cargo" | "build-std") {
let cargo_path = if test_compiler.stage == 0 {
// If we're using `--stage 0`, we should provide the bootstrap cargo.
builder.initial_cargo.clone()
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/src/core/builder/cli_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub(crate) const PATH_REMAP: &[(&str, &[&str])] = &[
&[
// tidy-alphabetical-start
"tests/assembly-llvm",
"tests/build-std",
"tests/codegen-llvm",
"tests/codegen-units",
"tests/coverage",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ expression: test tests
[Test] test::AssemblyLlvm
targets: [aarch64-unknown-linux-gnu]
- Suite(test::tests/assembly-llvm)
[Test] test::BuildStd
targets: [aarch64-unknown-linux-gnu]
- Suite(test::tests/build-std)
[Test] test::CodegenLlvm
targets: [aarch64-unknown-linux-gnu]
- Suite(test::tests/codegen-llvm)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ expression: test tests --skip=coverage
[Test] test::AssemblyLlvm
targets: [aarch64-unknown-linux-gnu]
- Suite(test::tests/assembly-llvm)
[Test] test::BuildStd
targets: [aarch64-unknown-linux-gnu]
- Suite(test::tests/build-std)
[Test] test::CodegenLlvm
targets: [aarch64-unknown-linux-gnu]
- Suite(test::tests/codegen-llvm)
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/src/core/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,7 @@ impl<'a> Builder<'a> {
test::CollectLicenseMetadata,
test::RunMake,
test::RunMakeCargo,
test::BuildStd,
),
Kind::Miri => describe!(test::Crate),
Kind::Bench => describe!(test::Crate, test::CrateLibrustc, test::CrateRustdoc),
Expand Down
4 changes: 2 additions & 2 deletions src/bootstrap/src/core/builder/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2077,7 +2077,7 @@ mod snapshot {
let ctx = TestCtx::new();
insta::assert_snapshot!(
prepare_test_config(&ctx)
.render_steps(), @r"
.render_steps(), @"
[build] rustc 0 <host> -> Tidy 1 <host>
[test] tidy <>
[build] rustdoc 0 <host>
Expand Down Expand Up @@ -2255,7 +2255,7 @@ mod snapshot {
insta::assert_snapshot!(
prepare_test_config(&ctx)
.stage(2)
.render_steps(), @r"
.render_steps(), @"
[build] rustc 0 <host> -> Tidy 1 <host>
[test] tidy <>
[build] rustdoc 0 <host>
Expand Down
10 changes: 10 additions & 0 deletions src/doc/rustc-dev-guide/src/tests/compiletest.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ The following test suites are available, with links for more information:

[`run-make`](#run-make-tests) are general purpose tests using Rust programs.

### The build-std test suite

[`build-std`](#build-std-tests) test that -Zbuild-std works.

### Rustdoc test suites

| Test suite | Purpose |
Expand Down Expand Up @@ -429,6 +433,12 @@ use cases that require testing in-tree `cargo` in conjunction with in-tree `rust
The `run-make` test suite does not have access to in-tree `cargo` (so it can be the
faster-to-iterate test suite).

### `build-std` tests

The tests in [`tests/build-std`] check that `-Zbuild-std` works. This is currently
just a run-make test suite with a single recipe. The recipe generates test cases
and runs them in parallel.

#### Using Rust recipes

Each test should be in a separate directory with a `rmake.rs` Rust program,
Expand Down
1 change: 1 addition & 0 deletions src/tools/compiletest/src/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ string_enum! {
RustdocUi => "rustdoc-ui",
Ui => "ui",
UiFullDeps => "ui-fulldeps",
BuildStd => "build-std",
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/tools/compiletest/src/runtest/run_make.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,8 @@ impl TestCx<'_> {
// through a specific CI runner).
.env("LLVM_COMPONENTS", &self.config.llvm_components);

// Only `run-make-cargo` test suite gets an in-tree `cargo`, not `run-make`.
if self.config.suite == TestSuite::RunMakeCargo {
// The `run-make-cargo` and `build-std` suites need an in-tree `cargo`, `run-make` does not.
if matches!(self.config.suite, TestSuite::RunMakeCargo | TestSuite::BuildStd) {
cmd.env(
"CARGO",
self.config.cargo_path.as_ref().expect("cargo must be built and made available"),
Expand Down
1 change: 1 addition & 0 deletions src/tools/run-make-support/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ object = "0.37"
regex = "1.11"
serde_json = "1.0"
similar = "2.7"
tempfile = "3"
wasmparser = { version = "0.236", default-features = false, features = ["std", "features", "validate"] }
# tidy-alphabetical-end

Expand Down
13 changes: 13 additions & 0 deletions src/tools/run-make-support/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ pub struct Command {
// Emulate linear type semantics.
drop_bomb: DropBomb,
already_executed: bool,

context: String,
}

impl Command {
Expand All @@ -60,6 +62,7 @@ impl Command {
stdout: None,
stderr: None,
already_executed: false,
context: String::new(),
}
}

Expand All @@ -69,6 +72,16 @@ impl Command {
self.cmd
}

pub(crate) fn get_context(&self) -> &str {
&self.context
}

/// Appends context to the command, to provide a better error message if the command fails.
pub fn context(&mut self, ctx: &str) -> &mut Self {
self.context.push_str(&format!("{ctx}\n"));
self
}

/// Specify a stdin input buffer. This is a convenience helper,
pub fn stdin_buf<I: AsRef<[u8]>>(&mut self, input: I) -> &mut Self {
self.stdin_buf = Some(input.as_ref().to_vec().into_boxed_slice());
Expand Down
4 changes: 3 additions & 1 deletion src/tools/run-make-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ pub mod rfs {
}

// Re-exports of third-party library crates.
pub use {bstr, gimli, libc, object, regex, rustdoc_json_types, serde_json, similar, wasmparser};
pub use {
bstr, gimli, libc, object, regex, rustdoc_json_types, serde_json, similar, tempfile, wasmparser,
};

// Helpers for building names of output artifacts that are potentially target-specific.
pub use crate::artifact_names::{
Expand Down
3 changes: 3 additions & 0 deletions src/tools/run-make-support/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ pub(crate) fn handle_failed_output(
eprintln!("output status: `{}`", output.status());
eprintln!("=== STDOUT ===\n{}\n\n", output.stdout_utf8());
eprintln!("=== STDERR ===\n{}\n\n", output.stderr_utf8());
if !cmd.get_context().is_empty() {
eprintln!("Context:\n{}", cmd.get_context());
}
std::process::exit(1)
}

Expand Down
131 changes: 131 additions & 0 deletions tests/build-std/configurations/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// 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();
}
Loading