diff --git a/.github/workflows/coreaudio-sys.yml b/.github/workflows/coreaudio-sys.yml index f03b950..1c5628a 100644 --- a/.github/workflows/coreaudio-sys.yml +++ b/.github/workflows/coreaudio-sys.yml @@ -7,8 +7,11 @@ jobs: strategy: matrix: toolchain: [stable, nightly] + # toolchain: [nightly] steps: - uses: actions/checkout@v4 + - name: remove rust-toolchain.toml + run: rm -rf rust-toolchain.toml - name: Install LLVM and Clang uses: KyleMayes/install-llvm-action@v2.0.3 with: @@ -28,6 +31,7 @@ jobs: strategy: matrix: toolchain: [stable, nightly] + # toolchain: [nightly] target: [aarch64-apple-ios, x86_64-apple-ios, aarch64-apple-ios-sim] steps: - uses: actions/checkout@v4 @@ -35,7 +39,8 @@ jobs: with: toolchain: ${{ matrix.toolchain }} targets: ${{ matrix.target }} - + - name: remove rust-toolchain.toml + run: rm -rf rust-toolchain.toml - name: Install LLVM and Clang uses: KyleMayes/install-llvm-action@v2.0.3 with: @@ -47,6 +52,36 @@ jobs: - name: Build for iOS target ${{matrix.target}} run: cargo build --verbose --target=${{matrix.target}} + apple-tier-3-check: # TBD: watchOS, tvOS + runs-on: macOS-latest + strategy: + matrix: + target: [aarch64-apple-visionos, aarch64-apple-visionos-sim] + steps: + - uses: actions/checkout@v4 + + - uses: dtolnay/rust-toolchain@master + with: + profile: minimal + toolchain: nightly + components: rust-src + + - name: Install Xcode Command Line Tools + run: sudo xcode-select --switch /Applications/Xcode_15.4.app/Contents/Developer + # run: sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer + + # https://github.com/actions/runner-images/blob/main/images/macos/macos-14-Readme.md + - name: Show Xcode SDKs + run: xcodebuild -showsdks + + - name: Find AudioUnit.h + run: find /Applications/Xcode_15.4.app -name AudioUnit.h + # run: find /Applications/Xcode.app -name AudioUnit.h + + - name: Build for visionOS target ${{matrix.target}} + # run: cargo build --verbose --target=${{matrix.target}} + run: cargo +nightly build -Z build-std=std,panic_abort --verbose --target=${{matrix.target}} + # Build the docs with all features to make sure docs.rs will work. macos-docs: runs-on: macOS-latest @@ -58,7 +93,8 @@ jobs: version: "15.0" - uses: dtolnay/rust-toolchain@master with: - toolchain: stable + # toolchain: stable + toolchain: nightly - name: cargo doc - all features run: cargo doc --all-features --verbose diff --git a/Cargo.toml b/Cargo.toml index 22eea86..d40c171 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.2.15" authors = ["Mitchell Nordine "] description = "Bindings for Apple's CoreAudio frameworks generated via rust-bindgen" license = "MIT" -keywords = ["core", "audio", "unit", "osx", "ios"] +keywords = ["core", "audio", "unit", "osx", "ios", "visionos"] readme = "README.md" homepage = "https://github.com/RustAudio/coreaudio-sys" repository = "https://github.com/RustAudio/coreaudio-sys.git" @@ -27,5 +27,5 @@ core_midi = [] [package.metadata.docs.rs] all-features = true -default-target = "x86_64-apple-darwin" -targets = ["x86_64-apple-darwin", "x86_64-apple-ios"] +default-target = "aarch64-apple-darwin" +targets = ["x86_64-apple-darwin", "x86_64-apple-ios", "aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-visionos"] diff --git a/README.md b/README.md index e6cacf3..b5fbf29 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # coreaudio-sys [![Actions Status](https://github.com/rustaudio/coreaudio-sys/workflows/coreaudio-sys/badge.svg)](https://github.com/rustaudio/coreaudio-sys/actions) [![Crates.io](https://img.shields.io/crates/v/coreaudio-sys.svg)](https://crates.io/crates/coreaudio-sys) [![Crates.io](https://img.shields.io/crates/l/coreaudio-sys.svg)](https://github.com/RustAudio/coreaudio-sys/blob/master/LICENSE) [![docs.rs](https://docs.rs/coreaudio-sys/badge.svg)](https://docs.rs/coreaudio-sys/) -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. +Raw bindings to Apple's Core Audio API for macos and iOS and visionOS 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. ## Cross Compiling diff --git a/build.rs b/build.rs index f3373cd..146c796 100644 --- a/build.rs +++ b/build.rs @@ -21,6 +21,10 @@ fn sdk_path(target: &str) -> Result { || target == "armv7s-apple-ios" { "iphoneos" + } else if target == "aarch64-apple-visionos" { + "xros" + } else if target == "aarch64-apple-visionos-sim" { + "xrsimulator" } else { unreachable!(); }; @@ -29,6 +33,7 @@ fn sdk_path(target: &str) -> Result { .output()? .stdout; let prefix_str = std::str::from_utf8(&output).expect("invalid output from `xcrun`"); + Ok(prefix_str.trim_end().to_string()) } @@ -45,41 +50,44 @@ fn build(sdk_path: Option<&str>, target: &str) { use std::env; use std::path::PathBuf; + #[allow(unused)] let mut headers: Vec<&'static str> = vec![]; #[cfg(feature = "audio_unit")] { - // Since iOS 10.0 and macOS 10.12, all the functionality in AudioUnit + // Since iOS 10.0, macOS 10.12, visionOS 1.0, all the functionality in AudioUnit // moved to AudioToolbox, and the AudioUnit headers have been simple // wrappers ever since. - if target.contains("apple-ios") { + if target.contains("apple-ios") || target.contains("apple-visionos") { // On iOS, the AudioUnit framework does not have (and never had) an // actual dylib to link to, it is just a few header files. // The AudioToolbox framework contains the symbols instead. println!("cargo:rustc-link-lib=framework=AudioToolbox"); + headers.push("AudioToolbox/AudioUnit.h"); } else { // On macOS, the symbols are present in the AudioToolbox framework, // but only on macOS 10.12 and above. // - // However, unlike on iOS, the AudioUnit framework on macOS + // However, unlike on iOS or visionOS, the AudioUnit framework on macOS // contains a dylib with the desired symbols, that we can link to // (in later versions just re-exports from AudioToolbox). println!("cargo:rustc-link-lib=framework=AudioUnit"); + headers.push("AudioUnit/AudioUnit.h"); } - headers.push("AudioUnit/AudioUnit.h"); } #[cfg(feature = "audio_toolbox")] { println!("cargo:rustc-link-lib=framework=AudioToolbox"); headers.push("AudioToolbox/AudioToolbox.h"); + headers.push("AudioToolbox/AudioSession.h"); } #[cfg(feature = "core_audio")] { println!("cargo:rustc-link-lib=framework=CoreAudio"); - if target.contains("apple-ios") { + if target.contains("apple-ios") || target.contains("apple-visionos") { headers.push("CoreAudio/CoreAudioTypes.h"); } else { headers.push("CoreAudio/CoreAudio.h"); @@ -93,21 +101,24 @@ fn build(sdk_path: Option<&str>, target: &str) { #[cfg(feature = "io_kit_audio")] { - assert!(target.contains("apple-darwin")); - println!("cargo:rustc-link-lib=framework=IOKit"); - headers.push("IOKit/audio/IOAudioTypes.h"); + if target.contains("apple-darwin") { + println!("cargo:rustc-link-lib=framework=IOKit"); + headers.push("IOKit/audio/IOAudioTypes.h"); + } } #[cfg(feature = "open_al")] { - println!("cargo:rustc-link-lib=framework=OpenAL"); - headers.push("OpenAL/al.h"); - headers.push("OpenAL/alc.h"); + if target.contains("ios") { + println!("cargo:rustc-link-lib=framework=OpenAL"); + headers.push("OpenAL/al.h"); + headers.push("OpenAL/alc.h"); + } } #[cfg(all(feature = "core_midi"))] { - if target.contains("apple-darwin") { + if target.contains("apple-darwin") || target.contains("apple-visionos") { println!("cargo:rustc-link-lib=framework=CoreMIDI"); headers.push("CoreMIDI/CoreMIDI.h"); } @@ -123,21 +134,21 @@ fn build(sdk_path: Option<&str>, target: &str) { // See https://github.com/rust-lang/rust-bindgen/issues/1211 // Technically according to the llvm mailing list, the argument to clang here should be // -arch arm64 but it looks cleaner to just change the target. - let target = if target == "aarch64-apple-ios" { - "arm64-apple-ios" - } else if target == "aarch64-apple-darwin" { - "arm64-apple-darwin" - } else { - target + let clang_target = match target { + "aarch64-apple-ios" => "arm64-apple-ios", + "aarch64-apple-visionos" => "arm64-apple-xros", + "aarch64-apple-visionos-sim" => "arm64-apple-xros-sim", + "aarch64-apple-darwin" => "arm64-apple-darwin", + _ => target }; builder = builder.size_t_is_usize(true); - builder = builder.clang_args(&[&format!("--target={}", target)]); + builder = builder.clang_args(&[&format!("--target={}", clang_target)]); if let Some(sdk_path) = sdk_path { builder = builder.clang_args(&["-isysroot", sdk_path]); } - if target.contains("apple-ios") { + if target.contains("apple-ios") || target.contains("apple-visionos") { // time.h as has a variable called timezone that conflicts with some of the objective-c // calls from NSCalendar.h in the Foundation framework. This removes that one variable. builder = builder.blocklist_item("timezone"); @@ -149,12 +160,29 @@ fn build(sdk_path: Option<&str>, target: &str) { // https://github.com/rust-lang/rust-bindgen/issues/1651 builder = builder.layout_tests(false); + if target.contains("apple-visionos") { + // /Applications/Xcode.app/Contents/Developer/Platforms/XROS.platform/Developer/SDKs/XROS1.1.sdk/System/Library/Frameworks/AudioToolbox.framework/Headers/AudioToolbox.h:43:11: fatal error: 'AudioToolbox/AudioFileComponent.h' file not found + headers.insert(0, "#define TARGET_OS_IPHONE 1"); + // https://github.com/phracker/MacOSX-SDKs/blob/master/MacOSX10.13.sdk/usr/include/MacTypes.h#L289 + // /Applications/Xcode.app/Contents/Developer/Platforms/XROS.platform/Developer/SDKs/XROS1.1.sdk/System/Library/Frameworks/CoreMIDI.framework/Headers/MIDIServices.h:1633:8: error: unknown type name 'ItemCount' + headers.insert(0, "typedef unsigned long ItemCount;"); + headers.insert(0, "typedef unsigned long ByteCount;"); + }; + let meta_header: Vec<_> = headers .iter() - .map(|h| format!("#include <{}>\n", h)) + .map(|h| { + if h.ends_with(".h") { + format!("#include <{}>\n", h) + } else { + format!("{}\n", h) + } + }) .collect(); - builder = builder.header_contents("coreaudio.h", &meta_header.concat()); + let contents = meta_header.concat(); + + builder = builder.header_contents("coreaudio.h", &contents); // Generate the bindings. builder = builder.trust_clang_mangling(false).derive_default(true); @@ -169,8 +197,11 @@ fn build(sdk_path: Option<&str>, target: &str) { fn main() { let target = std::env::var("TARGET").unwrap(); - if !(target.contains("apple-darwin") || target.contains("apple-ios")) { - panic!("coreaudio-sys requires macos or ios target"); + if !(target.contains("apple-darwin") + || target.contains("apple-ios") + || target.contains("apple-visionos")) + { + panic!("coreaudio-sys requires macos or ios or visionos target"); } let directory = sdk_path(&target).ok(); diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..ad306a7 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,7 @@ +[toolchain] +channel = "nightly" +# channel = "stable" +# components = ["rust-std", "rust-src", "rustc-dev", "llvm-tools-preview"] +profile = "minimal" +components = ["rust-src", "rustc-dev", "llvm-tools-preview"] +targets = ["aarch64-apple-darwin", "aarch64-apple-ios", "aarch64-apple-ios-sim", "aarch64-apple-vision", "aarch64-apple-vision-sim"] \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index c85c8e8..de3cf5b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![cfg(any(target_os = "macos", target_os = "ios"))] +#![cfg(any(target_os = "macos", target_os = "ios", target_os = "visionos"))] #![allow(non_camel_case_types)] #![allow(non_snake_case)] #![allow(non_upper_case_globals)]