Skip to content

Commit ad0f161

Browse files
amanjeevpvdrz
authored andcommitted
add(static inlined): tests
test(static inlined): pretty print the diff Issue: GH-1090 test(static inlined): refactor paths once again - Because directory structure is confusing to the author of this commit GH-1090 test(static inlined): refactor test files - Expected files should be under tests/expectations/generated - Remove extern_stub.h because we can reuse the header from generate-extern-functions.h test(static inlined): diff test; generated files refactor(static inlined): integration test Issue: GH-1090 GH-1090: Integration tests integration test: document the GH issue integration test (macro): same order in impl as the trait for consistency integration test: move each setup into its own function, just to save face inline static func integration test resolve accidental conflict
1 parent afbc4d8 commit ad0f161

File tree

7 files changed

+165
-29
lines changed

7 files changed

+165
-29
lines changed

bindgen-integration/build.rs

+90-28
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ extern crate cc;
44
use bindgen::callbacks::{
55
DeriveInfo, IntKind, MacroParsingBehavior, ParseCallbacks,
66
};
7-
use bindgen::{Builder, EnumVariation};
7+
use bindgen::{Builder, CargoCallbacks, EnumVariation};
88
use std::collections::HashSet;
99
use std::env;
1010
use std::path::PathBuf;
@@ -28,21 +28,14 @@ impl ParseCallbacks for MacroCallback {
2828
MacroParsingBehavior::Default
2929
}
3030

31-
fn item_name(&self, original_item_name: &str) -> Option<String> {
32-
if original_item_name.starts_with("my_prefixed_") {
33-
Some(
34-
original_item_name
35-
.trim_start_matches("my_prefixed_")
36-
.to_string(),
37-
)
38-
} else if original_item_name.starts_with("MY_PREFIXED_") {
39-
Some(
40-
original_item_name
41-
.trim_start_matches("MY_PREFIXED_")
42-
.to_string(),
43-
)
44-
} else {
45-
None
31+
fn int_macro(&self, name: &str, _value: i64) -> Option<IntKind> {
32+
match name {
33+
"TESTMACRO_CUSTOMINTKIND_PATH" => Some(IntKind::Custom {
34+
name: "crate::MacroInteger",
35+
is_signed: true,
36+
}),
37+
38+
_ => None,
4639
}
4740
}
4841

@@ -67,17 +60,6 @@ impl ParseCallbacks for MacroCallback {
6760
}
6861
}
6962

70-
fn int_macro(&self, name: &str, _value: i64) -> Option<IntKind> {
71-
match name {
72-
"TESTMACRO_CUSTOMINTKIND_PATH" => Some(IntKind::Custom {
73-
name: "crate::MacroInteger",
74-
is_signed: true,
75-
}),
76-
77-
_ => None,
78-
}
79-
}
80-
8163
fn func_macro(&self, name: &str, value: &[&[u8]]) {
8264
match name {
8365
"TESTMACRO_NONFUNCTIONAL" => {
@@ -122,6 +104,24 @@ impl ParseCallbacks for MacroCallback {
122104
}
123105
}
124106

107+
fn item_name(&self, original_item_name: &str) -> Option<String> {
108+
if original_item_name.starts_with("my_prefixed_") {
109+
Some(
110+
original_item_name
111+
.trim_start_matches("my_prefixed_")
112+
.to_string(),
113+
)
114+
} else if original_item_name.starts_with("MY_PREFIXED_") {
115+
Some(
116+
original_item_name
117+
.trim_start_matches("MY_PREFIXED_")
118+
.to_string(),
119+
)
120+
} else {
121+
None
122+
}
123+
}
124+
125125
// Test the "custom derives" capability by adding `PartialEq` to the `Test` struct.
126126
fn add_derives(&self, info: &DeriveInfo<'_>) -> Vec<String> {
127127
if info.name == "Test" {
@@ -149,7 +149,7 @@ impl Drop for MacroCallback {
149149
}
150150
}
151151

152-
fn main() {
152+
fn setup_macro_test() {
153153
cc::Build::new()
154154
.cpp(true)
155155
.file("cpp/Test.cc")
@@ -204,3 +204,65 @@ fn main() {
204204
"including stub via include dir must produce correct dep path",
205205
);
206206
}
207+
208+
fn setup_extern_test() {
209+
// GH-1090: https://github.com/rust-lang/rust-bindgen/issues/1090
210+
// set output directory under /target so it is easy to clean generated files
211+
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
212+
let out_rust_file = out_path.join("extern.rs");
213+
214+
let input_header_dir = PathBuf::from("../bindgen-tests/tests/headers/").canonicalize()
215+
.expect("Cannot canonicalize libdir path");
216+
let input_header_file_path = input_header_dir.join("generate-extern-functions.h");
217+
let input_header_file_path_str = input_header_file_path.to_str()
218+
.expect("Path could not be converted to a str");
219+
220+
// generate external bindings with the external .c and .h files
221+
let bindings = Builder::default()
222+
.header(input_header_file_path_str)
223+
.parse_callbacks(Box::new(CargoCallbacks))
224+
.generate_extern_functions(true)
225+
.extern_functions_directory(out_path.display().to_string())
226+
.generate()
227+
.expect("Unable to generate bindings");
228+
229+
println!("cargo:rustc-link-lib=extern"); // tell cargo to link libextern
230+
println!("bindings generated: {}", bindings);
231+
232+
let obj_path = out_path.join("extern.o");
233+
let lib_path = out_path.join("libextern.a");
234+
235+
// build the external files to check if they work
236+
if !std::process::Command::new("clang")
237+
.arg("-c")
238+
.arg("-o")
239+
.arg(&obj_path)
240+
.arg(out_path.join("extern.c"))
241+
.arg("-include")
242+
.arg(input_header_file_path)
243+
.output()
244+
.expect("`clang` command error")
245+
.status
246+
.success() {
247+
panic!("Could not compile object file");
248+
}
249+
250+
if !std::process::Command::new("ar")
251+
.arg("rcs")
252+
.arg(lib_path)
253+
.arg(obj_path)
254+
.output()
255+
.expect("`ar` command error")
256+
.status
257+
.success() {
258+
panic!("Could not emit library file");
259+
}
260+
261+
bindings.write_to_file(out_rust_file)
262+
.expect("Cound not write bindings to the Rust file");
263+
}
264+
265+
fn main() {
266+
setup_macro_test();
267+
setup_extern_test();
268+
}

bindgen-integration/src/lib.rs

+16
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ mod bindings {
44
include!(concat!(env!("OUT_DIR"), "/test.rs"));
55
}
66

7+
mod extern_bindings {
8+
include!(concat!(env!("OUT_DIR"), "/extern.rs"));
9+
}
10+
711
use std::ffi::CStr;
812
use std::mem;
913
use std::os::raw::c_int;
@@ -286,3 +290,15 @@ fn test_custom_derive() {
286290
assert!(meter < lightyear);
287291
assert!(meter > micron);
288292
}
293+
294+
#[test]
295+
fn test_extern_bindings() {
296+
// GH-1090: https://github.com/rust-lang/rust-bindgen/issues/1090
297+
unsafe {
298+
let f = extern_bindings::foo();
299+
assert_eq!(11, f);
300+
301+
let b = extern_bindings::bar();
302+
assert_eq!(1, b);
303+
}
304+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Generated C, C++, Header files
2+
3+
This directory contains files for features where extra files are generated
4+
as a part of the feature. For example, `--generated-extern-functions`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
int foo__extern() { return foo(); }
2+
int bar__extern() { return bar(); }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
int foo__extern();
2+
int bar__extern();

bindgen-tests/tests/headers/generate-extern-functions.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// bindgen-flags: --generate-extern-functions
22

33
static inline int foo() {
4-
return 0;
4+
return 11;
55
}
66
static int bar() {
77
return 1;

bindgen-tests/tests/tests.rs

+50
Original file line numberDiff line numberDiff line change
@@ -713,3 +713,53 @@ fn commandline_multiple_headers() {
713713
.header("tests/headers/16-byte-alignment.h");
714714
build_flags_output_helper(&bindings);
715715
}
716+
717+
#[test]
718+
fn test_extern_generated_headers() {
719+
// This test is for testing diffs of the generated C source and header files
720+
// TODO: If another such feature is added, convert this test into a more generic
721+
// test that looks at `tests/headers/generated` directory.
722+
let expect_path = PathBuf::from("tests/expectations/tests/generated");
723+
println!("In path is ::: {}", expect_path.to_str().unwrap());
724+
725+
let generated_path = PathBuf::from(env::var("OUT_DIR").unwrap());
726+
println!("Out path is ::: {}", generated_path.to_str().unwrap());
727+
728+
let _bindings = Builder::default()
729+
.header("tests/headers/generate-extern-functions.h")
730+
.generate_extern_functions(true)
731+
.extern_functions_directory(generated_path.display().to_string())
732+
.generate()
733+
.expect("Failed to generate bindings");
734+
735+
let expected_c = fs::read_to_string(expect_path.join("extern.c"))
736+
.expect("Could not read generated extern.c");
737+
let expected_h = fs::read_to_string(expect_path.join("extern.h"))
738+
.expect("Could not read generated extern.h");
739+
740+
let actual_c = fs::read_to_string(generated_path.join("extern.c"))
741+
.expect("Could not read actual extern.c");
742+
let actual_h = fs::read_to_string(generated_path.join("extern.h"))
743+
.expect("Could not read actual extern.h");
744+
745+
if expected_c != actual_c {
746+
error_diff_mismatch(
747+
&actual_c,
748+
&expected_c,
749+
None,
750+
Path::new(expect_path.join("extern.c").to_str().unwrap()),
751+
)
752+
.unwrap();
753+
}
754+
755+
if expected_h != actual_h {
756+
error_diff_mismatch(
757+
&actual_h,
758+
&expected_h,
759+
None,
760+
Path::new(expect_path.join("extern.h").to_str().unwrap()),
761+
)
762+
.unwrap();
763+
}
764+
765+
}

0 commit comments

Comments
 (0)