use std::env;
use std::path::PathBuf;
fn get_out_dir() -> PathBuf {
let out_dir = env::var("OUT_DIR").expect("OUT_DIR must be set");
if !out_dir.is_empty() {
let out_path_buf = PathBuf::from(out_dir);
return out_path_buf;
} else {
let out_dir_raw = env::temp_dir();
let out_dir_str = out_dir_raw.to_str().expect("Could not get out_dir");
env::set_var("OUT_DIR", out_dir_str);
let out_path_buf = PathBuf::from(out_dir_str);
return out_path_buf;
}
}
fn build(out_dir: PathBuf, name: &str, tool: &str) {
let include_dir = PathBuf::from("include")
.canonicalize()
.expect("Can not canonicalize path");
let header_path = include_dir.join(format!("{}.h", name));
let impl_path = include_dir.join(format!("{}.c", name));
let obj_path = out_dir.join(format!("{}.o", name));
let lib_path = out_dir.join(format!("lib{}.a", name));
let out_file = out_dir.join(format!("{}_bindings.rs", name));
let header_path_str = header_path.to_str().unwrap();
println!("cargo::rustc-link-search={}", include_dir.to_str().unwrap());
println!("cargo::rustc-link-lib={}", name);
if !std::process::Command::new(tool)
.arg("-c")
.arg("-o")
.arg(&obj_path)
.arg(&impl_path)
.arg(format!("-I{}", include_dir.to_str().unwrap()))
.output()
.expect(format!("Could not spawn: {}", tool).as_str())
.status
.success()
{
panic!("Could not compile: {}", impl_path.to_str().unwrap());
}
if !std::process::Command::new("ar")
.arg("rcs")
.arg(&lib_path)
.arg(&obj_path)
.output()
.expect(format!("Could not create library: {}", lib_path.to_str().unwrap()).as_str())
.status
.success()
{
panic!("Could not create library: {}", lib_path.to_str().unwrap());
}
let bindings = bindgen::Builder::default()
.header(header_path_str)
.clang_arg(format!("-I{}", include_dir.to_str().unwrap()))
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("Could not generate bindings");
bindings.write_to_file(out_file).expect("Could not write bindings");
}
fn main() {
let out = get_out_dir();
build(out, "jaggerstring", "clang");
}