diff --git a/android/README.md b/android/README.md index c5a49c70..b88ae8bb 100644 --- a/android/README.md +++ b/android/README.md @@ -77,6 +77,15 @@ The odrcore build is a normal one — `ODR_JNI=ON`, static core linked into `libodr_jni.so` — driven by the `android-` conan profiles in `.github/config/conan/profiles`, which pin the NDK and API 26. +The libraries ship unstripped — 60-72 MB per ABI, most of the AAR — so that a +consuming app's `ndk.debugSymbolLevel` can hand play what it needs to symbolicate +a crash inside the core. Devices never see it: play serves APKs built from the +stripped copies, so the weight is on maven central and developer builds only. + +It takes both `build_native.py` not stripping and the +`packaging.jniLibs.keepDebugSymbols` rule in `build.gradle.kts`. Without the +second the first is invisible. + ## Testing ```bash diff --git a/android/build.gradle.kts b/android/build.gradle.kts index 8ebc590d..7320fceb 100644 --- a/android/build.gradle.kts +++ b/android/build.gradle.kts @@ -102,6 +102,15 @@ android { targetCompatibility = JavaVersion.VERSION_17 } + packaging { + jniLibs { + // AGP strips the libraries on their way into the AAR unless told not + // to, silently — the published AAR comes out byte-identical to a + // fully stripped one however `build_native.py` built it. + keepDebugSymbols += "**/*.so" + } + } + // pushing the instrumented apk onto a cold emulator outlasts ddmlib's // default timeout, which surfaces as a ShellCommandUnresponsiveException // rather than as a failing test diff --git a/android/build_native.py b/android/build_native.py index fc6e4bdb..2df19b23 100644 --- a/android/build_native.py +++ b/android/build_native.py @@ -14,6 +14,10 @@ `libc++_shared.so` has to be shipped because the android profiles build against the shared c++ runtime and nothing else in a consuming app pulls it in. + +Neither is stripped: the NDK's unconditional `-g` is what a consumer's +`ndk.debugSymbolLevel` turns into symbolicated play crash reports. Costs 60-72 MB +per ABI, and needs the `keepDebugSymbols` rule in `build.gradle.kts` to survive. """ import argparse @@ -65,13 +69,8 @@ def libcxx_shared(ndk: Path, triple: str) -> Path: return matches[0] -def strip(ndk: Path, library: Path) -> None: - """The NDK compiles with `-g` in every configuration, so a release build of - the bindings is ~70 MB until it is stripped.""" - matches = sorted(ndk.glob("toolchains/llvm/prebuilt/*/bin/llvm-strip")) - if not matches: - raise SystemExit(f"no llvm-strip under {ndk}") - run([matches[0], "--strip-unneeded", library]) +def report(library: Path) -> None: + print(f" {library.name}: {library.stat().st_size // 1024} KiB", flush=True) def build(architecture: str, conan: str, build_profile: str, output: Path) -> None: @@ -106,7 +105,7 @@ def build(architecture: str, conan: str, build_profile: str, output: Path) -> No for source in (cmake_dir / "jni" / "libodr_jni.so", libcxx_shared(ndk, triple)): target = jni_libs / source.name shutil.copy2(source, target) - strip(ndk, target) + report(target) def main() -> int: