summaryrefslogtreecommitdiff
path: root/bindgen-integration/build.rs
diff options
context:
space:
mode:
Diffstat (limited to 'bindgen-integration/build.rs')
-rw-r--r--bindgen-integration/build.rs128
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();
+}