Skip to content

Commit 056333c

Browse files
committed
Run Bindings::generate again if required.
This adds a mechanism so `bindgen` is able to run `Bindings::generate` multiple times with the same user input if the `generate_static_inline` option is enabled and `GenerateError::ShouldRestart` is returned by `Bindings::generate`. This is done to eventually solve #1090 which would require to check for any static inline functions and generate a new header file to be used as an extra input and run `Bindings::generate` again.
1 parent 626797b commit 056333c

File tree

1 file changed

+39
-11
lines changed

1 file changed

+39
-11
lines changed

bindgen/lib.rs

+39-11
Original file line numberDiff line numberDiff line change
@@ -1559,25 +1559,33 @@ impl Builder {
15591559
}
15601560

15611561
/// Generate the Rust bindings using the options built up thus far.
1562-
pub fn generate(mut self) -> Result<Bindings, BindgenError> {
1562+
pub fn generate(self) -> Result<Bindings, BindgenError> {
1563+
let mut options = self.options.clone();
15631564
// Add any extra arguments from the environment to the clang command line.
1564-
self.options.clang_args.extend(get_extra_clang_args());
1565+
options.clang_args.extend(get_extra_clang_args());
15651566

15661567
// Transform input headers to arguments on the clang command line.
1567-
self.options.clang_args.extend(
1568-
self.options.input_headers
1569-
[..self.options.input_headers.len().saturating_sub(1)]
1568+
options.clang_args.extend(
1569+
options.input_headers
1570+
[..options.input_headers.len().saturating_sub(1)]
15701571
.iter()
15711572
.flat_map(|header| ["-include".into(), header.to_string()]),
15721573
);
15731574

15741575
let input_unsaved_files =
1575-
std::mem::take(&mut self.options.input_header_contents)
1576+
std::mem::take(&mut options.input_header_contents)
15761577
.into_iter()
15771578
.map(|(name, contents)| clang::UnsavedFile::new(name, contents))
15781579
.collect::<Vec<_>>();
15791580

1580-
Bindings::generate(self.options, input_unsaved_files)
1581+
match Bindings::generate(options, input_unsaved_files) {
1582+
Ok(bindings) => Ok(bindings),
1583+
Err(GenerateError::ShouldRestart { header }) => self
1584+
.header(header)
1585+
.generate_inline_functions(false)
1586+
.generate(),
1587+
Err(GenerateError::Bindgen(err)) => Err(err),
1588+
}
15811589
}
15821590

15831591
/// Preprocess and dump the input header files to disk.
@@ -2287,6 +2295,23 @@ fn ensure_libclang_is_loaded() {
22872295
#[cfg(not(feature = "runtime"))]
22882296
fn ensure_libclang_is_loaded() {}
22892297

2298+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2299+
enum GenerateError {
2300+
/// Error variant raised when bindgen requires to run again with a newly generated header
2301+
/// input.
2302+
#[allow(dead_code)]
2303+
ShouldRestart {
2304+
header: String,
2305+
},
2306+
Bindgen(BindgenError),
2307+
}
2308+
2309+
impl From<BindgenError> for GenerateError {
2310+
fn from(err: BindgenError) -> Self {
2311+
Self::Bindgen(err)
2312+
}
2313+
}
2314+
22902315
/// Error type for rust-bindgen.
22912316
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
22922317
#[non_exhaustive]
@@ -2380,7 +2405,7 @@ impl Bindings {
23802405
pub(crate) fn generate(
23812406
mut options: BindgenOptions,
23822407
input_unsaved_files: Vec<clang::UnsavedFile>,
2383-
) -> Result<Bindings, BindgenError> {
2408+
) -> Result<Bindings, GenerateError> {
23842409
ensure_libclang_is_loaded();
23852410

23862411
#[cfg(feature = "runtime")]
@@ -2501,17 +2526,20 @@ impl Bindings {
25012526
let path = Path::new(h);
25022527
if let Ok(md) = std::fs::metadata(path) {
25032528
if md.is_dir() {
2504-
return Err(BindgenError::FolderAsHeader(path.into()));
2529+
return Err(
2530+
BindgenError::FolderAsHeader(path.into()).into()
2531+
);
25052532
}
25062533
if !can_read(&md.permissions()) {
25072534
return Err(BindgenError::InsufficientPermissions(
25082535
path.into(),
2509-
));
2536+
)
2537+
.into());
25102538
}
25112539
let h = h.clone();
25122540
options.clang_args.push(h);
25132541
} else {
2514-
return Err(BindgenError::NotExist(path.into()));
2542+
return Err(BindgenError::NotExist(path.into()).into());
25152543
}
25162544
}
25172545

0 commit comments

Comments
 (0)