Skip to content

joltc-sys: native iOS cross-compile (stacked on #12)#13

Open
Solidor777 wants to merge 2 commits into
SecondHalfGames:mainfrom
Solidor777:ios-cross-compile
Open

joltc-sys: native iOS cross-compile (stacked on #12)#13
Solidor777 wants to merge 2 commits into
SecondHalfGames:mainfrom
Solidor777:ios-cross-compile

Conversation

@Solidor777
Copy link
Copy Markdown
Contributor

Stacked on #12 — adds an iOS branch alongside the Android branch covered there. From a macOS host:

cargo check --target aarch64-apple-ios -p joltc-sys
cargo check --target aarch64-apple-ios-sim -p joltc-sys

Both succeed with no extra env-var setup.

Problem

Without an iOS branch in joltc-sys/build.rs, the standard cargo iOS cross-compile flow fails in two distinct places:

1. CMake builds against the macOS SDK

cmake-rs picks the macOS SDK by default on a macOS host. The resulting static libs link against macOS-only symbols and fail at the rust-side link step with undefined symbol for every iOS-specific runtime entry point. Need to set CMAKE_SYSTEM_NAME=iOS + CMAKE_OSX_SYSROOT (iphoneos for device vs iphonesimulator for simulator) + CMAKE_OSX_ARCHITECTURES + CMAKE_OSX_DEPLOYMENT_TARGET.

Cargo distinguishes the simulator at the target-triple level via CARGO_CFG_TARGET_ABI=simaarch64-apple-ios-sim sets it, aarch64-apple-ios doesn't. Mirror that on the CMake side.

2. bindgen passes rustc's TARGET to clang verbatim

rustc's iOS-simulator triple aarch64-apple-ios-sim is invalid clang syntax — clang errors with version 'sim' in target triple is invalid. Translate to clang's recognised form (arm64-apple-ios-simulator for sim, arm64-apple-ios for device) and supply the matching SDK sysroot via xcrun --show-sdk-path so iOS system headers (stdint.h, etc.) resolve correctly.

Fix

Two coupled additions:

  • build_joltc() iOS branch. Sets the four CMake variables above; forces Ninja so the build is generator-agnostic on macos CI runners.
  • generate_bindings() clang-target translation. Maps rustc → clang triples for iOS targets and passes --target + -isysroot to bindgen.

Desktop targets unaffected (iOS branch gated on target_os == "ios").

Validation

  • cargo check --target aarch64-apple-ios -p joltc-sys on macOS host (Xcode 16.4, iPhoneOS 18.5 SDK): succeeds.
  • cargo check --target aarch64-apple-ios-sim -p joltc-sys: succeeds.
  • Downstream Titan engine's titan-jolt-3d builds against both iOS targets in CI on macos-latest — see Solidor777/Titan run 25579111428.

Stacking

Stacked on #12 (android-cross-compile-and-target-os-fix) to share the host-vs-target awareness scaffolding. Either PR can merge first — the iOS branch is a strict additive layer. If #12 merges first, this PR auto-narrows.

Test plan

  • cargo check --target aarch64-apple-ios -p joltc-sys on macOS host
  • cargo check --target aarch64-apple-ios-sim -p joltc-sys on macOS host
  • cargo check -p joltc-sys (default host target) — unaffected
  • iOS device hardware test — out of scope for this PR (cross-compile gate only)

Solidor777 added 2 commits May 8, 2026 02:39
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.
Adds an iOS branch alongside the Android branch from SecondHalfGames#12. Covers both
`aarch64-apple-ios` (device) and `aarch64-apple-ios-sim` (simulator on
Apple Silicon hosts); `x86_64-apple-ios` is the legacy Intel-Mac
simulator path. From a macOS host:

```sh
cargo check --target aarch64-apple-ios -p joltc-sys
cargo check --target aarch64-apple-ios-sim -p joltc-sys
```

Both succeed with no extra env-var setup.

## Two coupled fixes

1. **`build_joltc()` iOS branch.** Sets `CMAKE_SYSTEM_NAME=iOS`,
   `CMAKE_OSX_SYSROOT` (`iphoneos` for device vs `iphonesimulator` for
   simulator, distinguished via `CARGO_CFG_TARGET_ABI=sim`),
   `CMAKE_OSX_ARCHITECTURES` from `target_arch`, and
   `CMAKE_OSX_DEPLOYMENT_TARGET=12.0`. Forces Ninja so the build is
   generator-agnostic on macos CI runners.

2. **`generate_bindings()` clang-target translation.** bindgen passes
   rustc's TARGET to clang verbatim. rustc's iOS-simulator triple
   `aarch64-apple-ios-sim` is invalid clang syntax — clang errors with
   `version 'sim' in target triple is invalid`. Translate to clang's
   recognised form (`arm64-apple-ios-simulator` for sim, `arm64-apple-ios`
   for device) and supply the matching SDK sysroot via `xcrun
   --show-sdk-path` so iOS system headers (stdint.h, etc.) resolve.

## Validation

- `cargo check --target aarch64-apple-ios -p joltc-sys` on macOS host
  (Xcode 16.4, iPhoneOS 18.5 SDK): succeeds.
- `cargo check --target aarch64-apple-ios-sim -p joltc-sys`: succeeds.
- Downstream Titan engine's `titan-jolt-3d` builds against both iOS
  targets in CI on `macos-latest`.
- Desktop targets unaffected (iOS branch gated on `target_os == "ios"`).

## Stacking note

This PR is stacked on SecondHalfGames#12 (`android-cross-compile-and-target-os-fix`)
to share the host-vs-target awareness scaffolding. Either PR can merge
first — the iOS branch is a strict additive layer.
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