Skip to content

fix(android): ship the AAR's native libraries with their debug info - #650

Merged
andiwand merged 1 commit into
mainfrom
fix/android-native-symbols
Aug 2, 2026
Merged

fix(android): ship the AAR's native libraries with their debug info#650
andiwand merged 1 commit into
mainfrom
fix/android-native-symbols

Conversation

@andiwand

@andiwand andiwand commented Aug 2, 2026

Copy link
Copy Markdown
Member

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. Play reported every frame of a crash inside the core as a bare address.

Two strippers, not one

build_native.py stripped with --strip-unneeded. That was the obvious culprit, and fixing it alone does nothing — AGP's StripDebugSymbolsTask runs --strip-unneeded again on the way into the AAR.

The first push of this PR proved it: build_native.py produced a 7,326 KiB libodr_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.keepDebugSymbols holds AGP off them.

Size, measured

libodr_jni.so per ABI — the NDK compiles with -g in every configuration:

ABI unstripped --strip-debug --strip-unneeded (before)
arm64-v8a 72.1 MiB 7.15 MiB 5.49 MiB
armeabi-v7a 60.8 MiB 5.42 MiB 3.89 MiB
x86 59.6 MiB 6.40 MiB 5.17 MiB
x86_64 69.1 MiB 6.97 MiB 5.64 MiB

With libc++_shared.so that 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

  • The AAR CI now builds carries the debug info: arm64-v8a/libodr_jni.so is 75,638,648 bytes, up from 5,760,752
  • Both emulator matrices (API 26 and 36) pass against the unstripped libraries
  • Test-published as 6.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 .symtab only: ~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

publishToMavenCentral uploads 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 reports has been validated explicitly; the android path should too.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Lqc6gWzBBnoqvdaQ9HPoEa

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread android/build_native.py Outdated
@andiwand
andiwand force-pushed the fix/android-native-symbols branch from 771885b to 65b4955 Compare August 2, 2026 11:29
@andiwand andiwand changed the title fix(android): keep the symbol table in the AAR's native libraries fix(android): ship the AAR's native libraries with their debug info Aug 2, 2026
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
andiwand force-pushed the fix/android-native-symbols branch from 65b4955 to 87267e9 Compare August 2, 2026 11:36
@andiwand
andiwand merged commit 07bd166 into main Aug 2, 2026
34 of 41 checks passed
@andiwand
andiwand deleted the fix/android-native-symbols branch August 2, 2026 11:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant