From af20fa418aeafc18155c52755346b65d1feaf68a Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Thu, 9 Apr 2026 12:47:36 +0400 Subject: [PATCH] fix(android): bump minSdk 24 -> 26 to avoid broken __init_tcb in NDK 24 stub MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Build #7 crashed at launch on the Pixel 6 with SIGSEGV in __init_tcb / pthread_create called from tao::ndk_glue::create in WryActivity.onCreate: #00 __init_tcb(bionic_tcb*, pthread_internal_t*)+4 #01 pthread_create+360 #02 std::sys::thread::unix::Thread::new #04 tao::platform_impl::platform::ndk_glue::create #05 Java_com_wzp_desktop_WryActivity_create Tauri scaffolds build.gradle.kts with `minSdk = 24`, which makes the tauri-cli invoke `aarch64-linux-android24-clang` as the Rust linker. That linker transitively pulls broken static stubs from libc.a for getauxval, __init_tcb and pthread_create — these stubs only work in statically- linked executables because they read bionic state (__libc_auxv, TCB) that only the libc init path sets up. In a .so loaded via dlopen they SIGSEGV the moment anything spawns a thread. API 26+ has the real runtime symbols and the NDK-26 linker resolves them against libc.so instead of the static fallback. This is also the minimum Oboe supports. Patch the generated build.gradle.kts post-init to swap `minSdk = 24` for `minSdk = 26` — the legacy wzp-android crate solved the same issue with a .cargo/config.toml linker override plus a getauxval_fix.c shim. Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/build-tauri-android.sh | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/scripts/build-tauri-android.sh b/scripts/build-tauri-android.sh index 01d4e4b..8e82a7a 100755 --- a/scripts/build-tauri-android.sh +++ b/scripts/build-tauri-android.sh @@ -179,7 +179,19 @@ if [ "${DO_INIT}" = "1" ] || [ ! -x gen/android/gradlew ]; then cargo tauri android init 2>&1 | tail -20 fi -# ── Post-init patches: runtime mic permission + jniLibs dir ───────────────── +# ── Post-init patches ──────────────────────────────────────────────────────── + +# Bump minSdk 24 -> 26. Tauri scaffolds with minSdk=24, which forces cargo to +# use the aarch64-linux-android24-clang linker. That linker pulls a broken +# compiler-rt stub for __init_tcb / pthread_create that SIGSEGVs on first +# thread::spawn inside a .so (static libc init never runs in dlopen-loaded +# libraries). API 26 has working runtime symbols. Oboe also requires API 26+. +BUILD_GRADLE=gen/android/app/build.gradle.kts +if grep -q "minSdk = 24" "$BUILD_GRADLE"; then + echo ">>> bumping minSdk 24 -> 26 in build.gradle.kts" + sed -i "s|minSdk = 24|minSdk = 26|" "$BUILD_GRADLE" +fi + MANIFEST=gen/android/app/src/main/AndroidManifest.xml if ! grep -q "RECORD_AUDIO" "$MANIFEST"; then echo ">>> injecting RECORD_AUDIO + MODIFY_AUDIO_SETTINGS into AndroidManifest"