bnyr-sys 131.0.0

Unsafe bindings to Binaryen
use std::env;
use std::path::PathBuf;
use std::process::Command;

fn main() {
    let out_dir = PathBuf::from(env::var("OUT_DIR").expect("OUT_DIR not set"));
    let binaryen_dir = out_dir.join("binaryen");

    if !binaryen_dir.join(".git").exists() {
        let major_version =
            env::var("CARGO_PKG_VERSION_MAJOR").expect("CARGO_PKG_VERSION_MAJOR not set");
        let tag = format!("version_{}", major_version);

        let status = Command::new("git")
            .args([
                "clone",
                "--depth",
                "1",
                "--branch",
                &tag,
                "https://github.com/WebAssembly/binaryen.git",
            ])
            .arg(&binaryen_dir)
            .status()
            .expect("failed to run git clone");

        if !status.success() {
            panic!("failed to clone binaryen at tag {}", tag);
        }
    }

    let mut config = cmake::Config::new(&binaryen_dir);
    config
        .define("BUILD_SHARED_LIBS", "OFF")
        .define("ENABLE_WERROR", "OFF")
        // .define("BUILD_LLVM_DWARF", "OFF")
        .define("BUILD_TESTS", "OFF")
        .define("BUILD_TOOLS", "OFF");
    // .very_verbose(true);

    let dst = config.build();

    println!("cargo:rustc-link-search=native={}/build/lib", dst.display());
    println!("cargo:rustc-link-lib=static=binaryen");

    if env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("macos") {
        println!("cargo:rustc-link-lib=c++");
    } else {
        println!("cargo:rustc-link-lib=stdc++");
    }

    // Small C++ shim exposing a handful of things the C API doesn't cover
    // (e.g. adding a memory without replacing the module's existing one),
    // implemented directly against Binaryen's C++ core (src/wasm.h).
    let shim_src = PathBuf::from("src/shim.cpp");
    let shim_header = PathBuf::from("src/shim.h");
    println!("cargo:rerun-if-changed={}", shim_src.display());
    println!("cargo:rerun-if-changed={}", shim_header.display());

    cc::Build::new()
        .cpp(true)
        .std("c++20")
        .file(&shim_src)
        .include(binaryen_dir.join("src"))
        .include(binaryen_dir.join("third_party/FP16/include"))
        .warnings(false)
        .compile("bnyr_shim");

    let header = binaryen_dir.join("src/binaryen-c.h");
    println!("cargo:rerun-if-changed={}", header.display());

    let bindings = bindgen::Builder::default()
        .header(header.to_str().expect("header path is not valid UTF-8"))
        .header(
            shim_header
                .to_str()
                .expect("shim header path is not valid UTF-8"),
        )
        .clang_arg(format!("-I{}", binaryen_dir.join("src").display()))
        .clang_arg("-Isrc")
        .generate()
        .expect("failed to generate bindings");

    bindings
        .write_to_file(out_dir.join("bindings.rs"))
        .expect("failed to write bindings");
}