fn main() {
#[cfg(feature = "ebpf")]
compile_bpf_programs();
#[cfg(feature = "server-grpc")]
compile_grpc_protos();
}
#[cfg(feature = "server-grpc")]
fn compile_grpc_protos() {
println!("cargo:rerun-if-changed=proto/symbiot.proto");
tonic_prost_build::compile_protos("proto/symbiot.proto")
.expect("Failed to compile gRPC protos. Is protoc installed?");
}
#[cfg(feature = "ebpf")]
fn compile_bpf_programs() {
use std::env;
use std::path::{Path, PathBuf};
use std::process::Command;
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
let bpf_dir = Path::new(&manifest_dir).join("bpf");
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
let programs = ["sched_switch", "sched_tp_btf", "syscall_latency", "syscall_tp_btf", "lock_contention", "sense_hub", "pmu_sample"];
let arch_flag = match env::var("CARGO_CFG_TARGET_ARCH").as_deref() {
Ok("x86_64") => "-D__TARGET_ARCH_x86",
Ok("aarch64") => "-D__TARGET_ARCH_arm64",
_ => "-D__TARGET_ARCH_x86",
};
for prog in &programs {
let src = bpf_dir.join(format!("{}.bpf.c", prog));
let obj = out_dir.join(format!("{}.bpf.o", prog));
println!("cargo:rerun-if-changed={}", src.display());
let status = Command::new("clang")
.args([
"-target", "bpf",
arch_flag,
"-O2",
"-g", "-Wall",
"-I/usr/include",
&format!("-I{}", bpf_dir.display()),
"-c",
&src.to_string_lossy(),
"-o",
&obj.to_string_lossy(),
])
.status();
match status {
Ok(s) if s.success() => {
println!("cargo:warning=BPF: compiled {}.bpf.c", prog);
}
Ok(s) => {
panic!("clang failed for {}.bpf.c with exit code: {}", prog, s);
}
Err(e) => {
panic!(
"Failed to run clang for {}.bpf.c: {}. \
Install clang: dnf install clang",
prog, e
);
}
}
}
println!("cargo:rerun-if-changed={}", bpf_dir.join("common.h").display());
println!("cargo:rerun-if-changed={}", bpf_dir.join("vmlinux.h").display());
}