thlorenz / rid

Rust integrated Dart framework providing an easy way to build Flutter apps with Rust.
64 stars 4 forks source link

bindgen doesn't generate full path for dart_ffi.DynamicLibrary.open in rid-api.dart #43

Open enzotar opened 2 years ago

enzotar commented 2 years ago

Bindgen generated file missing full path on first if statement in /plugin/lib/generated/rid_api.dart Works when I add full path.

Flutter Linux/ Rid master pull today

Error message [ERROR:flutter/lib/ui/ui_dart_state.cc(207)] Unhandled Exception: Invalid argument(s): Failed to load dynamic library 'libridtest.so': libridtest.so: cannot open shared object file: No such file or directory

0 _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:11:55)

Current Generated Code

// Open Dynamic Library
//
dart_ffi.DynamicLibrary _open() {
  if (dart_io.Platform.isLinux || dart_io.Platform.isAndroid)
    return dart_ffi.DynamicLibrary.open(
        'libridtest.so');
  if (dart_io.Platform.isMacOS || dart_io.Platform.isIOS)
    return dart_ffi.DynamicLibrary.executable();
  if (dart_io.Platform.isLinux)
    return dart_ffi.DynamicLibrary.open(
        '/home/et/code/rust/ridtest/target/debug/libridtest.so');
  if (dart_io.Platform.isMacOS)
    return dart_ffi.DynamicLibrary.open(
        '/home/et/code/rust/ridtest/target/debug/libridtest.dylib');
  if (dart_io.Platform.isWindows)
    return dart_ffi.DynamicLibrary.open(
        '/home/et/code/rust/ridtest/target\\debug\\libridtest.dll');
  throw UnsupportedError(
      'Platform "${dart_io.Platform.operatingSystem}" is not supported.');
}

works when I manually add full path

  if (dart_io.Platform.isLinux || dart_io.Platform.isAndroid)
    return dart_ffi.DynamicLibrary.open(
        '/home/et/code/rust/ridtest/target/debug/libridtest.so');
thlorenz commented 2 years ago

Did this work before and broke recently? Could you try on a version before #38? Maybe something broke as part of that? It's odd though since the integration tests in CI pass for Linux.

Also what is puzzling is why we have a superfluous Linux check here, i.e. it will never hit since the Linux|Android branch matches it already.

if (dart_io.Platform.isLinux || dart_io.Platform.isAndroid)
    return dart_ffi.DynamicLibrary.open(
        'libridtest.so');
[ .. ]
if (dart_io.Platform.isLinux)
    return dart_ffi.DynamicLibrary.open(
        '/home/et/code/rust/ridtest/target/debug/libridtest.so');
enzotar commented 2 years ago

It did work before. I'll try later today on a previous version and post the results.

enzotar commented 2 years ago

Not sure how I got it working before because #37 and #28 (which I had used) have the same issue. But I think I found the issue.

In /rid-build/src/dart_generators.rs, in the function dart_open_dl line 238 is missing {path_to_target}/{sub}/ and the extra Linux check is on line 241

fn dart_open_dl(&self) -> String {
        let sub_target_folder = match self.target {
            BuildTarget::Release => "release",
            BuildTarget::Debug => "debug",
            BuildTarget::DebugExample(_) => "debug/examples",
        };
        match self.project {
            Project::Dart => {
                format!(
                    r###"{dart_ffi}.DynamicLibrary _open() {{
  if (dart_io.Platform.isLinux)
    return {dart_ffi}.DynamicLibrary.open('{path_to_target}/{sub}/{lib_name}.so');
  if (dart_io.Platform.isMacOS)
    return {dart_ffi}.DynamicLibrary.open('{path_to_target}/{sub}/{lib_name}.dylib');
  if (dart_io.Platform.isWindows)
    return {dart_ffi}.DynamicLibrary.open('{path_to_target}\\{sub}\\{lib_name}.dll');
  throw UnsupportedError(
      'Platform "${{dart_io.Platform.operatingSystem}}" is not supported.');
}}
"###,
                    dart_ffi = DART_FFI,
                    path_to_target = self.path_to_target,
                    sub = sub_target_folder,
                    lib_name = self.lib_name
                )
            }
            Project::Flutter(_) => {
                format!(
                    r###"{dart_ffi}.DynamicLibrary _open() {{
  if (dart_io.Platform.isLinux || dart_io.Platform.isAndroid)
    return {dart_ffi}.DynamicLibrary.open('{lib_name}.so');
  if (dart_io.Platform.isMacOS || dart_io.Platform.isIOS)
    return {dart_ffi}.DynamicLibrary.executable();
  if (dart_io.Platform.isLinux)
    return {dart_ffi}.DynamicLibrary.open('{path_to_target}/{sub}/{lib_name}.so');
  if (dart_io.Platform.isMacOS)
    return {dart_ffi}.DynamicLibrary.open('{path_to_target}/{sub}/{lib_name}.dylib');
  if (dart_io.Platform.isWindows)
    return {dart_ffi}.DynamicLibrary.open('{path_to_target}\\{sub}\\{lib_name}.dll');
  throw UnsupportedError(
    'Platform "${{dart_io.Platform.operatingSystem}}" is not supported.');
}}
"###,
                    dart_ffi = DART_FFI,
                    lib_name = self.lib_name,
                    path_to_target = self.path_to_target,
                    sub = sub_target_folder,
                )
            }
        }
    }

Also, unrelated, but once I run setup.sh, I always need to update Cargo.toml before I run bindgen from

rid_build = { path = "../../../rid/rid-build" }
rid = { path = "../../../rid" }

to

rid_build = { path = "../rid/rid-build" }
rid = { path = "../rid" }
thlorenz commented 2 years ago

Awesome, thanks for tracking this down. Could you please file a PR that fixes it?

WRT setup.sh eventually we'll have a proper rid CLI which will include scaffolding this in a better way. What we have now is just a simple stop-gap measure to have something to work with 😉

enzotar commented 2 years ago

Submitted PR.

Unable to test on Android as I am having issues successfully completing ./sh/android error: failed to run custom build command for 'openssl-sys v0.9.67'