-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix iOS bindings #17
base: master
Are you sure you want to change the base?
Fix iOS bindings #17
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,25 @@ fn osx_version() -> Result<String, std::io::Error> { | |
Ok(version.to_owned()) | ||
} | ||
|
||
fn isysroot_path(platform: &str) -> Result<String, std::io::Error> { | ||
use std::process::Command; | ||
|
||
let output = Command::new("xcrun") | ||
.arg("--sdk") | ||
.arg(platform) | ||
.arg("--show-sdk-path") | ||
.output()? | ||
.stdout; | ||
|
||
let sdk_path = | ||
std::str::from_utf8(&output).expect("invalid output from `xcrun --show-sdk-path`"); | ||
let directory = String::from(sdk_path.trim()); | ||
|
||
println!("SDK Directory: {}", directory); | ||
|
||
Ok(directory) | ||
} | ||
|
||
fn parse_version(version: &str) -> Option<i32> { | ||
version | ||
.split(".") | ||
|
@@ -23,7 +42,7 @@ fn parse_version(version: &str) -> Option<i32> { | |
.and_then(|m| m.parse::<i32>().ok()) | ||
} | ||
|
||
fn frameworks_path() -> Result<String, std::io::Error> { | ||
fn frameworks_path(platform: &str) -> Result<String, std::io::Error> { | ||
// For 10.13 and higher: | ||
// | ||
// While macOS has its system frameworks located at "/System/Library/Frameworks" | ||
|
@@ -40,18 +59,13 @@ fn frameworks_path() -> Result<String, std::io::Error> { | |
let prefix_str = std::str::from_utf8(&output).expect("invalid output from `xcode-select`"); | ||
let prefix = prefix_str.trim_right(); | ||
|
||
let platform = if cfg!(target_os = "macos") { | ||
"MacOSX" | ||
} else if cfg!(target_os = "ios") { | ||
"iPhoneOS" | ||
} else { | ||
unreachable!(); | ||
}; | ||
|
||
let infix = if prefix == "/Library/Developer/CommandLineTools" { | ||
format!("SDKs/{}.sdk", platform) | ||
} else { | ||
format!("Platforms/{}.platform/Developer/SDKs/{}.sdk", platform, platform) | ||
format!( | ||
"Platforms/{}.platform/Developer/SDKs/{}.sdk", | ||
platform, platform | ||
) | ||
}; | ||
|
||
let suffix = "System/Library/Frameworks"; | ||
|
@@ -63,7 +77,7 @@ fn frameworks_path() -> Result<String, std::io::Error> { | |
} | ||
} | ||
|
||
fn build(frameworks_path: &str) { | ||
fn build(frameworks_path: &str, sysroot: &str, platform: &str, target: &str) { | ||
// Generate one large set of bindings for all frameworks. | ||
// | ||
// We do this rather than generating a module per framework as some frameworks depend on other | ||
|
@@ -97,7 +111,13 @@ fn build(frameworks_path: &str) { | |
{ | ||
println!("cargo:rustc-link-lib=framework=CoreAudio"); | ||
frameworks.push("CoreAudio"); | ||
headers.push("CoreAudio.framework/Headers/CoreAudio.h"); | ||
match platform { | ||
"MacOSX" => headers.push("CoreAudio.framework/Headers/CoreAudio.h"), | ||
"iPhoneOS" | "iPhoneSimulator" => { | ||
headers.push("CoreAudio.framework/Headers/CoreAudioTypes.h") | ||
} | ||
_ => unreachable!(), | ||
} | ||
} | ||
|
||
#[cfg(feature = "open_al")] | ||
|
@@ -110,9 +130,13 @@ fn build(frameworks_path: &str) { | |
|
||
#[cfg(all(feature = "core_midi", target_os = "macos"))] | ||
{ | ||
println!("cargo:rustc-link-lib=framework=CoreMIDI"); | ||
frameworks.push("CoreMIDI"); | ||
headers.push("CoreMIDI.framework/Headers/CoreMIDI.h"); | ||
if (platform == "MacOSX") { | ||
println!("cargo:rustc-link-lib=framework=CoreMIDI"); | ||
frameworks.push("CoreMIDI"); | ||
headers.push("CoreMIDI.framework/Headers/CoreMIDI.h"); | ||
} else { | ||
panic!("framework CoreMIDI is not supported by Apple on this platform"); | ||
} | ||
} | ||
|
||
// Get the cargo out directory. | ||
|
@@ -121,7 +145,10 @@ fn build(frameworks_path: &str) { | |
// Begin building the bindgen params. | ||
let mut builder = bindgen::Builder::default(); | ||
|
||
builder = builder.clang_arg(format!("-F/{}", frameworks_path)); | ||
builder = builder | ||
.clang_arg(format!("-F/{}", frameworks_path)) | ||
.clang_arg("-isysroot") | ||
.clang_arg(sysroot); | ||
|
||
// Add all headers. | ||
for relative_path in headers { | ||
|
@@ -137,6 +164,8 @@ fn build(frameworks_path: &str) { | |
|
||
// Generate the bindings. | ||
let bindings = builder | ||
.clang_arg("-target") | ||
.clang_arg(target) | ||
.trust_clang_mangling(false) | ||
.derive_default(true) | ||
.rustfmt_bindings(false) | ||
|
@@ -149,16 +178,28 @@ fn build(frameworks_path: &str) { | |
.expect("could not write bindings"); | ||
} | ||
|
||
#[cfg(any(target_os = "macos", target_os = "ios"))] | ||
fn main() { | ||
if let Ok(directory) = frameworks_path() { | ||
build(&directory); | ||
let (target, platform) = match std::env::var("TARGET") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't there a better way of doing this? All of this should be exposed via cfg, no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe cfg will return the building platform as this is build.rs, so here it would always be darwin. Unless I'm wrong. I can't check right now unfortunately. |
||
Ok(val) => match val.as_ref() { | ||
"x86_64-apple-darwin" | "i686-apple-darwin" => (val, "MacOSX"), | ||
"aarch64-apple-ios" => (String::from("arm64-apple-ios"), "iPhoneOS"), | ||
"armv7-apple-ios" | "armv7s-apple-ios" | "i386-apple-ios" | "x86_64-apple-ios" => { | ||
(val, "iPhoneOS") | ||
} | ||
_ => panic!("coreaudio-sys requires macos or ios target. Found: {}", val), | ||
}, | ||
Err(_e) => { | ||
panic!("TARGET environment variable not found (are you running this outside of cargo?)") | ||
} | ||
}; | ||
|
||
if let Ok(directory) = frameworks_path(platform) { | ||
if let Ok(sysroot) = isysroot_path(&platform.to_lowercase()) { | ||
build(&directory, &sysroot, platform, &target); | ||
} else { | ||
eprintln!("coreaudio-sys could not find sysroot path"); | ||
} | ||
} else { | ||
eprintln!("coreaudio-sys could not find frameworks path"); | ||
} | ||
} | ||
|
||
#[cfg(not(any(target_os = "macos", target_os = "ios")))] | ||
fn main() { | ||
eprintln!("coreaudio-sys requires macos or ios target"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Has this been tested on older versions of osx ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, but I have no means to do it.