• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 extern crate bindgen;
2 #[cfg(feature = "logging")]
3 extern crate env_logger;
4 #[macro_use]
5 #[cfg(feature = "logging")]
6 extern crate log;
7 extern crate clap;
8 
9 use bindgen::clang_version;
10 use std::env;
11 use std::panic;
12 
13 #[macro_use]
14 #[cfg(not(feature = "logging"))]
15 mod log_stubs;
16 
17 mod options;
18 use crate::options::builder_from_flags;
19 
clang_version_check()20 fn clang_version_check() {
21     let version = clang_version();
22     let expected_version = if cfg!(feature = "testing_only_libclang_9") {
23         Some((9, 0))
24     } else if cfg!(feature = "testing_only_libclang_5") {
25         Some((5, 0))
26     } else if cfg!(feature = "testing_only_libclang_4") {
27         Some((4, 0))
28     } else if cfg!(feature = "testing_only_libclang_3_9") {
29         Some((3, 9))
30     } else {
31         None
32     };
33 
34     info!(
35         "Clang Version: {}, parsed: {:?}",
36         version.full, version.parsed
37     );
38 
39     if expected_version.is_some() {
40         // assert_eq!(version.parsed, version.parsed);
41     }
42 }
43 
main()44 pub fn main() {
45     #[cfg(feature = "logging")]
46     env_logger::init();
47 
48     match builder_from_flags(env::args()) {
49         Ok((builder, output, verbose)) => {
50             clang_version_check();
51             let builder_result = panic::catch_unwind(|| {
52                 builder.generate().expect("Unable to generate bindings")
53             });
54 
55             if builder_result.is_err() {
56                 if verbose {
57                     print_verbose_err();
58                 }
59                 std::process::exit(1);
60             }
61 
62             let bindings = builder_result.unwrap();
63             bindings.write(output).expect("Unable to write output");
64         }
65         Err(error) => {
66             println!("{}", error);
67             std::process::exit(1);
68         }
69     };
70 }
71 
print_verbose_err()72 fn print_verbose_err() {
73     println!("Bindgen unexpectedly panicked");
74     println!(
75         "This may be caused by one of the known-unsupported \
76          things (https://rust-lang.github.io/rust-bindgen/cpp.html), \
77          please modify the bindgen flags to work around it as \
78          described in https://rust-lang.github.io/rust-bindgen/cpp.html"
79     );
80     println!(
81         "Otherwise, please file an issue at \
82          https://github.com/rust-lang/rust-bindgen/issues/new"
83     );
84 }
85 
86 #[cfg(test)]
87 mod test {
build_flags_output_helper(builder: &bindgen::Builder)88     fn build_flags_output_helper(builder: &bindgen::Builder) {
89         let mut command_line_flags = builder.command_line_flags();
90         command_line_flags.insert(0, "bindgen".to_string());
91 
92         let flags_quoted: Vec<String> = command_line_flags
93             .iter()
94             .map(|x| format!("{}", shlex::quote(x)))
95             .collect();
96         let flags_str = flags_quoted.join(" ");
97         println!("{}", flags_str);
98 
99         let (builder, _output, _verbose) =
100             crate::options::builder_from_flags(command_line_flags.into_iter())
101                 .unwrap();
102         builder.generate().expect("failed to generate bindings");
103     }
104 
105     #[test]
commandline_multiple_headers()106     fn commandline_multiple_headers() {
107         let bindings = bindgen::Builder::default()
108             .header("tests/headers/char.h")
109             .header("tests/headers/func_ptr.h")
110             .header("tests/headers/16-byte-alignment.h");
111         build_flags_output_helper(&bindings);
112     }
113 }
114