Skip to content
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

jniLibs folder missing while trying to solve "libc++_shared.so" not found errors #2209

Closed
zhpixel517 opened this issue Jul 17, 2024 · 4 comments
Labels
awaiting Waiting for responses, PR, further discussions, upstream release, etc bug Something isn't working

Comments

@zhpixel517
Copy link

zhpixel517 commented Jul 17, 2024

Describe the bug

I've been trying to use the cpal crate on Android, but I am getting this error:

ArgumentError (Invalid argument(s): Failed to load dynamic library 'librust_lib_flutter_rust_test.so': dlopen failed: cannot locate symbol "__cxa_pure_virtual" referenced by "/data/app/~~LZ8AQs1ioV6ixGg4V_mDQA==/com.example.flutter_rust_test-9HkSZUPzs692QJUdLW2hCw==/lib/arm64/librust_lib_flutter_rust_test.so"...)

I know that this error is the same as this previous issue, but I have tried the suggestions in that issue here. That links to a 404 github page, but I was able to find the correct link for it here and add this code to my build.rs:

#[allow(dead_code)]
fn add_lib(name: impl AsRef<str>, _static: bool)
{
    #[cfg(not(feature = "test"))]
    println!(
        "cargo:rustc-link-lib={}{}",
        if _static { "static=" } else { "" },
        name.as_ref()
    );
}

fn main()
{
    let target = std::env::var("TARGET").expect("ERR: Could not check the target for the build.");

    if target.contains("android") {
        add_lib("c++_shared", false);
    }
}

this does not fix the error, but it changes it to this:

ArgumentError (Invalid argument(s): Failed to load dynamic library 'librust_lib_flutter_rust_test.so': dlopen failed: library "libc++_shared.so" not found: needed by /data/app/~~Ro6Lz7UAxhMyGMngCR07Kg==/com.example.flutter_rust_test-9hgSZf2OndGa1e0rYsmBMA==/lib/arm64/librust_lib_flutter_rust_test.so in namespace clns-4)

I searched through the documentation and I followed instructions on solving these kinds of errors here, by replacing the code in build.rs to this:

fn main() {
    #[cfg(target_os = "android")]
    println!("cargo:rustc-link-lib=c++_shared");
}

I started to follow instructions:

Then, in each jniLibs architecture directory, put the corresponding libc++_shared.so from the Android NDK. libc++_shared.so is typically located in $ANDROID_NDK/toolchains/llvm/prebuilt/. You will have to search for it, as it's different for each operating system.

however, I don't have any folder in my project called jniLibs, my android folder looks like this:

android/
   - app/
       - src/
           - debug/
           - main/
           - profile/

furthermore, the contents of ANDROID_NDK/toolchains/llvm/prebuilt just have a folder called darwin-x86_64 which has a bunch of random stuff in it. ANDROID_NDK is ~/Library/Android/sdk/ndk/27.0.12.077973/.

I tried these solutions to no success:

would this be something to take up with the cpal people instead?

Steps to reproduce

Create a new project with flutter_rust_bridge_codegen create, add cpal to cargo, and run this:

let host = cpal::default_host();

    let input_device = host.default_input_device().unwrap();
    let output_device = host.default_output_device().unwrap();

    let input_config = cpal::StreamConfig {
        channels: 1,
        sample_rate: cpal::SampleRate(48000),
        buffer_size: cpal::BufferSize::Default,
    };
    // let output_config: cpal::StreamConfig = input_config.clone();
    let output_config = cpal::StreamConfig {
        channels: 1,
        sample_rate: cpal::SampleRate(48000),
        buffer_size: cpal::BufferSize::Default,
    };

    let input_stream = input_device
        .build_input_stream(
            &input_config,
            move |data: &[f32], _: &_| {
            },
            move |err| {
                eprintln!("There was an input error: {:?}", err);
            },
            None,
        )
        .unwrap();

Logs

zacharyhaslam@MacBook-Air-208 flutter_rust_test % RUST_LOG=debug flutter_rust_bridge_codegen generate
[2024-07-17T19:37:02.913Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/main.rs:24] cli=Cli { verbose: false, command: Generate(GenerateCommandArgs { watch: false, primary: GenerateCommandArgsPrimary { config_file: None, rust_input: None, dart_output: None, c_output: None, duplicated_c_output: None, rust_root: None, rust_output: None, dart_entrypoint_class_name: None, dart_format_line_length: None, dart_preamble: None, rust_preamble: None, no_dart_enums_style: false, no_add_mod_to_lib: false, llvm_path: None, llvm_compiler_opts: None, dart_root: None, no_build_runner: false, extra_headers: None, no_web: false, no_deps_check: false, default_external_library_loader_web_prefix: None, no_dart3: false, full_dep: false, local: false, enable_lifetime: false, type_64bit_int: false, no_default_dart_async: false, stop_on_error: false, dump: None, dump_all: false } }) }
[2024-07-17T19:37:02.916Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/config/config_parser.rs:51] Found config file flutter_rust_bridge.yaml
[2024-07-17T19:37:02.919Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/mod.rs:23] config=Config { base_dir: Some(""), rust_input: Some("crate::api, crate::cpal"), dart_output: Some("lib/src/rust"), c_output: None, duplicated_c_output: None, rust_root: Some("rust/"), rust_output: None, dart_entrypoint_class_name: None, dart_format_line_length: None, dart_preamble: None, rust_preamble: None, dart_enums_style: None, add_mod_to_lib: None, llvm_path: None, llvm_compiler_opts: None, dart_root: None, build_runner: None, extra_headers: None, web: None, deps_check: None, dart3: None, full_dep: None, local: None, default_external_library_loader_web_prefix: None, dart_type_rename: None, enable_lifetime: None, type_64bit_int: None, default_dart_async: None, stop_on_error: None, dump: None, dump_all: None } meta_config=MetaConfig { watch: false }
[2024-07-17T19:37:02.920Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/config/internal_config_parser/mod.rs:33] InternalConfig.parse base_dir="/Users/zacharyhaslam/FlutterApplications/flutter_rust_test"
[2024-07-17T19:37:03.550Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/mod.rs:26] internal_config=InternalConfig { controller: ControllerInternalConfig { watch: false, watching_paths: ["/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust/src"], exclude_paths: ["/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust/src/frb_generated.rs"], max_count: None }, preparer: PreparerInternalConfig { dart_root: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test", deps_check: true, needs_ffigen: false }, parser: ParserInternalConfig { hir: ParserHirInternalConfig { rust_input_namespace_pack: RustInputNamespacePack { rust_input_namespace_prefixes: [Namespace { joined_path: "crate::api" }, Namespace { joined_path: "crate::cpal" }], rust_output_path_namespace: Namespace { joined_path: "crate::frb_generated" } }, rust_crate_dir: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust", third_party_crate_names: [] }, mir: ParserMirInternalConfig { rust_input_namespace_pack: RustInputNamespacePack { rust_input_namespace_prefixes: [Namespace { joined_path: "crate::api" }, Namespace { joined_path: "crate::cpal" }], rust_output_path_namespace: Namespace { joined_path: "crate::frb_generated" } }, force_codec_mode_pack: Some(CodecModePack { dart2rust: Pde, rust2dart: Pde }), default_stream_sink_codec: Sse, default_rust_opaque_codec: Moi, stop_on_error: false, enable_lifetime: false, type_64bit_int: false, default_dart_async: true } }, generator: GeneratorInternalConfig { api_dart: GeneratorApiDartInternalConfig { dart_enums_style: true, dart3: true, dart_decl_base_output_path: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/lib/src/rust", dart_impl_output_path: TargetOrCommonMap { common: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/lib/src/rust/frb_generated.dart", io: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/lib/src/rust/frb_generated.io.dart", web: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/lib/src/rust/frb_generated.web.dart" }, dart_entrypoint_class_name: "RustLib", dart_preamble: "", dart_type_rename: {} }, wire: GeneratorWireInternalConfig { dart: GeneratorWireDartInternalConfig { has_ffigen: false, web_enabled: true, llvm_path: ["/opt/homebrew/opt/llvm", "/usr/local/opt/llvm", "/usr/lib/llvm-9", "/usr/lib/llvm-10", "/usr/lib/llvm-11", "/usr/lib/llvm-12", "/usr/lib/llvm-13", "/usr/lib/llvm-14", "/usr/lib/", "/usr/lib64/", "C:/Program Files/llvm", "C:/msys64/mingw64"], llvm_compiler_opts: "", dart_root: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test", extra_headers: "", dart_impl_output_path: TargetOrCommonMap { common: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/lib/src/rust/frb_generated.dart", io: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/lib/src/rust/frb_generated.io.dart", web: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/lib/src/rust/frb_generated.web.dart" }, dart_output_class_name_pack: DartOutputClassNamePack { entrypoint_class_name: "RustLib", api_class_name: "RustLibApi", api_impl_class_name: "RustLibApiImpl", api_impl_platform_class_name: "RustLibApiImplPlatform", wire_class_name: "RustLibWire", wasm_module_name: "RustLibWasmModule" }, default_external_library_loader: GeneratorWireDartDefaultExternalLibraryLoaderInternalConfig { stem: "rust_lib_flutter_rust_test", io_directory: "rust/target/release/", web_prefix: "pkg/" }, c_symbol_prefix: "frbgen_flutter_rust_test_" }, rust: GeneratorWireRustInternalConfig { rust_crate_dir: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust", web_enabled: true, rust_output_path: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust/src/frb_generated.rs", c_symbol_prefix: "frbgen_flutter_rust_test_", has_ffigen: false, default_stream_sink_codec: Sse, default_rust_opaque_codec: Moi, rust_preamble: "" }, c: GeneratorWireCInternalConfig { enable: false, rust_crate_dir: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust", rust_output_path: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust/src/frb_generated.rs", c_output_path: None, c_symbol_prefix: "frbgen_flutter_rust_test_" } } }, polisher: PolisherInternalConfig { duplicated_c_output_path: [], dart_format_line_length: 80, add_mod_to_lib: true, build_runner: true, web_enabled: true, dart_root: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test", rust_crate_dir: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust", rust_output_path: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust/src/frb_generated.rs", c_output_path: None, enable_auto_upgrade: true }, dumper: DumperInternalConfig { dump_contents: [], dump_directory: "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust/target/frb_dump" } }
[2024-07-17T19:37:03.552Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/utils/dart_repository/dart_repo.rs:22] Guessing toolchain the runner is run into
[2024-07-17T19:37:03.553Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/commands/command_runner.rs:129] execute command: bin=sh args="-c \"flutter\" \"--version\"" current_dir=None cmd="sh" "-c" "\"flutter\" \"--version\""
[2024-07-17T19:37:04.189Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/commands/command_runner.rs:140] command="sh" "-c" "\"flutter\" \"--version\"" stdout=Flutter 3.22.2 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 761747bfc5 (6 weeks ago) • 2024-06-05 22:15:13 +0200
Engine • revision edd8546116
Tools • Dart 3.4.3 • DevTools 2.34.3
 stderr=
[2024-07-17T19:37:04.190Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/commands/cargo_expand/mod.rs:26] run_cargo_expand manifest_dir= rust_crate_dir="/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust"
[2024-07-17T19:37:04.190Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/commands/cargo_expand/real.rs:60] Running cargo expand in '"/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust"'
[2024-07-17T19:37:04.190Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/commands/command_runner.rs:129] execute command: bin=cargo args="expand --lib --theme=none --ugly" current_dir=Some("/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust") cmd=cd "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust" && RUSTFLAGS="--cfg frb_expand" "cargo" "expand" "--lib" "--theme=none" "--ugly"
[2024-07-17T19:37:04.965Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/commands/command_runner.rs:140] command=cd "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust" && RUSTFLAGS="--cfg frb_expand" "cargo" "expand" "--lib" "--theme=none" "--ugly" stdout=#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
pub mod api {

    pub mod simple {
        use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
        use log::*;
        use rtrb::RingBuffer;
        use std::env;
        use std::net::UdpSocket;
        use std::thread;
        use std::time::{Duration, SystemTime, UNIX_EPOCH};
        #[doc = "frb_encoded(235b6672622873796e63295d)"]
        pub fn greet(name: String) -> String {
            {
                let res =
                    ::alloc::fmt::format(format_args!("Hello, {0}!", name));
                res
            }
        }
        pub fn hello(a: String) -> String {
            { ::std::io::_print(format_args!("Hello was called\n")); };
            {
                let lvl = ::log::Level::Info;
                if lvl <= ::log::STATIC_MAX_LEVEL && lvl <= ::log::max_level()
                        {
                        ::log::__private_api::log(format_args!("Hello was called"),
                            lvl,
                            &("rust_lib_flutter_rust_test::api::simple",
                                    "rust_lib_flutter_rust_test::api::simple",
                                    ::log::__private_api::loc()), ());
                    }
            };
            {
                let lvl = ::log::Level::Debug;
                if lvl <= ::log::STATIC_MAX_LEVEL && lvl <= ::log::max_level()
                        {
                        ::log::__private_api::log(format_args!("Hello was called!"),
                            lvl,
                            &("rust_lib_flutter_rust_test::api::simple",
                                    "rust_lib_flutter_rust_test::api::simple",
                                    ::log::__private_api::loc()), ());
                    }
            };
            a.repeat(2)
        }
        pub fn loopback_audio() {
            const BUFFER_SIZE: usize = 1024;
            const RINGBUFFER_SIZE: usize = BUFFER_SIZE * 2;
            let (mut prod, mut cons) =
                RingBuffer::<f32>::new(RINGBUFFER_SIZE);
            let host = cpal::default_host();
            let input_device = host.default_input_device().unwrap();
            let output_device = host.default_output_device().unwrap();
            let input_config =
                cpal::StreamConfig {
                    channels: 1,
                    sample_rate: cpal::SampleRate(48000),
                    buffer_size: cpal::BufferSize::Default,
                };
            let output_config =
                cpal::StreamConfig {
                    channels: 1,
                    sample_rate: cpal::SampleRate(48000),
                    buffer_size: cpal::BufferSize::Default,
                };
            let input_stream =
                input_device.build_input_stream(&input_config,
                        move |data: &[f32], _: &_|
                            {
                                if let Ok(chunk) = prod.write_chunk_uninit(BUFFER_SIZE) {
                                        chunk.fill_from_iter(data.to_owned());
                                    }
                            },
                        move |err|
                            {
                                {
                                    ::std::io::_eprint(format_args!("There was an input error: {0:?}\n",
                                            err));
                                };
                            }, None).unwrap();
        }
        pub fn sender_side(addr: &str) {
            let socket =
                UdpSocket::bind("0.0.0.0:37069").expect("Couldn't bind!");
            let mut counter = 0;
            loop {
                let start = SystemTime::now();
                let since_epoch = start.duration_since(UNIX_EPOCH).unwrap();
                socket.send_to(&since_epoch.as_millis().to_le_bytes(),
                        addr).unwrap();
                counter += 1;
                {
                    ::std::io::_print(format_args!("Sent packet {0}\n",
                            counter));
                };
                thread::sleep(Duration::from_secs(1));
            }
        }
        #[doc = "frb_encoded(235b66726228696e6974295d)"]
        pub fn init_app() {
            env::set_var("RUST_BACKTRACE", "1");
            flutter_rust_bridge::setup_default_user_utils();
        }
    }
}
mod frb_generated {
    #![allow(non_camel_case_types, unused, non_snake_case, clippy ::
    needless_return, clippy :: redundant_closure_call, clippy ::
    redundant_closure, clippy :: useless_conversion, clippy :: unit_arg,
    clippy :: unused_unit, clippy :: double_parens, clippy :: let_and_return,
    clippy :: too_many_arguments, clippy :: match_single_binding, clippy ::
    clone_on_copy, clippy :: let_unit_value, clippy :: deref_addrof, clippy ::
    explicit_auto_deref, clippy :: borrow_deref_ref, clippy ::
    needless_borrow)]
    use flutter_rust_bridge::for_generated::byteorder::{
        NativeEndian, ReadBytesExt, WriteBytesExt,
    };
    use flutter_rust_bridge::for_generated::{
        transform_result_dco, Lifetimeable, Lockable,
    };
    use flutter_rust_bridge::{Handler, IntoIntoDart};
    #[doc(hidden)]
    pub(crate) struct FrbWrapper<T>(T);
    impl<T: Clone> Clone for FrbWrapper<T> {
        fn clone(&self) -> Self { FrbWrapper(self.0.clone()) }
    }
    impl<T: PartialEq> PartialEq for FrbWrapper<T> {
        fn eq(&self, other: &Self) -> bool { self.0.eq(&other.0) }
    }
    impl<T: Eq> Eq for FrbWrapper<T> {}
    impl<T: std::hash::Hash> std::hash::Hash for FrbWrapper<T> {
        fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
            self.0.hash(state)
        }
    }
    impl<T> From<T> for FrbWrapper<T> {
        fn from(t: T) -> Self { FrbWrapper(t) }
    }
    use std::collections::HashMap;
    use std::marker::PhantomData;
    use std::sync::Arc;
    pub struct MoiArc<T: ?Sized + MoiArcValue> {
        object_id: Option<ObjectId>,
        value: Option<Arc<T>>,
        _phantom: PhantomData<T>,
    }
    #[automatically_derived]
    impl<T: ::core::fmt::Debug + ?Sized + MoiArcValue> ::core::fmt::Debug for
        MoiArc<T> {
        #[inline]
        fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
            ::core::fmt::Formatter::debug_struct_field3_finish(f, "MoiArc",
                "object_id", &self.object_id, "value", &self.value,
                "_phantom", &&self._phantom)
        }
    }
    impl<T: ?Sized + MoiArcValue> Drop for MoiArc<T> {
        fn drop(&mut self) {
            if let Some(object_id) = self.object_id {
                    Self::decrement_strong_count(object_id);
                }
        }
    }
    impl<T: ?Sized + MoiArcValue> AsRef<T> for MoiArc<T> {
        fn as_ref(&self) -> &T { self.value.as_ref().unwrap().as_ref() }
    }
    impl<T: ?Sized + MoiArcValue>
        ::flutter_rust_bridge::for_generated::BaseArc<T> for MoiArc<T> {
        fn new(value: T) -> Self where T: Sized {
            let mut pool = T::get_pool().write().unwrap();
            let object_id = pool.id_generator.next_id();
            let value = Arc::new(value);
            let old_value =
                pool.map.insert(object_id,
                    MoiArcPoolValue { ref_count: 1, value: value.clone() });
            if !old_value.is_none() {
                    ::core::panicking::panic("assertion failed: old_value.is_none()")
                };
            Self {
                object_id: Some(object_id),
                value: Some(value),
                _phantom: PhantomData,
            }
        }
        fn try_unwrap(mut self) -> Result<T, Self> where T: Sized {
            let pool = &mut T::get_pool().write().unwrap();
            if pool.map.get(&self.object_id.unwrap()).unwrap().ref_count == 1
                    {
                    Self::decrement_strong_count_raw(self.object_id.unwrap(),
                        pool);
                    self.object_id.take().unwrap();
                    Ok(Arc::into_inner(self.value.take().unwrap()).unwrap())
                } else { Err(self) }
        }
        fn into_inner(self) -> Option<T> where T: Sized {
            self.try_unwrap().ok()
        }
        fn into_raw(mut self) -> usize { self.object_id.take().unwrap() }
    }
    impl<T: ?Sized + MoiArcValue> Clone for MoiArc<T> {
        fn clone(&self) -> Self {
            Self::increment_strong_count(self.object_id.unwrap());
            Self {
                object_id: self.object_id,
                value: self.value.clone(),
                _phantom: PhantomData,
            }
        }
    }
    impl<T: ?Sized + MoiArcValue> MoiArc<T> {
        pub(crate) fn from_raw(raw: usize) -> Self where T: Sized {
            let map = &T::get_pool().read().unwrap().map;
            Self {
                object_id: Some(raw),
                value: Some(map.get(&raw).unwrap().value.clone()),
                _phantom: PhantomData,
            }
        }
        pub fn increment_strong_count(raw: usize) {
            let map = &mut T::get_pool().write().unwrap().map;
            map.get_mut(&raw).unwrap().ref_count += 1;
        }
        pub fn decrement_strong_count(raw: usize) {
            let mut pool = T::get_pool().write().unwrap();
            let object = Self::decrement_strong_count_raw(raw, &mut pool);
            drop(pool);
            drop(object);
        }
        fn decrement_strong_count_raw(raw: usize,
            pool: &mut MoiArcPoolInner<T>) -> Option<MoiArcPoolValue<T>> {
            let value = pool.map.get_mut(&raw).unwrap();
            value.ref_count -= 1;
            if value.ref_count == 0 { pool.map.remove(&raw) } else { None }
        }
    }
    pub trait MoiArcValue: 'static {
        fn get_pool()
        -> &'static MoiArcPool<Self>;
    }
    type ObjectId = usize;
    pub type MoiArcPool<T> = std::sync::RwLock<MoiArcPoolInner<T>>;
    pub struct MoiArcPoolInner<T: ?Sized> {
        map: HashMap<ObjectId, MoiArcPoolValue<T>>,
        id_generator: IdGenerator,
    }
    impl<T: ?Sized> Default for MoiArcPoolInner<T> {
        fn default() -> Self {
            Self { map: HashMap::new(), id_generator: Default::default() }
        }
    }
    struct IdGenerator {
        next_id: ObjectId,
    }
    impl Default for IdGenerator {
        fn default() -> Self { Self { next_id: Self::MIN_ID } }
    }
    impl IdGenerator {
        const MIN_ID: ObjectId = 1;
        const MAX_ID: ObjectId = 2147483600;
        fn next_id(&mut self) -> ObjectId {
            let ans = self.next_id;
            self.next_id =
                if self.next_id >= Self::MAX_ID {
                        Self::MIN_ID
                    } else { self.next_id + 1 };
            ans
        }
    }
    impl<T: ?Sized> MoiArcPoolInner<T> {}
    struct MoiArcPoolValue<T: ?Sized> {
        ref_count: i32,
        value: Arc<T>,
    }
    use ::flutter_rust_bridge::for_generated::decode_rust_opaque_nom;
    fn decode_rust_opaque_moi<T: MoiArcValue + Send + Sync>(ptr: usize)
        -> RustOpaqueMoi<T> {
        RustOpaqueMoi::from_arc(MoiArc::<T>::from_raw(ptr))
    }
    use ::flutter_rust_bridge::for_generated::StdArc;
    use ::flutter_rust_bridge::RustOpaqueNom;
    /// Please refer to `RustOpaque` for doc.
    pub type RustOpaqueMoi<T> =
        ::flutter_rust_bridge::for_generated::RustOpaqueBase<T, MoiArc<T>>;
    /// A wrapper to support [arbitrary Rust types](https://cjycode.com/flutter_rust_bridge/guides/types/arbitrary).
    pub type RustOpaque<T> = RustOpaqueMoi<T>;
    use ::flutter_rust_bridge::RustAutoOpaqueNom;
    /// Please refer to `RustAutoOpaque` for doc.
    pub type RustAutoOpaqueMoi<T> =
        ::flutter_rust_bridge::for_generated::RustAutoOpaqueBase<T,
        MoiArc<::flutter_rust_bridge::for_generated::RustAutoOpaqueInner<T>>>;
    /// Usually this is unneeded, and just write down arbitrary types.
    /// However, when you need arbitrary types at places that are not supported yet,
    /// use `RustOpaqueOpaque<YourArbitraryType>`.
    pub type RustAutoOpaque<T> = RustAutoOpaqueMoi<T>;
    pub trait CstDecode<T> {
        fn cst_decode(self)
        -> T;
    }
    impl<T, S> CstDecode<Option<T>> for *mut S where *mut S: CstDecode<T> {
        fn cst_decode(self) -> Option<T> {
            (!self.is_null()).then(|| self.cst_decode())
        }
    }
    pub trait SseDecode {
        fn sse_decode(deserializer:
            &mut ::flutter_rust_bridge::for_generated::SseDeserializer)
        -> Self;
    }
    pub trait SseEncode {
        fn sse_encode(self,
        serializer: &mut ::flutter_rust_bridge::for_generated::SseSerializer);
    }
    fn transform_result_sse<T, E>(raw: Result<T, E>)
        ->
            Result<::flutter_rust_bridge::for_generated::Rust2DartMessageSse,
            ::flutter_rust_bridge::for_generated::Rust2DartMessageSse> where
        T: SseEncode, E: SseEncode {
        use ::flutter_rust_bridge::for_generated::{Rust2DartAction, SseCodec};
        match raw {
            Ok(raw) =>
                Ok(SseCodec::encode(Rust2DartAction::Success,
                        |serializer| { raw.sse_encode(serializer) })),
            Err(raw) =>
                Err(SseCodec::encode(Rust2DartAction::Error,
                        |serializer| { raw.sse_encode(serializer) })),
        }
    }
    pub struct StreamSink<T,
        Rust2DartCodec: ::flutter_rust_bridge::for_generated::BaseCodec =
        ::flutter_rust_bridge::for_generated::SseCodec> {
        base: ::flutter_rust_bridge::for_generated::StreamSinkBase<T,
        Rust2DartCodec>,
    }
    #[automatically_derived]
    impl<T: ::core::clone::Clone, Rust2DartCodec: ::core::clone::Clone +
        ::flutter_rust_bridge::for_generated::BaseCodec> ::core::clone::Clone
        for StreamSink<T, Rust2DartCodec> {
        #[inline]
        fn clone(&self) -> StreamSink<T, Rust2DartCodec> {
            StreamSink { base: ::core::clone::Clone::clone(&self.base) }
        }
    }
    impl<T, Rust2DartCodec: ::flutter_rust_bridge::for_generated::BaseCodec>
        StreamSink<T, Rust2DartCodec> {
        pub fn deserialize(raw: String) -> Self {
            Self {
                base: ::flutter_rust_bridge::for_generated::StreamSinkBase::deserialize(raw),
            }
        }
    }
    impl<T> StreamSink<T, ::flutter_rust_bridge::for_generated::DcoCodec> {
        pub fn add<T2>(&self, value: T)
            -> Result<(), ::flutter_rust_bridge::Rust2DartSendError> where
            T: ::flutter_rust_bridge::IntoIntoDart<T2>,
            T2: ::flutter_rust_bridge::IntoDart {
            self.add_raw(::flutter_rust_bridge::for_generated::Rust2DartAction::Success,
                value)
        }
        pub fn add_error<TR, T2>(&self, value: TR)
            -> Result<(), ::flutter_rust_bridge::Rust2DartSendError> where
            TR: ::flutter_rust_bridge::IntoIntoDart<T2>,
            T2: ::flutter_rust_bridge::IntoDart {
            self.add_raw(::flutter_rust_bridge::for_generated::Rust2DartAction::Error,
                value)
        }
        fn add_raw<TR,
            T2>(&self,
            action: ::flutter_rust_bridge::for_generated::Rust2DartAction,
            value: TR)
            -> Result<(), ::flutter_rust_bridge::Rust2DartSendError> where
            TR: ::flutter_rust_bridge::IntoIntoDart<T2>,
            T2: ::flutter_rust_bridge::IntoDart {
            self.base.add_raw(::flutter_rust_bridge::for_generated::DcoCodec::encode(action,
                    value.into_into_dart()))
        }
    }
    impl<T> StreamSink<T, ::flutter_rust_bridge::for_generated::SseCodec>
        where T: SseEncode {
        pub fn add(&self, value: T)
            -> Result<(), ::flutter_rust_bridge::Rust2DartSendError> {
            self.add_raw(::flutter_rust_bridge::for_generated::Rust2DartAction::Success,
                value)
        }
        pub fn add_error<TR: SseEncode>(&self, value: TR)
            -> Result<(), ::flutter_rust_bridge::Rust2DartSendError> {
            self.add_raw(::flutter_rust_bridge::for_generated::Rust2DartAction::Error,
                value)
        }
        pub fn add_raw<TR: SseEncode>(&self,
            action: ::flutter_rust_bridge::for_generated::Rust2DartAction,
            value: TR)
            -> Result<(), ::flutter_rust_bridge::Rust2DartSendError> {
            self.base.add_raw(::flutter_rust_bridge::for_generated::SseCodec::encode(action,
                    |serializer| value.sse_encode(serializer)))
        }
    }
    impl<T, Rust2DartCodec: ::flutter_rust_bridge::for_generated::BaseCodec>
        ::flutter_rust_bridge::IntoIntoDart<StreamSink<T, Rust2DartCodec>> for
        StreamSink<T, Rust2DartCodec> {
        fn into_into_dart(self) -> StreamSink<T, Rust2DartCodec> {
            ::core::panicking::panic("internal error: entered unreachable code")
        }
    }
    impl<T, Rust2DartCodec: ::flutter_rust_bridge::for_generated::BaseCodec>
        ::flutter_rust_bridge::IntoDart for StreamSink<T, Rust2DartCodec> {
        fn into_dart(self) -> ::flutter_rust_bridge::for_generated::DartAbi {
            ::core::panicking::panic("internal error: entered unreachable code")
        }
    }
    pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.1.0";
    pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 =
        970588621;
    #[allow(missing_copy_implementations)]
    #[allow(non_camel_case_types)]
    #[allow(dead_code)]
    pub struct FLUTTER_RUST_BRIDGE_HANDLER {
        __private_field: (),
    }
    #[doc(hidden)]
    pub static FLUTTER_RUST_BRIDGE_HANDLER: FLUTTER_RUST_BRIDGE_HANDLER =
        FLUTTER_RUST_BRIDGE_HANDLER { __private_field: () };
    impl ::lazy_static::__Deref for FLUTTER_RUST_BRIDGE_HANDLER {
        type Target =
            ::flutter_rust_bridge::DefaultHandler<::flutter_rust_bridge::for_generated::SimpleThreadPool>;
        fn deref(&self)
            ->
                &::flutter_rust_bridge::DefaultHandler<::flutter_rust_bridge::for_generated::SimpleThreadPool> {
            #[inline(always)]
            fn __static_ref_initialize()
                ->
                    ::flutter_rust_bridge::DefaultHandler<::flutter_rust_bridge::for_generated::SimpleThreadPool> {
                {
                    match (&FLUTTER_RUST_BRIDGE_CODEGEN_VERSION,
                            &flutter_rust_bridge::for_generated::FLUTTER_RUST_BRIDGE_RUNTIME_VERSION)
                        {
                        (left_val, right_val) => {
                            if !(*left_val == *right_val) {
                                    let kind = ::core::panicking::AssertKind::Eq;
                                    ::core::panicking::assert_failed(kind, &*left_val,
                                        &*right_val,
                                        ::core::option::Option::Some(format_args!("Please ensure flutter_rust_bridge\'s codegen ({0}) and runtime ({1}) versions are the same",
                                                FLUTTER_RUST_BRIDGE_CODEGEN_VERSION,
                                                flutter_rust_bridge::for_generated::FLUTTER_RUST_BRIDGE_RUNTIME_VERSION)));
                                }
                        }
                    };
                    ::flutter_rust_bridge::DefaultHandler::new_simple(Default::default())
                }
            }
            #[inline(always)]
            fn __stability()
                ->
                    &'static ::flutter_rust_bridge::DefaultHandler<::flutter_rust_bridge::for_generated::SimpleThreadPool> {
                static LAZY:
                    ::lazy_static::lazy::Lazy<::flutter_rust_bridge::DefaultHandler<::flutter_rust_bridge::for_generated::SimpleThreadPool>>
                    =
                    ::lazy_static::lazy::Lazy::INIT;
                LAZY.get(__static_ref_initialize)
            }
            __stability()
        }
    }
    impl ::lazy_static::LazyStatic for FLUTTER_RUST_BRIDGE_HANDLER {
        fn initialize(lazy: &Self) { let _ = &**lazy; }
    }
    fn wire__crate__api__simple__greet_impl(ptr_:
            flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
        rust_vec_len_: i32, data_len_: i32)
        -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse {
        FLUTTER_RUST_BRIDGE_HANDLER.wrap_sync::<flutter_rust_bridge::for_generated::SseCodec,
            _>(flutter_rust_bridge::for_generated::TaskInfo {
                debug_name: "greet",
                port: None,
                mode: flutter_rust_bridge::for_generated::FfiCallMode::Sync,
            },
            move ||
                {
                    let message =
                        unsafe {
                            flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_,
                                rust_vec_len_, data_len_)
                        };
                    let mut deserializer =
                        flutter_rust_bridge::for_generated::SseDeserializer::new(message);
                    let api_name = <String>::sse_decode(&mut deserializer);
                    deserializer.end();
                    transform_result_sse::<_,
                            ()>((move ||
                                    {
                                        let output_ok =
                                            Result::<_, ()>::Ok(crate::api::simple::greet(api_name))?;
                                        Ok(output_ok)
                                    })())
                })
    }
    fn wire__crate__api__simple__hello_impl(port_:
            flutter_rust_bridge::for_generated::MessagePort,
        ptr_:
            flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
        rust_vec_len_: i32, data_len_: i32) {
        FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec,
            _,
            _>(flutter_rust_bridge::for_generated::TaskInfo {
                debug_name: "hello",
                port: Some(port_),
                mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
            },
            move ||
                {
                    let message =
                        unsafe {
                            flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_,
                                rust_vec_len_, data_len_)
                        };
                    let mut deserializer =
                        flutter_rust_bridge::for_generated::SseDeserializer::new(message);
                    let api_a = <String>::sse_decode(&mut deserializer);
                    deserializer.end();
                    move |context|
                        {
                            transform_result_sse::<_,
                                    ()>((move ||
                                            {
                                                let output_ok =
                                                    Result::<_, ()>::Ok(crate::api::simple::hello(api_a))?;
                                                Ok(output_ok)
                                            })())
                        }
                })
    }
    fn wire__crate__api__simple__init_app_impl(port_:
            flutter_rust_bridge::for_generated::MessagePort,
        ptr_:
            flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
        rust_vec_len_: i32, data_len_: i32) {
        FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec,
            _,
            _>(flutter_rust_bridge::for_generated::TaskInfo {
                debug_name: "init_app",
                port: Some(port_),
                mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
            },
            move ||
                {
                    let message =
                        unsafe {
                            flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_,
                                rust_vec_len_, data_len_)
                        };
                    let mut deserializer =
                        flutter_rust_bridge::for_generated::SseDeserializer::new(message);
                    deserializer.end();
                    move |context|
                        {
                            transform_result_sse::<_,
                                    ()>((move ||
                                            {
                                                let output_ok =
                                                    Result::<_, ()>::Ok({ crate::api::simple::init_app(); })?;
                                                Ok(output_ok)
                                            })())
                        }
                })
    }
    fn wire__crate__api__simple__loopback_audio_impl(port_:
            flutter_rust_bridge::for_generated::MessagePort,
        ptr_:
            flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
        rust_vec_len_: i32, data_len_: i32) {
        FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec,
            _,
            _>(flutter_rust_bridge::for_generated::TaskInfo {
                debug_name: "loopback_audio",
                port: Some(port_),
                mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
            },
            move ||
                {
                    let message =
                        unsafe {
                            flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_,
                                rust_vec_len_, data_len_)
                        };
                    let mut deserializer =
                        flutter_rust_bridge::for_generated::SseDeserializer::new(message);
                    deserializer.end();
                    move |context|
                        {
                            transform_result_sse::<_,
                                    ()>((move ||
                                            {
                                                let output_ok =
                                                    Result::<_,
                                                                ()>::Ok({ crate::api::simple::loopback_audio(); })?;
                                                Ok(output_ok)
                                            })())
                        }
                })
    }
    fn wire__crate__api__simple__sender_side_impl(port_:
            flutter_rust_bridge::for_generated::MessagePort,
        ptr_:
            flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
        rust_vec_len_: i32, data_len_: i32) {
        FLUTTER_RUST_BRIDGE_HANDLER.wrap_normal::<flutter_rust_bridge::for_generated::SseCodec,
            _,
            _>(flutter_rust_bridge::for_generated::TaskInfo {
                debug_name: "sender_side",
                port: Some(port_),
                mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
            },
            move ||
                {
                    let message =
                        unsafe {
                            flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_,
                                rust_vec_len_, data_len_)
                        };
                    let mut deserializer =
                        flutter_rust_bridge::for_generated::SseDeserializer::new(message);
                    let api_addr = <String>::sse_decode(&mut deserializer);
                    deserializer.end();
                    move |context|
                        {
                            transform_result_sse::<_,
                                    ()>((move ||
                                            {
                                                let output_ok =
                                                    Result::<_,
                                                                ()>::Ok({ crate::api::simple::sender_side(&api_addr); })?;
                                                Ok(output_ok)
                                            })())
                        }
                })
    }
    impl SseDecode for String {
        fn sse_decode(deserializer:
                &mut flutter_rust_bridge::for_generated::SseDeserializer)
            -> Self {
            let mut inner = <Vec<u8>>::sse_decode(deserializer);
            return String::from_utf8(inner).unwrap();
        }
    }
    impl SseDecode for Vec<u8> {
        fn sse_decode(deserializer:
                &mut flutter_rust_bridge::for_generated::SseDeserializer)
            -> Self {
            let mut len_ = <i32>::sse_decode(deserializer);
            let mut ans_ = ::alloc::vec::Vec::new();
            for idx_ in 0..len_ { ans_.push(<u8>::sse_decode(deserializer)); }
            return ans_;
        }
    }
    impl SseDecode for u8 {
        fn sse_decode(deserializer:
                &mut flutter_rust_bridge::for_generated::SseDeserializer)
            -> Self {
            deserializer.cursor.read_u8().unwrap()
        }
    }
    impl SseDecode for () {
        fn sse_decode(deserializer:
                &mut flutter_rust_bridge::for_generated::SseDeserializer)
            -> Self {}
    }
    impl SseDecode for i32 {
        fn sse_decode(deserializer:
                &mut flutter_rust_bridge::for_generated::SseDeserializer)
            -> Self {
            deserializer.cursor.read_i32::<NativeEndian>().unwrap()
        }
    }
    impl SseDecode for bool {
        fn sse_decode(deserializer:
                &mut flutter_rust_bridge::for_generated::SseDeserializer)
            -> Self {
            deserializer.cursor.read_u8().unwrap() != 0
        }
    }
    fn pde_ffi_dispatcher_primary_impl(func_id: i32,
        port: flutter_rust_bridge::for_generated::MessagePort,
        ptr:
            flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
        rust_vec_len: i32, data_len: i32) {
        match func_id {
            2 =>
                wire__crate__api__simple__hello_impl(port, ptr, rust_vec_len,
                    data_len),
            3 =>
                wire__crate__api__simple__init_app_impl(port, ptr,
                    rust_vec_len, data_len),
            4 =>
                wire__crate__api__simple__loopback_audio_impl(port, ptr,
                    rust_vec_len, data_len),
            5 =>
                wire__crate__api__simple__sender_side_impl(port, ptr,
                    rust_vec_len, data_len),
            _ =>
                ::core::panicking::panic("internal error: entered unreachable code"),
        }
    }
    fn pde_ffi_dispatcher_sync_impl(func_id: i32,
        ptr:
            flutter_rust_bridge::for_generated::PlatformGeneralizedUint8ListPtr,
        rust_vec_len: i32, data_len: i32)
        -> flutter_rust_bridge::for_generated::WireSyncRust2DartSse {
        match func_id {
            1 =>
                wire__crate__api__simple__greet_impl(ptr, rust_vec_len,
                    data_len),
            _ =>
                ::core::panicking::panic("internal error: entered unreachable code"),
        }
    }
    impl SseEncode for String {
        fn sse_encode(self,
            serializer:
                &mut flutter_rust_bridge::for_generated::SseSerializer) {
            <Vec<u8>>::sse_encode(self.into_bytes(), serializer);
        }
    }
    impl SseEncode for Vec<u8> {
        fn sse_encode(self,
            serializer:
                &mut flutter_rust_bridge::for_generated::SseSerializer) {
            <i32>::sse_encode(self.len() as _, serializer);
            for item in self { <u8>::sse_encode(item, serializer); }
        }
    }
    impl SseEncode for u8 {
        fn sse_encode(self,
            serializer:
                &mut flutter_rust_bridge::for_generated::SseSerializer) {
            serializer.cursor.write_u8(self).unwrap();
        }
    }
    impl SseEncode for () {
        fn sse_encode(self,
            serializer:
                &mut flutter_rust_bridge::for_generated::SseSerializer) {}
    }
    impl SseEncode for i32 {
        fn sse_encode(self,
            serializer:
                &mut flutter_rust_bridge::for_generated::SseSerializer) {
            serializer.cursor.write_i32::<NativeEndian>(self).unwrap();
        }
    }
    impl SseEncode for bool {
        fn sse_encode(self,
            serializer:
                &mut flutter_rust_bridge::for_generated::SseSerializer) {
            serializer.cursor.write_u8(self as _).unwrap();
        }
    }
    #[cfg(not(target_family = "wasm"))]
    mod io {
        use super::*;
        use flutter_rust_bridge::for_generated::byteorder::{
            NativeEndian, ReadBytesExt, WriteBytesExt,
        };
        use flutter_rust_bridge::for_generated::{
            transform_result_dco, Lifetimeable, Lockable,
        };
        use flutter_rust_bridge::{Handler, IntoIntoDart};
        pub trait NewWithNullPtr {
            fn new_with_null_ptr()
            -> Self;
        }
        impl<T> NewWithNullPtr for *mut T {
            fn new_with_null_ptr() -> Self { std::ptr::null_mut() }
        }
        #[no_mangle]
        pub extern "C" fn frb_get_rust_content_hash() -> i32 {
            FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH
        }
        #[no_mangle]
        pub extern "C" fn frb_pde_ffi_dispatcher_primary(func_id: i32,
            port_: i64, ptr_: *mut u8, rust_vec_len_: i32, data_len_: i32) {
            pde_ffi_dispatcher_primary_impl(func_id, port_, ptr_,
                rust_vec_len_, data_len_)
        }
        #[no_mangle]
        pub extern "C" fn frb_pde_ffi_dispatcher_sync(func_id: i32,
            ptr_: *mut u8, rust_vec_len_: i32, data_len_: i32)
            -> ::flutter_rust_bridge::for_generated::WireSyncRust2DartSse {
            pde_ffi_dispatcher_sync_impl(func_id, ptr_, rust_vec_len_,
                data_len_)
        }
        #[no_mangle]
        pub extern "C" fn dart_fn_deliver_output(call_id: i32, ptr_: *mut u8,
            rust_vec_len_: i32, data_len_: i32) {
            let message =
                unsafe {
                    ::flutter_rust_bridge::for_generated::Dart2RustMessageSse::from_wire(ptr_,
                        rust_vec_len_, data_len_)
                };
            FLUTTER_RUST_BRIDGE_HANDLER.dart_fn_handle_output(call_id,
                message)
        }
    }
    #[cfg(not(target_family = "wasm"))]
    pub use io::*;
}
 stderr=   Compiling rust_lib_flutter_rust_test v0.1.0 (/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust)
warning: unused import: `StreamTrait`
 --> src/api/simple.rs:1:44
  |
1 | use cpal::traits::{DeviceTrait, HostTrait, StreamTrait};
  |                                            ^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default
    Finished dev [unoptimized + debuginfo] target(s) in 0.66s


[2024-07-17T19:37:04.981Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:139] parse_function function name: "greet"
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=greet inputs_lifetimes=[[]] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [false] }
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=String ans=Delegate(String)
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=String ans=Delegate(String)
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:139] parse_function function name: "hello"
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=hello inputs_lifetimes=[[]] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [false] }
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=String ans=Delegate(String)
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=String ans=Delegate(String)
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:139] parse_function function name: "init_app"
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=init_app inputs_lifetimes=[] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [] }
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:139] parse_function function name: "loopback_audio"
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=loopback_audio inputs_lifetimes=[] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [] }
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:139] parse_function function name: "sender_side"
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=sender_side inputs_lifetimes=[[]] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [false] }
[2024-07-17T19:37:04.982Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=str ans=Delegate(String)
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:139] parse_function function name: "greet"
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=greet inputs_lifetimes=[[]] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [false] }
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=String ans=Delegate(String)
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=String ans=Delegate(String)
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:139] parse_function function name: "hello"
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=hello inputs_lifetimes=[[]] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [false] }
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=String ans=Delegate(String)
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=String ans=Delegate(String)
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:139] parse_function function name: "init_app"
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=init_app inputs_lifetimes=[] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [] }
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:139] parse_function function name: "loopback_audio"
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=loopback_audio inputs_lifetimes=[] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [] }
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/mod.rs:139] parse_function function name: "sender_side"
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/function/real/lifetime.rs:36] parse_function_lifetime name=sender_side inputs_lifetimes=[[]] output_lifetimes=[] ans=ParseFunctionLifetimeOutput { needs_extend_lifetime_per_arg: [false] }
[2024-07-17T19:37:04.985Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/codegen/parser/mir/parser/ty/ty.rs:12] TypeParserWithContext.parse_type ty=str ans=Delegate(String)
[2024-07-17T19:37:04.988Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/commands/format_dart.rs:24] execute format_dart paths=["lib/src/rust/frb_generated.io.dart", "lib/src/rust/api/simple.dart", "lib/src/rust/frb_generated.dart", "lib/src/rust/frb_generated.web.dart"] line_length=80
[2024-07-17T19:37:04.988Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/commands/command_runner.rs:129] execute command: bin=sh args="-c \"dart\" \"format\" \"--line-length\" \"80\" \"lib/src/rust/frb_generated.io.dart\" \"lib/src/rust/api/simple.dart\" \"lib/src/rust/frb_generated.dart\" \"lib/src/rust/frb_generated.web.dart\"" current_dir=Some("/Users/zacharyhaslam/FlutterApplications/flutter_rust_test") cmd=cd "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test" && "sh" "-c" "\"dart\" \"format\" \"--line-length\" \"80\" \"lib/src/rust/frb_generated.io.dart\" \"lib/src/rust/api/simple.dart\" \"lib/src/rust/frb_generated.dart\" \"lib/src/rust/frb_generated.web.dart\""
[2024-07-17T19:37:06.490Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/commands/command_runner.rs:140] command=cd "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test" && "sh" "-c" "\"dart\" \"format\" \"--line-length\" \"80\" \"lib/src/rust/frb_generated.io.dart\" \"lib/src/rust/api/simple.dart\" \"lib/src/rust/frb_generated.dart\" \"lib/src/rust/frb_generated.web.dart\"" stdout=Formatted lib/src/rust/frb_generated.io.dart
Formatted lib/src/rust/api/simple.dart
Formatted lib/src/rust/frb_generated.dart
Formatted lib/src/rust/frb_generated.web.dart
Formatted 4 files (4 changed) in 0.27 seconds.
 stderr=
[2024-07-17T19:37:06.490Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/commands/format_rust.rs:9] execute format_rust paths=["src/frb_generated.rs"]
[2024-07-17T19:37:06.490Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/commands/command_runner.rs:129] execute command: bin=sh args="-c \"rustfmt\" \"--edition\" \"2018\" \"src/frb_generated.rs\"" current_dir=Some("/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust") cmd=cd "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust" && "sh" "-c" "\"rustfmt\" \"--edition\" \"2018\" \"src/frb_generated.rs\""
[2024-07-17T19:37:06.545Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/commands/command_runner.rs:140] command=cd "/Users/zacharyhaslam/FlutterApplications/flutter_rust_test/rust" && "sh" "-c" "\"rustfmt\" \"--edition\" \"2018\" \"src/frb_generated.rs\"" stdout= stderr=
[2024-07-17T19:37:06.545Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/utils/dart_repository/dart_repo.rs:22] Guessing toolchain the runner is run into
[2024-07-17T19:37:06.546Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/utils/dart_repository/dart_repo.rs:71] Checking presence of flutter_rust_bridge in dependencies at /Users/zacharyhaslam/FlutterApplications/flutter_rust_test
[2024-07-17T19:37:06.546Z DEBUG /Users/zacharyhaslam/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flutter_rust_bridge_codegen-2.1.0/src/library/utils/dart_repository/dart_repo.rs:103] Checking presence of flutter_rust_bridge in dependencies at /Users/zacharyhaslam/FlutterApplications/flutter_rust_test
[0.8s] Parse  
  └── [0.8s] Cargo expand & syn parse  
  └── [0.0s] Parse HIR  
  └── [0.0s] Parse MIR  
[0.0s] Generate  
[1.6s] Polish  
  └── [1.5s] Run Dart formatter  
  └── [0.1s] Run Rust formatter  
  └── [0.0s] Auto upgrade                                                                                                                                               Done!

Expected behavior

No response

Generated binding code

No response

OS

No response

Version of flutter_rust_bridge_codegen

No response

Flutter info

No response

Version of clang++

No response

Additional context

No response

@zhpixel517 zhpixel517 added the bug Something isn't working label Jul 17, 2024
@fzyzcjy
Copy link
Owner

fzyzcjy commented Jul 18, 2024

I am not an expert of cpal, and from the errors you mentioned, it seems to be related to cpal instead of flutter-rust-bridge. My naive guess of "jniLibs folder missing" is to create an empty folder.

would this be something to take up with the cpal people instead?

I think so, maybe try to ask there since it looks like a general "how to compile cpal on android".

@fzyzcjy fzyzcjy added the awaiting Waiting for responses, PR, further discussions, upstream release, etc label Jul 18, 2024
@zhpixel517
Copy link
Author

I was able to fix it. My original issue was that I couldn't actually find the libc++_shared.so on my system. The docs say that you can find it in $ANDROID_NDK/toolchains/llvm/prebuilt/ which is true, but in my case I had to search even deeper to find them in $ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/lib. Then inside that directory are the different folders for x86_64-linux-android, aarch64-linux-android, etc.

I had to make the jniLibs folder inside android/app/src, then inside that folder create folders with these names and copy the libc++_shared.so from each one into the new folders separately.

Next I added this to my android/app/src/build.gradle inside android { ....

sourceSets {
        main {
            jni.srcDirs = []
            jniLibs.srcDirs = ['src/jniLibs']
        }
    }

Finally , based on this, my build.rs looks like this:

#[allow(dead_code)]
fn add_lib(name: impl AsRef<str>, _static: bool)
{
    #[cfg(not(feature = "test"))]
    println!(
        "cargo:rustc-link-lib={}{}",
        if _static { "static=" } else { "" },
        name.as_ref()
    );
}

fn main()
{
    let target = std::env::var("TARGET").expect("ERR: Could not check the target for the build.");

    if target.contains("android") {
        add_lib("c++_shared", false);
    }
}

unfortunately, copying the build.rs sample from the doc's troubleshooting page about this issue didn't work for me. in fact with this setup, it actually brought Could not resolve symbol __cxa_pure_virtual error back.

after these steps, the issue is solved. For extra reference, here is a template repo someone setup with cpal setup on Android.

@fzyzcjy
Copy link
Owner

fzyzcjy commented Jul 26, 2024

Happy to see the cpal compilation problem is fixed!

Copy link
Contributor

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
awaiting Waiting for responses, PR, further discussions, upstream release, etc bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants