|
|
|
@ -6,6 +6,7 @@ use std::{
|
|
|
|
|
process::{Child, Command, Output, Stdio},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
use anyhow::{anyhow, Context as _, Ok, Result};
|
|
|
|
|
use aya_build::cargo_metadata::{Metadata, MetadataCommand, Package, Target, TargetKind};
|
|
|
|
|
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
|
|
|
|
|
/// 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.
|
|
|
|
|
fn main() {
|
|
|
|
|
println!("cargo:rerun-if-env-changed={}", AYA_BUILD_INTEGRATION_BPF);
|
|
|
|
|
fn main() -> Result<()> {
|
|
|
|
|
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
|
|
|
|
|
// aya-build if we can determine that we're in a check build.
|
|
|
|
|
let build_integration_bpf = env::var(AYA_BUILD_INTEGRATION_BPF)
|
|
|
|
|
.as_deref()
|
|
|
|
|
.map(str::parse)
|
|
|
|
|
.map(Result::unwrap)
|
|
|
|
|
let build_integration_bpf = env::var_os(AYA_BUILD_INTEGRATION_BPF)
|
|
|
|
|
.map(|build_integration_bpf| {
|
|
|
|
|
let build_integration_bpf = std::str::from_utf8(
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
.into_iter()
|
|
|
|
|
.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 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);
|
|
|
|
|
|
|
|
|
|
const C_BPF: &[(&str, bool)] = &[
|
|
|
|
@ -55,22 +72,18 @@ fn main() {
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
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" {
|
|
|
|
|
"bpfeb"
|
|
|
|
|
} else if endian == "little" {
|
|
|
|
|
"bpfel"
|
|
|
|
|
} else {
|
|
|
|
|
panic!("unsupported endian={:?}", endian)
|
|
|
|
|
return Err(anyhow!("unsupported endian={endian:?}"));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let libbpf_dir = manifest_dir
|
|
|
|
|
.parent()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.parent()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.join(LIBBPF_DIR);
|
|
|
|
|
println!("cargo:rerun-if-changed={}", libbpf_dir.to_str().unwrap());
|
|
|
|
|
let libbpf_dir = workspace_root.join(LIBBPF_DIR);
|
|
|
|
|
println!("cargo:rerun-if-changed={libbpf_dir}");
|
|
|
|
|
|
|
|
|
|
let libbpf_headers_dir = out_dir.join("libbpf_headers");
|
|
|
|
|
|
|
|
|
@ -84,15 +97,15 @@ fn main() {
|
|
|
|
|
.arg(libbpf_dir.join("src"))
|
|
|
|
|
.arg(includedir)
|
|
|
|
|
.arg("install_headers"),
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
let bpf_dir = manifest_dir.join("bpf");
|
|
|
|
|
|
|
|
|
|
let mut target_arch = OsString::new();
|
|
|
|
|
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" {
|
|
|
|
|
target_arch.push("x86");
|
|
|
|
|
} else if arch == "aarch64" {
|
|
|
|
@ -125,9 +138,12 @@ fn main() {
|
|
|
|
|
for (src, build_btf) in C_BPF {
|
|
|
|
|
let dst = out_dir.join(src).with_extension("o");
|
|
|
|
|
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 {
|
|
|
|
|
let mut cmd = clang();
|
|
|
|
@ -137,10 +153,10 @@ fn main() {
|
|
|
|
|
.args(["-o", "-"])
|
|
|
|
|
.stdout(Stdio::piped())
|
|
|
|
|
.spawn()
|
|
|
|
|
.unwrap_or_else(|err| panic!("failed to spawn {cmd:?}: {err}"));
|
|
|
|
|
.with_context(|| format!("failed to spawn {cmd:?}"))?;
|
|
|
|
|
|
|
|
|
|
let Child { stdout, .. } = &mut child;
|
|
|
|
|
let stdout = stdout.take().unwrap();
|
|
|
|
|
let stdout = stdout.take().expect("stdout");
|
|
|
|
|
|
|
|
|
|
let dst = dst.with_extension("target.o");
|
|
|
|
|
|
|
|
|
@ -154,25 +170,26 @@ fn main() {
|
|
|
|
|
.arg(output)
|
|
|
|
|
.arg("-")
|
|
|
|
|
.stdin(stdout),
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
let output = child
|
|
|
|
|
.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;
|
|
|
|
|
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 {
|
|
|
|
|
for (src, build_btf) in C_BPF {
|
|
|
|
|
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 {
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
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(())
|
|
|
|
|
}
|
|
|
|
|