Compare commits

...

5 commits

Author SHA1 Message Date
8179082517 delete core stuff 2025-07-12 13:29:17 +02:00
c90b94ee69 Handle pre-2024 cargo and pre-knows-whether-to-build-std cargo 2025-07-12 13:29:17 +02:00
9f18ad0d06 -j1 2025-07-12 13:29:17 +02:00
8e9ff1e9fd Run cargo build instead of cargo check for std
And use --release and respect rustflags.

Just to make doubly-sure that even in the future, a build will be done
instead of check.
2025-07-12 13:29:17 +02:00
4969eaeb36 Stop building core
Core is now a subset of std
2025-07-12 13:29:17 +02:00
6 changed files with 85 additions and 129 deletions

View file

@ -2,6 +2,7 @@ use std::{
fmt::{Debug, Display},
num::NonZeroUsize,
path::Path,
process::Output,
time::{Duration, Instant, SystemTime},
};
@ -233,14 +234,9 @@ async fn build_single_target(db: &Db, nightly: &str, target: &str, mode: BuildMo
let start_time = Instant::now();
let result = build_target(
tmpdir.path(),
&Toolchain::from_nightly(nightly),
target,
mode,
)
.await
.wrap_err("running build")?;
let result = build_target(tmpdir.path(), &Toolchain::from_nightly(nightly), target)
.await
.wrap_err("running build")?;
db.insert(FullBuildInfo {
nightly: nightly.into(),
@ -272,16 +268,19 @@ struct BuildResult {
}
/// Build a target core in a temporary directory and see whether it passes or not.
async fn build_target(
tmpdir: &Path,
toolchain: &Toolchain,
target: &str,
mode: BuildMode,
) -> Result<BuildResult> {
async fn build_target(tmpdir: &Path, toolchain: &Toolchain, target: &str) -> Result<BuildResult> {
let mut rustflags = None;
let init = Command::new("cargo")
.args(["init", "--lib", "--name", "target-test"])
.arg(format!("+{toolchain}"))
.args([
"init",
"--lib",
"--name",
"target-test",
"--edition",
"2015",
])
.current_dir(tmpdir)
.output()
.await
@ -294,41 +293,58 @@ async fn build_target(
std::fs::write(&librs, "#![no_std]\n")
.wrap_err_with(|| format!("writing to {}", librs.display()))?;
let mut cmd = Command::new("cargo");
async fn run(
toolchain: &Toolchain,
target: &str,
rustflags: &mut Option<String>,
tmpdir: &Path,
build_std: &str,
) -> Result<Output> {
let mut cmd = Command::new("cargo");
cmd.arg(format!("+{toolchain}"))
.args(["build", "--release", "-j1"])
.arg(build_std)
.args(["--target", target]);
match mode {
BuildMode::Core => {
cmd.arg(format!("+{toolchain}"))
.args(["build", "-Zbuild-std=core", "--release"])
.args(["--target", target]);
let extra_flags = CUSTOM_CORE_FLAGS
.iter()
.find(|flags| flags.target == target);
let extra_flags = CUSTOM_CORE_FLAGS
.iter()
.find(|flags| flags.target == target);
if let Some(extra_flags) = extra_flags {
let flags = extra_flags.flags.join(" ");
cmd.env("RUSTFLAGS", &flags);
rustflags = Some(flags);
}
if let Some(extra_flags) = extra_flags {
let flags = extra_flags.flags.join(" ");
cmd.env("RUSTFLAGS", &flags);
*rustflags = Some(flags);
}
BuildMode::Std => {
cmd.arg(format!("+{toolchain}"))
.args(["check", "-Zbuild-std"])
.args(["--target", target]);
}
};
let output = cmd
.current_dir(tmpdir)
.output()
.await
.wrap_err("spawning cargo build")?;
cmd.current_dir(tmpdir)
.output()
.await
.wrap_err("spawning cargo build")
}
let stderr = String::from_utf8(output.stderr).wrap_err("cargo stderr utf8")?;
let mut output = run(toolchain, target, &mut rustflags, tmpdir, "-Zbuild-std").await?;
let mut stderr = String::from_utf8(output.stderr).wrap_err("cargo stderr utf8")?;
let status = if output.status.success() {
Status::Pass
// older cargo (before 2024-12-15) is clueless about std support
} else if stderr.contains("building std is not supported") {
info!("Retrying build because std is not supported");
output = run(
toolchain,
target,
&mut rustflags,
tmpdir,
"-Zbuild-std=core",
)
.await?;
stderr = String::from_utf8(output.stderr).wrap_err("cargo stderr utf8")?;
if output.status.success() {
Status::Pass
} else {
Status::Error
}
} else {
Status::Error
};

View file

@ -17,16 +17,13 @@ pub static MIGRATOR: Migrator = sqlx::migrate!();
#[derive(Debug, Clone, Copy, sqlx::Type, Serialize, PartialEq, Eq, Hash)]
#[sqlx(rename_all = "kebab-case")]
pub enum BuildMode {
/// `build -Zbuild-std=core`
Core,
/// `check -Zbuild-std`
/// `build --release -Zbuild-std`
Std,
}
impl Display for BuildMode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Core => f.write_str("core"),
Self::Std => f.write_str("std"),
}
}

View file

@ -44,7 +44,7 @@ impl Nightlies {
self.all
.iter()
.flat_map(|nightly| [(nightly, BuildMode::Core), (nightly, BuildMode::Std)])
.flat_map(|nightly| [(nightly, BuildMode::Std)])
.find(|(nightly, mode)| {
!already_finished.contains(&FinishedNightly {
nightly: (*nightly).to_owned(),

View file

@ -44,14 +44,14 @@ impl<'de> serde::Deserialize<'de> for LegacyBuildMode {
{
let s = String::deserialize(deserializer)?;
match s.as_str() {
"core" => Ok(LegacyBuildMode(BuildMode::Core)),
"core" => Ok(LegacyBuildMode(BuildMode::Std)),
"std" => Ok(LegacyBuildMode(BuildMode::Std)),
// This mode used to be called "miri-std" but it has been renamed to "std" using build-std.
// Allow the old value to keep links working but map it to std.
"miri-std" => Ok(LegacyBuildMode(BuildMode::Std)),
_ => Err(serde::de::Error::custom(format!(
"invalid build mode, expected 'core', 'std', or 'miri-std'"
))),
_ => Err(serde::de::Error::custom(
"invalid build mode, expected 'core', 'std', or 'miri-std'".to_owned(),
)),
}
}
}
@ -85,7 +85,7 @@ async fn web_build(State(state): State<AppState>, Query(query): Query<BuildQuery
.build_status_full(
&query.nightly,
&query.target,
query.mode.map(|mode| mode.0).unwrap_or(BuildMode::Core),
query.mode.map(|mode| mode.0).unwrap_or(BuildMode::Std),
)
.await
{
@ -144,26 +144,14 @@ async fn web_target(State(state): State<AppState>, Query(query): Query<TargetQue
match state.db.history_for_target(&query.target).await {
Ok(builds) => {
let latest_core = builds
let latest_std = builds
.iter()
.filter(|build| build.mode == BuildMode::Core)
.max_by_key(|elem| elem.nightly.clone());
let latest_miri = builds
.iter()
.filter(|build| build.mode == BuildMode::Core)
.filter(|build| build.mode == BuildMode::Std)
.max_by_key(|elem| elem.nightly.clone());
let status = match (latest_core, latest_miri) {
(Some(core), Some(std)) => {
if core.status == Status::Error || std.status == Status::Error {
Status::Error
} else {
Status::Pass
}
.to_string()
}
(Some(one), None) | (None, Some(one)) => one.status.to_string(),
(None, None) => "missing".to_owned(),
let status = match latest_std {
Some(one) => one.status.to_string(),
None => "missing".to_owned(),
};
let mut builds_grouped =
@ -171,7 +159,6 @@ async fn web_target(State(state): State<AppState>, Query(query): Query<TargetQue
for build in builds {
let v = builds_grouped.entry(build.nightly.clone()).or_default();
match build.mode {
BuildMode::Core => v.0 = Some(build),
BuildMode::Std => v.1 = Some(build),
}
}
@ -217,9 +204,7 @@ async fn web_nightly(State(state): State<AppState>, Query(query): Query<NightlyQ
nightly: String,
version: &'static str,
builds: Vec<(String, Option<BuildInfo>, Option<BuildInfo>)>,
core_failures: usize,
std_failures: usize,
core_broken: Option<String>,
std_broken: Option<String>,
showing_failures: bool,
}
@ -234,17 +219,14 @@ async fn web_nightly(State(state): State<AppState>, Query(query): Query<NightlyQ
for build in &builds {
let v = builds_grouped.entry(build.target.clone()).or_default();
match build.mode {
BuildMode::Core => v.0 = Some(build.clone()),
BuildMode::Std => v.1 = Some(build.clone()),
}
}
let mut std_failures = 0;
let mut core_failures = 0;
for build in builds {
if build.status == Status::Error {
match build.mode {
BuildMode::Core => core_failures += 1,
BuildMode::Std => std_failures += 1,
}
}
@ -260,10 +242,6 @@ async fn web_nightly(State(state): State<AppState>, Query(query): Query<NightlyQ
.collect::<Vec<_>>();
builds.sort_by_cached_key(|build| build.0.clone());
let core_broken = info
.iter()
.find(|info| info.mode == BuildMode::Core && info.is_broken)
.and_then(|info| info.broken_error.clone());
let std_broken = info
.iter()
.find(|info| info.mode == BuildMode::Std && info.is_broken)
@ -274,8 +252,6 @@ async fn web_nightly(State(state): State<AppState>, Query(query): Query<NightlyQ
version: crate::VERSION,
builds,
std_failures,
core_failures,
core_broken,
std_broken,
showing_failures: filter_failures,
};

View file

@ -10,27 +10,13 @@
<h1>Nightly build state for {{nightly}}</h1>
<a href="/">Home</a>
<p>
This contains the status of this nightly. Core is built with
<code>cargo build --release -Zbuild-std=core</code>. This checks that
codegen/linking of core works, but does not check whether std builds.
</p>
<p>
std is being built with <code>cargo check -Zbuild-std</code>. If a target
does not support std, the std column represents core/alloc. This checks
that std checks (on targets that have it) but does not check whether
codegen/linking works.
The build is performned with <code>cargo build --release -Zbuild-std</code> for a library crate.
For older builds, <code>cargo miri setup</code> was used instead.
</p>
{% if let Some(core_broken) = core_broken %}
<p>
⚠️ The core build is broken in general for this nightly, so no data is available ⚠️
This checks whether everything builds successfully (excluding binary linking, which often requires complex toolchains).
For no-std targets, Cargo's build-std logic is used for figuring out whether to build std or not.
On older targets (older than November 2024) this does not always work reliably, so some failed std builds there are simply no-std targets.
</p>
<pre>
{{core_broken}}
</pre>
{% endif %}
{% if let Some(std_broken) = std_broken %}
<p>
⚠️ The std build is broken for this nightly, so no data is available ⚠️
@ -43,8 +29,6 @@
<p>
<dl>
<dt>core failures</dt>
<dd>{{core_failures}}</dd>
<dt>std failures</dt>
<dd>{{std_failures}}</dd>
</dl>
@ -61,21 +45,12 @@
<table>
<tr>
<th>nightly</th>
<th>core<br>codegen</th>
<th>std<br>check</th>
<th>std<br>build</th>
</tr>
{% for build in builds %}
<tr>
<td><a href="/target?target={{build.0}}">{{ build.0 }}</a></td>
{% match build.1 %} {% when Some with (build) %}
<td class="build-cell">
<a class="build-info-a" href="{{ build.link() }}">
{{ build.status.to_emoji() }}
</a>
</td>
{% when None %}
<td class="missing"></td>
{% endmatch %} {% match build.2 %} {% when Some with (build) %}
{% match build.2 %} {% when Some with (build) %}
<td class="build-cell">
<a class="build-info-a" href="{{ build.link() }}">
<span> {{ build.status.to_emoji() }} </span>

View file

@ -23,12 +23,13 @@
codegen/linking of core works, but does not check whether std builds.
</p>
<p>
std is being built with <code>cargo check -Zbuild-std</code>. If a target
does not support std, the std column represents core/alloc. This checks
that std checks (on targets that have it) but does not check whether
codegen/linking works.
For older builds, <code>cargo miri setup</code> was used instead.
The build is performned with
<code>cargo build --release -Zbuild-std</code> for a library crate. This
checks whether everything builds successfully (excluding binary linking,
which often requires complex toolchains). For no-std targets, Cargo's
build-std logic is used for figuring out whether to build std or not. On
older targets (older than November 2024) this does not always work
reliably, so some failed std builds there are simply no-std targets.
</p>
{% if showing_failures %}
<p>
@ -42,21 +43,12 @@
<table>
<tr>
<th>nightly</th>
<th>core<br />codegen</th>
<th>std<br />check</th>
<th>std<br />build</th>
</tr>
{% for build in builds %}
<tr>
<td><a href="/nightly?nightly={{build.0}}">{{ build.0 }}</a></td>
{% match build.1 %} {% when Some with (build) %}
<td class="build-cell">
<a class="build-info-a" href="{{ build.link() }}">
{{ build.status.to_emoji() }}
</a>
</td>
{% when None %}
<td class="missing"></td>
{% endmatch %} {% match build.2 %} {% when Some with (build) %}
{% match build.2 %} {% when Some with (build) %}
<td class="build-cell">
<a class="build-info-a" href="{{ build.link() }}">
<span> {{ build.status.to_emoji() }} </span>