Use Result in integration-test's build script

Something of an experiment.
reviewable/pr805/r5
Tamir Duberstein 2 months ago committed by Michal Rostecki
parent 2b2af44915
commit b01bc3f49b

@ -30,6 +30,7 @@ tokio = { workspace = true, features = ["macros", "rt-multi-thread", "time"] }
xdpilone = { workspace = true } xdpilone = { workspace = true }
[build-dependencies] [build-dependencies]
anyhow = { workspace = true }
aya-build = { path = "../../aya-build" } aya-build = { path = "../../aya-build" }
# TODO(https://github.com/rust-lang/cargo/issues/12375): this should be an artifact dependency, but # TODO(https://github.com/rust-lang/cargo/issues/12375): this should be an artifact dependency, but
# it's not possible to tell cargo to use `-Z build-std` to build it. We cargo-in-cargo in the build # it's not possible to tell cargo to use `-Z build-std` to build it. We cargo-in-cargo in the build

@ -6,6 +6,7 @@ use std::{
process::{Child, Command, Output, Stdio}, process::{Child, Command, Output, Stdio},
}; };
use anyhow::{anyhow, Context as _, Ok, Result};
use aya_build::cargo_metadata::{Metadata, MetadataCommand, Package, Target, TargetKind}; use aya_build::cargo_metadata::{Metadata, MetadataCommand, Package, Target, TargetKind};
use xtask::{exec, AYA_BUILD_INTEGRATION_BPF, LIBBPF_DIR}; use xtask::{exec, AYA_BUILD_INTEGRATION_BPF, LIBBPF_DIR};
@ -22,26 +23,42 @@ use xtask::{exec, AYA_BUILD_INTEGRATION_BPF, LIBBPF_DIR};
/// occur on metadata-only actions such as `cargo check` or `cargo clippy` of this crate. This means /// occur on metadata-only actions such as `cargo check` or `cargo clippy` of this crate. This means
/// that naively attempting to `cargo test --no-run` this crate will produce binaries that fail at /// that naively attempting to `cargo test --no-run` this crate will produce binaries that fail at
/// runtime because the stubs are inadequate for actually running the tests. /// runtime because the stubs are inadequate for actually running the tests.
fn main() { fn main() -> Result<()> {
println!("cargo:rerun-if-env-changed={}", AYA_BUILD_INTEGRATION_BPF); println!("cargo:rerun-if-env-changed={AYA_BUILD_INTEGRATION_BPF}");
// TODO(https://github.com/rust-lang/cargo/issues/4001): generalize this and move it to // TODO(https://github.com/rust-lang/cargo/issues/4001): generalize this and move it to
// aya-build if we can determine that we're in a check build. // aya-build if we can determine that we're in a check build.
let build_integration_bpf = env::var(AYA_BUILD_INTEGRATION_BPF) let build_integration_bpf = env::var_os(AYA_BUILD_INTEGRATION_BPF)
.as_deref() .map(|build_integration_bpf| {
.map(str::parse) let build_integration_bpf = std::str::from_utf8(
.map(Result::unwrap) build_integration_bpf.as_encoded_bytes(),
)
.with_context(|| format!("{AYA_BUILD_INTEGRATION_BPF}={build_integration_bpf:?}"))?;
let build_integration_bpf = build_integration_bpf
.parse()
.with_context(|| format!("{AYA_BUILD_INTEGRATION_BPF}={build_integration_bpf}"))?;
Ok(build_integration_bpf)
})
.transpose()?
.unwrap_or_default(); .unwrap_or_default();
let Metadata { packages, .. } = MetadataCommand::new().no_deps().exec().unwrap(); let Metadata {
packages,
workspace_root,
..
} = MetadataCommand::new()
.no_deps()
.exec()
.context("MetadataCommand::exec")?;
let integration_ebpf_package = packages let integration_ebpf_package = packages
.into_iter() .into_iter()
.find(|Package { name, .. }| name == "integration-ebpf") .find(|Package { name, .. }| name == "integration-ebpf")
.unwrap(); .ok_or_else(|| anyhow!("integration-ebpf package not found"))?;
let manifest_dir = env::var_os("CARGO_MANIFEST_DIR").unwrap(); let manifest_dir =
env::var_os("CARGO_MANIFEST_DIR").ok_or(anyhow!("CARGO_MANIFEST_DIR not set"))?;
let manifest_dir = PathBuf::from(manifest_dir); let manifest_dir = PathBuf::from(manifest_dir);
let out_dir = env::var_os("OUT_DIR").unwrap(); let out_dir = env::var_os("OUT_DIR").ok_or(anyhow!("OUT_DIR not set"))?;
let out_dir = PathBuf::from(out_dir); let out_dir = PathBuf::from(out_dir);
const C_BPF: &[(&str, bool)] = &[ const C_BPF: &[(&str, bool)] = &[
@ -55,22 +72,18 @@ fn main() {
]; ];
if build_integration_bpf { if build_integration_bpf {
let endian = env::var_os("CARGO_CFG_TARGET_ENDIAN").unwrap(); let endian = env::var_os("CARGO_CFG_TARGET_ENDIAN")
.ok_or(anyhow!("CARGO_CFG_TARGET_ENDIAN not set"))?;
let target = if endian == "big" { let target = if endian == "big" {
"bpfeb" "bpfeb"
} else if endian == "little" { } else if endian == "little" {
"bpfel" "bpfel"
} else { } else {
panic!("unsupported endian={:?}", endian) return Err(anyhow!("unsupported endian={endian:?}"));
}; };
let libbpf_dir = manifest_dir let libbpf_dir = workspace_root.join(LIBBPF_DIR);
.parent() println!("cargo:rerun-if-changed={libbpf_dir}");
.unwrap()
.parent()
.unwrap()
.join(LIBBPF_DIR);
println!("cargo:rerun-if-changed={}", libbpf_dir.to_str().unwrap());
let libbpf_headers_dir = out_dir.join("libbpf_headers"); let libbpf_headers_dir = out_dir.join("libbpf_headers");
@ -84,15 +97,15 @@ fn main() {
.arg(libbpf_dir.join("src")) .arg(libbpf_dir.join("src"))
.arg(includedir) .arg(includedir)
.arg("install_headers"), .arg("install_headers"),
) )?;
.unwrap();
let bpf_dir = manifest_dir.join("bpf"); let bpf_dir = manifest_dir.join("bpf");
let mut target_arch = OsString::new(); let mut target_arch = OsString::new();
target_arch.push("-D__TARGET_ARCH_"); target_arch.push("-D__TARGET_ARCH_");
let arch = env::var_os("CARGO_CFG_TARGET_ARCH").unwrap(); let arch =
env::var_os("CARGO_CFG_TARGET_ARCH").ok_or(anyhow!("CARGO_CFG_TARGET_ARCH not set"))?;
if arch == "x86_64" { if arch == "x86_64" {
target_arch.push("x86"); target_arch.push("x86");
} else if arch == "aarch64" { } else if arch == "aarch64" {
@ -125,9 +138,12 @@ fn main() {
for (src, build_btf) in C_BPF { for (src, build_btf) in C_BPF {
let dst = out_dir.join(src).with_extension("o"); let dst = out_dir.join(src).with_extension("o");
let src = bpf_dir.join(src); let src = bpf_dir.join(src);
println!("cargo:rerun-if-changed={}", src.to_str().unwrap()); {
let src = src.to_str().with_context(|| format!("{src:?}"))?;
println!("cargo:rerun-if-changed={src}");
}
exec(clang().arg(&src).arg("-o").arg(&dst)).unwrap(); exec(clang().arg(&src).arg("-o").arg(&dst))?;
if *build_btf { if *build_btf {
let mut cmd = clang(); let mut cmd = clang();
@ -137,10 +153,10 @@ fn main() {
.args(["-o", "-"]) .args(["-o", "-"])
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.spawn() .spawn()
.unwrap_or_else(|err| panic!("failed to spawn {cmd:?}: {err}")); .with_context(|| format!("failed to spawn {cmd:?}"))?;
let Child { stdout, .. } = &mut child; let Child { stdout, .. } = &mut child;
let stdout = stdout.take().unwrap(); let stdout = stdout.take().expect("stdout");
let dst = dst.with_extension("target.o"); let dst = dst.with_extension("target.o");
@ -154,25 +170,26 @@ fn main() {
.arg(output) .arg(output)
.arg("-") .arg("-")
.stdin(stdout), .stdin(stdout),
) )?;
.unwrap();
let output = child let output = child
.wait_with_output() .wait_with_output()
.unwrap_or_else(|err| panic!("failed to wait for {cmd:?}: {err}")); .with_context(|| format!("failed to wait for {cmd:?}"))?;
let Output { status, .. } = &output; let Output { status, .. } = &output;
assert_eq!(status.code(), Some(0), "{cmd:?} failed: {output:?}"); if !status.success() {
return Err(anyhow!("{cmd:?} failed: {status:?}"));
}
} }
} }
aya_build::build_ebpf([integration_ebpf_package]).unwrap(); aya_build::build_ebpf([integration_ebpf_package])?;
} else { } else {
for (src, build_btf) in C_BPF { for (src, build_btf) in C_BPF {
let dst = out_dir.join(src).with_extension("o"); let dst = out_dir.join(src).with_extension("o");
fs::write(&dst, []).unwrap_or_else(|err| panic!("failed to create {dst:?}: {err}")); fs::write(&dst, []).with_context(|| format!("failed to create {dst:?}"))?;
if *build_btf { if *build_btf {
let dst = dst.with_extension("target.o"); let dst = dst.with_extension("target.o");
fs::write(&dst, []).unwrap_or_else(|err| panic!("failed to create {dst:?}: {err}")); fs::write(&dst, []).with_context(|| format!("failed to create {dst:?}"))?;
} }
} }
@ -182,7 +199,8 @@ fn main() {
continue; continue;
} }
let dst = out_dir.join(name); let dst = out_dir.join(name);
fs::write(&dst, []).unwrap_or_else(|err| panic!("failed to create {dst:?}: {err}")); fs::write(&dst, []).with_context(|| format!("failed to create {dst:?}"))?;
} }
} }
Ok(())
} }

Loading…
Cancel
Save