use std::path::{Path, PathBuf};
const STAGED_MANIFEST: &str = "Cargo.toml.embedded";
fn main() -> Result<(), Box<dyn std::error::Error>> {
let manifest_dir =
PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR is not set by Cargo"));
let sibling_probes = manifest_dir.join("../aa-ebpf-probes");
let embedded_probes = manifest_dir.join("_embedded/aa-ebpf-probes");
let probes_dir: Option<PathBuf> = if sibling_probes.join("Cargo.toml").exists() {
println!("cargo:rerun-if-changed={}", sibling_probes.display());
Some(sibling_probes)
} else if embedded_probes.join(STAGED_MANIFEST).exists() || embedded_probes.join("Cargo.toml").exists() {
restore_manifest_from_stage(&embedded_probes)?;
println!("cargo:rerun-if-changed={}", embedded_probes.display());
Some(embedded_probes)
} else {
None
};
#[cfg(target_os = "linux")]
{
use std::{env, fs, process::Command};
let out_dir = env::var("OUT_DIR")?;
let target_dir = PathBuf::from(&out_dir).join("aa-ebpf-probes");
let release_dir = target_dir.join("bpfel-unknown-none/release");
let binaries = ["aa-file-io", "aa-exec-probes", "aa-tls-probes"];
let build_ok = if let Some(dir) = probes_dir.as_ref() {
let status = Command::new("rustup")
.args(["run", "nightly", "cargo", "build", "--release"])
.arg("--target-dir")
.arg(&target_dir)
.current_dir(dir)
.env_remove("RUSTC")
.env_remove("RUSTC_WORKSPACE_WRAPPER")
.status();
matches!(status, Ok(s) if s.success())
} else {
false
};
if !build_ok {
eprintln!(
"cargo:warning=BPF probe compilation skipped/failed (no probe source or nightly toolchain missing). \
Creating empty stubs — eBPF loaders will degrade at runtime."
);
fs::create_dir_all(&release_dir)?;
for name in &binaries {
let path = release_dir.join(name);
if !path.exists() {
fs::write(&path, b"")?;
}
}
}
}
let _ = probes_dir;
Ok(())
}
fn restore_manifest_from_stage(probes_dir: &Path) -> std::io::Result<()> {
let real = probes_dir.join("Cargo.toml");
let staged = probes_dir.join(STAGED_MANIFEST);
if real.exists() {
return Ok(());
}
if staged.exists() {
std::fs::rename(&staged, &real)?;
}
Ok(())
}