Description
package:jni
can be used in multiple ways. And all these ways require (1) a different way to build/link the native code (2) a different way to run on CI.
- As a Flutter plugin:
flutter build
,flutter run
,flutter drive
.
a. as Linux Desktop app
b. as MacOS Desktop app
c. as Windows Desktop app
d. as Android app - As a Dart standalone package:
dart run
,dart test
,flutter test
.
a. on Linux host
b. on MacOS host
c. on Windows host
Native code building / bundling
Flutter
1a and 1b use the CMake build to bundle native source code.
- Do we need to bundle transitive dll for JNI?
1c uses CocoaPods to bundle native source code.
- How do we get
jni.h
as a dependency there?
1d uses Gradle which invokes CMake, so this should work the same as 1a/1b.
Dart standalone
- When packages use
package:jni
through pub get, we should not modify the pub cache. So then we should not build in the directory our package is at.
Usually we then build something like .dart_tools/packages/native/jni/<linux_x64,...>/<libdartjni.so,...>.
We usually build this by bin/setup.dart
invoking the CMake build.
This requires some path juggling:
An alternative is to pre-build the dll and let bin/setup.dart
download the dll/so/dylib.
We take this approach on the Cronet repo
https://github.com/google/cronet.dart/blob/main/bin/setup.dart
Native dependencies bundling
If we want to make Flutter apps fully portable, we should include the dynamic libraries for JNI and a full JVM in Flutter apps. For now, we should probably leave this.
For example package:ffigen
requires libclang to be installed on the machines where it is run.
CI support
- I'm not aware of being able to run
flutter run
orflutter drive
on CI. We would need a graphical environment. So the best we can do here isflutter build
. - We should install the JVM + JNI dependencies on the bots. Build our dartjni with CMake directly (or with
bin/setup.dart
invoking CMake). And then rundart test
that uses the dependencies + our own built lib.