From da61693797420c5c16bcc754d758948025bd5be7 Mon Sep 17 00:00:00 2001 From: Solidor777 Date: Fri, 8 May 2026 02:39:23 -0700 Subject: [PATCH 1/2] joltc-sys: native Android cross-compile + host-vs-target /EHsc fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two coupled bugs surfaced when cross-compiling joltc-sys to Android (aarch64-linux-android via NDK r26d clang from a Windows host): 1. `cfg!(windows)` is a HOST-OS check inside build.rs. When targeting Android from Windows, the conditional always fires and adds the MSVC-only `/EHsc` flag to the cmake config — NDK clang then receives `/EHsc` as a path argument and errors out ("error: no such file or directory: '/EHsc'"). Fix: read `CARGO_CFG_TARGET_OS` and only add `/EHsc` when the actual target is windows. 2. Building for Android requires three CMake-side hints that joltc-sys does not currently set: `CMAKE_TOOLCHAIN_FILE` (NDK's `android.toolchain.cmake`), `ANDROID_ABI` (string the toolchain reads — env var alone is ignored), and the generator (Ninja, since cmake-rs defaults to MSBuild on Windows hosts). Fix: when `target_os == "android"`, derive ANDROID_ABI from `CARGO_CFG_TARGET_ARCH` (aarch64 → arm64-v8a, arm → armeabi-v7a, etc.), look up the NDK at `ANDROID_NDK_HOME` / `ANDROID_NDK_ROOT` / `ANDROID_NDK`, and force Ninja. End-user contract after this change: set ANDROID_NDK_HOME, run `cargo ndk --target aarch64-linux-android check -p joltc-sys`. The standard cargo-ndk + nttld/setup-ndk@v1 flow Just Works. Validated locally on Windows-host → aarch64-linux-android with NDK r26d (full JoltPhysics + JoltC compiles in ~20s). 32-bit ARM (armv7-linux-androideabi) hits an unrelated upstream JoltC LAYOUT_COMPATIBLE static_assert (`JPC_*Settings` 16-byte alignment vs `JPH::*Settings` 8-byte alignment on 32-bit ARM) that this PR does not address. --- crates/joltc-sys/build.rs | 53 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/crates/joltc-sys/build.rs b/crates/joltc-sys/build.rs index dc88c67..beaf6dd 100644 --- a/crates/joltc-sys/build.rs +++ b/crates/joltc-sys/build.rs @@ -28,13 +28,64 @@ fn build_joltc() { // features just based on opt-level. config.profile("Release"); + // Read the actual cross-compile target rather than the build host so + // the rest of this fn can dispatch correctly. `cfg!(...)` would + // evaluate at build-script-compile time on the HOST. + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_default(); + let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_default(); + // Jolt fails to compile via the cmake crate without specifying exception // handling behavior under MSVC. I'm not sure that this is the correct // exception handling mode. - if cfg!(windows) { + // + // The original `cfg!(windows)` is a HOST-OS check (build.rs runs on + // the host, so it is always true on Windows). When cross-compiling + // to Android from a Windows host, NDK clang receives `/EHsc` as a + // path argument and errors. Switch to the target check so the flag + // only applies to actual Windows targets. + if target_os == "windows" { config.cxxflag("/EHsc"); } + // Native Android cross-compile setup. Without this, building + // joltc-sys for Android via the standard + // `cargo ndk --target check` flow fails because + // (a) cmake-rs defaults to MSBuild on Windows hosts which can't + // target Android; (b) the NDK's `android.toolchain.cmake` requires + // `ANDROID_ABI` to be set as a CMake variable (env var is + // ignored); (c) `ANDROID_NDK_HOME` is the canonical env name set + // by `nttld/setup-ndk` GitHub Action + cargo-ndk's local + // workflow. + // + // We translate cargo's target arch to NDK's ABI string and route + // CMake through the NDK toolchain file. `ANDROID_PLATFORM=android-21` + // is the same baseline most cargo-ndk users target. + if target_os == "android" { + let android_ndk_home = env::var("ANDROID_NDK_HOME") + .or_else(|_| env::var("ANDROID_NDK_ROOT")) + .or_else(|_| env::var("ANDROID_NDK")) + .expect( + "Android cross-compile requires ANDROID_NDK_HOME (or ANDROID_NDK_ROOT / \ + ANDROID_NDK) to point at the NDK install. Install via \ + `nttld/setup-ndk@v1` in CI or the Android SDK manager locally.", + ); + let toolchain_file = format!("{android_ndk_home}/build/cmake/android.toolchain.cmake"); + config.define("CMAKE_TOOLCHAIN_FILE", &toolchain_file); + let android_abi = match target_arch.as_str() { + "aarch64" => "arm64-v8a", + "arm" => "armeabi-v7a", + "x86" => "x86", + "x86_64" => "x86_64", + _ => panic!("unsupported Android target arch: {target_arch}"), + }; + config.define("ANDROID_ABI", android_abi); + config.define("ANDROID_PLATFORM", "android-21"); + // cmake-rs defaults to the host-OS generator (MSBuild on Win); + // the NDK toolchain only supports Ninja / Makefiles. Force + // Ninja explicitly. + config.generator("Ninja"); + } + // Having IPO/LTO turned on breaks lld on Windows. config.define("INTERPROCEDURAL_OPTIMIZATION", "OFF"); From c4709b6f92b7079abea537d783aa5afbfff70fe7 Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Mon, 11 May 2026 16:39:21 -0400 Subject: [PATCH 2/2] Update build.rs --- crates/joltc-sys/build.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/crates/joltc-sys/build.rs b/crates/joltc-sys/build.rs index beaf6dd..4e0611c 100644 --- a/crates/joltc-sys/build.rs +++ b/crates/joltc-sys/build.rs @@ -37,12 +37,6 @@ fn build_joltc() { // Jolt fails to compile via the cmake crate without specifying exception // handling behavior under MSVC. I'm not sure that this is the correct // exception handling mode. - // - // The original `cfg!(windows)` is a HOST-OS check (build.rs runs on - // the host, so it is always true on Windows). When cross-compiling - // to Android from a Windows host, NDK clang receives `/EHsc` as a - // path argument and errors. Switch to the target check so the flag - // only applies to actual Windows targets. if target_os == "windows" { config.cxxflag("/EHsc"); }