use std::{ env, path::{Path, PathBuf}, process::Command, }; fn main() { generate_source(); generate_bindings(); compile_and_link(); } fn generate_source() { let src_path = Path::new("vendor"); let required_files = ["coco.c", "coco.h", "coco_internal.h"]; let files_exist = || { required_files .iter() .all(|file| src_path.join(file).exists()) }; if !files_exist() { let build_script_path = Path::new("../../../../do.py"); assert!(build_script_path.exists(), "build script does not exist"); Command::new("python") .arg(build_script_path) .arg("prepare-build-rust") .output() .expect("failed to run prepare-build-rust command"); } assert!(files_exist(), "failed to generate code files"); } fn generate_bindings() { println!("cargo:rerun-if-changed=wrapper.h"); let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); let bindings = bindgen::Builder::default() .header("wrapper.h") .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .blocklist_item("FP_NORMAL") .blocklist_item("FP_SUBNORMAL") .blocklist_item("FP_ZERO") .blocklist_item("FP_INFINITE") .blocklist_item("FP_NAN") .generate() .expect("Unable to generate bindings"); bindings .write_to_file(out_path.join("coco_sys.rs")) .expect("Couldn't write bindings to 'OUT_DIR/coco_sys.rs'!"); } fn compile_and_link() { let src_path = Path::new("vendor"); cc::Build::new() .file(src_path.join("coco.c")) .file("wrapper.c") .warnings(false) .compile("coco"); }