Version: @op-engineering/op-sqlite 18.2.1 (latest), with "op-sqlite": { "sqliteVec": true }
Environment: React Native 0.86.3 (New Architecture), Expo SDK 57, release build with -PreactNativeArchitectures=armeabi-v7a
Device: Infinix X6823, Android 12, 32-bit userland (ro.product.cpu.abilist = armeabi-v7a,armeabi)
What happens
The first open() throws:
Exception in HostFunction: dlopen failed: cannot locate symbol "ceil" referenced by "/data/app/~~…/base.apk!/lib/armeabi-v7a/libsqlite_vec.so"
Cause
The prebuilt android/src/main/libsqlitevec/armeabi-v7a/libsqlite_vec.so leaves ceil undefined but does not list libm.so as a dependency. Output from llvm-readelf (NDK 27.1.12297006):
$ llvm-readelf -d armeabi-v7a/libsqlite_vec.so | grep NEEDED
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libc.so]
$ llvm-readelf --dyn-syms armeabi-v7a/libsqlite_vec.so | awk '$7=="UND"' | grep ceil
... UND ceil
The arm64-v8a build has the same NEEDED list but no undefined ceil (presumably the compiler inlines it there), so the failure only shows on 32-bit ARM. On Android, ceil lives in libm.so, and the dynamic linker resolves a library's undefined symbols only from its own NEEDED entries. I only checked armeabi-v7a and arm64-v8a, not x86 / x86_64.
Likely fix
Link the 32-bit libsqlite_vec.so against libm (e.g. -lm) so that libm.so appears in NEEDED.
Repro
- Set
"op-sqlite": { "sqliteVec": true } in package.json.
- Build a release APK for
armeabi-v7a and install it on a 32-bit Android device.
- Call
open({ name: 'test.db' }).
Version:
@op-engineering/op-sqlite18.2.1 (latest), with"op-sqlite": { "sqliteVec": true }Environment: React Native 0.86.3 (New Architecture), Expo SDK 57, release build with
-PreactNativeArchitectures=armeabi-v7aDevice: Infinix X6823, Android 12, 32-bit userland (
ro.product.cpu.abilist=armeabi-v7a,armeabi)What happens
The first
open()throws:Cause
The prebuilt
android/src/main/libsqlitevec/armeabi-v7a/libsqlite_vec.soleavesceilundefined but does not listlibm.soas a dependency. Output fromllvm-readelf(NDK 27.1.12297006):The
arm64-v8abuild has the sameNEEDEDlist but no undefinedceil(presumably the compiler inlines it there), so the failure only shows on 32-bit ARM. On Android,ceillives inlibm.so, and the dynamic linker resolves a library's undefined symbols only from its ownNEEDEDentries. I only checkedarmeabi-v7aandarm64-v8a, notx86/x86_64.Likely fix
Link the 32-bit
libsqlite_vec.soagainst libm (e.g.-lm) so thatlibm.soappears inNEEDED.Repro
"op-sqlite": { "sqliteVec": true }inpackage.json.armeabi-v7aand install it on a 32-bit Android device.open({ name: 'test.db' }).