diff --git a/src/build.rs b/src/build.rs index 6bded12..8e81c91 100644 --- a/src/build.rs +++ b/src/build.rs @@ -2,7 +2,6 @@ use std::{ fmt::{Debug, Display}, num::NonZeroUsize, path::Path, - process::Output, time::{Duration, Instant, SystemTime}, }; @@ -234,9 +233,14 @@ 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) - .await - .wrap_err("running build")?; + let result = build_target( + tmpdir.path(), + &Toolchain::from_nightly(nightly), + target, + mode, + ) + .await + .wrap_err("running build")?; db.insert(FullBuildInfo { nightly: nightly.into(), @@ -268,19 +272,16 @@ 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) -> Result { +async fn build_target( + tmpdir: &Path, + toolchain: &Toolchain, + target: &str, + mode: BuildMode, +) -> Result { let mut rustflags = None; let init = Command::new("cargo") - .arg(format!("+{toolchain}")) - .args([ - "init", - "--lib", - "--name", - "target-test", - "--edition", - "2015", - ]) + .args(["init", "--lib", "--name", "target-test"]) .current_dir(tmpdir) .output() .await @@ -293,58 +294,41 @@ async fn build_target(tmpdir: &Path, toolchain: &Toolchain, target: &str) -> Res std::fs::write(&librs, "#![no_std]\n") .wrap_err_with(|| format!("writing to {}", librs.display()))?; - async fn run( - toolchain: &Toolchain, - target: &str, - rustflags: &mut Option, - tmpdir: &Path, - build_std: &str, - ) -> Result { - let mut cmd = Command::new("cargo"); - cmd.arg(format!("+{toolchain}")) - .args(["build", "--release", "-j1"]) - .arg(build_std) - .args(["--target", target]); + let mut cmd = Command::new("cargo"); - let extra_flags = CUSTOM_CORE_FLAGS - .iter() - .find(|flags| flags.target == target); + match mode { + BuildMode::Core => { + cmd.arg(format!("+{toolchain}")) + .args(["build", "-Zbuild-std=core", "--release"]) + .args(["--target", target]); - if let Some(extra_flags) = extra_flags { - let flags = extra_flags.flags.join(" "); - cmd.env("RUSTFLAGS", &flags); - *rustflags = Some(flags); + 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); + } } + BuildMode::Std => { + cmd.arg(format!("+{toolchain}")) + .args(["check", "-Zbuild-std"]) + .args(["--target", target]); + } + }; - cmd.current_dir(tmpdir) - .output() - .await - .wrap_err("spawning cargo build") - } + let output = cmd + .current_dir(tmpdir) + .output() + .await + .wrap_err("spawning cargo build")?; - 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 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 }; diff --git a/src/db.rs b/src/db.rs index 7083dd0..71f34fe 100644 --- a/src/db.rs +++ b/src/db.rs @@ -17,13 +17,16 @@ 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 --release -Zbuild-std` + /// `build -Zbuild-std=core` + Core, + /// `check -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"), } } diff --git a/src/nightlies.rs b/src/nightlies.rs index ab78e04..dd925d5 100644 --- a/src/nightlies.rs +++ b/src/nightlies.rs @@ -44,7 +44,7 @@ impl Nightlies { self.all .iter() - .flat_map(|nightly| [(nightly, BuildMode::Std)]) + .flat_map(|nightly| [(nightly, BuildMode::Core), (nightly, BuildMode::Std)]) .find(|(nightly, mode)| { !already_finished.contains(&FinishedNightly { nightly: (*nightly).to_owned(), diff --git a/src/web.rs b/src/web.rs index b6528ce..9d2c2d2 100644 --- a/src/web.rs +++ b/src/web.rs @@ -44,14 +44,14 @@ impl<'de> serde::Deserialize<'de> for LegacyBuildMode { { let s = String::deserialize(deserializer)?; match s.as_str() { - "core" => Ok(LegacyBuildMode(BuildMode::Std)), + "core" => Ok(LegacyBuildMode(BuildMode::Core)), "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( - "invalid build mode, expected 'core', 'std', or 'miri-std'".to_owned(), - )), + _ => Err(serde::de::Error::custom(format!( + "invalid build mode, expected 'core', 'std', or 'miri-std'" + ))), } } } @@ -85,7 +85,7 @@ async fn web_build(State(state): State, Query(query): Query, Query(query): Query { - let latest_std = builds + let latest_core = builds .iter() - .filter(|build| build.mode == BuildMode::Std) + .filter(|build| build.mode == BuildMode::Core) + .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()); - let status = match latest_std { - Some(one) => one.status.to_string(), - None => "missing".to_owned(), + 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 mut builds_grouped = @@ -159,6 +171,7 @@ async fn web_target(State(state): State, Query(query): Query v.0 = Some(build), BuildMode::Std => v.1 = Some(build), } } @@ -204,7 +217,9 @@ async fn web_nightly(State(state): State, Query(query): Query, Option)>, + core_failures: usize, std_failures: usize, + core_broken: Option, std_broken: Option, showing_failures: bool, } @@ -219,14 +234,17 @@ async fn web_nightly(State(state): State, Query(query): Query 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, } } @@ -242,6 +260,10 @@ async fn web_nightly(State(state): State, Query(query): Query>(); 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) @@ -252,6 +274,8 @@ async fn web_nightly(State(state): State, Query(query): QueryNightly build state for {{nightly}} Home

- The build is performned with cargo build --release -Zbuild-std for a library crate. + This contains the status of this nightly. Core is built with + cargo build --release -Zbuild-std=core. This checks that + codegen/linking of core works, but does not check whether std builds. +

+

+ std is being built with cargo check -Zbuild-std. 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. - 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. + For older builds, cargo miri setup was used instead. +

+ {% if let Some(core_broken) = core_broken %} +

+ ⚠️ The core build is broken in general for this nightly, so no data is available ⚠️

+
+      {{core_broken}}
+    
+ {% endif %} {% if let Some(std_broken) = std_broken %}

⚠️ The std build is broken for this nightly, so no data is available ⚠️ @@ -29,6 +43,8 @@

+
core failures
+
{{core_failures}}
std failures
{{std_failures}}
@@ -45,12 +61,21 @@ - + + {% for build in builds %} - {% match build.2 %} {% when Some with (build) %} + {% match build.1 %} {% when Some with (build) %} + + {% when None %} + + {% endmatch %} {% match build.2 %} {% when Some with (build) %}
nightlystd
build
core
codegen
std
check
{{ build.0 }} + + {{ build.status.to_emoji() }} + + {{ build.status.to_emoji() }} diff --git a/templates/target.html b/templates/target.html index a39765c..07b7a43 100644 --- a/templates/target.html +++ b/templates/target.html @@ -23,13 +23,12 @@ codegen/linking of core works, but does not check whether std builds.

- The build is performned with - cargo build --release -Zbuild-std 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. + std is being built with cargo check -Zbuild-std. 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, cargo miri setup was used instead.

{% if showing_failures %}

@@ -43,12 +42,21 @@ - + + {% for build in builds %} - {% match build.2 %} {% when Some with (build) %} + {% match build.1 %} {% when Some with (build) %} + + {% when None %} + + {% endmatch %} {% match build.2 %} {% when Some with (build) %}
nightlystd
build
core
codegen
std
check
{{ build.0 }} + + {{ build.status.to_emoji() }} + + {{ build.status.to_emoji() }}