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

[iOS] Failed to load dynamic library dylib using the dart:ffi #116950

Closed
Aquarian-Age opened this issue Dec 13, 2022 · 17 comments
Closed

[iOS] Failed to load dynamic library dylib using the dart:ffi #116950

Aquarian-Age opened this issue Dec 13, 2022 · 17 comments
Labels
c: crash Stack traces logged to the console dependency: dart Dart team may need to help us found in release: 3.3 Found to occur in 3.3 found in release: 3.7 Found to occur in 3.7 has reproducible steps The issue has been confirmed reproducible and is ready to work on platform-ios iOS applications specifically r: solved Issue is closed as solved tool Affects the "flutter" command-line tool. See also t: labels.

Comments

@Aquarian-Age
Copy link

I compiled the libgo.so with go code, and it works fine with ffi calls on Android. On iOS, how do I invoke this compiled libgo.so?

On flutter.cn website, it is not very clear about the use of third-party libraries for ffi calls. For example, using go code should be compiled to
libxxx.a or libxxx.so? Compiled libxxx.a or libxxx.so? Where is it in the iOS directory? How should it be called?

@Aquarian-Age Aquarian-Age changed the title How do I call compiled SO on ffi on iOS? How do I call compiled libxxx.so on ffi on iOS? Dec 13, 2022
@Aquarian-Age Aquarian-Age changed the title How do I call compiled libxxx.so on ffi on iOS? On iOS, how to call compiled libxxx.so using ffi? Dec 13, 2022
@exaby73 exaby73 added the in triage Presently being triaged by the triage team label Dec 13, 2022
@exaby73
Copy link
Member

exaby73 commented Dec 13, 2022

Hello @Aquarian-Age. Have you gone through the steps provided on https://docs.flutter.dev/development/platform-integration/ios/c-interop

@exaby73 exaby73 added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Dec 13, 2022
@Aquarian-Age
Copy link
Author

Hello @Aquarian-Age. Have you gone through the steps provided on https://docs.flutter.dev/development/platform-integration/ios/c-interop


Yes, already seen. Already searched some on the Internet, still do not understand. Maybe my level is too low 😂
It would be nice to have an example.

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Dec 13, 2022
@dcharkes
Copy link
Contributor

If you have an already compiled library: https://docs.flutter.dev/development/platform-integration/ios/c-interop#closed-source-third-party-library

Dynamic libraries are lib<name>.dylib on MacOS and iOS. (Not lib<name>.so as on Linux/Android.)

#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint mylib_dylib.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
  s.name             = 'mylib_dylib'
  s.version          = '0.0.1'
  s.summary          = 'A new flutter plugin project.'
  s.description      = <<-DESC
A new flutter plugin project.
                       DESC
  s.homepage         = 'http://example.com'
  s.license          = { :file => '../LICENSE' }
  s.author           = { 'Your Company' => 'email@example.com' }
  s.source           = { :path => '.' }
  s.source_files = 'Classes/**/*'
  s.dependency 'Flutter'
  s.platform = :ios, '10.0'
  # TODO(dacoharkes): exclude i386 again, and enable simulator on Mac M1.
  s.pod_target_xcconfig = {
    'DEFINES_MODULE' => 'YES',
    'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64'
  }
  s.vendored_libraries = 'Frameworks/libmylib_dylib.dylib', 'Frameworks/libmylib_dylib_dependency.dylib'
  s.swift_version = '5.0'
end

@exaby73
Copy link
Member

exaby73 commented Dec 13, 2022

@dcharkes Can this be concluded to be a documentation issue, or would you consider this an invalid issue?

@Aquarian-Age
Copy link
Author

Aquarian-Age commented Dec 14, 2022

cannot find .dylib

ffi-error

dylib的编译脚本

ffi-error3

add method

ffi-error3a


Both golib.dylib and golibsimulator.dylib have been tried, the same error content

ffi-error2

ffi-error1

@huycozy
Copy link
Member

huycozy commented Dec 21, 2022

@Aquarian-Age Please provide a completed and minimal reproducible code sample so that we may verify this. Also, please provide the output of flutter doctor -v and the error log in quoting format so that we may verify it. Thanks!

@huycozy huycozy added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Dec 21, 2022
@Aquarian-Age
Copy link
Author

@Aquarian-Age Please provide a completed and minimal reproducible code sample so that we may verify this. Also, please provide the output of flutter doctor -v and the error log in quoting format so that we may verify it. Thanks!

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Dec 21, 2022
@huycozy
Copy link
Member

huycozy commented Dec 22, 2022

@Aquarian-Age thanks for providing the sample code. I also see the same error when running it. Labeling this issue for further insights from the team.

Logs
======== Exception caught by widgets library =======================================================
The following ArgumentError was thrown building FFiExample(dirty, state: _FFiExampleState#fa443):
Invalid argument(s): Failed to load dynamic library 'golibsimulator.dylib': dlopen(golibsimulator.dylib, 0x0001): tried: '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRootgolibsimulator.dylib' (errno=2), '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/swift/golibsimulator.dylib' (errno=2), '/usr/lib/swift/golibsimulator.dylib' (errno=2, not in dyld cache), '/Users/huynq/Library/Developer/CoreSimulator/Devices/B5C9F133-A0DA-4F5E-BF54-DFFF9A9BFFA6/data/Containers/Bundle/Application/B7924F97-4106-4FA3-B50A-7DAD0EDCE11F/Runner.app/Frameworks/golibsimulator.dylib' (errno=2), '/usr/lib/golibsimulator.dylib' (errno=2, not in dyld cache), 'golibsimulator.dylib' (errno=2), '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/golibsimulator.dylib' (errno=2)

The relevant error-causing widget was: 
  FFiExample FFiExample:file:///Users/huynq/Documents/NEVERCODE.IO/RepoduceProjects/OPClone/golang-flutter/goffi/lib/main.dart:9:16
When the exception was thrown, this was the stack: 
#0      _open (dart:ffi-patch/ffi_dynamic_library_patch.dart:12:43)
#1      new DynamicLibrary.open (dart:ffi-patch/ffi_dynamic_library_patch.dart:23:12)
#2      _FFiExampleState.build (package:goffi/main.dart:31:28)
#3      StatefulElement.build (package:flutter/src/widgets/framework.dart:4992:27)
#4      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4878:15)
#5      StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5050:11)
#6      Element.rebuild (package:flutter/src/widgets/framework.dart:4604:5)
#7      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4859:5)
#8      StatefulElement._firstBuild (package:flutter/src/widgets/framework.dart:5041:11)
#9      ComponentElement.mount (package:flutter/src/widgets/framework.dart:4853:5)
#10     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3863:16)
#11     Element.updateChild (package:flutter/src/widgets/framework.dart:3592:18)
#12     RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1195:16)
#13     RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:1164:5)
#14     RenderObjectToWidgetAdapter.attachToRenderTree.<anonymous closure> (package:flutter/src/widgets/binding.dart:1111:18)
#15     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2605:19)
#16     RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:1110:13)
#17     WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:945:7)
#18     WidgetsBinding.scheduleAttachRootWidget.<anonymous closure> (package:flutter/src/widgets/binding.dart:925:7)
(elided 4 frames from class _RawReceivePortImpl, class _Timer, and dart:async-patch)
====================================================================================================
flutter doctor -v (stable and master)
[✓] Flutter (Channel stable, 3.3.10, on macOS 13.0.1 22A400 darwin-x64, locale en-VN)
    • Flutter version 3.3.10 on channel stable at /Users/huynq/Documents/GitHub/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 135454af32 (13 hours ago), 2022-12-15 07:36:55 -0800
    • Engine revision 3316dd8728
    • Dart version 2.18.6
    • DevTools version 2.15.0

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /Users/huynq/Library/Android/sdk
    • Platform android-33, build-tools 31.0.0
    • ANDROID_HOME = /Users/huynq/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14B47b
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[✓] IntelliJ IDEA Community Edition (version 2022.1.1)
    • IntelliJ at /Users/huynq/Library/Application Support/JetBrains/Toolbox/apps/IDEA-C/ch-0/221.5591.52/IntelliJ IDEA CE.app
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart

[✓] VS Code (version 1.73.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.54.0

[✓] Connected device (3 available)
    • SM T225 (mobile) • R9JT3004VRJ • android-arm64  • Android 12 (API 31)
    • macOS (desktop)  • macos       • darwin-x64     • macOS 13.0.1 22A400 darwin-x64
    • Chrome (web)     • chrome      • web-javascript • Google Chrome 108.0.5359.124

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!
[!] Flutter (Channel master, 3.7.0-13.0.pre.38, on macOS 13.0.1 22A400 darwin-x64, locale en-VN)
    • Flutter version 3.7.0-13.0.pre.38 on channel master at /Users/huynq/Documents/GitHub/flutter_master
    ! Warning: `flutter` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
    ! Warning: `dart` on your path resolves to /Users/huynq/Documents/GitHub/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/huynq/Documents/GitHub/flutter_master. Consider adding /Users/huynq/Documents/GitHub/flutter_master/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ca7ca3b8f0 (3 hours ago), 2022-12-21 18:51:21 -0500
    • Engine revision a90c45db3f
    • Dart version 3.0.0 (build 3.0.0-55.0.dev)
    • DevTools version 2.20.0
    • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /Users/huynq/Library/Android/sdk
    • Platform android-33, build-tools 31.0.0
    • ANDROID_HOME = /Users/huynq/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14B47b
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[✓] IntelliJ IDEA Community Edition (version 2022.1.1)
    • IntelliJ at /Users/huynq/Library/Application Support/JetBrains/Toolbox/apps/IDEA-C/ch-0/221.5591.52/IntelliJ IDEA CE.app
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart

[✓] VS Code (version 1.74.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.54.0

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-x64     • macOS 13.0.1 22A400 darwin-x64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 108.0.5359.124

[✓] HTTP Host Availability
    • All required HTTP hosts are available

! Doctor found issues in 1 category.

@huycozy huycozy added c: crash Stack traces logged to the console platform-ios iOS applications specifically tool Affects the "flutter" command-line tool. See also t: labels. dependency: dart Dart team may need to help us p: framework has reproducible steps The issue has been confirmed reproducible and is ready to work on found in release: 3.3 Found to occur in 3.3 found in release: 3.7 Found to occur in 3.7 and removed in triage Presently being triaged by the triage team labels Dec 22, 2022
@huycozy huycozy changed the title On iOS, how to call compiled libxxx.so using ffi? [iOS] Failed to load dynamic library dylib using the dart:ffi Dec 22, 2022
@jmagman
Copy link
Member

jmagman commented Dec 22, 2022

At a minimum this sounds like a request for documentation.

@jmagman
Copy link
Member

jmagman commented Jan 4, 2023

Example app is actually on the https://docs.flutter.dev/development/platform-integration/ios/c-interop#compiled-dynamic-library path so shouldn't need a podspec. I linked and embedded the frameworks (though IRL this would need to be embedded differently on simulator vs physical device, i.e. using an xcframework):
Screenshot 2023-01-03 at 6 04 12 PM

Then I updated the open code to point to a real path (the error that's actually being displayed):
https://github.com/Aquarian-Age/golang-flutter/blob/078aa4aa0d11a17a94b4da72fb0be07cdeb85082/goffi/lib/main.dart#L31

      final executable = File(Platform.executable);
      final dyLibPath = '${executable.parent.path}/Frameworks/golibsimulator.dylib';
      final DynamicLibrary dylib = Platform.isIOS
          ? DynamicLibrary.open(dyLibPath)
          : DynamicLibrary.process();

That's indeed pointed to the right path in the installed app, but I'm getting not a mach-o file
Screenshot 2023-01-03 at 6 06 40 PM

Though it sure looks like one from otool.

I'm not sure how to get loading a pure dylib working, and even if you did I don't think it would be approved by the App Store--it needs to be packaged in a .framework bundle (I think), or be static. Which may be the real problem.

@dcharkes from your podspec example were you actually able to get this working with pure dylibs?

@dcharkes
Copy link
Contributor

dcharkes commented Jan 4, 2023

I'm not sure how to get loading a pure dylib working, and even if you did I don't think it would be approved by the App Store--it needs to be packaged in a .framework bundle (I think), or be static. Which may be the real problem.

@dcharkes from your podspec example were you actually able to get this working with pure dylibs?

Copying the .dylib in the Frameworks/ folder works for me locally. I've never published an app on the iOS store before, so I don't know if that works yes or no.

I've tried putting dylibs in an xcframework before, but I couldn't figure it out. I called xcodebuild -create-xcframework:

executable: 'xcodebuild',
arguments: [
  '-create-xcframework',
  for (final uri in srcUris) ...[
    '-library',
    uri.toFilePath(),
  ],
  '-output',
  targetUri.toFilePath(),
],

And then I tried adding it in the podspec as vendored_frameworks instead of vendored_libraries, but that resulted in:
[!] Invalid XCFramework slice type .dylib

@jmagman
Copy link
Member

jmagman commented Jan 4, 2023

Copying the .dylib in the Frameworks/ folder works for me locally.

How did you DynamicLibrary.open it? I had to make it relative to Platform.executable. The iOS ffi code could really use a sample app.

@Aquarian-Age I recommend totally going the podspec path recommended in https://docs.flutter.dev/development/platform-integration/ios/c-interop#closed-source-third-party-library, which involves making a plugin (not a normal Flutter app, as your example as) and letting CocoaPods embed your precompiled code. I also don't think you're going to have a good time embedding a dylib on iOS, suggest converting it to a static library or making it a proper iOS framework bundle (that part has nothing to do with Flutter, it's an iOS restriction).

@Aquarian-Age
Copy link
Author

Copying the .dylib in the Frameworks/ folder works for me locally.

How did you DynamicLibrary.open it? I had to make it relative to Platform.executable. The iOS ffi code could really use a sample app.

@Aquarian-Age I recommend totally going the podspec path recommended in https://docs.flutter.dev/development/platform-integration/ios/c-interop#closed-source-third-party-library, which involves making a plugin (not a normal Flutter app, as your example as) and letting CocoaPods embed your precompiled code. I also don't think you're going to have a good time embedding a dylib on iOS, suggest converting it to a static library or making it a proper iOS framework bundle (that part has nothing to do with Flutter, it's an iOS restriction).


The ffi method is no longer used. All code rewritten.

@Aquarian-Age Aquarian-Age closed this as not planned Won't fix, can't repro, duplicate, stale Jan 5, 2023
@jmagman
Copy link
Member

jmagman commented Jan 5, 2023

Filed dart-lang/samples#162

@jmagman
Copy link
Member

jmagman commented Jan 5, 2023

Also filed flutter/samples#1547 for Flutter app versions matching website instructions
https://docs.flutter.dev/development/platform-integration/ios/c-interop

@exaby73 exaby73 added the r: solved Issue is closed as solved label Jan 5, 2023
@dcharkes
Copy link
Contributor

dcharkes commented Jan 5, 2023

making a plugin (not a normal Flutter app, as your example as)

I've never been able to get it to work with a normal Flutter app either, only with flutter create --template=plugin_ffi. The generated boilerplate + Flutter's own logic of doing extra build steps for plugins and FFI plugins are required.

@github-actions
Copy link

github-actions bot commented Mar 4, 2023

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 bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
c: crash Stack traces logged to the console dependency: dart Dart team may need to help us found in release: 3.3 Found to occur in 3.3 found in release: 3.7 Found to occur in 3.7 has reproducible steps The issue has been confirmed reproducible and is ready to work on platform-ios iOS applications specifically r: solved Issue is closed as solved tool Affects the "flutter" command-line tool. See also t: labels.
Projects
None yet
Development

No branches or pull requests

5 participants