extern crate bindgen;
use std::collections::HashSet;
use std::env;
use std::io;
use std::path::Path;
use std::process::Command;
fn checkout(dir: &Path, tag: &str) -> io::Result<()> {
Command::new("git")
.current_dir(dir)
.arg("clone")
.args(&["--depth", "100"])
.arg("--single-branch")
.arg("https://github.com/ashinn/chibi-scheme")
.status()?;
let status = Command::new("git")
.current_dir(dir.join("chibi-scheme"))
.arg("checkout")
.arg(format!("tags/{}", tag))
.status()?;
if status.success() {
Ok(())
} else {
Err(io::Error::new(io::ErrorKind::Other, "Failed to checkout"))
}
}
fn make(dir: &Path) -> io::Result<()> {
let status = Command::new("make")
.current_dir(dir.join("chibi-scheme"))
.status()?;
if status.success() {
Ok(())
} else {
Err(io::Error::new(io::ErrorKind::Other, "Failed to run make"))
}
}
#[derive(Debug)]
struct IgnoreMacros(HashSet<String>);
impl bindgen::callbacks::ParseCallbacks for IgnoreMacros {
fn will_parse_macro(&self, name: &str) -> bindgen::callbacks::MacroParsingBehavior {
if self.0.contains(name) {
bindgen::callbacks::MacroParsingBehavior::Ignore
} else {
bindgen::callbacks::MacroParsingBehavior::Default
}
}
}
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
checkout(Path::new(&out_dir), "0.8").unwrap();
make(Path::new(&out_dir)).unwrap();
let ignored_macros = IgnoreMacros(
vec![
"FP_INFINITE".into(),
"FP_NAN".into(),
"FP_NORMAL".into(),
"FP_SUBNORMAL".into(),
"FP_ZERO".into(),
"IPPORT_RESERVED".into(),
].into_iter()
.collect(),
);
let bindings = bindgen::Builder::default()
.header(format!("{}/chibi-scheme/include/chibi/eval.h", &out_dir))
.parse_callbacks(Box::new(ignored_macros))
.generate()
.expect("Unable to generate bindings");
bindings
.write_to_file(format!("{}/bindings.rs", out_dir))
.expect("Could not write bindings");
println!(
"cargo:rustc-link-search=native={}/chibi-scheme/libchibi-scheme.so",
&out_dir
);
println!("cargo:rustc-link-lib=chibi-scheme");
}