16 KB page size for your own C/C++ code: NDK versions, linker flags, AGP
Short answer: build with NDK r28 or newer and your shared libraries are 16 KB-aligned by default. With NDK r27 or older, add the linker flags -Wl,-z,max-page-size=16384 and -Wl,-z,common-page-size=16384. Then package with AGP 8.5.1 or newer so uncompressed libraries are 16 KB zip-aligned, and check the result with llvm-objdump or the free checker.
Checked 2026-10-13 · by hermonLabs · Google Play deadlines
NDK r28 and newer
Google: “NDK version r28 and higher compile 16 KB-aligned by default.” Pin it so every machine and CI runner uses it:
android {
ndkVersion = "28.2.13676358"
}NDK r27 and older: linker flags
CMake (CMakeLists.txt):
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE
"-Wl,-z,max-page-size=16384"
"-Wl,-z,common-page-size=16384")ndk-build (Android.mk):
LOCAL_LDFLAGS += -Wl,-z,max-page-size=16384 -Wl,-z,common-page-size=16384Every library you link needs it, including ones pulled in with add_subdirectory. Google also notes that some libc++_shared.so builds from NDK r26 and lower are not 16 KB-aligned; if you cannot upgrade the NDK, statically linking the C++ standard library is the documented alternative.
Packaging: AGP 8.5.1
Devices with 16 KB pages need uncompressed shared libraries to start on a 16 KB zip boundary. Google: upgrade to AGP 8.5.1 or higher. On older AGP, ship compressed libraries instead:
android {
packagingOptions {
jniLibs {
useLegacyPackaging = true
}
}
}Compressed libraries take more space once installed. On AGP 8.0 or lower, Google also lists android.bundle.enableUncompressedNativeLibs=false in gradle.properties.
Verify
# every LOAD segment should read align 2**14 (or higher)
llvm-objdump -p libfoo.so | grep LOAD
# APK zip alignment
zipalign -c -P 16 -v 4 app-release.apk
# AAB: look for PAGE_ALIGNMENT_16K
bundletool dump config --bundle=app-release.aab | grep alignmentOr drop the APK/AAB in the in-browser checker, which checks both the ELF alignment and (for APKs) the zip offset of stored libraries.
Third-party libraries
Flags only fix what you compile. Prebuilt SDK libraries need a new release from the vendor: look them up in the measured library index.
Sources
Read 2026-10-13. Our own numbers are measured from published artifacts (how); anything else is quoted from the sources above.
The paid kit ($12, v2.1) contains the complete measured fix map for all 80+ libraries as JSON and a table, every raw per-version measurement, the spot-check evidence, and the CI checker. This page and the checker script stay free.
- fixmap.json 209 KB
- fixmap.md 41 KB
- tools/check16k.py 6 KB
- GUIDE.md 17 KB
Full refund within 14 days if the kit didn't help you find or fix your blocker, no questions — email us and we process it via Polar's Refunds API.