Tauri, Rodio and iOS: cross-compiling and linking C dependencies for IOS

Hey peeps! Sorry for taking your time, but thanks for helping me if you can! I am building a Music Player App for my iPhone. Everything was fine, but then I started having problems with my playback strategy... For context, I'm on a mac m2, trying to build for the latest ios18. I'm using Tauri for compiling my app (which bundles a wry webview and a rust backend to run.)

Here is some more context: I use navidrome to host music and my navidrome sever streams it, and now, I want that music to play on my app. At first, I used the html5 audio tag with transcoding to mp3. Problem is that navidrome seems to return different status codes if using transcoding or not. If I simply query the stream, it'll return 206, but if I target the mp3 format, it will return 200. The problem with that is that the audio element will kind of "queue" or restart playing the song if they are 200, is my understanding. So, randomly, the song will go back to the beginning without updating anything. In the best of worlds, I wouldn't use transcodings tho and would use directly the ogg files I host...

So here comes rodio. I'm using Rodio to create a sink and then play the contents of a stream-download. Everything works fine on my mac, I can test it and it works magically well. Problem is that when I try to build my app, now, on ios, I get problems about arm64 linking.

Ld /Users/virginie/Library/Developer/Xcode/DerivedData/audio-fdawhbbdqociephgkolhkimibjno/Build/Products/release-iphoneos/Acapella.app/Acapella normal (in target 'audio_iOS' from project 'audio')
    cd /Users/virginie/Documents/audio/src-tauri/gen/apple
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++ -Xlinker -reproducible -target arm64-apple-ios13.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.2.sdk -Os -L/Users/virginie/Library/Developer/Xcode/DerivedData/audio-fdawhbbdqociephgkolhkimibjno/Build/Intermediates.noindex/EagerLinkingTBDs/release-iphoneos -L/Users/virginie/Library/Developer/Xcode/DerivedData/audio-fdawhbbdqociephgkolhkimibjno/Build/Products/release-iphoneos -L/Users/virginie/Documents/audio/src-tauri/gen/apple/Externals/arm64/release -L/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.2.sdk/usr/lib/swift -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos -L/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift-5.0/iphoneos -F/Users/virginie/Library/Developer/Xcode/DerivedData/audio-fdawhbbdqociephgkolhkimibjno/Build/Intermediates.noindex/EagerLinkingTBDs/release-iphoneos -F/Users/virginie/Library/Developer/Xcode/DerivedData/audio-fdawhbbdqociephgkolhkimibjno/Build/Products/release-iphoneos -F. -filelist /Users/virginie/Library/Developer/Xcode/DerivedData/audio-fdawhbbdqociephgkolhkimibjno/Build/Intermediates.noindex/audio.build/release-iphoneos/audio_iOS.build/Objects-normal/arm64/Acapella.LinkFileList -Xlinker -rpath -Xlinker @executable_path/Frameworks -dead_strip -Xlinker -object_path_lto -Xlinker /Users/virginie/Library/Developer/Xcode/DerivedData/audio-fdawhbbdqociephgkolhkimibjno/Build/Intermediates.noindex/audio.build/release-iphoneos/audio_iOS.build/Objects-normal/arm64/Acapella_lto.o -stdlib\=libc++ -fobjc-arc -fobjc-link-runtime -lapp -framework CoreGraphics -framework Metal -framework MetalKit -framework QuartzCore -framework Security -framework UIKit -framework WebKit -Xlinker -no_adhoc_codesign -Xlinker -dependency_info -Xlinker /Users/virginie/Library/Developer/Xcode/DerivedData/audio-fdawhbbdqociephgkolhkimibjno/Build/Intermediates.noindex/audio.build/release-iphoneos/audio_iOS.build/Objects-normal/arm64/Acapella_dependency_info.dat -o /Users/virginie/Library/Developer/Xcode/DerivedData/audio-fdawhbbdqociephgkolhkimibjno/Build/Products/release-iphoneos/Acapella.app/Acapella
Undefined symbols for architecture arm64:
  "_AudioComponentFindNext", referenced from:
      cpal::host::coreaudio::ios::default_output_asbd::h70674f290ebe7aa7 in libapp.a[204](cpal-639a6e59b94eef9f.cpal.38edb62eea3645c6-cgu.0.rcgu.o)
      coreaudio::audio_unit::AudioUnit::new_with_flags::h0904247d3efb6189 in libapp.a[205](cpal-639a6e59b94eef9f.cpal.38edb62eea3645c6-cgu.1.rcgu.o)
  "_AudioComponentInstanceDispose", referenced from:
      _$LT$coreaudio..audio_unit..AudioUnit$u20$as$u20$core..ops..drop..Drop$GT$::drop::h79a38b7ddddef596 in libapp.a[208](coreaudio-4b8b72ff723c5e5d.coreaudio.1eb8e4b6d847150b-cgu.0.rcgu.o)
  "_AudioComponentInstanceNew", referenced from:
      cpal::host::coreaudio::ios::default_output_asbd::h70674f290ebe7aa7 in libapp.a[204](cpal-639a6e59b94eef9f.cpal.38edb62eea3645c6-cgu.0.rcgu.o)
      coreaudio::audio_unit::AudioUnit::new_with_flags::h0904247d3efb6189 in libapp.a[205](cpal-639a6e59b94eef9f.cpal.38edb62eea3645c6-cgu.1.rcgu.o)
  "_AudioOutputUnitStart", referenced from:
      coreaudio::audio_unit::AudioUnit::start::h8e0af14f535fb184 in libapp.a[208](coreaudio-4b8b72ff723c5e5d.coreaudio.1eb8e4b6d847150b-cgu.0.rcgu.o)
  "_AudioOutputUnitStop", referenced from:
      _$LT$coreaudio..audio_unit..AudioUnit$u20$as$u20$core..ops..drop..Drop$GT$::drop::h79a38b7ddddef596 in libapp.a[208](coreaudio-4b8b72ff723c5e5d.coreaudio.1eb8e4b6d847150b-cgu.0.rcgu.o)
  "_AudioUnitGetProperty", referenced from:
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::h0ebf11505cd886bd in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::h60c4840cdaef5a16 in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::h6df9016d5c931376 in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::h8e47a9acc794fd2c in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::h94776238f34bd213 in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::h94e2a7a243eecbf6 in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::hd57ef6430d3f6b69 in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      ...
  "_AudioUnitInitialize", referenced from:
      cpal::host::coreaudio::ios::default_output_asbd::h70674f290ebe7aa7 in libapp.a[204](cpal-639a6e59b94eef9f.cpal.38edb62eea3645c6-cgu.0.rcgu.o)
      coreaudio::audio_unit::AudioUnit::new_with_flags::h0904247d3efb6189 in libapp.a[205](cpal-639a6e59b94eef9f.cpal.38edb62eea3645c6-cgu.1.rcgu.o)
  "_AudioUnitSetProperty", referenced from:
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::h0ebf11505cd886bd in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::h60c4840cdaef5a16 in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::h6df9016d5c931376 in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::h8e47a9acc794fd2c in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::h94776238f34bd213 in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::h94e2a7a243eecbf6 in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      coreaudio::audio_unit::render_callback::_$LT$impl$u20$coreaudio..audio_unit..AudioUnit$GT$::set_render_callback::hd57ef6430d3f6b69 in libapp.a[68](rodio-fab04265af4507f7.rodio.5e49c4efbe8ce145-cgu.01.rcgu.o)
      ...
  "_AudioUnitUninitialize", referenced from:
      _$LT$coreaudio..audio_unit..AudioUnit$u20$as$u20$core..ops..drop..Drop$GT$::drop::h79a38b7ddddef596 in libapp.a[208](coreaudio-4b8b72ff723c5e5d.coreaudio.1eb8e4b6d847150b-cgu.0.rcgu.o)
ld: symbol(s) not found for architecture arm64
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

** BUILD FAILED **

Here is the tauri info, if it helps...

$ tauri info

[✔] Environment
    - OS: Mac OS 15.3.0 arm64 (X64)
    ✔ Xcode Command Line Tools: installed
    ✔ rustc: 1.84.0 (9fc6b4312 2025-01-07)
    ✔ cargo: 1.84.0 (66221abde 2024-11-19)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: stable-aarch64-apple-darwin (default)
    - node: 21.7.3
    - pnpm: 9.15.3
    - npm: 10.9.0
    - bun: 1.1.45

[-] Packages
    - tauri 🦀: 2.2.3
    - tauri-build 🦀: 2.0.5
    - wry 🦀: 0.48.1
    - tao 🦀: 0.31.1
    - @tauri-apps/api : 2.2.0
    - @tauri-apps/cli : 2.2.5

[-] Plugins
    - tauri-plugin-log 🦀: 2.2.0
    - @tauri-apps/plugin-log : 2.2.0
    - tauri-plugin-fs 🦀: 2.2.0
    - @tauri-apps/plugin-fs : 2.2.0
    - tauri-plugin-sql 🦀: 2.2.0
    - @tauri-apps/plugin-sql : 2.2.0
    - tauri-plugin-opener 🦀: 2.2.5
    - @tauri-apps/plugin-opener : 2.2.5

[-] App
    - build-type: bundle
    - CSP: unset
    - frontendDist: ../build
    - devUrl: http://localhost:1420/
    - framework: Svelte
    - bundler: Vite

So... How can I get Rodio to build for target arm64? Is that really my problem? I've looked into rodio's deps and they use cpal, which in turn uses coreaudio-rs for iOS mobile devices. I've tried manually exporting the path to the SDK as explained in the coreaudio-sys readme, but to no avail. It all seems to be working for other people not using Tauri... Any ideas?

There is a section on cross-compiling for aarch64 in Rodio's readme, with instructions for setting up the cross-compilation toolchain on Ubuntu. Don't know how straight-forward it is to set up a similar environment on macOS:

So people from the github specifally told me to ask on other platforms my question because they did not know how to solve it, and then report back with an answer... That is why I came to this forum after posting an issue there. I feel like it is not that easy to setup one and would love to know if someone achieved this or something, I'd love to get a hand and would very much appreciate it :slight_smile:

-framework CoreGraphics -framework Metal -framework MetalKit -framework QuartzCore -framework Security -framework UIKit -framework WebKit

There's no -framework AudioToolbox where all these symbols are defined.

How are you cross-compiling to ios?
Do any of your dependencies disable cpal's default features, since it does properly link the AudioToolbox framework for ios.

I am using Tauri which seems to do the linking for me. I just run "tauri ios build". Are you saying maybe there's just some symbol missing?

Also, here is the cargo.toml for Rodio, which is the library linking cpal for playback.

For anyone having the same problem as me, I found the answer. OKAY! Thanks MoAlyousef! The problem is that rodio uses cpal, but tauri needs "a plugin" to enable linking dependencies et cetera. There are no tauri plugins for rodio so you have to enable the AudioToolbox framework yourself in Xcode.

Adding the appropriate framework which coreaudio uses did the trick! :smile: