mirror of
https://gitee.com/openharmony/third_party_rust_bindgen
synced 2024-12-04 05:22:20 +00:00
Add a mechanism to rerun bindgen with the same user options (#2292)
* 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 `GenerateResult::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.
This commit is contained in:
parent
4f92dfb7c5
commit
a2fe04cbaf
@ -1559,25 +1559,33 @@ impl Builder {
|
||||
}
|
||||
|
||||
/// Generate the Rust bindings using the options built up thus far.
|
||||
pub fn generate(mut self) -> Result<Bindings, BindgenError> {
|
||||
pub fn generate(self) -> Result<Bindings, BindgenError> {
|
||||
let mut options = self.options.clone();
|
||||
// Add any extra arguments from the environment to the clang command line.
|
||||
self.options.clang_args.extend(get_extra_clang_args());
|
||||
options.clang_args.extend(get_extra_clang_args());
|
||||
|
||||
// Transform input headers to arguments on the clang command line.
|
||||
self.options.clang_args.extend(
|
||||
self.options.input_headers
|
||||
[..self.options.input_headers.len().saturating_sub(1)]
|
||||
options.clang_args.extend(
|
||||
options.input_headers
|
||||
[..options.input_headers.len().saturating_sub(1)]
|
||||
.iter()
|
||||
.flat_map(|header| ["-include".into(), header.to_string()]),
|
||||
);
|
||||
|
||||
let input_unsaved_files =
|
||||
std::mem::take(&mut self.options.input_header_contents)
|
||||
std::mem::take(&mut options.input_header_contents)
|
||||
.into_iter()
|
||||
.map(|(name, contents)| clang::UnsavedFile::new(name, contents))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Bindings::generate(self.options, input_unsaved_files)
|
||||
match Bindings::generate(options, input_unsaved_files) {
|
||||
GenerateResult::Ok(bindings) => Ok(bindings),
|
||||
GenerateResult::ShouldRestart { header } => self
|
||||
.header(header)
|
||||
.generate_inline_functions(false)
|
||||
.generate(),
|
||||
GenerateResult::Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
|
||||
/// Preprocess and dump the input header files to disk.
|
||||
@ -2282,6 +2290,18 @@ fn ensure_libclang_is_loaded() {
|
||||
#[cfg(not(feature = "runtime"))]
|
||||
fn ensure_libclang_is_loaded() {}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum GenerateResult {
|
||||
Ok(Bindings),
|
||||
/// Error variant raised when bindgen requires to run again with a newly generated header
|
||||
/// input.
|
||||
#[allow(dead_code)]
|
||||
ShouldRestart {
|
||||
header: String,
|
||||
},
|
||||
Err(BindgenError),
|
||||
}
|
||||
|
||||
/// Error type for rust-bindgen.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
#[non_exhaustive]
|
||||
@ -2375,7 +2395,7 @@ impl Bindings {
|
||||
pub(crate) fn generate(
|
||||
mut options: BindgenOptions,
|
||||
input_unsaved_files: Vec<clang::UnsavedFile>,
|
||||
) -> Result<Bindings, BindgenError> {
|
||||
) -> GenerateResult {
|
||||
ensure_libclang_is_loaded();
|
||||
|
||||
#[cfg(feature = "runtime")]
|
||||
@ -2496,17 +2516,22 @@ impl Bindings {
|
||||
let path = Path::new(h);
|
||||
if let Ok(md) = std::fs::metadata(path) {
|
||||
if md.is_dir() {
|
||||
return Err(BindgenError::FolderAsHeader(path.into()));
|
||||
return GenerateResult::Err(
|
||||
BindgenError::FolderAsHeader(path.into()).into(),
|
||||
);
|
||||
}
|
||||
if !can_read(&md.permissions()) {
|
||||
return Err(BindgenError::InsufficientPermissions(
|
||||
path.into(),
|
||||
));
|
||||
return GenerateResult::Err(
|
||||
BindgenError::InsufficientPermissions(path.into())
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
let h = h.clone();
|
||||
options.clang_args.push(h);
|
||||
} else {
|
||||
return Err(BindgenError::NotExist(path.into()));
|
||||
return GenerateResult::Err(
|
||||
BindgenError::NotExist(path.into()).into(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2534,12 +2559,14 @@ impl Bindings {
|
||||
|
||||
{
|
||||
let _t = time::Timer::new("parse").with_output(time_phases);
|
||||
parse(&mut context)?;
|
||||
if let Err(err) = parse(&mut context) {
|
||||
return GenerateResult::Err(err);
|
||||
}
|
||||
}
|
||||
|
||||
let (module, options, warnings) = codegen::codegen(context);
|
||||
|
||||
Ok(Bindings {
|
||||
GenerateResult::Ok(Bindings {
|
||||
options,
|
||||
warnings,
|
||||
module,
|
||||
|
Loading…
Reference in New Issue
Block a user