1 use bindgen;
2 use bindgen::callbacks::{IntKind, ParseCallbacks};
3 use cc;
4 use std::env;
5 use std::path::PathBuf;
6 
main()7 fn main() {
8     generate_bindings();
9 }
10 
generate_bindings()11 fn generate_bindings() {
12     let mut bindings = bindgen::Builder::default()
13         .header("wrapper.h")
14         // filter out stuff from <linux/types.h>
15         .blocklist_item("__BITS_PER_LONG")
16         .blocklist_item("__FD_SETSIZE")
17         .blocklist_type("__[lb]e.*")
18         .blocklist_type("__w?sum.*")
19         .blocklist_type("__kernel_*")
20         .parse_callbacks(Box::new(Callbacks {}));
21 
22     if let Ok(linux_headers) = std::env::var("LINUX_HEADERS") {
23         let mut incl_dir = PathBuf::from(&linux_headers);
24         incl_dir.push("include");
25         assert!(
26             incl_dir.exists(),
27             "LINUX_HEADERS env variable contains an include/ directory"
28         );
29         incl_dir.push("uapi");
30         assert!(
31             incl_dir.exists(),
32             "LINUX_HEADERS env variable contains an include/uapi/ directory"
33         );
34         bindings = bindings
35             .clang_arg(format!("-isystem{}/include", linux_headers))
36             .clang_arg(format!("-isystem{}/include/uapi", linux_headers));
37     }
38 
39     let bindings = bindings.generate().expect("binding generation failed");
40 
41     let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
42     bindings
43         .write_to_file(out_path.join("bindings.rs"))
44         .expect("binding file couldn't be written");
45 }
46 
47 // all this stuff with callbacks is to give the integer constants the right types
48 
49 #[derive(Debug)]
50 struct Callbacks {}
51 
52 impl ParseCallbacks for Callbacks {
int_macro(&self, name: &str, _value: i64) -> Option<IntKind>53     fn int_macro(&self, name: &str, _value: i64) -> Option<IntKind> {
54         for (prefix, kind) in [
55             ("_UFFDIO_", IntKind::U64),
56             ("UFFD_API", IntKind::U64),
57             ("UFFDIO", IntKind::U8),
58             ("UFFD_EVENT_", IntKind::U8),
59             ("UFFD_PAGEFAULT_FLAG_", IntKind::U64),
60             ("UFFD_FEATURE_", IntKind::U64),
61         ]
62         .iter()
63         {
64             if name.starts_with(prefix) {
65                 return Some(*kind);
66             }
67         }
68         return None;
69     }
70 }
71