extern crate bindgen;
use libperl_config::*;
use std::env;
use std::path::{PathBuf, Path};
fn is_older_file(dest: &Path, src: &Path) -> bool {
dest.metadata().unwrap().modified().unwrap()
< src.metadata().unwrap().modified().unwrap()
}
fn cargo_topdir_file(file: &str) -> PathBuf {
PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join(file)
}
fn cargo_outdir() -> PathBuf {
PathBuf::from(env::var("OUT_DIR").unwrap())
}
fn look_updated_against<'a>(checked: &Path, against: &[&'a Path]) -> Option<&'a Path> {
for f in against.iter() {
if is_older_file(checked, f) {
return Some(f)
}
}
None
}
fn main() {
let perl = PerlConfig::default();
perl.emit_cargo_ldopts();
let archlib = String::from(&perl.dict["archlib"]);
let perl_h = Path::new(&archlib).join("CORE/perl.h");
let cop_h = Path::new(&archlib).join("CORE/cop.h");
let ccopts = perl.read_ccopts().unwrap();
println!("# perl ccopts = {:?}, ", ccopts);
perl.emit_features(&["useithreads"]);
perl.emit_perlapi_vers(10, 40);
let src_file_name = "wrapper.h";
let src_path = cargo_topdir_file(src_file_name);
let out_file = cargo_outdir().join("bindings.rs");
let do_build = if !out_file.exists() {
println!("# will generate new {}", out_file.display());
true
}
else if let Some(src_path) = look_updated_against(
&out_file, &[
&src_path,
&cargo_topdir_file("build.rs"),
]) {
println!("# out_file {} is older than src {}"
, out_file.display(), src_path.display());
true
}
else {
println!("# out_file {} exists and up-to-date with src {}\n# out_file={{{:?}}} src_file={{{:?}}}"
, out_file.display(), src_path.display()
, out_file.metadata().unwrap().modified()
, src_path.metadata().unwrap().modified()
);
false
};
if do_build {
let bindings = bindgen::Builder::default()
.derive_debug(true)
.impl_debug(true)
.formatter(bindgen::Formatter::Prettyplease)
.rustified_enum("OPclass|opcode|svtype")
.header(src_file_name)
.clang_arg("-DPERL_CORE")
.clang_args(ccopts.iter())
.opaque_type("timex")
.allowlist_file(perl_h.to_str().unwrap())
.allowlist_file(cop_h.to_str().unwrap())
.allowlist_item("opcode")
.allowlist_item("(Perl|perl|PL)_.*")
.allowlist_item("([SAHRGC]V|xpv).*")
.allowlist_item("OP.*")
.allowlist_item("G_.*")
.generate()
.expect("Unable to generate bindings");
bindings
.write_to_file(out_file.to_str().unwrap())
.expect("Couldn't write bindings!");
}
}