mirror of https://github.com/aya-rs/aya
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.
85 lines
2.4 KiB
Plaintext
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(())
|
|
} |