-
Notifications
You must be signed in to change notification settings - Fork 32
Does ffi have function "-Wl,rpath"? #118
Comments
What are you trying to accomplish? Can you give more information? Are you doing Dart standalone or Flutter? |
I want to use ffmpeg to display net streams. |
Do you want to bundle the .so files in the package? or have users install it on their machine? For Android and iOS see the bundling documentation on https://dart.dev/guides/libraries/c-interop (I don't think we have Linux and Windows documentation as of yet.) Also see https://pub.dev/packages/webcrypto which ships a part of BoringSSL to learn how to set things up. |
I see. |
In a Flutter app, both Android and iOS you will need to package all required |
I have read the link https://dart.dev/guides/libraries/c-interop |
Linux when already having an .so file: Add the path of the .so files to: # List of absolute paths to libraries that should be bundled with the plugin
set(mylib_dylib_bundled_libraries
"${CMAKE_CURRENT_SOURCE_DIR}/../native/lib/linux_x64/libmylib_dylib.so"
PARENT_SCOPE
) This will copy the .so file to the bundle/lib (the main executable is in bundle itself). And then find the .so file relative to the executable: if (Platform.isLinux) {
// The default include path is from the root of the application folder.
// Opening 'build/linux/x64/debug/bundle/lib/lib$libName.so' works but
// is not portable for when the app is shipped.
// Instead, find it relative to the executable in the bundle.
final path = File(Platform.resolvedExecutable)
.parent
.uri
.resolve('lib/lib$libName.so')
.path;
return DynamicLibrary.open(path);
} Just opening |
@dcharkes |
Can you elaborate? (Please do so in general, half of my posts are asking you for more information.) The boilerplate generated by # List of absolute paths to libraries that should be bundled with the plugin
set(<your plugin name>_bundled_libraries
""
PARENT_SCOPE
) So you can add it in there. |
@dcharkes I just want to use libffmpeg on flutter. Thank you for your help! |
Please use Are all the dependencies in bundle/lib? If so, you're probably running into flutter/flutter#78819 (comment). You could try dlopening the dependencies first. |
@dcharkes libavformat.so contains libavcodec.so, it can find libavformat.so,but libavcodec.so can't be found. [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: Invalid argument(s): Failed to load dynamic library 'ffiplugin/example/build/linux/x64/debug/bundle/lib/libavformat.so': libavcodec.so.58: cannot open shared object file: No such file or directory |
@dcharkes |
This is my WIP: # Link bundled libraries from plugins into main executable to enable dlopen
# with only library name.
foreach(plugin ${FLUTTER_PLUGIN_LIST})
if(${plugin}_bundled_libraries)
target_link_libraries(
${BINARY_NAME}
PRIVATE
${${plugin}_bundled_libraries}
)
endif()
endforeach(plugin) It links the libraries from their source location in the build step, before the install step copies them to the final location. When the libraries are linked in the build step, we can do (I am not sure why shared libraries that are not linked during building are not working, this requires more digging.) I still find this somewhat hacky, and it requires developers making a |
@fayfive It turns out we were looking at the wrong (build flutter app)
$ ./build/linux/x64/release/bundle/flutter_app
(fails)
$ readelf -d build/linux/x64/release/bundle/flutter_app | grep RUNPATH
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN/lib]
$ readelf -d build/linux/x64/release/bundle/lib/libflutter_linux_gtk.so | grep RUNPATH
(not result)
$ patchelf --set-rpath '$ORIGIN' build/linux/x64/release/bundle/lib/libflutter_linux_gtk.so
$ readelf -d build/linux/x64/release/bundle/lib/libflutter_linux_gtk.so | grep RUNPATH
0x000000000000001d (RUNPATH) Library runpath: [$ORIGIN]
$ ./build/linux/x64/release/bundle/flutter_app
(works) When the |
@dcharkes |
@dcharkes thanks for your work on this! Especially documenting the comments the workarounds. I just wanted to report that combining your instructions from this comment to add to my plugin's # List of absolute paths to libraries that should be bundled with the plugin
set(mylib_dylib_bundled_libraries
"${CMAKE_CURRENT_SOURCE_DIR}/my_native_lib.so"
PARENT_SCOPE
) and then also your workaround described in the PR in my apps # Link bundled libraries from plugins into main executable to enable dlopen
# with only library name.
# Will NOT be needed once: https://github.com/flutter/engine/pull/28525 lands in Flutter channel we are using
foreach(plugin ${FLUTTER_PLUGIN_LIST})
if(${plugin}_bundled_libraries)
target_link_libraries(
${BINARY_NAME}
PRIVATE
${${plugin}_bundled_libraries}
)
endif()
endforeach(plugin) Gets me a working Flutter Linux Desktop using a plugin which calls into a (Zig compiled) native lib via FFI 🎉 I'll look out for your recently merged PR to make its way into Flutter beta channel to test that out later on too. |
@dcharkes following up on this, I'm now trying to use a prebuilt .so in my plugin. What I did was follow your example code in previous comment here and added to my plugin's
I then depend on this plugin in my Flutter Linux desktop app and it all works except I found that in the Flutter apps As I said, it all works, but I wanted to check if it's expected that the |
oops sorry, I have been rather dense here! Of course I just spotted that I have this in my CMake file:
|
Any PR we could track which Flutter version fixes the problem? |
This has been fixed since flutter/engine#28525. |
Does ffi have function "-Wl,rpath" to redirect the *.so or similar function?
The text was updated successfully, but these errors were encountered: