diff options
Diffstat (limited to 'bindgen-integration/build.rs')
-rw-r--r-- | bindgen-integration/build.rs | 128 |
1 files changed, 100 insertions, 28 deletions
diff --git a/bindgen-integration/build.rs b/bindgen-integration/build.rs index 0f30ad47..3cc0edb9 100644 --- a/bindgen-integration/build.rs +++ b/bindgen-integration/build.rs @@ -4,7 +4,7 @@ extern crate cc; use bindgen::callbacks::{ DeriveInfo, IntKind, MacroParsingBehavior, ParseCallbacks, }; -use bindgen::{Builder, EnumVariation}; +use bindgen::{Builder, CargoCallbacks, EnumVariation}; use std::collections::HashSet; use std::env; use std::path::PathBuf; @@ -28,21 +28,14 @@ impl ParseCallbacks for MacroCallback { MacroParsingBehavior::Default } - fn item_name(&self, original_item_name: &str) -> Option<String> { - if original_item_name.starts_with("my_prefixed_") { - Some( - original_item_name - .trim_start_matches("my_prefixed_") - .to_string(), - ) - } else if original_item_name.starts_with("MY_PREFIXED_") { - Some( - original_item_name - .trim_start_matches("MY_PREFIXED_") - .to_string(), - ) - } else { - None + fn int_macro(&self, name: &str, _value: i64) -> Option<IntKind> { + match name { + "TESTMACRO_CUSTOMINTKIND_PATH" => Some(IntKind::Custom { + name: "crate::MacroInteger", + is_signed: true, + }), + + _ => None, } } @@ -67,17 +60,6 @@ impl ParseCallbacks for MacroCallback { } } - fn int_macro(&self, name: &str, _value: i64) -> Option<IntKind> { - match name { - "TESTMACRO_CUSTOMINTKIND_PATH" => Some(IntKind::Custom { - name: "crate::MacroInteger", - is_signed: true, - }), - - _ => None, - } - } - fn func_macro(&self, name: &str, value: &[&[u8]]) { match name { "TESTMACRO_NONFUNCTIONAL" => { @@ -122,6 +104,24 @@ impl ParseCallbacks for MacroCallback { } } + fn item_name(&self, original_item_name: &str) -> Option<String> { + if original_item_name.starts_with("my_prefixed_") { + Some( + original_item_name + .trim_start_matches("my_prefixed_") + .to_string(), + ) + } else if original_item_name.starts_with("MY_PREFIXED_") { + Some( + original_item_name + .trim_start_matches("MY_PREFIXED_") + .to_string(), + ) + } else { + None + } + } + // Test the "custom derives" capability by adding `PartialEq` to the `Test` struct. fn add_derives(&self, info: &DeriveInfo<'_>) -> Vec<String> { if info.name == "Test" { @@ -149,7 +149,7 @@ impl Drop for MacroCallback { } } -fn main() { +fn setup_macro_test() { cc::Build::new() .cpp(true) .file("cpp/Test.cc") @@ -204,3 +204,75 @@ fn main() { "including stub via include dir must produce correct dep path", ); } + +fn setup_wrap_static_fns_test() { + // GH-1090: https://github.com/rust-lang/rust-bindgen/issues/1090 + // set output directory under /target so it is easy to clean generated files + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + let out_rust_file = out_path.join("extern.rs"); + + let input_header_dir = PathBuf::from("../bindgen-tests/tests/headers/") + .canonicalize() + .expect("Cannot canonicalize libdir path"); + let input_header_file_path = input_header_dir.join("wrap-static-fns.h"); + let input_header_file_path_str = input_header_file_path + .to_str() + .expect("Path could not be converted to a str"); + + // generate external bindings with the external .c and .h files + let bindings = Builder::default() + .header(input_header_file_path_str) + .parse_callbacks(Box::new(CargoCallbacks)) + .wrap_static_fns(true) + .wrap_static_fns_path( + out_path.join("wrap_static_fns").display().to_string(), + ) + .generate() + .expect("Unable to generate bindings"); + + println!("cargo:rustc-link-lib=static=wrap_static_fns"); // tell cargo to link libextern + println!("bindings generated: {}", bindings); + + let obj_path = out_path.join("wrap_static_fns.o"); + let lib_path = out_path.join("libwrap_static_fns.a"); + + // build the external files to check if they work + let clang_output = std::process::Command::new("clang") + .arg("-c") + .arg("-o") + .arg(&obj_path) + .arg(out_path.join("wrap_static_fns.c")) + .arg("-include") + .arg(input_header_file_path) + .output() + .expect("`clang` command error"); + if !clang_output.status.success() { + panic!( + "Could not compile object file:\n{}", + String::from_utf8_lossy(&clang_output.stderr) + ); + } + + let ar_output = std::process::Command::new("ar") + .arg("rcs") + .arg(lib_path) + .arg(obj_path) + .output() + .expect("`ar` command error"); + + if !ar_output.status.success() { + panic!( + "Could not emit library file:\n{}", + String::from_utf8_lossy(&ar_output.stderr) + ); + } + + bindings + .write_to_file(out_rust_file) + .expect("Cound not write bindings to the Rust file"); +} + +fn main() { + setup_macro_test(); + setup_wrap_static_fns_test(); +} |