[CP-beta] [tool] Fix libapp.so dropped from APK/app bundle (#188119)#188589
Conversation
## Summary `libapp.so` could be silently dropped from release APKs and app bundles, surfacing as either: - a runtime crash on launch — `VM snapshot invalid and could not be inferred from settings` — for APKs, or - a `Release app bundle failed to strip debug symbols from native libraries` build failure for app bundles. ## Root cause Regression from flutter#181275, which moved `libapp.so` from a jar dependency onto a Flutter Gradle Plugin source-set `jniLibs` directory. That delivery was fragile in two ways, both of which dropped `libapp.so` from the merged native libraries (while `libflutter.so`/`libdartjni.so`, delivered as AAR dependencies, were unaffected — which is why the failure looked asymmetric): 1. The source-set `jniLibs` `srcDir` was resolved eagerly (`.get().asFile`) at `:app` configuration time, while the copy task wrote lazily. When `:app` was evaluated before its build directory had been redirected — a combined `subprojects { … evaluationDependsOn(":app") }` block (the pre-flutter#91030 template shape) together with a plugin whose Gradle subproject name sorts before `:app` — the two disagreed on the build directory and the staged `libapp.so` was never merged. (flutter#186810) 2. The copy task wrote into a directory nested inside the Flutter task's own output directory, creating overlapping task outputs that undermined Gradle's incremental checks — e.g. a flavored project where a prior single-ABI build (a `flutter run` on one device) left the other ABIs missing `libapp.so`. (flutter#187388) ## Fix Stage `libapp.so` (and any bundled native assets) through a dedicated `CopyFlutterJniLibsTask` whose output is registered on each variant via AGP's variant API: [`variant.sources.jniLibs.addGeneratedSourceDirectory(...)`](https://developer.android.com/reference/tools/gradle-api/9.1/com/android/build/api/variant/SourceDirectories#addStaticSourceDirectory(kotlin.String)). AGP then owns the task dependency, resolves the output path lazily (correct regardless of project evaluation order or build-dir redirection), keeps it in its own output directory (no overlapping outputs), and strips/extracts debug symbols from it like any other native library. This restores the robustness of the original jar-based inclusion while keeping `libapp.so` strippable. ## Tests New integration test `gradle_libapp_so_packaging_test.dart` covering both triggers: the combined `subprojects` block + a plugin sorted before `:app`, and a flavored single-ABI build preceding a multi-ABI build. Fixes flutter#186810 Fixes flutter#187388 Fixes flutter#187553
|
This pull request was opened from and to a release candidate branch. This should only be done as part of the official Flutter release process. If you are attempting to make a regular contribution to the Flutter project, please close this PR and follow the instructions at Tree Hygiene for detailed instructions on contributing to Flutter. Reviewers: Use caution before merging pull requests to release branches. Ensure the proper procedure has been followed. |
There was a problem hiding this comment.
Code Review
This pull request migrates the staging of Flutter native libraries to the Android Components Extension by introducing a dedicated CopyFlutterJniLibsTask and adds corresponding integration tests. Feedback on the changes suggests safely handling null ABIs in the copy task, simplifying the task output directory provider mapping with descriptive error handling, and unescaping paths read from local.properties to ensure integration tests pass on Windows.
|
@walley892 Updated! |
|
autosubmit label was removed for flutter/flutter/188589, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label. |
677d472
into
flutter:flutter-3.46-candidate.0
Issue Link:
What is the link to the issue this cherry-pick is addressing?
#186810
#187388
#187553
Impact Description:
What is the impact (ex. visual jank on Samsung phones, app crash, cannot ship an iOS app)?
Does it impact development (ex. flutter doctor crashes when Android Studio is installed),
or the shipping of production apps (the app crashes on launch).
This information is for domain experts and release engineers to understand the consequences of saying yes or no to the cherry pick.
The root cause either presents as the app crashing on startup, or the build failing with the message
Changelog Description:
Explain this cherry pick:
See best practices for examples.
< Replace with changelog description here >
[flutter/186810 flutter/187388 flutter/187553] When building android app bundles using flavors, or with an old app template combined with a plugin coming alphabetically before app, fixes problems with failing to include libapp.so in the produced app bundle.
Workaround:
Is there a workaround for this issue?
For the case of the old app template combined with a plugin coming before "app" alphabetically, there is a workaround here #186810 (comment). For the flavors case there is not a workaround.
Risk:
What is the risk level of this cherry-pick?
Test Coverage:
Are you confident that your fix is well-tested by automated tests?
Validation Steps:
What are the steps to validate that this fix works?
android/build.gradle(.kts):find
subprojects { val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) project.layout.buildDirectory.value(newSubprojectBuildDir) } subprojects { project.evaluationDependsOn(":app") }and combine
subprojects { val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) project.layout.buildDirectory.value(newSubprojectBuildDir) project.evaluationDependsOn(":app") }Also, you can separately test the repro steps listed in
#187388
to validate that this fixes the flavors-symptom of this underlying root cause.