-
Notifications
You must be signed in to change notification settings - Fork 27.3k
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
☂️ Native assets support #129757
Comments
Support for FFI calls with `@Native external` functions through Native assets on MacOS and iOS. This enables bundling native code without any build-system boilerplate code. For more info see: * #129757 ### Implementation details for MacOS and iOS. Dylibs are bundled by (1) making them fat binaries if multiple architectures are targeted, (2) code signing these, and (3) copying them to the frameworks folder. These steps are done manual rather than via CocoaPods. CocoaPods would have done the same steps, but (a) needs the dylibs to be there before the `xcodebuild` invocation (we could trick it, by having a minimal dylib in the place and replace it during the build process, that works), and (b) can't deal with having no dylibs to be bundled (we'd have to bundle a dummy dylib or include some dummy C code in the build file). The dylibs are build as a new target inside flutter assemble, as that is the moment we know what build-mode and architecture to target. The mapping from asset id to dylib-path is passed in to every kernel compilation path. The interesting case is hot-restart where the initial kernel file is compiled by the "inner" flutter assemble, while after hot restart the "outer" flutter run compiled kernel file is pushed to the device. Both kernel files need to contain the mapping. The "inner" flutter assemble gets its mapping from the NativeAssets target which builds the native assets. The "outer" flutter run get its mapping from a dry-run invocation. Since this hot restart can be used for multiple target devices (`flutter run -d all`) it contains the mapping for all known targets. ### Example vs template The PR includes a new template that uses the new native assets in a package and has an app importing that. Separate discussion in: #131209. ### Tests This PR adds new tests to cover the various use cases. * dev/devicelab/bin/tasks/native_assets_ios.dart * Runs an example app with native assets in all build modes, doing hot reload and hot restart in debug mode. * dev/devicelab/bin/tasks/native_assets_ios_simulator.dart * Runs an example app with native assets, doing hot reload and hot restart. * packages/flutter_tools/test/integration.shard/native_assets_test.dart * Runs (incl hot reload/hot restart), builds, builds frameworks for iOS, MacOS and flutter-tester. * packages/flutter_tools/test/general.shard/build_system/targets/native_assets_test.dart * Unit tests the new Target in the backend. * packages/flutter_tools/test/general.shard/ios/native_assets_test.dart * packages/flutter_tools/test/general.shard/macos/native_assets_test.dart * Unit tests the native assets being packaged on a iOS/MacOS build. It also extends various existing tests: * dev/devicelab/bin/tasks/module_test_ios.dart * Exercises the add2app scenario. * packages/flutter_tools/test/general.shard/features_test.dart * Unit test the new feature flag.
Support for FFI calls with `@Native external` functions through Native assets on Linux. This enables bundling native code without any build-system boilerplate code. For more info see: * #129757 ### Implementation details for Linux. Mainly follows the design of #130494. Some differences are: * Linux does not support cross compiling or compiling for multiple architectures, so this has not been implemented. * Linux has no add2app. The assets copying is done in the install-phase of the CMake build of a flutter app. CMake requires the native assets folder to exist, so we create it also when the feature is disabled or there are no assets. ### Tests This PR adds new tests to cover the various use cases. * packages/flutter_tools/test/general.shard/linux/native_assets_test.dart * Unit tests the Linux-specific part of building native assets. It also extends various existing tests: * packages/flutter_tools/test/integration.shard/native_assets_test.dart * Runs (incl hot reload/hot restart), builds, builds frameworks for Linux and flutter-tester.
Move test added in #130494 out of staging. * https://ci.chromium.org/ui/p/flutter/builders/luci.flutter.staging/Mac_ios native_assets_ios * https://ci.chromium.org/ui/p/flutter/builders/luci.flutter.staging/Mac_ios native_assets_ios_simulator > Monitor the CI results of the new shard on the [Flutter build dashboard](https://flutter-dashboard.appspot.com/#/build). After 50 consecutive passing builds without any flakes, the flake bot will create a PR to remove the bringup: true parameter from .ci.yaml in the Framework tree. This will allow the test to block the tree, preventing breakages. With this change, the new shard will start running in presubmit automatically, unless specify presubmit: false. https://github.com/flutter/flutter/wiki/Adding-a-new-Test-Shard#steps-to-add-a-new-framework-test-shard Umbrella issue: * #129757
@dcharkes I wonder if you could give me an example of use cases for this feature? |
Any use case in which you want to call native code and bundle that native code:
|
@dcharkes Thanks a lot for clarification |
@dcharkes does this also support compiling code then linking to third-party/precompiled static libraries (and by extension, specifying the platform-specific path to these libraries in |
Currently the only constraint is that the output must be a dynamic library. So as long as that static library is linked into a dynamic library everything works. We can invoke arbitrary native tools in your |
@dcharkes thanks for the quick response. Are there any examples for invoking the native build tools, or do you mean simply using regular Dart like Process.run? |
Simply The helper package Let's move the discussion there. Please open an issue (or PR!) on that repo. |
There's two errors thrown by Xcode 15.3 when submitting Flutter apps built with First is:
Per the Apple reference, underscores can't be used in CFBundleIdentifier, so perhaps we could replace hyphens with underscores here, e.g.
The second issue is similar, the generated
Workaround is to add the following to
I haven't submitted a PR because I suspect there's a broader fix to the |
@dcharkes, is there any timeline or estimation for when native assets will move out of the experimental flag? |
Unfortunately I cannot give an estimation. We're working hard on getting some other pieces in place that are needed for the build and link hooks. And these will likely cause breaking changes to the hook APIs and the protocol between the Dart/Flutter SDK and the hooks. Some issues to follow besides this one: |
Hi all! I've been working on a little utility to help make it easier to build native assets with bazel and incorporate them into flutter or dart applications. Currently, it's working for Android, iOS & MacOS, haven't had a chance to test on Linux and Windows yet. It's main role is to build dynamic libs for the defined platforms, bundle in the assets, plus give a typesafe & platform independent abstraction to load the libraries in code. Give it a go at bazel_builder I'm wondering if: Note: This is also relevant for dart-lang/sdk#50565, I haven't had a chance to test how assets should be bundled with dart yet though. |
Very cool!
We have considered making Dart and Flutter bazel builds, but this seems out of reach for now. Maybe @mraleph can comment. With native assets we have at least a well-defined protocol. But of course it is not as powerful as arbitrary bazel build files.
Native assets would be the way to go. The native assets (build hooks) are the well-defined extension point. (Note it's currently only available in an experiment.)
I'd love it. But I don't actually build any apps. 🙃 Every once in a while people give it a shot. Some shots in the past: https://github.com/dart-archive/bazel/tree/master/dazel, https://github.com/scalio/bazel-flutter.
Flutter also supports native assets. You're replying to the native assets tracking issue, but your example doesn't use |
Native assets support in Flutter MacOS, iOS, Linux, and Windows is available on the master channel behind an experimental flag:
flutter config --enable-native-assets
andflutter create --template=package_ffi [package name]
.A high level tracking issue for supporting native assets.
Native assets enables packages to specify a top-level
build.dart
that is invoked by launchers (dartdev and flutter_tools) to build/download native libraries and communicate back which native libraries need to be bundled and under which "asset id".From a Flutter context, the native assets feature will enable testing native code with
flutter test
, which the FFI plugins do not support. From a Dart Flutter context packages will be compatible with both Dart and Flutter, removing the need for publishing two versions on pub (one for Dart and one for Flutter).More details can be found in:
Dart standalone support has landed behind an experimental flag (
dart --enable-experiment=native-assets
).This issue tracks implementing native assets in flutter tools
Use cases that should be supported
flutter run
flutter build
debug/release/profileflutter test
/dart test
flutter build macos-framework
for MacOS)flutter run -dflutter-tester
Test coverage will be through end-to-end integration tests that exercise the dynamic libraries provided by packages.
Landing plan is to land this behind an experimental flag on the main branch only. This has the following benefits:
build.dart
protocol until before we get it out of experimental. Users should not publish packages on pub.dev while this feature is in experimental phase.Please feel free to note additional use cases that we have missed or ask questions on this issue.
Foot notes:
References:
cc @stuartmorgan @vashworth
Ongoing work related to native assets, build.dart and link.dart hooks:
hook/link.dart
support in flutter_tools #146263hook/build.dart
Data assets support #146264hook/link.dart
consume data assets from pubspec.yaml #146265native_assets
to the App Store. #148044flutter clean
should delete all native assets #151890flutter run
#154425package_ffi
template language options #151646The text was updated successfully, but these errors were encountered: