Skip to content

Commit

Permalink
feat: add headers option
Browse files Browse the repository at this point in the history
Problem: It's cumbersome to define multiple input headers using the
existing `header` API. It's difficult for the user to configure the
`Builder` with a list of input headers.

Solution: Add `headers` method that permits adding multiple headers via
an iterable of Strings.

Testing: Added `test_headers_call_in_builder`. Ran `cargo test` in
`bindgen-tests/tests/expectations`.

Issue: #2738
  • Loading branch information
christianheussy authored and Christian Heussy committed Feb 2, 2024
1 parent b7de6ee commit 18dbe81
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 0 deletions.
36 changes: 36 additions & 0 deletions bindgen-tests/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,42 @@ fn test_multiple_header_calls_in_builder() {
}
}

#[test]
fn test_headers_call_in_builder() {
let actual = builder()
.headers([
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/func_ptr.h"),
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/char.h"),
])
.clang_arg("--target=x86_64-unknown-linux")
.generate()
.unwrap()
.to_string();

let actual = format_code(actual).unwrap();

let expected_filename = concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/expectations/tests/test_multiple_header_calls_in_builder.rs"
);
let expected = include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/expectations/tests/test_multiple_header_calls_in_builder.rs"
));
let expected = format_code(expected).unwrap();

if actual != expected {
println!("Generated bindings differ from expected!");
error_diff_mismatch(
&actual,
&expected,
None,
Path::new(expected_filename),
)
.unwrap();
}
}

#[test]
fn test_multiple_header_contents() {
let actual = builder()
Expand Down
26 changes: 26 additions & 0 deletions bindgen/options/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,32 @@ options! {
self.options.input_headers.push(header.into().into_boxed_str());
self
}

/// Add input C/C++ header(s) to generate bindings for.
///
/// This can be used to generate bindings for a single header:
///
/// ```ignore
/// let bindings = bindgen::Builder::default()
/// .headers(["input.h"])
/// .generate()
/// .unwrap();
/// ```
///
/// Or for multiple headers:
///
/// ```ignore
/// let bindings = bindgen::Builder::default()
/// .headers(["first.h", "second.h", "third.h"])
/// .generate()
/// .unwrap();
/// ```
pub fn headers<I: IntoIterator>(mut self, headers: I) -> Builder
where I::Item: Into<String>{
self.options.input_headers
.extend(headers.into_iter().map(Into::into).map(Into::into));
self
}
},
// This field is handled specially inside the macro.
as_args: ignore,
Expand Down

0 comments on commit 18dbe81

Please sign in to comment.