Skip to content

Commit

Permalink
Bug 1591249 - Bump coreaudio-sys to 0.2.3. r=glandium
Browse files Browse the repository at this point in the history
The current coreaudio-sys in gecko is a custom 0.2.2 version that used
to avoid the cross-compiling issue mentioned in bug 1569003. The issue
has been fixed in the coreaudio-sys 0.2.3, so we should follow the
upstream instead of using a custom version. As a result, the
coreaudio-sys would generate API bindings based on the MacOS SDK defined
in the build settings.

Differential Revision: https://phabricator.services.mozilla.com/D50531

--HG--
extra : moz-landing-system : lando
  • Loading branch information
ChunMinChang committed Oct 31, 2019
1 parent 5f86f24 commit 7f26e8d
Show file tree
Hide file tree
Showing 11 changed files with 100 additions and 42,639 deletions.
6 changes: 4 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,3 @@ rev = "da179e4fd83d49b7ad6c9f286b1ea04d4f64907e"
[patch.crates-io.cranelift-wasm]
git = "https://github.com/CraneStation/Cranelift"
rev = "da179e4fd83d49b7ad6c9f286b1ea04d4f64907e"

[patch.crates-io.coreaudio-sys]
path = "third_party/rust/coreaudio-sys"
7 changes: 7 additions & 0 deletions config/makefiles/rust.mk
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,13 @@ export PKG_CONFIG_ALLOW_CROSS=1
export RUST_BACKTRACE=full
export MOZ_TOPOBJDIR=$(topobjdir)

# Set COREAUDIO_SDK_PATH for third_party/rust/coreaudio-sys/build.rs
ifeq ($(OS_ARCH), Darwin)
ifdef MACOS_SDK_DIR
export COREAUDIO_SDK_PATH=$(MACOS_SDK_DIR)
endif
endif

target_rust_ltoable := force-cargo-library-build
target_rust_nonltoable := force-cargo-test-run force-cargo-library-check $(foreach b,build check,force-cargo-program-$(b))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ core-foundation-sys = { version = "0.6" }

[dependencies.coreaudio-sys]
default-features = false
features = ["audio_unit", "core_audio", "nobindgen"]
features = ["audio_unit", "core_audio"]
version = "0.2"
2 changes: 1 addition & 1 deletion third_party/rust/coreaudio-sys/.cargo-checksum.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"files":{".travis.yml":"9b7d846653c87d1f9bc48463633205f380ae903a109e2ac43f41fa41bed6c18c","Cargo.toml":"d07a26fe98b835d6894acf60de65ef6f8ade246efd15bac77a3807ecb94443fc","LICENSE":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README.md":"e4de3b20e6b6766ea274991679faf7489505bf6fb3130351b3a81acc3f6bf526","build.rs":"03d2af33d0251cf323f50ab29c064908d22640b7ac9929755c3da8ffc02d5118","src/fullback_coreaudio.rs":"e918093ccbbb15ea6dabf3a722b45d67032f9d33be43685c778bd9294aad44ff","src/lib.rs":"a66e454e234e9187ab930b58a064485924fcc3e460ba12ac6ed76eb61a2567a5"},"package":null}
{"files":{"Cargo.toml":"249473baf82e224de8b2a97b66d837d56efe1e3060813727b4be9e88a0a6a04c","LICENSE":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README.md":"4712c7a0f626e72a87440871f4ae136d9b35c04a361c679139ad5da1dd32f534","build.rs":"2d59eb3d84e95733e004ce4de00a3db01b461518626128bcbad3d59c1c348a04","src/lib.rs":"22c9dbbb1dc38d6f77b9362e806a7ee59a8ca1aa9b2c9344d1a487a91287ed59"},"package":"7e8f5954c1c7ccb55340443e8b29fca24013545a5e7d72c1ca7db4fc02b982ce"}
16 changes: 0 additions & 16 deletions third_party/rust/coreaudio-sys/.travis.yml

This file was deleted.

33 changes: 22 additions & 11 deletions third_party/rust/coreaudio-sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,23 +1,34 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)

[package]
name = "coreaudio-sys"
version = "0.2.2"
version = "0.2.3"
authors = ["Mitchell Nordine <[email protected]>"]
build = "build.rs"
description = "Bindings for Apple's CoreAudio frameworks generated via rust-bindgen"
license = "MIT"
keywords = ["core", "audio", "unit", "osx", "ios"]
readme = "README.md"
homepage = "https://github.com/RustAudio/coreaudio-sys"
readme = "README.md"
keywords = ["core", "audio", "unit", "osx", "ios"]
license = "MIT"
repository = "https://github.com/RustAudio/coreaudio-sys.git"
build = "build.rs"

[build-dependencies]
bindgen = {version = "0.51.1-oldsyn", default-features = false}
[build-dependencies.bindgen]
version = "0.51"
default-features = false

[features]
default = ["audio_toolbox", "audio_unit", "core_audio", "open_al", "core_midi"]
audio_toolbox = []
audio_unit = []
core_audio = []
open_al = []
core_midi = []
nobindgen = []
default = ["audio_toolbox", "audio_unit", "core_audio", "open_al", "core_midi"]
open_al = []
18 changes: 15 additions & 3 deletions third_party/rust/coreaudio-sys/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

Raw bindings to Apple's Core Audio API for macos and iOS generated using [rust-bindgen](https://github.com/rust-lang-nursery/rust-bindgen). [coreaudio-rs](https://github.com/RustAudio/coreaudio-rs) is an attempt at offering a higher level API around this crate.

## TODO
- Add/Organize raw bindings manually
- [reference](https://github.com/djg/core-audio-rs/tree/master/core-audio-sys)
## Cross Compiling

[Rust Cross](https://github.com/japaric/rust-cross) has a good explanation of how cross-compiling Rust works in general. While the author of Rust Cross advises against it, it is perfectly possible to cross-compile Rust for MacOS on Linux. [OSXCross](https://github.com/tpoechtrager/osxcross) can be used to create a compiler toolchain that can compile for MacOS on Linux.

### Environment Variables

When cross-compiling for MacOS on Linux there are two environment variables that are used to configure how `coreaudio-sys` finds the required headers and libraries. The following examples assume that you have OSXCross installed at `/build/osxcross`.

#### `COREAUDIO_SDK_PATH`

This tell `coreaudio-sys` where to find the MacOS SDK:

```bash
export COREAUDIO_SDK_PATH=/build/osxcross/target/SDK/MacOSX10.11.sdk
```
165 changes: 49 additions & 116 deletions third_party/rust/coreaudio-sys/build.rs
Original file line number Diff line number Diff line change
@@ -1,72 +1,30 @@
extern crate bindgen;

fn osx_version() -> Result<String, std::io::Error> {
fn sdk_path(target: &str) -> Result<String, std::io::Error> {
// Use environment variable if set
println!("cargo:rerun-if-env-changed=COREAUDIO_SDK_PATH");
if let Ok(path) = std::env::var("COREAUDIO_SDK_PATH") {
return Ok(path);
}

use std::process::Command;

let output = Command::new("defaults")
.arg("read")
.arg("loginwindow")
.arg("SystemVersionStampAsString")
let sdk = if target.contains("apple-darwin") {
"macosx"
} else if target.contains("apple-ios") {
"iphoneos"
} else {
unreachable!();
};
let output = Command::new("xcrun")
.args(&["--sdk", sdk, "--show-sdk-path"])
.output()?
.stdout;
let version_str = std::str::from_utf8(&output).expect("invalid output from `defaults`");
let version = version_str.trim_right();

Ok(version.to_owned())
}

fn parse_version(version: &str) -> Option<i32> {
version
.split(".")
.skip(1)
.next()
.and_then(|m| m.parse::<i32>().ok())
}

fn frameworks_path() -> Result<String, std::io::Error> {
// For 10.13 and higher:
//
// While macOS has its system frameworks located at "/System/Library/Frameworks"
// for actually linking against them (especially for cross-compilation) once
// has to refer to the frameworks as found within "Xcode.app/Contents/Developer/…".

if osx_version()
.and_then(|version| Ok(parse_version(&version).map(|v| v >= 13).unwrap_or(false)))
.unwrap_or(false)
{
use std::process::Command;

let output = Command::new("xcode-select").arg("-p").output()?.stdout;
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
)
};

let suffix = "System/Library/Frameworks";
let directory = format!("{}/{}/{}", prefix, infix, suffix);

Ok(directory)
} else {
Ok("/System/Library/Frameworks".to_string())
}
let prefix_str = std::str::from_utf8(&output).expect("invalid output from `xcrun`");
Ok(prefix_str.trim_end().to_string())
}

fn build(frameworks_path: &str) {
fn build(sdk_path: Option<&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
Expand All @@ -79,105 +37,80 @@ fn build(frameworks_path: &str) {
use std::env;
use std::path::PathBuf;

let mut frameworks = Vec::<&str>::new();
let mut headers = Vec::<&str>::new();
let mut headers = vec![];

#[cfg(feature = "audio_toolbox")]
{
println!("cargo:rustc-link-lib=framework=AudioToolbox");
frameworks.push("AudioToolbox");
headers.push("AudioToolbox.framework/Headers/AudioToolbox.h");
headers.push("AudioToolbox/AudioToolbox.h");
}

#[cfg(feature = "audio_unit")]
{
println!("cargo:rustc-link-lib=framework=AudioUnit");
frameworks.push("AudioUnit");
headers.push("AudioUnit.framework/Headers/AudioUnit.h");
headers.push("AudioUnit/AudioUnit.h");
}

#[cfg(feature = "core_audio")]
{
println!("cargo:rustc-link-lib=framework=CoreAudio");
frameworks.push("CoreAudio");
headers.push("CoreAudio.framework/Headers/CoreAudio.h");
headers.push("CoreAudio/CoreAudio.h");
}

#[cfg(feature = "open_al")]
{
println!("cargo:rustc-link-lib=framework=OpenAL");
frameworks.push("OpenAL");
headers.push("OpenAL.framework/Headers/al.h");
headers.push("OpenAL.framework/Headers/alc.h");
headers.push("OpenAL/al.h");
headers.push("OpenAL/alc.h");
}

#[cfg(all(feature = "core_midi", target_os = "macos"))]
#[cfg(all(feature = "core_midi"))]
{
println!("cargo:rustc-link-lib=framework=CoreMIDI");
frameworks.push("CoreMIDI");
headers.push("CoreMIDI.framework/Headers/CoreMIDI.h");
if target.contains("apple-darwin") {
println!("cargo:rustc-link-lib=framework=CoreMIDI");
headers.push("CoreMIDI/CoreMIDI.h");
}
}

println!("cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS");
// Get the cargo out directory.
let out_dir = PathBuf::from(env::var("OUT_DIR").expect("env variable OUT_DIR not found"));

// Begin building the bindgen params.
let mut builder = bindgen::Builder::default();

builder = builder.clang_arg(format!("-F/{}", frameworks_path));
builder = builder.clang_args(&[&format!("--target={}", target)]);

// Add all headers.
for relative_path in headers {
let absolute_path = format!("{}/{}", frameworks_path, relative_path);
builder = builder.header(absolute_path);
if let Some(sdk_path) = sdk_path {
builder = builder.clang_args(&["-isysroot", sdk_path]);
}

// Link to all frameworks.
for relative_path in frameworks {
let link_instruction = format!("#[link = \"{}/{}\"]", frameworks_path, relative_path);
builder = builder.raw_line(link_instruction);
}
let meta_header: Vec<_> = headers
.iter()
.map(|h| format!("#include <{}>\n", h))
.collect();

builder = builder.header_contents("coreaudio.h", &meta_header.concat());

// Generate the bindings.
let bindings = builder
builder = builder
.trust_clang_mangling(false)
.derive_default(true)
.rustfmt_bindings(false)
.generate()
.expect("unable to generate bindings");
.derive_default(true);

let bindings = builder.generate().expect("unable to generate bindings");

// Write them to the crate root.
bindings
.write_to_file(out_dir.join("coreaudio.rs"))
.expect("could not write bindings");
}

#[cfg(all(
not(feature = "nobindgen"),
any(target_os = "macos", target_os = "ios")
))]
fn main() {
if let Ok(directory) = frameworks_path() {
build(&directory);
} else {
eprintln!("coreaudio-sys could not find frameworks path");
}
}

#[cfg(any(
feature = "nobindgen",
not(any(target_os = "macos", target_os = "ios"))
))]
fn main() {
let target = std::env::var("TARGET").unwrap();
// If target's operating system is not macos or ios but the build target
// is apple's platform (e.g., mac os virtual machine on Linux), use
// the fullback raw bindings instead.
if target.contains("-apple") {
println!("cargo:rustc-link-lib=framework=AudioUnit");
println!("cargo:rustc-link-lib=framework=CoreAudio");
println!("cargo:rustc-cfg=fullback_bindings");
} else {
eprintln!("{} is not a valid target for coreaudio-sys.", target);
if !(target.contains("apple-darwin") || target.contains("apple-ios")) {
panic!("coreaudio-sys requires macos or ios target");
}

let directory = sdk_path(&target).ok();
build(directory.as_ref().map(String::as_ref), &target);
}
Loading

0 comments on commit 7f26e8d

Please sign in to comment.