Skip to content

Add size optimizations to the Android build - #7

Open
peachbits wants to merge 1 commit into
mainfrom
matthew/android-size-flags
Open

Add size optimizations to the Android build#7
peachbits wants to merge 1 commit into
mainfrom
matthew/android-size-flags

Conversation

@peachbits

@peachbits peachbits commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

Cuts the Android native payload by roughly a third, measured on real builds of both ABIs against the published 0.4.2 binaries:

ABI APK bytes (stripped) delta download (deflate)
arm64-v8a 15.24 MiB -> 9.46 MiB -37.9% 6.23 -> 4.04 MiB
armeabi-v7a 12.44 MiB -> 8.27 MiB -33.5% 5.54 -> 3.80 MiB

What changed:

  • The final link now passes --gc-sections, --icf=safe, --pack-dyn-relocs=android (APS2, supported since API 23), --strip-debug, and --build-id=sha1. The version script exports only 4 JNI symbols, so the linker discards everything unreachable from them: dead consensus and daemon code (BlockchainLMDB, miniupnp), OpenSSL precompute tables, and about 440 KiB of duplicate template instantiations.
  • Every dependency compiles with -ffunction-sections -fdata-sections so the link-time GC has whole-function granularity.
  • OpenSSL drops 36 features a TLS client wallet never touches (QUIC, DTLS, SM2/3/4, CMS/OCSP/TS, legacy ciphers). Each no-* name is validated against 3.6.0's Configure disablables. libunbound gains --disable-gost because GOST verification needs the removed ENGINE API.
  • lwsf/monero Release builds move from -O3 to -O2; cold C code (OpenSSL, expat, unbound) builds -Oz. Hand-written asm crypto paths are unaffected. libsodium stays -O2.
  • The npm artifact halves (30.0 -> 15.4 MB arm64) because DWARF is stripped at link time. The symbol table stays, so Sentry native symbolication still gets function names.

Verified on both ABIs: the 4 JNI exports are the only dynamic symbols, and every live path survives the GC by real reachability, including all 13 mnemonic wordlists, bulletproof_plus_PROVE (send path), wallet2, lwsf, the TLS client, and cn_slow_hash (wallet-cache KDF, not mining code as previously assumed).

Notes:

  • libzmq cannot be dropped despite never linking into the .so: monero's CMakeLists declares it with pkg_check_modules(REQUIRED), so it must exist at configure time. A comment now records this.
  • The OpenSSL trim and gost switch apply to the iOS build too; the next iOS build-native run will exercise them and should shrink the xcframework similarly.
  • Needs an on-device QA pass (create/restore/sync/send) before release.

Note

Cursor Bugbot is generating a summary for commit acba3e8. Configure here.

Link with --gc-sections, --icf=safe, --pack-dyn-relocs=android, and
--strip-debug, compile every dependency with -ffunction-sections
-fdata-sections, trim 36 unused OpenSSL features, and drop lwsf/monero
Release builds from -O3 to -O2. The APK-stripped payload shrinks 37.9%
on arm64-v8a (15.2 MiB to 9.5 MiB) and 33.5% on armeabi-v7a (12.4 MiB
to 8.3 MiB); the npm artifact halves because DWARF is stripped at link
time while the symbol table stays for symbolication.

Verified on both ABIs: the 4 JNI exports are the only dynamic symbols,
all 13 mnemonic wordlists, bulletproof_plus_PROVE, wallet2, lwsf, and
the TLS client survive gc-sections, and dead consensus/daemon code
(BlockchainLMDB, SM2 tables, miniupnp) is gone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@peachbits
peachbits marked this pull request as ready for review August 4, 2026 23:02
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