use std::env; use std::path::PathBuf; #[allow(unused)] fn get_out_dir() -> PathBuf { let _raw = env::var("OUT_DIR"); let _out = if _raw.is_ok() { PathBuf::from(_raw.unwrap()) } else { let _tmp = env::temp_dir(); let out = _tmp.join("out"); env::set_var("OUT_DIR", out.to_str().unwrap()); std::fs::create_dir_all(&out).expect("could not create temp dir"); out }; _out } #[allow(unused)] fn build_bootstrap(name: &str, out_dir: &PathBuf) { // Here define wir now our flex version. let libdir_path = PathBuf::from("include") .canonicalize() .expect("cannot canonicalize path"); let headers_path = libdir_path.join(format!("{}.h", name)); let obj_path = libdir_path.join(format!("{}.o", name)); let lib_path = libdir_path.join(format!("lib{}.a", name)); let headers_path_str = headers_path.to_str().expect("Path is not a valid string"); let lib_path_str = lib_path.to_str().expect("Path is not a valid string"); println!("cargo:rustc-link-search={}", libdir_path.to_str().unwrap()); println!("cargo:rustc-link-lib={}", name); if !std::process::Command::new("clang") .arg("-c") .arg("-o") .arg(&obj_path) .arg("-I") .arg(&libdir_path) .arg(&libdir_path.join(format!("{}.c", name))) .output() .expect("could not spawn `clang`") .status .success() { panic!("could not compile object file"); } if !std::process::Command::new("ar") .arg("rcs") .arg(&lib_path_str) .arg(obj_path) .output() .expect("could not spawn `ar`") .status .success() { panic!("could not emit library file"); } let tmp = lib_path_str; // The bindgen::Builder is the main entry point // to bindgen, and lets you build up options for // the resulting bindings. let bind = bindgen::CargoCallbacks::new(); let bindings = bindgen::Builder::default() // The input header we would like to generate // bindings for. .header(headers_path_str) .clang_arg(format!("-l{}", name)) // Tell cargo to invalidate the built crate whenever any of the // included header files changed. .parse_callbacks(Box::new(bind)) // Finish the builder and generate the bindings. .generate() // Unwrap the Result and panic on failure. .expect("Unable to generate bindings"); let out_path = PathBuf::from(out_dir).join(format!("{}_bindings.rs", name)); bindings .write_to_file(out_path) .expect("Couldn't write bindings!"); } #[allow(unused)] fn build_mastrust_header(out_dir: &PathBuf) { // Here define wir now our flex version. let name: &str = "mastrust"; let libdir_path = PathBuf::from("include") .canonicalize() .expect("cannot canonicalize path"); let headers_path = libdir_path.join(format!("{}.h", name)); let obj_path = out_dir.join(format!("{}.o", name)); let lib_path = out_dir.join(format!("lib{}.a", name)); let headers_path_str = headers_path.to_str().expect("Path is not a valid string"); let lib_path_str = lib_path.to_str().expect("Path is not a valid string"); println!("cargo:rustc-link-search={}", libdir_path.to_str().unwrap()); println!("cargo:rustc-link-lib={}", name); if !std::process::Command::new("clang") .arg("-c") .arg("-o") .arg(&obj_path) .arg("-I") .arg(&libdir_path) .arg(&libdir_path.join(format!("{}.c", name))) .output() .expect("could not spawn `clang`") .status .success() { panic!("could not compile object file"); } if !std::process::Command::new("ar") .arg("rcs") .arg(lib_path_str) .arg(obj_path) .output() .expect("could not spawn `ar`") .status .success() { panic!("could not emit library file"); } let tmp = lib_path_str; // The bindgen::Builder is the main entry point // to bindgen, and lets you build up options for // the resulting bindings. let bind = bindgen::CargoCallbacks::new(); let bindings = bindgen::Builder::default() // The input header we would like to generate // bindings for. .header(headers_path_str) .clang_arg(format!("-l{}", name)) .allowlist_type("CToken") .allowlist_type("CBufferFile") .allowlist_function("ctoken_init") .allowlist_function("ctoken_tokenize") .allowlist_function("ctoken_get_token") .allowlist_function("ctoken_get_string") .allowlist_function("ctoken_get_type") .allowlist_function("ctoken_get_size") // Tell cargo to invalidate the built crate whenever any of the // included header files changed. .parse_callbacks(Box::new(bind)) // Finish the builder and generate the bindings. .generate() // Unwrap the Result and panic on failure. .expect("Unable to generate bindings"); // Write the bindings to the $OUT_DIR/bindings.rs file. let out_path = PathBuf::from(out_dir).join(format!("{}_bindings.rs", name)); bindings .write_to_file(out_path) .expect("Couldn't write bindings!"); } fn main() { let out_dir = get_out_dir(); build_mastrust_header(&out_dir); }