Avoid generating and writing bindings when called recursively
from a build script.
This commit is contained in:
committed by
Emilio Cobos Álvarez
parent
ca7a942ce5
commit
aeb81934d1
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user