fix(android): ship the AAR's native libraries with their debug info - #650
Merged
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 771885bdee
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
andiwand
force-pushed
the
fix/android-native-symbols
branch
from
August 2, 2026 11:29
771885b to
65b4955
Compare
A consuming app's `ndk.debugSymbolLevel` has only the merged native libraries to extract from, and both halves of this repo were throwing that away: `build_native.py` stripped with `--strip-unneeded`, and AGP's own StripDebugSymbolsTask stripped again on the way into the AAR. Play reported every frame of a crash inside the core as a bare address. Fixing only the script is invisible - AGP undoes it, and the published AAR comes out byte-identical to the fully stripped one. So `build_native.py` now leaves the libraries alone and `packaging.jniLibs.keepDebugSymbols` holds AGP off them. That is 60-72 MB per ABI of DWARF, and it is the point: play turns it into `file:line` with the inline chain intact. None of it reaches a device, which serves APKs the consuming app's own build strips - the weight is paid by maven central and by developer builds. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Lqc6gWzBBnoqvdaQ9HPoEa
andiwand
force-pushed
the
fix/android-native-symbols
branch
from
August 2, 2026 11:36
65b4955 to
87267e9
Compare
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.
A consuming app's
ndk.debugSymbolLevelhas only the merged native libraries to extract from, and both halves of this repo were throwing that away. Play reported every frame of a crash inside the core as a bare address.Two strippers, not one
build_native.pystripped with--strip-unneeded. That was the obvious culprit, and fixing it alone does nothing — AGP'sStripDebugSymbolsTaskruns--strip-unneededagain on the way into the AAR.The first push of this PR proved it:
build_native.pyproduced a 7,326 KiBlibodr_jni.so, and the AAR CI built from it contained 5,760,752 bytes — byte-identical to the fully stripped one. Caught in review; the evidence is that run's AAR artifact.So this needs both: the script leaves the libraries alone, and
packaging.jniLibs.keepDebugSymbolsholds AGP off them.Size, measured
libodr_jni.soper ABI — the NDK compiles with-gin every configuration:--strip-debug--strip-unneeded(before)With
libc++_shared.sothat is 292 MiB uncompressed across four ABIs — but DWARF deflates about 4:1, so the published AAR is 76.7 MiB (80,459,111 bytes), against ~7 MiB before.Verified end to end
arm64-v8a/libodr_jni.sois 75,638,648 bytes, up from 5,760,7526.1.1-test2— the central portal accepted the ~77 MiB bundle and listed the AAR at exactly the 80,459,111 bytes CI produced. Deployment dropped afterwards.Why the size is the right trade
Debug symbols never reach a phone. AGP puts them in
BUNDLE-METADATA/com.android.tools.build.debugsymbols/inside the.aab; play uses them to symbolicate and serves device APKs built from the stripped libraries. The cost is maven central storage and developer builds on a cold cache — not app size.The alternative was
--strip-debug, keeping.symtabonly: ~32 MiB uncompressed, function names but no line numbers and inlined frames collapsed into their callers. Since end users pay nothing either way, the full DWARF is worth it — and it is what OpenDocument.droid already had via conan, before opendocument-app/OpenDocument.droid#558 moved it onto this AAR.Follow-up worth its own change
publishToMavenCentraluploads and exits without waiting for validation, so a release cannot tell a validated deployment from a failed one. The maven jar's path polls and reportshas been validatedexplicitly; the android path should too.🤖 Generated with Claude Code
https://claude.ai/code/session_01Lqc6gWzBBnoqvdaQ9HPoEa