Fix cross compilation (#73)

* Update and fixup code

* Fix cross compilation

* Bring back error printing code in case it is useful

* Add version features

* oops

* Fix clippy

* Remove cargo print
This commit is contained in:
Jake Shadle 2022-11-16 12:51:26 +01:00 committed by GitHub
parent dad0ba2738
commit 719c7cd4c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 175 additions and 219 deletions

79
.cargo/config.toml Normal file
View file

@ -0,0 +1,79 @@
[target.'cfg(all())']
rustflags = [
# BEGIN - Embark standard lints v6 for Rust 1.55+
# do not change or add/remove here, but one can add exceptions after this section
# for more info see: <https://github.com/EmbarkStudios/rust-ecosystem/issues/59>
"-Dunsafe_code",
"-Wclippy::all",
"-Wclippy::await_holding_lock",
"-Wclippy::char_lit_as_u8",
"-Wclippy::checked_conversions",
"-Wclippy::dbg_macro",
"-Wclippy::debug_assert_with_mut_call",
"-Wclippy::doc_markdown",
"-Wclippy::empty_enum",
"-Wclippy::enum_glob_use",
"-Wclippy::exit",
"-Wclippy::expl_impl_clone_on_copy",
"-Wclippy::explicit_deref_methods",
"-Wclippy::explicit_into_iter_loop",
"-Wclippy::fallible_impl_from",
"-Wclippy::filter_map_next",
"-Wclippy::flat_map_option",
"-Wclippy::float_cmp_const",
"-Wclippy::fn_params_excessive_bools",
"-Wclippy::from_iter_instead_of_collect",
"-Wclippy::if_let_mutex",
"-Wclippy::implicit_clone",
"-Wclippy::imprecise_flops",
"-Wclippy::inefficient_to_string",
"-Wclippy::invalid_upcast_comparisons",
"-Wclippy::large_digit_groups",
"-Wclippy::large_stack_arrays",
"-Wclippy::large_types_passed_by_value",
"-Wclippy::let_unit_value",
"-Wclippy::linkedlist",
"-Wclippy::lossy_float_literal",
"-Wclippy::macro_use_imports",
"-Wclippy::manual_ok_or",
"-Wclippy::map_err_ignore",
"-Wclippy::map_flatten",
"-Wclippy::map_unwrap_or",
"-Wclippy::match_on_vec_items",
"-Wclippy::match_same_arms",
"-Wclippy::match_wild_err_arm",
"-Wclippy::match_wildcard_for_single_variants",
"-Wclippy::mem_forget",
"-Wclippy::mismatched_target_os",
"-Wclippy::missing_enforced_import_renames",
"-Wclippy::mut_mut",
"-Wclippy::mutex_integer",
"-Wclippy::needless_borrow",
"-Wclippy::needless_continue",
"-Wclippy::needless_for_each",
"-Wclippy::option_option",
"-Wclippy::path_buf_push_overwrite",
"-Wclippy::ptr_as_ptr",
"-Wclippy::rc_mutex",
"-Wclippy::ref_option_ref",
"-Wclippy::rest_pat_in_fully_bound_structs",
"-Wclippy::same_functions_in_if_condition",
"-Wclippy::semicolon_if_nothing_returned",
"-Wclippy::single_match_else",
"-Wclippy::string_add_assign",
"-Wclippy::string_add",
"-Wclippy::string_lit_as_bytes",
"-Wclippy::string_to_string",
"-Wclippy::todo",
"-Wclippy::trait_duplication_in_bounds",
"-Wclippy::unimplemented",
"-Wclippy::unnested_or_patterns",
"-Wclippy::unused_self",
"-Wclippy::useless_transmute",
"-Wclippy::verbose_file_reads",
"-Wclippy::zero_sized_map_values",
"-Wfuture_incompatible",
"-Wnonstandard_style",
"-Wrust_2018_idioms",
# END - Embark standard lints v6 for Rust 1.55+
]

View file

@ -2,8 +2,11 @@
name = "ash-molten" name = "ash-molten"
description = "Statically linked MoltenVK for Vulkan on Mac using Ash" description = "Statically linked MoltenVK for Vulkan on Mac using Ash"
version = "0.13.1+1.1.10" version = "0.13.1+1.1.10"
authors = ["Embark <opensource@embark-studios.com>", "Maik Klein <maik.klein@embark-studios.com>"] authors = [
edition = "2018" "Embark <opensource@embark-studios.com>",
"Maik Klein <maik.klein@embark-studios.com>",
]
edition = "2021"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
readme = "README.md" readme = "README.md"
keywords = ["vulkan", "metal"] keywords = ["vulkan", "metal"]
@ -31,9 +34,12 @@ plist = { version = "1.0" }
[features] [features]
# Build features # Build features
# Without build feature enabled MoltenVK will be build from source # Without build feature enabled MoltenVK will be build from source
external = [] # Supply own MoltenVK lib external = [] # Supply own MoltenVK lib
pre-built = [] # Download pre-built MoltenVK from github release pre-built = [] # Download pre-built MoltenVK from github release
# Optional versions to use instead of the default version
v1_1_10 = []
v1_1_5 = []
[package.metadata.docs.rs] [package.metadata.docs.rs]
default-target = "x86_64-apple-darwin" default-target = "x86_64-apple-darwin"

View file

@ -1,80 +1,6 @@
// BEGIN - Embark standard lints v0.4
// do not change or add/remove here, but one can add exceptions after this section
// for more info see: <https://github.com/EmbarkStudios/rust-ecosystem/issues/59>
#![deny(unsafe_code)]
#![warn(
clippy::all,
clippy::await_holding_lock,
clippy::char_lit_as_u8,
clippy::checked_conversions,
clippy::dbg_macro,
clippy::debug_assert_with_mut_call,
clippy::doc_markdown,
clippy::empty_enum,
clippy::enum_glob_use,
clippy::exit,
clippy::expl_impl_clone_on_copy,
clippy::explicit_deref_methods,
clippy::explicit_into_iter_loop,
clippy::fallible_impl_from,
clippy::filter_map_next,
clippy::float_cmp_const,
clippy::fn_params_excessive_bools,
clippy::if_let_mutex,
clippy::implicit_clone,
clippy::imprecise_flops,
clippy::inefficient_to_string,
clippy::invalid_upcast_comparisons,
clippy::large_types_passed_by_value,
clippy::let_unit_value,
clippy::linkedlist,
clippy::lossy_float_literal,
clippy::macro_use_imports,
clippy::manual_ok_or,
clippy::map_err_ignore,
clippy::map_flatten,
clippy::map_unwrap_or,
clippy::match_on_vec_items,
clippy::match_same_arms,
clippy::match_wildcard_for_single_variants,
clippy::mem_forget,
clippy::mismatched_target_os,
clippy::mut_mut,
clippy::mutex_integer,
clippy::needless_borrow,
clippy::needless_continue,
clippy::option_option,
clippy::path_buf_push_overwrite,
clippy::ptr_as_ptr,
clippy::ref_option_ref,
clippy::rest_pat_in_fully_bound_structs,
clippy::same_functions_in_if_condition,
clippy::semicolon_if_nothing_returned,
clippy::string_add_assign,
clippy::string_add,
clippy::string_lit_as_bytes,
clippy::string_to_string,
clippy::todo,
clippy::trait_duplication_in_bounds,
clippy::unimplemented,
clippy::unnested_or_patterns,
clippy::unused_self,
clippy::useless_transmute,
clippy::verbose_file_reads,
clippy::zero_sized_map_values,
future_incompatible,
nonstandard_style,
rust_2018_idioms
)]
// END - Embark standard lints v0.4
// crate-specific exceptions:
#![allow(unsafe_code)]
mod xcframework; mod xcframework;
#[cfg(any(target_os = "macos", target_os = "ios"))]
mod mac { mod mac {
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
// MoltenVK git tagged release to use // MoltenVK git tagged release to use
@ -89,29 +15,52 @@ mod mac {
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_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"); pub static MOLTEN_VK_LOCAL: Option<&str> = None; // for example, Some("/Users/my_user_name/dev/MoltenVK");
#[inline]
fn iter_features() -> impl Iterator<Item = String> {
std::env::vars()
.filter_map(|(flag, _)| flag.strip_prefix("CARGO_FEATURE_").map(String::from))
}
/// Each release by default uses a particular version of molten vk, but we
/// also allow features to override that version.
///
/// This is needed since the rust version may have features/fixes in a later
/// version, but the moltenvk version that it wants is older since a newer
/// version can be...broken. :p
fn get_version() -> String {
let feat_vers = iter_features().fold(None, |mut to_use, feat| {
if let Some(version) = feat.strip_prefix('V') {
let voverride = version.replace('_', ".");
if let Some(cur) = &to_use {
panic!("{cur} is being overriden by {voverride}, please set only one `v<version>` feature");
}
to_use = Some(voverride);
}
to_use
});
feat_vers.unwrap_or_else(|| MOLTEN_VK_VERSION.to_owned())
}
// Return the artifact tag in the form of "x.x.x" or if there is a patch specified "x.x.x#yyyyyyy" // 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 { pub(crate) fn get_artifact_tag() -> String {
if let Some(patch) = MOLTEN_VK_PATCH { if let Some(patch) = MOLTEN_VK_PATCH {
format!("{}#{}", MOLTEN_VK_VERSION, patch) format!("{}#{patch}", get_version())
} else { } else {
MOLTEN_VK_VERSION.to_owned() get_version()
} }
} }
// Features are not used inside build scripts, so we have to explicitly query them from the // Features are not used inside build scripts, so we have to explicitly query them from the
// environment // environment
pub(crate) fn is_feature_enabled(feature: &str) -> bool { pub(crate) fn is_feature_enabled(feature: &str) -> bool {
std::env::vars() let mut cargo_feat = format!("CARGO_FEATURE_{}", feature.replace('-', "_"));
.filter_map(|(flag, _)| { cargo_feat.make_ascii_uppercase();
const NAME: &str = "CARGO_FEATURE_";
if flag.starts_with(NAME) { std::env::var_os(&cargo_feat).is_some()
let feature = flag.split(NAME).nth(1).expect("").to_string();
println!("{:?}", feature);
return Some(feature);
}
None
})
.any(|f| f == feature)
} }
pub(crate) fn build_molten() -> &'static str { pub(crate) fn build_molten() -> &'static str {
@ -153,29 +102,25 @@ mod mac {
let git_status = Command::new("git") let git_status = Command::new("git")
.current_dir(&checkout_dir) .current_dir(&checkout_dir)
.arg("pull") .arg("pull")
.spawn() .status()
.expect("failed to spawn git") .expect("failed to spawn git");
.wait()
.expect("failed to pull MoltenVK");
assert!(git_status.success(), "failed to pull MoltenVK from git"); assert!(git_status.success(), "failed to pull MoltenVK from git");
} }
} else if MOLTEN_VK_LOCAL.is_none() { } else if MOLTEN_VK_LOCAL.is_none() {
let branch = format!("v{}", MOLTEN_VK_VERSION.to_owned()); let branch = format!("v{}", get_version());
let clone_args = if MOLTEN_VK_PATCH.is_none() { let clone_args = if MOLTEN_VK_PATCH.is_none() {
vec!["--branch", branch.as_str(), "--depth", "1"] vec!["--branch", branch.as_str(), "--depth", "1"]
} else { } else {
vec!["--single-branch", "--branch", "master"] // Can't specify depth if you switch to a different commit hash later. vec!["--single-branch", "--branch", "main"] // Can't specify depth if you switch to a different commit hash later.
}; };
let git_status = Command::new("git") let git_status = Command::new("git")
.arg("clone") .arg("clone")
.args(clone_args) .args(clone_args)
.arg("https://github.com/KhronosGroup/MoltenVK.git") .arg("https://github.com/KhronosGroup/MoltenVK.git")
.arg(&checkout_dir) .arg(&checkout_dir)
.spawn() .status()
.expect("failed to spawn git") .expect("failed to spawn git");
.wait()
.expect("failed to clone MoltenVK");
assert!(git_status.success(), "failed to clone MoltenVK"); assert!(git_status.success(), "failed to clone MoltenVK");
} }
@ -196,31 +141,27 @@ mod mac {
Ok(target) => match target.as_ref() { Ok(target) => match target.as_ref() {
"macos" => ("macos", "macOS"), "macos" => ("macos", "macOS"),
"ios" => ("ios", "iOS"), "ios" => ("ios", "iOS"),
target => panic!("unknown target '{}'", target), target => panic!("unknown target '{target}'"),
}, },
Err(e) => panic!("failed to determine target os '{}'", e), Err(e) => panic!("failed to determine target os '{e}'"),
}; };
let status = Command::new("sh") let status = Command::new("sh")
.current_dir(&checkout_dir) .current_dir(&checkout_dir)
.arg("fetchDependencies") .arg("fetchDependencies")
.arg(format!("--{}", target_name)) .arg(format!("--{target_name}"))
.spawn() .status()
.expect("failed to spawn fetchDependencies") .expect("failed to spawn fetchDependencies");
.wait()
.expect("failed to fetchDependencies");
assert!(status.success(), "failed to fetchDependencies"); assert!(status.success(), "failed to fetchDependencies");
println!("running make in {:?}", checkout_dir); println!("running make in {checkout_dir:?}");
let status = Command::new("make") let status = Command::new("make")
.current_dir(&checkout_dir) .current_dir(&checkout_dir)
.arg(target_name) .arg(target_name)
.spawn() .status()
.expect("failed to build MoltenVK") .expect("failed to run make");
.wait()
.expect("failed to build MoltenVK");
assert!(status.success(), "failed to build MoltenVK"); assert!(status.success(), "failed to build MoltenVK");
@ -232,7 +173,7 @@ mod mac {
pub(crate) fn download_prebuilt_molten<P: AsRef<Path>>(target_dir: &P) { pub(crate) fn download_prebuilt_molten<P: AsRef<Path>>(target_dir: &P) {
use std::process::Command; use std::process::Command;
std::fs::create_dir_all(&target_dir).expect("Couldn't create directory"); std::fs::create_dir_all(target_dir).expect("Couldn't create directory");
let download_url = format!( let download_url = format!(
"https://github.com/EmbarkStudios/ash-molten/releases/download/MoltenVK-{}/MoltenVK.xcframework.zip", "https://github.com/EmbarkStudios/ash-molten/releases/download/MoltenVK-{}/MoltenVK.xcframework.zip",
@ -241,14 +182,15 @@ mod mac {
let download_path = target_dir.as_ref().join("MoltenVK.xcframework.zip"); let download_path = target_dir.as_ref().join("MoltenVK.xcframework.zip");
let curl_status = Command::new("curl") let curl_status = Command::new("curl")
.args(&["--location", "--silent", &download_url, "-o"]) .args(["--fail", "--location", "--silent", &download_url, "-o"])
.arg(&download_path) .arg(&download_path)
.spawn() .status()
.expect("Couldn't launch curl") .expect("Couldn't launch curl");
.wait()
.expect("failed to wait on curl");
assert!(curl_status.success()); assert!(
curl_status.success(),
"failed to download prebuilt libraries"
);
let unzip_status = Command::new("unzip") let unzip_status = Command::new("unzip")
.arg("-o") .arg("-o")
@ -257,24 +199,21 @@ mod mac {
.arg("__MACOSX/*") .arg("__MACOSX/*")
.arg("-d") .arg("-d")
.arg(target_dir.as_ref()) .arg(target_dir.as_ref())
.spawn() .status()
.expect("Couldn't launch unzip") .expect("Couldn't launch unzip");
.wait()
.expect("failed to wait on unzip"); assert!(unzip_status.success(), "failed to run unzip");
if !unzip_status.success() { if !unzip_status.success() {
let bytes = std::fs::read(download_path) let bytes = std::fs::read(download_path)
.expect("unzip failed, and further, could not open output zip file"); .expect("unzip failed, and further, could not open downloaded zip file");
match std::str::from_utf8(&bytes) { if let Ok(zip_text) = std::str::from_utf8(&bytes) {
Ok(string) => { panic!("Could not unzip MoltenVK.xcframework.zip. File was utf8, perhaps an error?\n{zip_text}");
panic!( } else {
"Could not unzip MoltenVK.xcframework.zip. File was utf8, perhaps an error?\n{}", panic!(
string "Could not unzip MoltenVK.xcframework.zip: {:?}",
); unzip_status.code()
} );
Err(_) => {
panic!("Could not unzip MoltenVK.xcframework.zip");
}
} }
} }
} }
@ -285,14 +224,20 @@ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
#[cfg(any(target_os = "macos", target_os = "ios"))]
fn main() { fn main() {
use crate::mac::*; 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") && MOLTEN_VK_LOCAL.is_none();
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap(); let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
if target_os != "macos" && target_os != "ios" {
eprintln!("ash-molten requires either 'macos' or 'ios' target");
return;
}
// 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") && MOLTEN_VK_LOCAL.is_none();
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap(); let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
assert!( assert!(
@ -323,7 +268,7 @@ fn main() {
let target_dir = Path::new(&std::env::var("OUT_DIR").unwrap()) let target_dir = Path::new(&std::env::var("OUT_DIR").unwrap())
.join(format!("MoltenVK-{}", crate::mac::get_artifact_tag())); .join(format!("MoltenVK-{}", crate::mac::get_artifact_tag()));
let _target_name = build_molten(); let _target_name = build_molten();
println!("Target dir was {:?}", target_dir); println!("Target dir was {target_dir:?}");
let mut pb = PathBuf::from( let mut pb = PathBuf::from(
std::env::var("CARGO_MANIFEST_DIR").expect("unable to find env:CARGO_MANIFEST_DIR"), std::env::var("CARGO_MANIFEST_DIR").expect("unable to find env:CARGO_MANIFEST_DIR"),
@ -339,7 +284,7 @@ fn main() {
}; };
let xcframework = xcframework::XcFramework::parse(&project_dir) let xcframework = xcframework::XcFramework::parse(&project_dir)
.unwrap_or_else(|_| panic!("Failed to parse XCFramework from {:?}", project_dir)); .unwrap_or_else(|_| panic!("Failed to parse XCFramework from {project_dir:?}"));
let native_libs = xcframework let native_libs = xcframework
.AvailableLibraries .AvailableLibraries
.into_iter() .into_iter()
@ -371,8 +316,3 @@ fn main() {
println!("cargo:rustc-link-lib=dylib=c++"); println!("cargo:rustc-link-lib=dylib=c++");
println!("cargo:rustc-link-lib=static=MoltenVK"); println!("cargo:rustc-link-lib=static=MoltenVK");
} }
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
fn main() {
eprintln!("ash-molten requires either 'macos' or 'ios' target");
}

View file

@ -80,7 +80,7 @@ impl UniversalLibrary {
let mut out_path = xcframework_dir.join(new_identifier.clone()); let mut out_path = xcframework_dir.join(new_identifier.clone());
std::fs::create_dir_all(&out_path)?; std::fs::create_dir_all(&out_path)?;
out_path.push(&lib_path); out_path.push(lib_path);
assert!(Command::new("lipo") assert!(Command::new("lipo")
.arg(&full_path) .arg(&full_path)

View file

@ -1,75 +1,3 @@
// BEGIN - Embark standard lints v0.4
// do not change or add/remove here, but one can add exceptions after this section
// for more info see: <https://github.com/EmbarkStudios/rust-ecosystem/issues/59>
#![deny(unsafe_code)]
#![warn(
clippy::all,
clippy::await_holding_lock,
clippy::char_lit_as_u8,
clippy::checked_conversions,
clippy::dbg_macro,
clippy::debug_assert_with_mut_call,
clippy::doc_markdown,
clippy::empty_enum,
clippy::enum_glob_use,
clippy::exit,
clippy::expl_impl_clone_on_copy,
clippy::explicit_deref_methods,
clippy::explicit_into_iter_loop,
clippy::fallible_impl_from,
clippy::filter_map_next,
clippy::float_cmp_const,
clippy::fn_params_excessive_bools,
clippy::if_let_mutex,
clippy::implicit_clone,
clippy::imprecise_flops,
clippy::inefficient_to_string,
clippy::invalid_upcast_comparisons,
clippy::large_types_passed_by_value,
clippy::let_unit_value,
clippy::linkedlist,
clippy::lossy_float_literal,
clippy::macro_use_imports,
clippy::manual_ok_or,
clippy::map_err_ignore,
clippy::map_flatten,
clippy::map_unwrap_or,
clippy::match_on_vec_items,
clippy::match_same_arms,
clippy::match_wildcard_for_single_variants,
clippy::mem_forget,
clippy::mismatched_target_os,
clippy::mut_mut,
clippy::mutex_integer,
clippy::needless_borrow,
clippy::needless_continue,
clippy::option_option,
clippy::path_buf_push_overwrite,
clippy::ptr_as_ptr,
clippy::ref_option_ref,
clippy::rest_pat_in_fully_bound_structs,
clippy::same_functions_in_if_condition,
clippy::semicolon_if_nothing_returned,
clippy::string_add_assign,
clippy::string_add,
clippy::string_lit_as_bytes,
clippy::string_to_string,
clippy::todo,
clippy::trait_duplication_in_bounds,
clippy::unimplemented,
clippy::unnested_or_patterns,
clippy::unused_self,
clippy::useless_transmute,
clippy::verbose_file_reads,
clippy::zero_sized_map_values,
future_incompatible,
nonstandard_style,
rust_2018_idioms
)]
// END - Embark standard lints v0.4
// crate-specific exceptions:
#![allow(unsafe_code)]
use ash::{vk, Entry}; use ash::{vk, Entry};
extern "system" { extern "system" {
@ -84,5 +12,8 @@ pub fn load() -> Entry {
let static_fn = vk::StaticFn { let static_fn = vk::StaticFn {
get_instance_proc_addr: vkGetInstanceProcAddr, get_instance_proc_addr: vkGetInstanceProcAddr,
}; };
unsafe { Entry::from_static_fn(static_fn) } #[allow(unsafe_code)]
unsafe {
Entry::from_static_fn(static_fn)
}
} }