Skip to content

Introduce ParseCallbacks::header_file #2653

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,19 @@
# Unreleased

## Added
- Added the `ParseCallbacks::header_file` callback which runs on every filename passed to `Builder::header`.
- Added the `CargoCallbacks::new` constructor which emits a cargo-rerun line
for every input header file by default.
- Added the `CargoCallbacks::rerun_on_header_files` method to configure whether
a cargo-rerun line should be emitted for every input header file.
## Changed
- The `--wrap-static-fns` feature was updated so function types that has no
argument use `void` as its sole argument.
- `CargoCallbacks` is no longer a [unit-like
struct](https://doc.rust-lang.org/reference/items/structs.html) and the
`CargoCallbacks` constant was added to mitigate the breaking nature of this
change. This constant has been marked as deprecated and users will have to
use the new `CargoCallbacks::new` method in the future.
## Removed
## Fixed
- Allow compiling `bindgen-cli` with a static libclang.
Expand Down
3 changes: 3 additions & 0 deletions bindgen/callbacks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ pub trait ParseCallbacks: fmt::Debug {
None
}

/// This will be called on every header filename passed to (`Builder::header`)[`crate::Builder::header`].
fn header_file(&self, _filename: &str) {}

/// This will be called on every file inclusion, with the full path of the included file.
fn include_file(&self, _filename: &str) {}

Expand Down
52 changes: 51 additions & 1 deletion bindgen/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,11 @@ impl Builder {
.map(String::into_boxed_str),
);

for header in &self.options.input_headers {
self.options
.for_each_callback(|cb| cb.header_file(header.as_ref()));
}

// Transform input headers to arguments on the clang command line.
self.options.clang_args.extend(
self.options.input_headers
Expand Down Expand Up @@ -566,6 +571,10 @@ impl BindgenOptions {
.collect()
}

fn for_each_callback(&self, f: impl Fn(&dyn callbacks::ParseCallbacks)) {
self.parse_callbacks.iter().for_each(|cb| f(cb.as_ref()));
}

fn process_comment(&self, comment: &str) -> String {
let comment = comment::preprocess(comment);
self.parse_callbacks
Expand Down Expand Up @@ -1232,9 +1241,50 @@ fn get_target_dependent_env_var(
/// .generate();
/// ```
#[derive(Debug)]
pub struct CargoCallbacks;
pub struct CargoCallbacks {
rerun_on_header_files: bool,
}

/// Create a new `CargoCallbacks` value with [`CargoCallbacks::rerun_on_header_files`] disabled.
///
/// This constructor has been deprecated in favor of [`CargoCallbacks::new`] where
/// [`CargoCallbacks::rerun_on_header_files`] is enabled by default.
#[deprecated = "Use `CargoCallbacks::new()` instead. Please, check the documentation for further information."]
pub const CargoCallbacks: CargoCallbacks = CargoCallbacks {
rerun_on_header_files: false,
};

impl CargoCallbacks {
/// Create a new `CargoCallbacks` value.
pub fn new() -> Self {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could make this const, and use new in the deprecated const as well?

Copy link
Contributor Author

@pvdrz pvdrz Oct 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit conservative with const fns as removing the const in the future will always be a breaking change and I'm not sure if new fields added in the future could be initialized as consts or not.

Self {
rerun_on_header_files: true,
}
}

/// Whether Cargo should re-run the build script if any of the input header files has changed.
///
/// This option is enabled by default unless the deprecated [`const@CargoCallbacks`]
/// constructor is used.
pub fn rerun_on_header_files(mut self, doit: bool) -> Self {
self.rerun_on_header_files = doit;
self
}
}

impl Default for CargoCallbacks {
fn default() -> Self {
Self::new()
}
}

impl callbacks::ParseCallbacks for CargoCallbacks {
fn header_file(&self, filename: &str) {
if self.rerun_on_header_files {
println!("cargo:rerun-if-changed={}", filename);
}
}

fn include_file(&self, filename: &str) {
println!("cargo:rerun-if-changed={}", filename);
}
Expand Down