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