diff --git a/build/build.rs b/build/build.rs index 28869ef..59f51f1 100644 --- a/build/build.rs +++ b/build/build.rs @@ -75,12 +75,20 @@ mod xcframework; #[cfg(any(target_os = "macos", target_os = "ios"))] mod mac { - use std::path::Path; + use std::path::{Path, PathBuf}; // MoltenVK git tagged release to use pub static MOLTEN_VK_VERSION: &str = "1.1.10"; pub static MOLTEN_VK_PATCH: Option<&str> = None; + // The next two are useful for different kinds of bisection to find bugs. + // MOLTEN_VK_LOCAL_BIN lets you specify a local MoltenVK binary directly from a Vulkan SDK, for example. + // MOLTEN_VK_LOCAL lets you build directly from a local MoltenVK checkout, in which you can run + // a `git bisect`, for example. + // TODO: Make it possible to set these by environment variable? + pub static MOLTEN_VK_LOCAL_BIN: Option<&str> = None; // for example, Some("/Users/my_user_name/VulkanSDK/1.3.211.0/MoltenVK") + pub static MOLTEN_VK_LOCAL: Option<&str> = None; // for example, Some("/Users/my_user_name/dev/MoltenVK"); + // Return the artifact tag in the form of "x.x.x" or if there is a patch specified "x.x.x#yyyyyyy" pub(crate) fn get_artifact_tag() -> String { if let Some(patch) = MOLTEN_VK_PATCH { @@ -106,7 +114,7 @@ mod mac { .any(|f| f == feature) } - pub(crate) fn build_molten>(_target_dir: &P) -> &'static str { + pub(crate) fn build_molten() -> &'static str { use std::{ process::Command, sync::{ @@ -115,8 +123,12 @@ mod mac { }, }; - let checkout_dir = Path::new(&std::env::var("OUT_DIR").expect("Couldn't find OUT_DIR")) - .join(format!("MoltenVK-{}", get_artifact_tag())); + let checkout_dir = if let Some(local_dir) = MOLTEN_VK_LOCAL { + PathBuf::from(local_dir) + } else { + Path::new(&std::env::var("OUT_DIR").expect("Couldn't find OUT_DIR")) + .join(format!("MoltenVK-{}", get_artifact_tag())) + }; let exit = Arc::new(AtomicBool::new(false)); let wants_exit = exit.clone(); @@ -137,7 +149,7 @@ mod mac { if Path::new(&checkout_dir).exists() { // Don't pull if a specific hash has been checked out - if MOLTEN_VK_PATCH.is_none() { + if MOLTEN_VK_PATCH.is_none() && MOLTEN_VK_LOCAL.is_none() { let git_status = Command::new("git") .current_dir(&checkout_dir) .arg("pull") @@ -146,9 +158,9 @@ mod mac { .wait() .expect("failed to pull MoltenVK"); - assert!(git_status.success(), "failed to get MoltenVK"); + assert!(git_status.success(), "failed to pull MoltenVK from git"); } - } else { + } else if MOLTEN_VK_LOCAL.is_none() { let branch = format!("v{}", MOLTEN_VK_VERSION.to_owned()); let clone_args = if MOLTEN_VK_PATCH.is_none() { vec!["--branch", branch.as_str(), "--depth", "1"] @@ -165,8 +177,8 @@ mod mac { .wait() .expect("failed to clone MoltenVK"); - assert!(git_status.success(), "failed to get MoltenVK"); - }; + assert!(git_status.success(), "failed to clone MoltenVK"); + } if let Some(patch) = MOLTEN_VK_PATCH { let git_status = Command::new("git") @@ -200,6 +212,8 @@ mod mac { assert!(status.success(), "failed to fetchDependencies"); + println!("running make in {:?}", checkout_dir); + let status = Command::new("make") .current_dir(&checkout_dir) .arg(target_name) @@ -276,7 +290,7 @@ fn main() { use crate::mac::*; // The 'external' feature was not enabled. Molten will be built automatically. let external_enabled = is_feature_enabled("EXTERNAL"); - let pre_built_enabled = is_feature_enabled("PRE_BUILT"); + let pre_built_enabled = is_feature_enabled("PRE_BUILT") && MOLTEN_VK_LOCAL.is_none(); let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); @@ -287,7 +301,11 @@ fn main() { ); if !external_enabled { - let mut project_dir = if pre_built_enabled { + let mut project_dir = if let Some(local_bin_path) = MOLTEN_VK_LOCAL_BIN { + let mut pb = PathBuf::from(local_bin_path); + pb.push("MoltenVK.xcframework"); + pb + } else if pre_built_enabled { let target_dir = Path::new(&std::env::var("OUT_DIR").unwrap()).join(format!( "Prebuilt-MoltenVK-{}", crate::mac::get_artifact_tag() @@ -304,19 +322,24 @@ fn main() { } else { let target_dir = Path::new(&std::env::var("OUT_DIR").unwrap()) .join(format!("MoltenVK-{}", crate::mac::get_artifact_tag())); - let _target_name = build_molten(&target_dir); + let _target_name = build_molten(); + println!("Target dir was {:?}", target_dir); let mut pb = PathBuf::from( std::env::var("CARGO_MANIFEST_DIR").expect("unable to find env:CARGO_MANIFEST_DIR"), ); - pb.push(target_dir); + if let Some(local) = MOLTEN_VK_LOCAL { + pb.push(local); + } else { + pb.push(target_dir); + } pb.push("Package/Latest/MoltenVK/MoltenVK.xcframework"); pb }; - let xcframework = - xcframework::XcFramework::parse(&project_dir).expect("Failed to parse XCFramework"); + let xcframework = xcframework::XcFramework::parse(&project_dir) + .unwrap_or_else(|_| panic!("Failed to parse XCFramework from {:?}", project_dir)); let native_libs = xcframework .AvailableLibraries .into_iter()