use std::process::Command;
fn main() {
let version = std::env::var("GUT_VERSION")
.ok()
.filter(|s| !s.is_empty())
.or_else(get_git_version)
.unwrap_or_else(|| env!("CARGO_PKG_VERSION").to_string());
println!("cargo:rustc-env=GUT_VERSION={version}");
println!("cargo:rerun-if-changed=.git/HEAD");
println!("cargo:rerun-if-changed=.git/refs/tags");
#[cfg(all(target_os = "linux", feature = "tc_ebpf"))]
{
compile_tc_ebpf();
}
}
#[cfg(all(target_os = "linux", feature = "tc_ebpf"))]
fn compile_tc_ebpf() {
use libbpf_cargo::SkeletonBuilder;
use std::env;
use std::path::PathBuf;
println!("cargo:rerun-if-changed=src/tc/bpf/");
println!("cargo:rerun-if-changed=src/tc/bpf/tc_gut_egress.bpf.c");
println!("cargo:rerun-if-changed=src/tc/bpf/xdp_gut_ingress.bpf.c");
println!("cargo:rerun-if-changed=src/tc/bpf/gut_common.h");
let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR not set"));
let chacha_rounds = env::var("CHACHA_ROUNDS").unwrap_or_else(|_| "4".to_string());
let chacha_define = format!("-DCHACHA_ROUNDS={chacha_rounds}");
println!("cargo:warning=BPF CHACHA_ROUNDS={chacha_rounds}");
let arch_include = format!(
"-I/usr/include/{}",
std::env::consts::ARCH.replace("x86_64", "x86_64-linux-gnu")
);
let egress_skel = out_dir.join("tc_gut_egress.skel.rs");
SkeletonBuilder::new()
.source("src/tc/bpf/tc_gut_egress.bpf.c")
.clang_args(["-I", "src/tc/bpf", &chacha_define, &arch_include])
.build_and_generate(&egress_skel)
.expect("Failed to generate TC egress (v4) skeleton");
let egress_v6_skel = out_dir.join("tc_gut_egress_v6.skel.rs");
SkeletonBuilder::new()
.source("src/tc/bpf/tc_gut_egress.bpf.c")
.clang_args([
"-I",
"src/tc/bpf",
&chacha_define,
"-DGUT_OUTER_IPV6",
&arch_include,
])
.build_and_generate(&egress_v6_skel)
.expect("Failed to generate TC egress (v6) skeleton");
let ingress_skel = out_dir.join("xdp_gut_ingress.skel.rs");
SkeletonBuilder::new()
.source("src/tc/bpf/xdp_gut_ingress.bpf.c")
.clang_args(["-I", "src/tc/bpf", &chacha_define, &arch_include])
.build_and_generate(&ingress_skel)
.expect("Failed to generate XDP ingress skeleton");
println!("cargo:warning=TC eBPF skeletons generated successfully");
}
fn get_git_version() -> Option<String> {
let tag_output = Command::new("git")
.args(["describe", "--tags", "--exact-match"])
.output()
.ok()?;
if tag_output.status.success() {
let tag = String::from_utf8(tag_output.stdout).ok()?;
return Some(tag.trim().to_string());
}
let describe_output = Command::new("git")
.args(["describe", "--tags", "--always", "--dirty"])
.output()
.ok()?;
if describe_output.status.success() {
let version = String::from_utf8(describe_output.stdout).ok()?;
return Some(version.trim().to_string());
}
let commit_output = Command::new("git")
.args(["rev-parse", "--short", "HEAD"])
.output()
.ok()?;
if commit_output.status.success() {
let commit = String::from_utf8(commit_output.stdout).ok()?;
return Some(format!("git-{}", commit.trim()));
}
None
}