From c9cd0436578e55e366eb61064c7252bb6f951439 Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Thu, 9 Apr 2026 16:58:37 +0400 Subject: [PATCH] test: tauri.conf.json bundle.android.minSdkVersion=26 + cpp_smoke.cpp c++_shared MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User theory: tauri-cli hardcodes minSdkVersion=24 into its rustc invocation regardless of gradle build.gradle.kts, .cargo/config.toml, or env var overrides — but DOES read from tauri.conf.json's bundle.android block. That would explain why every cc::Build C++ compile crashed with __init_tcb+4 via pthread_create: API-24 bionic's .init_array routines for the linked-in .init_array clash with the pthread_create state tao later expects. This commit applies the fix AND re-adds the smallest known crashing variant (E.1 with cpp_link_stdlib('c++_shared')) so the test has one clear failure mode to compare against: tauri.conf.json bundle: "android": { "minSdkVersion": 26 } build.rs (on android target): - hello.c (plain C, worked in Step A) - getauxval_fix.c (plain C, worked in Step D) - hello2.c (plain C, worked in Step D+1) - cpp_smoke.cpp (C++ via cc::Build .cpp(true), crashed in E.1) Also re-emits the libc++_shared.so copy into gen/android jniLibs so the runtime linker can resolve the NEEDED entry cc-rs added via cpp_link_stdlib('c++_shared'). If this launches → theory validated, proceed with Oboe integration. If this crashes → need to keep digging. Co-Authored-By: Claude Opus 4.6 (1M context) --- desktop/src-tauri/build.rs | 39 ++++++++++++++++++++++++++--- desktop/src-tauri/cpp/cpp_smoke.cpp | 9 +++++++ desktop/src-tauri/tauri.conf.json | 5 +++- 3 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 desktop/src-tauri/cpp/cpp_smoke.cpp diff --git a/desktop/src-tauri/build.rs b/desktop/src-tauri/build.rs index 06e81be..51ebd5c 100644 --- a/desktop/src-tauri/build.rs +++ b/desktop/src-tauri/build.rs @@ -34,13 +34,46 @@ fn main() { .compile("getauxval_fix"); // Step D+1: identical-content clone of hello.c as a third cc::Build - // static library. Tests the "any 3rd static lib triggers the crash" - // theory in isolation — no C++, no external deps, same C content as - // the known-working hello.c. + // static library. Kept around as a sanity check: if this C compile + // suddenly started crashing, we'd know the environment regressed. println!("cargo:rerun-if-changed=cpp/hello2.c"); cc::Build::new() .file("cpp/hello2.c") .compile("wzp_hello2"); + + // ─── minSdkVersion theory test: the original E.1 crashing cpp ────── + // Re-add the smallest crashing variant (cpp_smoke.cpp with cpp(true) + // + cpp_link_stdlib("c++_shared")) on top of the working Step D+1 + // baseline. The only additional variable compared to the previous + // crashing runs is tauri.conf.json bundle.android.minSdkVersion=26, + // which may make tauri-cli stop hardcoding API 24 in its rustc + // invocation. If THIS build launches, the minSdkVersion fix is + // validated and we can proceed with Oboe integration. + println!("cargo:rerun-if-changed=cpp/cpp_smoke.cpp"); + cc::Build::new() + .cpp(true) + .std("c++17") + .cpp_link_stdlib(Some("c++_shared")) + .file("cpp/cpp_smoke.cpp") + .compile("wzp_cpp_smoke"); + + // Copy libc++_shared.so from the NDK sysroot to gen/android jniLibs + // so the runtime linker can find it at dlopen time (it's now in the + // .so's NEEDED list thanks to cpp_link_stdlib("c++_shared") above). + if let Ok(ndk) = std::env::var("ANDROID_NDK_HOME").or_else(|_| std::env::var("NDK_HOME")) { + let lib_dir = format!( + "{ndk}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android" + ); + println!("cargo:rustc-link-search=native={lib_dir}"); + let shared_so = format!("{lib_dir}/libc++_shared.so"); + if std::path::Path::new(&shared_so).exists() { + let manifest = std::env::var("CARGO_MANIFEST_DIR").unwrap_or_default(); + let jni_dir = format!("{manifest}/gen/android/app/src/main/jniLibs/arm64-v8a"); + if std::fs::create_dir_all(&jni_dir).is_ok() { + let _ = std::fs::copy(&shared_so, format!("{jni_dir}/libc++_shared.so")); + } + } + } } tauri_build::build() diff --git a/desktop/src-tauri/cpp/cpp_smoke.cpp b/desktop/src-tauri/cpp/cpp_smoke.cpp new file mode 100644 index 0000000..092c7ee --- /dev/null +++ b/desktop/src-tauri/cpp/cpp_smoke.cpp @@ -0,0 +1,9 @@ +// cpp_smoke.cpp — original Step E.1 minimal crashing C++ file. +// Compiled with cc::Build::new().cpp(true).cpp_link_stdlib("c++_shared"). +// Never called from Rust (dead-stripped at link time). Used to validate +// the tauri.conf.json minSdkVersion=26 fix against the smallest variant +// that was reliably crashing with __init_tcb+4. + +extern "C" int wzp_cpp_hello(void) { + return 42; +} diff --git a/desktop/src-tauri/tauri.conf.json b/desktop/src-tauri/tauri.conf.json index 745d01e..5a8dea1 100644 --- a/desktop/src-tauri/tauri.conf.json +++ b/desktop/src-tauri/tauri.conf.json @@ -28,6 +28,9 @@ "targets": "all", "icon": [ "icons/icon.png" - ] + ], + "android": { + "minSdkVersion": 26 + } } }