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