coco-sys 0.6.0

Generated Rust bindings for COCO benchmarking framework
Documentation
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");
}