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()); }