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"
description = "Statically linked MoltenVK for Vulkan on Mac using Ash"
version = "0.13.1+1.1.10"
authors = ["Embark <opensource@embark-studios.com>", "Maik Klein <maik.klein@embark-studios.com>"]
edition = "2018"
authors = [
"Embark <opensource@embark-studios.com>",
"Maik Klein <maik.klein@embark-studios.com>",
]
edition = "2021"
license = "MIT OR Apache-2.0"
readme = "README.md"
keywords = ["vulkan", "metal"]
@ -31,9 +34,12 @@ plist = { version = "1.0" }
[features]
# Build features
# 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
# Optional versions to use instead of the default version
v1_1_10 = []
v1_1_5 = []
[package.metadata.docs.rs]
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;
#[cfg(any(target_os = "macos", target_os = "ios"))]
mod mac {
use std::path::{Path, PathBuf};
// 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: 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"
pub(crate) fn get_artifact_tag() -> String {
if let Some(patch) = MOLTEN_VK_PATCH {
format!("{}#{}", MOLTEN_VK_VERSION, patch)
format!("{}#{patch}", get_version())
} else {
MOLTEN_VK_VERSION.to_owned()
get_version()
}
}
// Features are not used inside build scripts, so we have to explicitly query them from the
// environment
pub(crate) fn is_feature_enabled(feature: &str) -> bool {
std::env::vars()
.filter_map(|(flag, _)| {
const NAME: &str = "CARGO_FEATURE_";
if flag.starts_with(NAME) {
let feature = flag.split(NAME).nth(1).expect("").to_string();
println!("{:?}", feature);
return Some(feature);
}
None
})
.any(|f| f == feature)
let mut cargo_feat = format!("CARGO_FEATURE_{}", feature.replace('-', "_"));
cargo_feat.make_ascii_uppercase();
std::env::var_os(&cargo_feat).is_some()
}
pub(crate) fn build_molten() -> &'static str {
@ -153,29 +102,25 @@ mod mac {
let git_status = Command::new("git")
.current_dir(&checkout_dir)
.arg("pull")
.spawn()
.expect("failed to spawn git")
.wait()
.expect("failed to pull MoltenVK");
.status()
.expect("failed to spawn git");
assert!(git_status.success(), "failed to pull MoltenVK from git");
}
} 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() {
vec!["--branch", branch.as_str(), "--depth", "1"]
} 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")
.arg("clone")
.args(clone_args)
.arg("https://github.com/KhronosGroup/MoltenVK.git")
.arg(&checkout_dir)
.spawn()
.expect("failed to spawn git")
.wait()
.expect("failed to clone MoltenVK");
.status()
.expect("failed to spawn git");
assert!(git_status.success(), "failed to clone MoltenVK");
}
@ -196,31 +141,27 @@ mod mac {
Ok(target) => match target.as_ref() {
"macos" => ("macos", "macOS"),
"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")
.current_dir(&checkout_dir)
.arg("fetchDependencies")
.arg(format!("--{}", target_name))
.spawn()
.expect("failed to spawn fetchDependencies")
.wait()
.expect("failed to fetchDependencies");
.arg(format!("--{target_name}"))
.status()
.expect("failed to spawn fetchDependencies");
assert!(status.success(), "failed to fetchDependencies");
println!("running make in {:?}", checkout_dir);
println!("running make in {checkout_dir:?}");
let status = Command::new("make")
.current_dir(&checkout_dir)
.arg(target_name)
.spawn()
.expect("failed to build MoltenVK")
.wait()
.expect("failed to build MoltenVK");
.status()
.expect("failed to run make");
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) {
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!(
"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 curl_status = Command::new("curl")
.args(&["--location", "--silent", &download_url, "-o"])
.args(["--fail", "--location", "--silent", &download_url, "-o"])
.arg(&download_path)
.spawn()
.expect("Couldn't launch curl")
.wait()
.expect("failed to wait on curl");
.status()
.expect("Couldn't launch curl");
assert!(curl_status.success());
assert!(
curl_status.success(),
"failed to download prebuilt libraries"
);
let unzip_status = Command::new("unzip")
.arg("-o")
@ -257,24 +199,21 @@ mod mac {
.arg("__MACOSX/*")
.arg("-d")
.arg(target_dir.as_ref())
.spawn()
.expect("Couldn't launch unzip")
.wait()
.expect("failed to wait on unzip");
.status()
.expect("Couldn't launch unzip");
assert!(unzip_status.success(), "failed to run unzip");
if !unzip_status.success() {
let bytes = std::fs::read(download_path)
.expect("unzip failed, and further, could not open output zip file");
match std::str::from_utf8(&bytes) {
Ok(string) => {
panic!(
"Could not unzip MoltenVK.xcframework.zip. File was utf8, perhaps an error?\n{}",
string
);
}
Err(_) => {
panic!("Could not unzip MoltenVK.xcframework.zip");
}
.expect("unzip failed, and further, could not open downloaded zip file");
if let Ok(zip_text) = std::str::from_utf8(&bytes) {
panic!("Could not unzip MoltenVK.xcframework.zip. File was utf8, perhaps an error?\n{zip_text}");
} else {
panic!(
"Could not unzip MoltenVK.xcframework.zip: {:?}",
unzip_status.code()
);
}
}
}
@ -285,14 +224,20 @@ use std::{
path::{Path, PathBuf},
};
#[cfg(any(target_os = "macos", target_os = "ios"))]
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") && MOLTEN_VK_LOCAL.is_none();
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();
assert!(
@ -323,7 +268,7 @@ fn main() {
let target_dir = Path::new(&std::env::var("OUT_DIR").unwrap())
.join(format!("MoltenVK-{}", crate::mac::get_artifact_tag()));
let _target_name = build_molten();
println!("Target dir was {:?}", target_dir);
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"),
@ -339,7 +284,7 @@ fn main() {
};
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
.AvailableLibraries
.into_iter()
@ -371,8 +316,3 @@ fn main() {
println!("cargo:rustc-link-lib=dylib=c++");
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());
std::fs::create_dir_all(&out_path)?;
out_path.push(&lib_path);
out_path.push(lib_path);
assert!(Command::new("lipo")
.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};
extern "system" {
@ -84,5 +12,8 @@ pub fn load() -> Entry {
let static_fn = vk::StaticFn {
get_instance_proc_addr: vkGetInstanceProcAddr,
};
unsafe { Entry::from_static_fn(static_fn) }
#[allow(unsafe_code)]
unsafe {
Entry::from_static_fn(static_fn)
}
}