You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
aya/test/cases/_lib/compile-ebpf.ers

85 lines
2.4 KiB
Plaintext

//! ```cargo
//! [dependencies]
//! libbpf-sys = { version = "0.6.1-1" }
//! anyhow = "1"
//! ```
use std::{
env,
fs::{self, OpenOptions},
io::Write,
path::Path,
process::Command,
string::String,
};
use anyhow::{bail, Context, Result};
static CLANG_DEFAULT: &str = "/usr/bin/clang";
/// Extract vendored libbpf headers from libbpf-sys.
fn extract_libbpf_headers<P: AsRef<Path>>(include_path: P) -> Result<()> {
let dir = include_path.as_ref().join("bpf");
fs::create_dir_all(&dir)?;
for (filename, contents) in libbpf_sys::API_HEADERS.iter() {
let path = dir.as_path().join(filename);
let mut file = OpenOptions::new().write(true).create(true).open(path)?;
file.write_all(contents.as_bytes())?;
}
Ok(())
}
/// Build eBPF programs with clang and libbpf headers.
fn build_ebpf<P: Clone + AsRef<Path>>(in_file: P, out_file: P, include_path: P) -> Result<()> {
extract_libbpf_headers(include_path.clone())?;
let clang = match env::var("CLANG") {
Ok(val) => val,
Err(_) => String::from(CLANG_DEFAULT),
};
let arch = match std::env::consts::ARCH {
"x86_64" => "x86",
"aarch64" => "arm64",
_ => std::env::consts::ARCH,
};
let mut cmd = Command::new(clang);
cmd.arg(format!("-I{}", include_path.as_ref().to_string_lossy()))
.arg("-g")
.arg("-O2")
.arg("-target")
.arg("bpf")
.arg("-c")
.arg(format!("-D__TARGET_ARCH_{}", arch))
.arg(in_file.as_ref().as_os_str())
.arg("-o")
.arg(out_file.as_ref().as_os_str());
let output = cmd.output().context("Failed to execute clang")?;
if !output.status.success() {
bail!(
"Failed to compile eBPF programs\n \
stdout=\n \
{}\n \
stderr=\n \
{}\n",
String::from_utf8(output.stdout).unwrap(),
String::from_utf8(output.stderr).unwrap()
);
}
Ok(())
}
fn main() -> Result<()> {
let args: Vec<String> = env::args().collect();
if args.len() != 3 {
bail!("requires 2 arguments. src and dst")
}
let path = env::current_dir()?;
let src = Path::new(&args[1]);
let dst = Path::new(&args[2]);
let include_path = path.join("include");
fs::create_dir_all(include_path.clone())?;
build_ebpf(src, dst, &include_path)?;
Ok(())
}