Skip to content

Native libraries are not 16 KB page-aligned (blocks Play updates, warns on Android 15+ devices) #47

Closed

Description

@parawanderer
Image

Symptom

On a 16 KB page-size device (reproduced on a Galaxy S25, Android 16), launching a debuggable build shows the system dialog:

Android app compatibility
This warning is showing because this is a debuggable app which is currently being tested.
This app isn't 16 KB-compatible. ELF alignment check failed. Please follow the steps on https://developer.android.com/16kb-page-size

Production builds do not show the dialog — Android only surfaces it for debuggable apps — so this has been invisible until now.

Unaligned libraries

Reported by the dialog. All come from third-party dependencies; none are built by this project.

Library Comes from Currently pinned
libpython3.12.so, libchaquopy_java.so, libsqlite3_chaquopy.so, libssl_chaquopy.so, libcrypto_chaquopy.so, libssl_python.so, libsqlite3_python.so, libcrypto_python.so Chaquopy 16.0.0
libcronet.119.0.6045.31.so org.chromium.net:cronet-embedded 119.6045.31
libdatastore_shared_counter.so androidx.datastore 1.1.3

cronet-embedded 119 corresponds to Chrome 119 (late 2023), by some distance the most stale native dependency in the build.

Why it matters

  • Google Play requires 16 KB alignment for apps targeting Android 15+. This project sets compileSdk/targetSdk = 35, so this blocks publishing an update there.
  • 16 KB page size is becoming the default on new arm64 hardware. Unaligned libraries will eventually fail to load rather than merely warn.

What the fix involves

The .so files are prebuilt upstream, so they cannot be realigned here — each has to be rebuilt with -Wl,-z,max-page-size=16384 by its publisher. In practice this is a dependency-bump exercise:

  1. Bump Chaquopy to a release shipping 16 KB-aligned native libs, and confirm the Python runtime plus the FindMy / NSKeyedUnArchiver wheels still resolve.
  2. Bump cronet-embedded — a large jump, and the most likely to require code changes.
  3. Bump androidx.datastore.
  4. Verify on a real 16 KB device (adb shell getconf PAGE_SIZE reports 16384). The CI emulator is 4 KB and will not reproduce this.

Notes

Deliberately kept out of the FindMy 0.9.x backend work (#30 / #44), which touches persistence and the Apple auth path and should not also carry a networking-stack upgrade.

Found while testing the FindMy 0.9.x migration branch.

Activity

  1. added
    bugSomething isn't working
    @appIssues regarding the OpenTagViewer Android app
    on Aug 9, 2026
  2. parawanderer commented on Aug 15, 2026

    @parawanderer
    OwnerAuthor

    Measured the alignment directly from the built APK's PT_LOAD segments rather than from the
    dialog and release notes. The table in the issue description is wrong in both directions,
    so correcting it here before it sends somebody down the wrong path.

    Libraries listed as unaligned that are already aligned

    At the versions currently pinned — Chaquopy 16.0.0, androidx.datastore 1.1.3:

    Library Actual
    libpython3.12.so 0x4000 — aligned
    libchaquopy_java.so 0x4000 — aligned
    libssl_python.so, libcrypto_python.so, libsqlite3_python.so 0x4000 — aligned
    libdatastore_shared_counter.so 0x4000 — aligned

    androidx.datastore therefore needs no bump at all, removing step 3 of "What the fix
    involves".

    Unaligned libraries missing from the table

    Library Source
    libAMapSDK_MAP_v9_8_3.so com.amap.api:3dmap, added by the #49 fork merge
    libopentagviewer.so ours, app/src/main/cpp
    libCoreFoundation.so ours — ADI stub
    libmediaplatform.so ours — ADI stub

    Three of the eight offenders were our own. The comment in app/build.gradle.kts asserting
    that NDK r27 aligns shared libraries to 16 KB by default is incorrect — r27 needs
    -Wl,-z,max-page-size=16384 passed explicitly, and r28 is the release that makes it the
    default. Without the flag, an r27 build emits PT_LOAD at 0x1000.

    Chaquopy: 16.1.0, not 17.0.0

    Since libpython and libchaquopy_java are already fine, the only Chaquopy offenders are the
    three _chaquopy stubs — precisely what 16.1.0 fixes ("the _chaquopy stub libraries for
    OpenSSL and SQLite are now linked in 16 KB mode").

    17.0.0 was tried first and fails to resolve: FindMy → bleak → dbus-fast, which has
    no Android distribution. Worth knowing that on 16.x this quietly resolves to a locally built
    win_amd64 wheel from the pip cache. Nothing in the app imports bleak, so a stub wheel
    like app/stubs/unicorn/ is the way to 17.0.0 whenever it is wanted.

    Result

    #67 takes the debug APK from 16 unaligned to 2. Both remaining are the AMap SDK, which has
    no aligned build at any version — the latest is still 0x1000 and additionally drops
    x86_64. Split out as #66.

    One correction to the framing

    The issue leads with Play Store publishing. This app is distributed as APKs on GitHub releases
    and build-release.yml does not build an AAB, so there is no store gate today. The reason
    that does bite is the second one given: 16 KB is becoming the default on new arm64 hardware,
    where unaligned libraries eventually fail to load rather than warn — which applies to a
    sideloaded APK identically.

    Reproducing

    llvm-readelf -l -W <lib>.so | awk '$1 == "LOAD" { print $NF }'
    # 0x4000 or greater is 16 KB compatible; 0x1000 is not

    This comment was written by Claude Code.

  3. self-assigned this
    on Aug 25, 2026
  4. parawanderer commented on Aug 25, 2026

    @parawanderer
    OwnerAuthor

    Closing this: it is done apart from the AMap SDK, which is tracked separately as #66.

    #67 aligned everything that could be aligned here, and the current pins are:

    Was Now
    Chaquopy 16.0.0 16.1.0 — the release that links the _chaquopy stubs in 16 KB mode
    cronet-embedded 119.6045.31 143.7445.0
    our own libopentagviewer.so, libCoreFoundation.so, libmediaplatform.so built with -Wl,-z,max-page-size=16384

    androidx.datastore needed no change — it was already aligned at 1.1.3 and is still pinned there. Step 3 of "What the fix involves" above was wrong, as was the table listing the Chaquopy and datastore libraries as offenders; the earlier comment has the measured detail.

    That took the debug APK from 16 unaligned libraries to 2. Both remaining are libAMapSDK_MAP_v9_8_3.so, which has no 16 KB-aligned build at any published version — that is not something this repository can fix, so it lives in #66.

    Verifying:

    llvm-readelf -l -W <lib>.so | awk '$1 == "LOAD" { print $NF }'
    # 0x4000 or greater is 16 KB compatible; 0x1000 is not

    This comment was written by Claude Code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

@appIssues regarding the OpenTagViewer Android appbugSomething isn't working

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions