Description
Dynamic libraries can try to load other dynamic libraries when they are dlopened.
For this case, the build.dart
needs to add the transitive closure of dynamic libraries as assets.
When we want to start doing tree shaking of whole dylibs (not static linking), we need to take into account the dependencies between dylibs.
This means we need to extend the CLI protocol to be able to communicate the dependencies between assets.
Also, if the dylib paths inside the dylib need to be rewritten in Flutter: install_name_tool -change <abs-deps-path> @executable_path/../Frameworks/lib…dylib dependent.dylib
(We already do something like this in Flutter for the main dylib name itself.)
[ ] Add dependencies to protocol- Use install_name_tool to patch up moved dylibs in Flutter
- Add example / test on this repo for Dart standalone.
- Add a way to to build two dylibs with
CBuilder
where one depends on the dynamic linker to load the other as dependency.
Concrete use case: libexif
depends on libintl
.
Thanks for reporting @mkustermann
Metadata
Metadata
Assignees
Type
Projects
Status
Activity
[jnigen] Bump SDK constraint to 4.0.0 (#190)
[jnigen] Bump SDK constraint to 4.0.0 (#190)
blaugold commentedon Jul 29, 2024
I need support for this with a use case where I have a library, but for some features of the library I need some native glue code so that I can use them with Dart. The library is only available as a prebuilt binary, so I can't compile the library and the glue code into one binary. The library with the glue code needs to be linked to the primary library. Loading the primary library from the glue code library works for most configurations (only Flutter + macOS has been a problem), but that's probably coincidental.
@dcharkes I'm happy to work on this if you could give me some pointers.
dcharkes commentedon Jul 29, 2024
One of the challenges here is that the embedder renames/repackages dylibs. So relying on the C/C++ dynamic loader with a fixed
char*
name doesn't work well. (I presume this is the cause of the issues for MacOS?)And Flutter does something else than Dart. So you'd need a different file path when called from Flutter than when called from Dart.
Some options:
dart_api.h
function that allows you to get the absolutedlopen
path for an asset ID maybe? And then in your code you can calldlopen
with the resolved path?Both of these assume that you use "dynamic loading" e.g. nothing happens at the link step in the native compiler.
I believe this is not needed. The way we have designed the link hooks should allow for simply reporting both the main and support dylib (based on the eventual tree-shaking info / resources.json)
@blaugold Can you elaborate on your use case? Are you doing dynamic loading? e.g. doing
dlopen
at runtime?blaugold commentedon Jul 29, 2024
That's precisely the issue.
I have two libraries:
cblite
andcblitedart
.cblite
is downloaded by thebuild
hook.cblitedart
contains the glue code to be able to usecblite
and is built withCBuilder
by thebuild
hook. I have generated@Native
bindings throughffigen
for both libraries, so they are being loaded by whatever API Dart is using to load libraries for@Native
bindings.Here is the
build
hook:The full package is also available publicly on GitHub.
On macOS + Flutter I get the following exception:
dcharkes commentedon Jul 29, 2024
Thanks @blaugold!
Where on https://github.com/cbl-dart/cbl-dart/ is
cblitedart
loadinglibcblite.3.dylib
? Is it adlopen
in C/C++ (dynamic loading)? Or is it a reference to a symbol and the C dynamic linker adds the machine code that is triggering the loading oflibcblite.3.dylib
(dynamic linking).As a workaround, can you force loading of
libcblite
first by doing aNative.addressOf
on one of it's symbols before invoking a function with a@Native
fromcblitedart
. (This workaround might not work though due to theinstall_name
being changed.)blaugold commentedon Jul 29, 2024
Sorry, I thought that was implied. 🙈
cblitedart
is linked tocblite
(here in the build hook), socblite
is implicitly loaded when I try the invoke a function fromcblitedart
in Dart.Ah, yes, I'm already doing that. If I remember correctly, that was a workaround that helped on iOS.
dcharkes commentedon Jul 29, 2024
I think conceptually what we have to do is: not only update the install_path with the
install_name_tool
, but also all the paths that the dynamic linker will look at. Probably in the style of https://stackoverflow.com/questions/33991581/install-name-tool-to-update-a-executable-to-search-for-dylib-in-mac-os-xFor that we either need to (a) come up with an algorithm/heuristic to decide which dynamic linking paths we need to update or (b) explicitly specify these paths in the
NativeCodeAsset
somewhere (path -> assetId. And then flutter_tools which does theinstall_name
change can then do path -> new path.)@blaugold Can you explore this with
install_name_tool
andotool
in flutter_tools ?Hopefully that should not be needed anymore afterwards. 🙂
blaugold commentedon Jul 29, 2024
@dcharkes Thanks for the pointers! I'll see how far I can get. 🙂
blaugold commentedon Aug 7, 2024
@dcharkes I've created a PR: flutter/flutter#153054. Let me know what you think.
28 remaining items