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