Issue Summary — BWIOSGdx.xcframework fails to run on iOS Simulator

Background: The app embeds an in-app game feature ("Game Hub" / Fallinmoji) that is written in Java against libGDX and cross-compiled to native code for iOS using RoboVM (via ./gradlew :ios:robovmInstall). The build produces BWIOSGdx.xcframework, which is linked and embedded into the main iOS target.

What we confirmed in the framework itself: The .xcframework does contain two genuinely separate Mach-O slices — one tagged LC_BUILD_VERSION platform=IOS (device) and one tagged platform=IOS SIMULATOR (arm64 simulator), so at the packaging level Xcode sees a proper simulator slice. Despite that, the framework does not run correctly under the Simulator, so our build script deliberately skips building/linking it entirely for iphonesimulator runs ("libGDX is device-only") and the feature is device-only in practice.

Root cause (working theory): RoboVM AOT-compiles JVM bytecode into native ARM64 machine code and relies on hand-written runtime scaffolding (trampolines, dynamic method dispatch, JIT-adjacent code generation) that predates Apple Silicon simulators. That scaffolding appears to assume the calling conventions/execution environment of a physical device and does not behave correctly when executed inside the Simulator's process (which runs under different memory-protection/JIT and code-signing rules than a device). The result is that even though a correctly-tagged simulator slice exists, code compiled by RoboVM's toolchain does not execute reliably there — RoboVM itself has been effectively unmaintained since ~2017 and was never updated for Apple's current arm64 Simulator runtime.

Impact: We cannot build/run/debug the Game Hub feature (and by extension, sometimes the whole app when this framework is force-included) in the Simulator, which blocks fast local iteration, CI-based UI testing, and any workflow that depends on Simulator rather than a provisioned physical device.

Ask for Apple: Is this a known/expected limitation of running JIT-adjacent or non-Apple-toolchain-compiled native code (e.g., from RoboVM or similar Java→native cross-compilers) inside the iOS Simulator on Apple Silicon, versus on a physical device? Is there a supported mechanism (entitlement, code-signing flag, JIT-related capability) that would let such a framework execute correctly under Simulator, or is Simulator execution of dynamically-generated/trampoline-based native code from third-party toolchains fundamentally unsupported?

is Simulator execution of dynamically-generated/trampoline-based native code from third-party toolchains fundamentally unsupported?

It’s not fundamentally unsupported, but rather it has to be supported by the vendor of those tools. If you were that vendor, we could talk about the best way to create a Mach-O shared library that’s compatible with various Apple platforms [1], including the simulator [2]. But you’re the client of such a tool, and my advice in that case is to start with the tool’s vendor first.

Clearly that’s not feasible in this case, so you have a choice:

  • You can move to different tooling.
  • As these tools are open source, you can act like the tool vendor, but that means I’m gonna start asking you questions about how the tool generates code.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] Step 1 being to use the Apple linker to create your Mach-O image, rather than trying to replicate its behaviour.

[2] Keep in mind that Apple tooling treats the simulator as a distinct platform. I talk about this, and a lot more, in An Apple Library Primer.

Issue Summary — BWIOSGdx.xcframework fails to run on iOS Simulator
 
 
Q