Avoid generating and writing bindings when called recursively

from a build script.
This commit is contained in:
Vadim Petrochenkov
2022-03-31 19:46:41 +03:00
committed by Emilio Cobos Álvarez
parent ca7a942ce5
commit aeb81934d1
3 changed files with 35 additions and 7 deletions
+17
View File
@@ -27,6 +27,9 @@ pub struct Bindings {
constants: Vec<Constant>,
items: Vec<ItemContainer>,
functions: Vec<Function>,
/// Bindings are generated by a recursive call to cbindgen
/// and shouldn't do anything when written anywhere.
noop: bool,
}
#[derive(PartialEq)]
@@ -43,6 +46,7 @@ impl Bindings {
globals: Vec<Static>,
items: Vec<ItemContainer>,
functions: Vec<Function>,
noop: bool,
) -> Bindings {
Bindings {
config,
@@ -52,6 +56,7 @@ impl Bindings {
constants,
items,
functions,
noop,
}
}
@@ -93,6 +98,10 @@ impl Bindings {
}
pub fn write_to_file<P: AsRef<path::Path>>(&self, path: P) -> bool {
if self.noop {
return false;
}
// Don't compare files if we've never written this file before
if !path.as_ref().is_file() {
if let Some(parent) = path::Path::new(path.as_ref()).parent() {
@@ -121,6 +130,10 @@ impl Bindings {
}
pub fn write_headers<F: Write>(&self, out: &mut SourceWriter<F>) {
if self.noop {
return;
}
if let Some(ref f) = self.config.header {
out.new_line_if_not_start();
write!(out, "{}", f);
@@ -247,6 +260,10 @@ impl Bindings {
}
pub fn write<F: Write>(&self, file: F) {
if self.noop {
return;
}
let mut out = SourceWriter::new(file, self);
self.write_headers(&mut out);
+18
View File
@@ -54,6 +54,23 @@ impl Library {
}
pub fn generate(mut self) -> Result<Bindings, Error> {
// If macro expansion is enabled, then cbindgen will attempt to build the crate
// and will run its build script which may run cbindgen again. That second run may start
// infinite recursion, or overwrite previously written files with bindings.
// So if we are called recursively, we are skipping the whole generation
// and produce "noop" bindings that won't be able to overwrite anything.
if std::env::var("_CBINDGEN_IS_RUNNING").is_ok() {
return Ok(Bindings::new(
self.config,
Default::default(),
Default::default(),
Default::default(),
Default::default(),
Default::default(),
true,
));
}
self.transfer_annotations();
self.simplify_standard_types();
@@ -134,6 +151,7 @@ impl Library {
globals,
items,
functions,
false,
))
}
-7
View File
@@ -187,13 +187,6 @@ impl<'a> Parser<'a> {
fn parse_expand_crate(&mut self, pkg: &PackageRef) -> Result<(), Error> {
assert!(self.lib.is_some());
// If you want to expand the crate you run cbindgen on you might end up in an endless
// recursion if the cbindgen generation is triggered from build.rs. Hence don't run the
// expansion if the build was already triggered by cbindgen.
if std::env::var("_CBINDGEN_IS_RUNNING").is_ok() {
return Ok(());
}
let mod_items = {
if !self.cache_expanded_crate.contains_key(&pkg.name) {
let s = self