fix(build): only package requested --arch ABIs in Android APK/AAB#6578
Open
ndonkoHenri wants to merge 14 commits into
Open
fix(build): only package requested --arch ABIs in Android APK/AAB#6578ndonkoHenri wants to merge 14 commits into
--arch ABIs in Android APK/AAB#6578ndonkoHenri wants to merge 14 commits into
Conversation
…6567) The build template has mapped `--arch` to defaultConfig.ndk.abiFilters since 0.85.0, but that filter is silently defeated: the Flutter Gradle plugin programmatically adds all default ABIs as buildType-level abiFilters when split-per-abi is off, and AGP merges the two levels as a set union. Artifacts therefore always shipped serious_python's Python dists for all three ABIs. - Generate packaging.jniLibs.excludes for unrequested ABI directories in the app build.gradle.kts. Exclusion happens in AGP's MergeNativeLibsTask, upstream of both APK and AAB packaging, and filters libs from all sources including AAR/library-module dependencies. - Forward --arch to flutter build as --target-platform, so engine/AOT artifacts are only built for the requested ABIs and --split-per-abi produces only the requested split APKs. - Validate --arch values for Android builds (arm64-v8a, armeabi-v7a, x86_64) with a clear CLI error: serious_python also accepts x86, which Flutter no longer supports, and macOS-style values (arm64, x64) previously produced APKs with no site-packages that crashed at runtime.
…a-separated list Dart's args parser accepts multi-option values only comma-separated or via repeated flags; with the previous space-separated form, every value after the first was silently consumed as a positional argument, so multi-arch builds shipped libpythonsitepackages.so only for the first ABI and crashed at import time on the others.
…build flutter-apk/ and bundle/ accumulate artifacts across builds, and copy_build_output copies them wholesale — switching --arch or --split-per-abi between runs landed artifacts of the previous build in the user's output directory.
Generalizes the Android-only cleanup: every platform's output directories
are final assembly areas that the native toolchain fully regenerates, so
wiping them before 'flutter build' guarantees copy_build_output only
harvests artifacts of the current build. Beyond the Android flag-toggle
case, this also covers stale old-named binaries left behind in
Release/, bundle/ or build/ios/ipa/ after a product rename.
Extracts the outputs-glob placeholder resolution from copy_build_output
into resolve_output_path() — the linux outputs glob has {arch} in its
directory part, so cleaning its dirname requires the substitution.
… and --permissions flags These options were declared with nargs="+" but argparse's default store action, so repeating the flag silently replaced earlier values (--arch arm64-v8a --arch x86_64 kept only x86_64). action="extend" makes repetition accumulate, matching --exclude, --info-plist and the other multi-value options in this file. Space-separated single-flag usage is unchanged. --flutter-build-args is intentionally left on action="append": repeats already accumulate as nested lists, which its consumers flatten.
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Fixes Android --arch builds inadvertently packaging all default ABIs by ensuring only requested ABIs’ native libs and Flutter artifacts are produced and included.
Changes:
- Add Gradle
packaging.jniLibs.excludesfor unrequested Android ABI directories in the generated app template. - Introduce Android ABI helpers (ABI ↔ Flutter
--target-platform, excluded ABIs) and validate Android--archvalues. - Improve CLI handling of multi-value flags and clear stale Flutter build outputs before copying artifacts.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| sdk/python/templates/build/{{cookiecutter.out_dir}}/android/app/build.gradle.kts | Excludes unrequested ABI lib/<abi>/ directories during native libs merge/packaging. |
| sdk/python/packages/flet-cli/src/flet_cli/utils/android.py | Adds Android ABI mapping/validation helpers used by the build pipeline. |
| sdk/python/packages/flet-cli/src/flet_cli/commands/build_base.py | Fixes multi-value parsing for flags and validates Android --arch; passes excluded ABIs into templates. |
| sdk/python/packages/flet-cli/src/flet_cli/commands/build.py | Forwards --arch to Flutter via --target-platform and deletes stale output dirs before building. |
| CHANGELOG.md | Documents the Android --arch packaging fix and multi-flag behavior fix. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Deploying flet-website-v2 with
|
| Latest commit: |
2d8f4a1
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://46716290.flet-website-v2.pages.dev |
| Branch Preview URL: | https://fix-android-arch-filtering.flet-website-v2.pages.dev |
…-filtering # Conflicts: # CHANGELOG.md # sdk/python/packages/flet-cli/src/flet_cli/commands/build_base.py
…pports python-build dropped 32-bit Android in 3.13 (PEP 738), so with the new 3.14 default a no---arch build packaged armeabi-v7a engine libs without a Python runtime — 32-bit devices could install the app but it crashed at startup. Each PythonRelease row now declares its android_abis, the default target_arch materializes from it, and an explicit --arch armeabi-v7a with Python >= 3.13 fails fast suggesting --python-version 3.12. Adds registry-consistency tests for android_abis.
…pports python-build dropped 32-bit Android in 3.13 (PEP 738), so with the new 3.14 default a no---arch build packaged armeabi-v7a engine libs without a Python runtime — 32-bit devices could install the app but it crashed at startup. Each PythonRelease row now declares its android_abis, the default target_arch materializes from it, and an explicit --arch armeabi-v7a with Python >= 3.13 fails fast suggesting --python-version 3.12. Adds registry-consistency tests for android_abis.
… fix-android-arch-filtering # Conflicts: # CHANGELOG.md # sdk/python/packages/flet-cli/src/flet_cli/commands/build_base.py
The multi-version Python PR (#6577) removed flet.version.pyodide_version but the 'Get Pyodide version' step still read it, failing every 'Build Flet Client for Web' run. Resolve the version from the flet_cli.utils.python_versions registry instead (default release's Pyodide), and replace the hand-rolled tarball + wheel downloads with flet_cli.utils.pyodide.ensure_pyodide — the hardcoded micropip-0.8.0/packaging-24.2 filenames would have silently broken on the new Pyodide line (3.14's lock resolves micropip 0.11.1), since curl without -f writes 404 pages into the .whl files.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
flet build apk --arch arm64-v8aproduced an APK that still containedlib/armeabi-v7aandlib/x86_64— including a full Python distribution per ABI (~20 MB each).Fixes #6567
Root cause
The build template has mapped
--arch→defaultConfig.ndk.abiFilterssince 0.85.0 (#6331), but that filter is silently defeated:buildType.ndk.abiFiltersto all default ABIs (armeabi-v7a,arm64-v8a,x86_64) whenever split-per-abi is off (FlutterPlugin.kt, usingDEFAULT_PLATFORMS— not the requested--target-platform).abiFiltersas a set union (MergedNdkConfig.append→abiFilters.addAll), so{arm64-v8a} ∪ {all 3} = all 3.Changes
app/build.gradle.ktsnow addspackaging.jniLibs.excludesfor unrequested ABI directories. Exclusion happens in AGP'sMergeNativeLibsTask— upstream of both APK and AAB packaging — and filters native libs from all sources, including library-module/AAR dependencies likeserious_python_android.--archto Flutter as--target-platform: engine/AOT artifacts are only built for the requested ABIs, and--split-per-abinow produces only the requested split APK(s).--split-per-abiis not auto-enabled — output shape is unchanged unless explicitly requested.--archvalues for Android (arm64-v8a,armeabi-v7a,x86_64) with a clear CLI error. Previouslyx86(accepted by serious_python, dropped by Flutter) or macOS-style values (arm64) produced opaque Gradle failures or APKs with no site-packages that crashed at runtime.--arch: values were passed toserious_pythonspace-separated, but Dart's args parser only accepts multi-options comma-separated/repeated — every value after the first was silently dropped, so multi-arch builds shippedlibpythonsitepackages.soonly for the first ABI.flutter build(all platforms): Flutter never removes previous artifacts from e.g.flutter-apk/, andcopy_build_outputharvests these directories wholesale — switching--arch/--split-per-abi(or renaming the product) between runs landed artifacts of the previous build in the user's output directory.flet_cli/utils/android.pyhelpers + unit tests.Test code
Full validation matrix (clean state, verified with
unzip -l, sizes from a minimal counter app):apk --arch arm64-v8alib/arm64-v8aapk --arch arm64-v8a x86_64apk --arch arm64-v8a --split-per-abi*-arm64-v8a.apk, arm64 libs onlyaab --arch arm64-v8abase/lib/arm64-v8aonlyapk(no--arch)apk --split-per-abi(no--arch)apk --arch x86[tool.flet.android] target_arch = ["arm64-v8a"]--arch arm64-v8aThe single-ABI APK was also installed and launched on an arm64 emulator (Python boots, site-packages import, UI renders).
Additional details
ndk.abiFiltersblock: harmless today and useful again if Flutter's plugin behavior changes. Flutter'sdisable-abi-filteringGradle property was considered as an alternative but rejected to avoid coupling to a Flutter-internal property name.Summary by Sourcery
Fix Android builds so APKs/AABs respect requested architectures and cleanly regenerate artifacts per build.
Bug Fixes:
flet build apkandflet build aabonly package native libraries for the Android ABIs requested via--arch, instead of all default ABIs.--archvalues to Flutter as--target-platformso engine artifacts and--split-per-abioutputs are generated only for the requested ABIs.--archvalues at the CLI level and surface a clear error when unsupported architectures are specified.--arch,--source-packages, and--permissionsflags so all provided values are preserved.Enhancements:
--archvalues to Flutter target platforms and to compute excluded ABIs for Gradle packaging.--archto clearly list supported Android and macOS architectures.Documentation:
--archhandling fixes and related build behavior changes in the changelog.