An AAB's native libraries are read from base/lib/* only:
https://github.com/saimskywalker/android-16kb-check/blob/main/android-16kb-check#L355-L362
A bundle with dynamic feature modules stores each module's libraries under
<module>/lib/<abi>/, not under base/. Those modules are packaged into APKs
and installed on device, and Play checks them at upload like any other, so an
unaligned .so that arrives inside a feature module is invisible here and the
run reports PASS.
It is the same shape as the prebuilt-AAR case the README is written around: the
.so came from somewhere else, your own ndkVersion says nothing about it, and
the artifact is the only place to measure it. A feature module is a fairly
normal place for a heavy prebuilt dependency to end up, precisely because it is
the thing you want delivered on demand.
Reproducing it needs only the layout:
import zipfile
with zipfile.ZipFile("feature.aab", "w", zipfile.ZIP_STORED) as z:
z.writestr("BundleConfig.pb", b"fixture\n")
z.writestr("base/lib/arm64-v8a/libexample.so", SO) # aligned
z.writestr("heavy_feature/lib/arm64-v8a/libvendor.so", SO) # never opened
Filing rather than sending a patch, because it changes what "the artifact"
means — every module rather than the base one — and that is worth a decision
rather than a diff. Two things that would need settling:
- Whether a module directory that yields no
.so should be reported, and how a
module name fits the <abi> <lib> report columns without making the common
single-module output noisier.
- Whether
*/lib/* is a safe glob for every bundle shape, or whether the
module list should come from the archive's own top-level directories with
BUNDLE-METADATA/ and META-INF/ excluded.
Happy to write it if you have a preference on those two. APKs are unaffected —
they have a single flat lib/.
Found while auditing the repo from a fresh clone; the exit-code fixes from the
same pass are in #1.
An AAB's native libraries are read from
base/lib/*only:https://github.com/saimskywalker/android-16kb-check/blob/main/android-16kb-check#L355-L362
A bundle with dynamic feature modules stores each module's libraries under
<module>/lib/<abi>/, not underbase/. Those modules are packaged into APKsand installed on device, and Play checks them at upload like any other, so an
unaligned
.sothat arrives inside a feature module is invisible here and therun reports
PASS.It is the same shape as the prebuilt-AAR case the README is written around: the
.socame from somewhere else, your ownndkVersionsays nothing about it, andthe artifact is the only place to measure it. A feature module is a fairly
normal place for a heavy prebuilt dependency to end up, precisely because it is
the thing you want delivered on demand.
Reproducing it needs only the layout:
Filing rather than sending a patch, because it changes what "the artifact"
means — every module rather than the base one — and that is worth a decision
rather than a diff. Two things that would need settling:
.soshould be reported, and how amodule name fits the
<abi> <lib>report columns without making the commonsingle-module output noisier.
*/lib/*is a safe glob for every bundle shape, or whether themodule list should come from the archive's own top-level directories with
BUNDLE-METADATA/andMETA-INF/excluded.Happy to write it if you have a preference on those two. APKs are unaffected —
they have a single flat
lib/.Found while auditing the repo from a fresh clone; the exit-code fixes from the
same pass are in #1.