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() { PathBuf::from(out_dir) } 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); PathBuf::from(out_dir_str) } } fn build(out_dir: PathBuf, name: &str, tool: &str) { let include_dir = PathBuf::from("include") .canonicalize() .expect("Cannot canonicalize path"); let (header_path, impl_path) = match tool { "clang" => ( include_dir.join(format!("{}.h", name)), include_dir.join(format!("{}.c", name)), ), "clang++" => ( include_dir.join(format!("{}.hpp", name)), include_dir.join(format!("{}.cpp", name)), ), _ => panic!("Only clang and clang++ available."), }; 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=native={}", out_dir.to_str().unwrap()); println!("cargo:rustc-link-lib=static={}", 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)) .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())) .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())) .clang_arg(format!("-L{}", out_dir.to_str().unwrap())) .clang_arg(format!("-l{}", name)); let bind = bindings.generate().expect("Unable to generate bindings"); bind.write_to_file(out_file).expect("Couldn't write bindings!"); } fn main() { let out = get_out_dir(); build(out, "jstring", "clang"); }