1use std::{
7 fs::File,
8 path::{Path, PathBuf},
9};
10
11include!("clang_info.rs");
12
13const BPF_H: &str = "bpf_h";
14
15pub struct Builder;
16
17impl Builder {
18 pub fn new() -> Self {
19 Builder
20 }
21
22 fn gen_bpf_h(&self) {
23 let out_dir = env::var("OUT_DIR").unwrap();
24 let file = File::create(PathBuf::from(&out_dir).join(format!("{}.tar", BPF_H))).unwrap();
25 let mut ar = tar::Builder::new(file);
26
27 ar.follow_symlinks(false);
28 ar.append_dir_all(".", BPF_H).unwrap();
29 ar.finish().unwrap();
30
31 for ent in walkdir::WalkDir::new(BPF_H) {
32 let ent = ent.unwrap();
33 if !ent.file_type().is_dir() {
34 println!("cargo:rerun-if-changed={}", ent.path().to_string_lossy());
35 }
36 }
37 }
38
39 fn gen_bindings(&self) {
40 let out_dir = env::var("OUT_DIR").unwrap();
41 let clang = ClangInfo::new().unwrap();
42 let kernel_target = clang.kernel_target().unwrap();
43 let vmlinux_h = Path::new(&BPF_H)
44 .join("arch")
45 .join(kernel_target)
46 .join("vmlinux.h")
47 .to_str()
48 .unwrap()
49 .to_string();
50
51 let bindings = bindgen::Builder::default()
52 .header(vmlinux_h)
53 .allowlist_type("scx_exit_kind")
54 .allowlist_type("scx_consts")
55 .parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
56 .generate()
57 .expect("Unable to generate bindings");
58
59 bindings
60 .write_to_file(PathBuf::from(&out_dir).join("bindings.rs"))
61 .expect("Couldn't write bindings");
62 }
63
64 pub fn build(self) {
65 self.gen_bpf_h();
66 self.gen_bindings();
67 }
68}