Skip to content

build(android): link libdocument_detector against shared libc++ - #726

Merged
farfromrefug merged 1 commit into
mainfrom
chore/android-shared-libcxx
Sep 13, 2026
Merged

farfromrefug merged 1 commit into
mainfrom
chore/android-shared-libcxx

Conversation

@farfromrefug

Copy link
Copy Markdown
Collaborator

Summary

  • libdocument_detector.so was built with -DANDROID_STL=c++_static, so each ABI carried a private copy of libc++/libc++abi. The napi runtime (@nativescript/android-quickjs-ng) already ships libc++_shared.so for all 4 ABIs, so that copy was pure duplication.
  • Switch to -DANDROID_STL=c++_shared. The existing pickFirst 'lib/*/libc++_shared.so' rules in App_Resources/*/Android/app.gradle keep exactly one copy in the APK — verified, APK still has a single libc++_shared.so (the runtime's).
  • Align src-native/.../build.gradle ndkVersion with the one the real build actually uses (27.3.13750724, from before-plugins.gradle).

Stripped libdocument_detector.so, before -> after:

ABI before after saved
arm64-v8a 7132720 6695728 427 KB
armeabi-v7a 4503864 4247608 250 KB
x86 8374820 7955876 409 KB
x86_64 9591536 9174512 407 KB

Bulk of it is locale.cpp.o (145 KB) and cxa_demangle.cpp.o (113 KB).

ABI compatibility

The runtime's libc++_shared.so is NDK r28 (clang 21); the plugin builds with NDK 27.3 (clang 18). Both use the std::__ndk1 inline namespace, as do the prebuilt libopencv_*.a / libtesseract.a / libleptonica.a. Only 12 symbols differ between the two shared libs (all std::pmr / GC-declare) and none are referenced by libdocument_detector.so. After the switch the .so has zero unresolved non-libc symbols; all 170 libc++ imports are exported by the runtime's copy. libNativeScript.so's own 113 libc++ imports resolve against either copy, so pickFirst is safe whichever wins.

Testing

Built and installed the arm64 debug APK on an emulator:

  • libdocument_detector.so now lists NEEDED libc++_shared.so on all 4 ABIs
  • nativeloader: Load ... libdocument_detector.so ... : ok — no dlopen/symbol errors
  • Camera preview with live document detection runs; capture produces a detected corner quad

Still needs a check on a real arm64 device: the emulator run crashes in kleidicv::sve2::remap_s16point5 (SIGILL) during crop, which is the pre-existing Apple-Silicon-emulator SVE issue documented in cpp/CMakeLists.txt (DISABLE_SVE), not related to this change — with -PdisableSVE the crop path gets past it. OCR (tesseract), QR scan (cardwallet flavour, -PwithQRCode) and PDF export have not been exercised end-to-end yet.

The napi runtime (@nativescript/android-quickjs-ng) already ships libc++_shared.so
for every ABI, so the static STL inside libdocument_detector.so was a duplicate.
Switch ANDROID_STL to c++_shared. Stripped .so per ABI:

  arm64-v8a    7132720 -> 6695728  (-427 KB)
  armeabi-v7a  4503864 -> 4247608  (-250 KB)
  x86          8374820 -> 7955876  (-409 KB)
  x86_64       9591536 -> 9174512  (-407 KB)

The existing pickFirst rules in App_Resources/*/Android/app.gradle keep a single
copy in the APK. Also align src-native ndkVersion with the one the real build uses.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@farfromrefug
farfromrefug marked this pull request as ready for review September 13, 2026 13:28
@farfromrefug
farfromrefug merged commit ac70683 into main Sep 13, 2026
1 check passed
@farfromrefug
farfromrefug deleted the chore/android-shared-libcxx branch September 13, 2026 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant