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}, fmt::{Debug, Display},
num::NonZeroUsize, num::NonZeroUsize,
path::Path, path::Path,
process::Output,
time::{Duration, Instant, SystemTime}, 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 start_time = Instant::now();
let result = build_target( let result = build_target(tmpdir.path(), &Toolchain::from_nightly(nightly), target)
tmpdir.path(), .await
&Toolchain::from_nightly(nightly), .wrap_err("running build")?;
target,
mode,
)
.await
.wrap_err("running build")?;
db.insert(FullBuildInfo { db.insert(FullBuildInfo {
nightly: nightly.into(), nightly: nightly.into(),
@ -272,16 +268,19 @@ struct BuildResult {
} }
/// Build a target core in a temporary directory and see whether it passes or not. /// Build a target core in a temporary directory and see whether it passes or not.
async fn build_target( async fn build_target(tmpdir: &Path, toolchain: &Toolchain, target: &str) -> Result<BuildResult> {
tmpdir: &Path,
toolchain: &Toolchain,
target: &str,
mode: BuildMode,
) -> Result<BuildResult> {
let mut rustflags = None; let mut rustflags = None;
let init = Command::new("cargo") 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) .current_dir(tmpdir)
.output() .output()
.await .await
@ -294,41 +293,58 @@ async fn build_target(
std::fs::write(&librs, "#![no_std]\n") std::fs::write(&librs, "#![no_std]\n")
.wrap_err_with(|| format!("writing to {}", librs.display()))?; .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 { let extra_flags = CUSTOM_CORE_FLAGS
BuildMode::Core => { .iter()
cmd.arg(format!("+{toolchain}")) .find(|flags| flags.target == target);
.args(["build", "-Zbuild-std=core", "--release"])
.args(["--target", target]);
let extra_flags = CUSTOM_CORE_FLAGS if let Some(extra_flags) = extra_flags {
.iter() let flags = extra_flags.flags.join(" ");
.find(|flags| flags.target == target); 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 cmd.current_dir(tmpdir)
.current_dir(tmpdir) .output()
.output() .await
.await .wrap_err("spawning cargo build")
.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() { let status = if output.status.success() {
Status::Pass 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 { } else {
Status::Error Status::Error
}; };

View file

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

View file

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

View file

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

View file

@ -10,27 +10,13 @@
<h1>Nightly build state for {{nightly}}</h1> <h1>Nightly build state for {{nightly}}</h1>
<a href="/">Home</a> <a href="/">Home</a>
<p> <p>
This contains the status of this nightly. Core is built with The build is performned with <code>cargo build --release -Zbuild-std</code> for a library crate.
<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.
For older builds, <code>cargo miri setup</code> was used instead. This checks whether everything builds successfully (excluding binary linking, which often requires complex toolchains).
</p> For no-std targets, Cargo's build-std logic is used for figuring out whether to build std or not.
{% if let Some(core_broken) = core_broken %} 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>
⚠️ The core build is broken in general for this nightly, so no data is available ⚠️
</p> </p>
<pre>
{{core_broken}}
</pre>
{% endif %}
{% if let Some(std_broken) = std_broken %} {% if let Some(std_broken) = std_broken %}
<p> <p>
⚠️ The std build is broken for this nightly, so no data is available ⚠️ ⚠️ The std build is broken for this nightly, so no data is available ⚠️
@ -43,8 +29,6 @@
<p> <p>
<dl> <dl>
<dt>core failures</dt>
<dd>{{core_failures}}</dd>
<dt>std failures</dt> <dt>std failures</dt>
<dd>{{std_failures}}</dd> <dd>{{std_failures}}</dd>
</dl> </dl>
@ -61,21 +45,12 @@
<table> <table>
<tr> <tr>
<th>nightly</th> <th>nightly</th>
<th>core<br>codegen</th> <th>std<br>build</th>
<th>std<br>check</th>
</tr> </tr>
{% for build in builds %} {% for build in builds %}
<tr> <tr>
<td><a href="/target?target={{build.0}}">{{ build.0 }}</a></td> <td><a href="/target?target={{build.0}}">{{ build.0 }}</a></td>
{% match build.1 %} {% when Some with (build) %} {% match build.2 %} {% 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) %}
<td class="build-cell"> <td class="build-cell">
<a class="build-info-a" href="{{ build.link() }}"> <a class="build-info-a" href="{{ build.link() }}">
<span> {{ build.status.to_emoji() }} </span> <span> {{ build.status.to_emoji() }} </span>

View file

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