symbiotic 0.1.0

High-resolution performance profiling with hardware PMU counters, eBPF, and tracing integration
Documentation
/// Build script for symbiotic.
///
/// When the `ebpf` feature is enabled, compiles BPF C programs with clang
/// and places the object files where the Rust code can embed them via
/// include_bytes!().

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"];

    // Determine target arch flag
    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",                    // BTF debug info for CO-RE
                "-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
                );
            }
        }
    }

    // Rerun if common header changes
    println!("cargo:rerun-if-changed={}", bpf_dir.join("common.h").display());
    println!("cargo:rerun-if-changed={}", bpf_dir.join("vmlinux.h").display());
}