fzyzcjy / flutter_rust_bridge

Flutter/Dart <-> Rust binding generator, feature-rich, but seamless and simple.

Home Page:https://fzyzcjy.github.io/flutter_rust_bridge/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

cpal not building properly on macOS

Unbreathable opened this issue · comments

Describe the bug

I'm having trouble compiling my project that works on Windows and Linux perfectly fine for macOS. I recently got myself a Mac system and am using the exact same code base as on the 2 other platforms that I had before. There seems to be some kind of issue with coreaudio not being compiled properly through either flutter_rust_bridge or cargokit. I'm not sure where to post this issue so I just went here because you can probably help me out with that.

Steps to reproduce

This is quite hard to reproduce by hand, so I just created a GitHub repo you can clone to test it: https://github.com/Unbreathable/microphone_test.
Just running flutter run -v there reproduces the issue hopefully.

If you want to do it on your own machine without downloading my code, here is a simple tutorial on how to reproduce it step by step.

  1. Create a new project with frb on macOS (you should be familiar with this xd).
  2. Add cpal to the project by typing cd rust && cargo add cpal
  3. Write some code to interact with cpal.
use std::{thread, time::Duration};

use cpal::{traits::{DeviceTrait, HostTrait, StreamTrait}, StreamConfig};

pub fn record() {
    thread::spawn(move || {
        // Get a cpal host
        let host = cpal::default_host(); // Current host on computer

        // Get input device (using new API)
        let device = host
            .default_input_device()
            .expect("no input device available"); // Current device

        // Create a stream config
        let default_config = device
            .default_input_config()
            .expect("no stream config found");
        
        let sample_rate: u32 = default_config.sample_rate().0;
        let _work_channels = 1; // Stereo doesn't work at the moment (will fix in the future or never)
        let mic_channels = default_config.channels();
        let config: StreamConfig = StreamConfig {
            channels: mic_channels,
            sample_rate: cpal::SampleRate(sample_rate),
            buffer_size: cpal::BufferSize::Fixed(4096),
        };

        // Create a stream
        let stream = match device.build_input_stream(
            &config.into(),
            move |data: &[f32], _: &_| {

                let mut max = 0.0;
                for sample in data.iter() {
                    if *sample > max {
                        max = *sample;
                    }
                }

                println!("Max: {}", max);
            },
            move |err| {
                println!("an error occurred on stream: {}", err);
            },
            None,
        ) {
            Ok(stream) => stream,
            Err(_) => {
                return;
            }
        };

        // Play the stream
        stream.play().unwrap();

        loop {
            thread::sleep(Duration::from_millis(100));
        }
    });
}
  1. Try running the project again with flutter run -v (-v for verbose mode)

Logs

[        ] ld: symbol(s) not found for architecture arm64
[        ] clang: error: linker command failed with exit code 1 (use -v to see invocation)
[        ] note: Run script build phase 'Run Script' will be run during every build because the option to run the script phase "Based on dependency
analysis" is unchecked. (in target 'Runner' from project 'Runner')
[   +1 ms] ** BUILD FAILED **
[        ] The following build commands failed:
[        ]      Ld
/Users/julian/Documents/microphone/build/macos/Build/Products/Debug/rust_lib_microphone/rust_lib_microphone.framework/Versions/A/rust_lib_microphone normal
(in target 'rust_lib_microphone' from project 'Pods')
[        ] (1 failure)
[  +11 ms] Building macOS application... (completed in 2,237ms)
[        ] Error: Build process failed
[        ] "flutter run" took 7,968ms.
[   +6 ms] 
           #0      throwToolExit (package:flutter_tools/src/base/common.dart:10:3)
           #1      RunCommand.runCommand (package:flutter_tools/src/commands/run.dart:815:9)
           <asynchronous suspension>
           #2      FlutterCommand.run.<anonymous closure> (package:flutter_tools/src/runner/flutter_command.dart:1389:27)
           <asynchronous suspension>
           #3      AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:153:19)
           <asynchronous suspension>
           #4      CommandRunner.runCommand (package:args/command_runner.dart:212:13)
           <asynchronous suspension>
           #5      FlutterCommandRunner.runCommand.<anonymous closure> (package:flutter_tools/src/runner/flutter_command_runner.dart:355:9)
           <asynchronous suspension>
           #6      AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:153:19)
           <asynchronous suspension>
           #7      FlutterCommandRunner.runCommand (package:flutter_tools/src/runner/flutter_command_runner.dart:295:5)
           <asynchronous suspension>
           #8      run.<anonymous closure>.<anonymous closure> (package:flutter_tools/runner.dart:119:9)
           <asynchronous suspension>
           #9      AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:153:19)
           <asynchronous suspension>
           #10     main (package:flutter_tools/executable.dart:90:3)
           <asynchronous suspension>

Expected behavior

No response

Generated binding code

No response

OS

MacOS

Version of flutter_rust_bridge_codegen

2.0.0-dev.28

Flutter info

No response

Version of clang++

No response

Additional context

No response

Hi, could you please firstly run flutter run --verbose and paste the logs, usually there are some useful information

I guess it is something related to cpal+macos. A quick search about cpal gives possibly related: #1690 and #1610 (comment)

Here is a log from the build process I uploaded to github gist: https://gist.github.com/Unbreathable/e59eaeff016cce3a95d9c0e26d356864.
After trying out the stuff from both of these issues, nothing worked for me.

So it seems that these symbols are not found:

[ +172 ms] Undefined symbols for architecture arm64:
[        ]   "_AudioObjectAddPropertyListener", referenced from:
[        ]       cpal::host::coreaudio::macos::property_listener::AudioObjectPropertyListener::new::h1235b9b10713a8d0 in librust_lib_microphone.a[arm64][46](rust_lib_microphone.3vtwaaftg5z9b48p.rcgu.o)
[        ]       cpal::host::coreaudio::macos::property_listener::AudioObjectPropertyListener::new::h2663444e4a7e3c55 in
librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       coreaudio::audio_unit::macos_helpers::RateListener::register::hf9d47954241a229f in librust_lib_microphone.a[arm64][199](coreaudio-0681dda8d128d987.coreaudio.208191b5c637fb5d-cgu.4.rcgu.o)
[        ]       coreaudio::audio_unit::macos_helpers::AliveListener::register::h44560ef786813afd in
librust_lib_microphone.a[arm64][199](coreaudio-0681dda8d128d987.coreaudio.208191b5c637fb5d-cgu.4.rcgu.o)
[        ]   "_AudioObjectGetPropertyData", referenced from:
[        ]       cpal::host::coreaudio::macos::Device::name::h3267e1a302e7fc99 in librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       cpal::host::coreaudio::macos::Device::name::h3267e1a302e7fc99 in librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       cpal::host::coreaudio::macos::Device::supported_configs::h8b1b8bd9f5e9f0e7 in librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       cpal::host::coreaudio::macos::Device::supported_configs::h8b1b8bd9f5e9f0e7 in librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       cpal::host::coreaudio::macos::Device::default_config::h745e25f92bd3e42e in librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       cpal::host::coreaudio::macos::set_sample_rate::hd82cfb9489818fba in librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       cpal::host::coreaudio::macos::set_sample_rate::hd82cfb9489818fba in librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       ...
[        ]   "_AudioObjectGetPropertyDataSize", referenced from:
[        ]       cpal::host::coreaudio::macos::Device::supported_configs::h8b1b8bd9f5e9f0e7 in librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       cpal::host::coreaudio::macos::Device::supported_configs::h8b1b8bd9f5e9f0e7 in librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       cpal::host::coreaudio::macos::set_sample_rate::hd82cfb9489818fba in librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       cpal::host::coreaudio::macos::enumerate::audio_devices::h6acff2c91b4ac468 in librust_lib_microphone.a[arm64][187](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.1.rcgu.o)
[        ]       coreaudio::audio_unit::macos_helpers::get_audio_device_ids_for_scope::h16645aa23d38445d in
librust_lib_microphone.a[arm64][199](coreaudio-0681dda8d128d987.coreaudio.208191b5c637fb5d-cgu.4.rcgu.o)
[        ]       coreaudio::audio_unit::macos_helpers::get_audio_device_supports_scope::h68b0af41548f0e42 in
librust_lib_microphone.a[arm64][199](coreaudio-0681dda8d128d987.coreaudio.208191b5c637fb5d-cgu.4.rcgu.o)
[        ]       coreaudio::audio_unit::macos_helpers::set_device_sample_rate::h09afa22c961f5af1 in librust_lib_microphone.a[arm64][199](coreaudio-0681dda8d128d987.coreaudio.208191b5c637fb5d-cgu.4.rcgu.o)
[        ]       ...
[        ]   "_AudioObjectRemovePropertyListener", referenced from:
[        ]       cpal::host::coreaudio::macos::property_listener::AudioObjectPropertyListener::remove_inner::h69a405e2141fd53a in
librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       coreaudio::audio_unit::macos_helpers::RateListener::unregister::hdb2276f85a20c291 in
librust_lib_microphone.a[arm64][199](coreaudio-0681dda8d128d987.coreaudio.208191b5c637fb5d-cgu.4.rcgu.o)
[        ]       coreaudio::audio_unit::macos_helpers::AliveListener::unregister::haaf6f952c9a737e7 in
librust_lib_microphone.a[arm64][199](coreaudio-0681dda8d128d987.coreaudio.208191b5c637fb5d-cgu.4.rcgu.o)
[        ]   "_AudioObjectSetPropertyData", referenced from:
[        ]       cpal::host::coreaudio::macos::set_sample_rate::hd82cfb9489818fba in librust_lib_microphone.a[arm64][186](cpal-4fe1478ffcebe343.cpal.b5ed2ec6efb8e2b1-cgu.0.rcgu.o)
[        ]       coreaudio::audio_unit::macos_helpers::set_device_sample_rate::h09afa22c961f5af1 in librust_lib_microphone.a[arm64][199](coreaudio-0681dda8d128d987.coreaudio.208191b5c637fb5d-cgu.4.rcgu.o)
[        ]       coreaudio::audio_unit::macos_helpers::set_device_physical_stream_format::hd28242475451425c in
librust_lib_microphone.a[arm64][199](coreaudio-0681dda8d128d987.coreaudio.208191b5c637fb5d-cgu.4.rcgu.o)
[        ]       coreaudio::audio_unit::macos_helpers::toggle_hog_mode::ha537b210c62c04b3 in librust_lib_microphone.a[arm64][199](coreaudio-0681dda8d128d987.coreaudio.208191b5c637fb5d-cgu.4.rcgu.o)
[        ] ld: symbol(s) not found for architecture arm64
[        ] clang: error: linker command failed with exit code 1 (use -v to see invocation)

What about asking in cpal, I guess it is like a general question "how to compile cpal on mac (indeed ios?)"

Alright, after some more trouble-shooting I figured out that I just had to link a few Apple frameworks statically. Sorry for wasting your time again. I truly appreciate everything you do for this community and your rust bridge helps me in so many ways. Thank you.

Now for everyone using cpal, here's how I fixed my problem:

  1. Go into rust_builder/macos and then go into your .podspec file.
  2. Somewhere near the end there should be an option called OTHER_LDFLAGS. Add -lc++ -framework AudioToolbox -framework AudioUnit -framework IOKit -framework CoreAudio -framework OpenAL' to the end of that option, so it statically links everything cpal needs to operate. The line should then look something like this:
'OTHER_LDFLAGS' => '-force_load ${BUILT_PRODUCTS_DIR}/librust_lib.a -lc++ -framework AudioToolbox -framework AudioUnit -framework IOKit -framework CoreAudio -framework OpenAL',

@fzyzcjy I was also thinking we could put this onto the trouble-shooting page for flutter rust bridge. Just in case someone else stumbles upon the same issue. I've also seen some other people in the issues you linked describing the exact same issue, but not listing their solution and just saying roughly what to do (which is how I came up with this solution).

Again thanks for your time!

You are welcome, and happy to see it is solved! Feel free to PR to add to troubleshooting :)

EDIT: I have edited the doc, no worries for the PR

Alright, was about to do it. Anyway, thanks for doing it for me.

You are welcome!

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new issue.