Handle pre-2024 cargo and pre-knows-whether-to-build-std cargo

This commit is contained in:
nora 2025-07-07 19:04:42 +02:00 committed by nora
parent 9f18ad0d06
commit c90b94ee69

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,51 +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", "-j1"])
.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(["build", "-Zbuild-std", "--release", "-j1"])
.args(["--target", target]);
let extra_flags = CUSTOM_CORE_FLAGS cmd.current_dir(tmpdir)
.iter() .output()
.find(|flags| flags.target == target); .await
.wrap_err("spawning cargo build")
}
if let Some(extra_flags) = extra_flags { let mut output = run(&toolchain, target, &mut rustflags, tmpdir, "-Zbuild-std").await?;
let flags = extra_flags.flags.join(" "); let mut stderr = String::from_utf8(output.stderr).wrap_err("cargo stderr utf8")?;
cmd.env("RUSTFLAGS", &flags);
rustflags = Some(flags);
}
}
};
let output = cmd
.current_dir(tmpdir)
.output()
.await
.wrap_err("spawning cargo build")?;
let 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
}; };