moltenvk-sys 0.1.1

Crate to build MoltenVK dylib
use std::{env::var_os, path::Path, process::Command};

fn main() {
    println!("cargo:rerun-if-env-changed=FORCE_MVK_FROM_SOURCE");

    let force = match var_os("FORCE_MVK_FROM_SOURCE") {
        None => false,
        Some(value) => value == "yes" || value == "1",
    };

    let use_from_source = if force {
        true
    } else {
        unsafe { libloading::Library::new("libvulkan.dylib").is_err() }
    };

    let out_dir = var_os("OUT_DIR").expect("Failed to find OUT_DIR");
    let out_dir = Path::new(&out_dir);
    let target_lib_path = out_dir.join("libvulkan.dylib");

    if !use_from_source {
        if target_lib_path.exists() {
            let _ = std::fs::remove_file(&target_lib_path);
        }
        return;
    }

    let out_dir = var_os("OUT_DIR").expect("Failed to find OUT_DIR");
    let out_dir = Path::new(&out_dir);
    let mvk_dir = out_dir.join("MoltenVK");

    let (target_name, dylib_dir) = match std::env::var("CARGO_CFG_TARGET_OS") {
        Ok(target) => match target.as_ref() {
            "macos" => ("macos", "macOS"),
            "ios" => ("ios", "iOS"),
            target => panic!("Unknown target '{}'", target),
        },
        Err(e) => panic!("Failed to determinte target os '{}'", e),
    };

    if mvk_dir.exists() {
        let git_status = Command::new("git")
            .current_dir(&mvk_dir)
            .args(["pull", "--ff-only"])
            .spawn()
            .expect("Failed to run git")
            .wait()
            .expect("Failed to pull MoltenVK");

        assert!(git_status.success(), "Failed to get MoltenVK");
    } else {
        let git_status = Command::new("git")
            .arg("clone")
            .args(["--depth", "1"])
            .arg("https://github.com/KhronosGroup/MoltenVK.git")
            .arg(&mvk_dir)
            .spawn()
            .expect("Failed to run git")
            .wait()
            .expect("Failed to clone MoltenVK");

        assert!(git_status.success(), "Failed to get MoltenVK");
    };

    let status = Command::new("sh")
        .current_dir(&mvk_dir)
        .arg("fetchDependencies")
        .arg(format!("--{}", target_name))
        .spawn()
        .expect("Failed to run fetchDependencies script")
        .wait()
        .expect("Failed to fetch dependencies");

    assert!(status.success(), "Failed to fetch dependencies");

    let status = Command::new("make")
        .current_dir(&mvk_dir)
        .arg(target_name)
        .spawn()
        .expect("Failed to build MoltenVK")
        .wait()
        .expect("Failed to build MoltenVK");

    assert!(status.success(), "Failed to build MoltenVK");

    let dylib_path = mvk_dir
        .join("MoltenVK")
        .join("dylib")
        .join(dylib_dir)
        .join("libMoltenVK.dylib");

    std::fs::copy(&dylib_path, &target_lib_path).expect("Failed to copy MoltenVK dylib");
    println!("cargo:rustc-link-search=native={}", out_dir.display());
}