| extern crate bindgen; |
| #[cfg(feature = "logging")] |
| extern crate env_logger; |
| #[macro_use] |
| #[cfg(feature = "logging")] |
| extern crate log; |
| extern crate clap; |
| |
| use bindgen::clang_version; |
| use std::env; |
| use std::panic; |
| |
| #[macro_use] |
| #[cfg(not(feature = "logging"))] |
| mod log_stubs; |
| |
| mod options; |
| use crate::options::builder_from_flags; |
| |
| fn clang_version_check() { |
| let version = clang_version(); |
| let expected_version = if cfg!(feature = "testing_only_libclang_9") { |
| Some((9, 0)) |
| } else if cfg!(feature = "testing_only_libclang_5") { |
| Some((5, 0)) |
| } else if cfg!(feature = "testing_only_libclang_4") { |
| Some((4, 0)) |
| } else if cfg!(feature = "testing_only_libclang_3_9") { |
| Some((3, 9)) |
| } else { |
| None |
| }; |
| |
| info!( |
| "Clang Version: {}, parsed: {:?}", |
| version.full, version.parsed |
| ); |
| |
| if expected_version.is_some() { |
| assert_eq!(version.parsed, version.parsed); |
| } |
| } |
| |
| pub fn main() { |
| #[cfg(feature = "logging")] |
| env_logger::init(); |
| |
| let bind_args: Vec<_> = env::args().collect(); |
| |
| match builder_from_flags(bind_args.into_iter()) { |
| Ok((builder, output, verbose)) => { |
| clang_version_check(); |
| let builder_result = panic::catch_unwind(|| { |
| builder.generate().expect("Unable to generate bindings") |
| }); |
| |
| if builder_result.is_err() { |
| if verbose { |
| print_verbose_err(); |
| } |
| std::process::exit(1); |
| } |
| |
| let bindings = builder_result.unwrap(); |
| bindings.write(output).expect("Unable to write output"); |
| } |
| Err(error) => { |
| println!("{}", error); |
| std::process::exit(1); |
| } |
| }; |
| } |
| |
| fn print_verbose_err() { |
| println!("Bindgen unexpectedly panicked"); |
| println!( |
| "This may be caused by one of the known-unsupported \ |
| things (https://rust-lang.github.io/rust-bindgen/cpp.html), \ |
| please modify the bindgen flags to work around it as \ |
| described in https://rust-lang.github.io/rust-bindgen/cpp.html" |
| ); |
| println!( |
| "Otherwise, please file an issue at \ |
| https://github.com/rust-lang/rust-bindgen/issues/new" |
| ); |
| } |
| |
| #[cfg(test)] |
| mod test { |
| fn build_flags_output_helper(builder: &bindgen::Builder) { |
| let mut command_line_flags = builder.command_line_flags(); |
| command_line_flags.insert(0, "bindgen".to_string()); |
| |
| let flags_quoted: Vec<String> = command_line_flags |
| .iter() |
| .map(|x| format!("{}", shlex::quote(x))) |
| .collect(); |
| let flags_str = flags_quoted.join(" "); |
| println!("{}", flags_str); |
| |
| let (builder, _output, _verbose) = |
| crate::options::builder_from_flags(command_line_flags.into_iter()) |
| .unwrap(); |
| builder.generate().expect("failed to generate bindings"); |
| } |
| |
| #[test] |
| fn commandline_multiple_headers() { |
| let bindings = bindgen::Builder::default() |
| .header("tests/headers/char.h") |
| .header("tests/headers/func_ptr.h") |
| .header("tests/headers/16-byte-alignment.h"); |
| build_flags_output_helper(&bindings); |
| } |
| } |