TUTORIAL / 02
Build for other targets
Build native, wasm and mobile bindings, then add each platform to one haxelib package.
1. Build native bindings
Run these commands from the greeter crate created in the first tutorial. Rust and Haxe are required throughout. build generates the binding and prints the Haxe compiler arguments; run also compiles and runs the example app.
| Runtime | Build | Tools to run the app |
|---|---|---|
| HashLink | hxn build hl --release | HashLink, or Ash with --vm ash. |
| hxcpp | hxn build cpp --release | hxcpp from git and a host C++ toolchain. |
| CPPIA | hxn build cppia --release | hxcpp and a C++ toolchain; hxn also builds the script host. |
Use hxn run hl, hxn run cpp or hxn run cppia to execute. hxn run hl --vm "ash --mode jit" selects Ash’s JIT; --mode interp selects its interpreter.
2. Build wasm
HashLink bytecode runs through Ash; hxcpp uses Emscripten. Activate the tools for the runtime you choose before building.
rustup toolchain install nightly --component rust-src
RUSTUP_TOOLCHAIN=nightly hxn build hl --wasm --release
RUSTUP_TOOLCHAIN=nightly hxn run hl --wasm --release --vm ash
Ash must be on PATH. This build recompiles Rust’s standard library with nightly and produces a wasm32-wasip1 binding.
rustup target add wasm32-unknown-emscripten
hxn build cpp --wasm --release
hxn run cpp --wasm --release
Activate the Emscripten SDK so emcc and emar are on PATH. Running also needs Node.js and hxcpp from git with wasm exception support. The binding target is wasm32-unknown-emscripten. CPPIA has no wasm target.
3. Cross-compile a binding
Both hl and cpp build and package mobile bindings. Choose the runtime and Rust triple for your application; rustc --print target-list lists Rust’s built-in targets. Install the chosen triple with rustup target add <triple>. The library’s dependencies must also support that platform.
| Platform | HashLink through Ash | hxcpp |
|---|---|---|
| Linux x86-64 | x86_64-unknown-linux-gnu | x86_64-unknown-linux-gnu |
| Windows x86-64 | x86_64-pc-windows-msvc | x86_64-pc-windows-msvc |
| iOS device | aarch64-apple-ios | aarch64-apple-ios |
| iOS simulator | aarch64-apple-ios-sim | x86_64-apple-ios |
| Android ARM64 | aarch64-linux-android | aarch64-linux-android |
| Android x86-64 emulator | x86_64-linux-android | x86_64-linux-android |
rustup target add aarch64-apple-ios aarch64-apple-ios-sim aarch64-linux-android
hxn doctor --target aarch64-linux-android
hxn build cpp --target aarch64-linux-android --release
hxn build hl --target aarch64-linux-android --release
Both commands produce static libraries: Ash links the hl archive into its executable, and hxcpp links the cpp archive into the app. Building the complete app also needs its platform toolchain: Xcode for iOS, the Android NDK for Android, or the matching desktop linker and SDK. Dependencies that compile C may need those tools during the binding build too. doctor --target checks Rust prerequisites only.
Use --target with build hl, build cpp or package. It cannot be combined with --wasm or cppia. run and check reject cross-compiled targets.
4. Add targets to a package
From the greeter crate, package only the targets you prepared. Reuse the same output directory; each command adds a native/<triple>/ entry and keeps the other platforms.
hxn package hl cpp --release --out ../greeter-haxelib
RUSTUP_TOOLCHAIN=nightly hxn package hl --wasm --release --out ../greeter-haxelib
hxn package cpp --wasm --release --out ../greeter-haxelib
hxn package hl --target aarch64-apple-ios --release --out ../greeter-haxelib
hxn package hl --target aarch64-apple-ios-sim --release --out ../greeter-haxelib
hxn package hl --target aarch64-linux-android --release --out ../greeter-haxelib
hxn package cpp --target aarch64-apple-ios --release --out ../greeter-haxelib
hxn package cpp --target x86_64-apple-ios --release --out ../greeter-haxelib
hxn package cpp --target aarch64-linux-android --release --out ../greeter-haxelib
Use hxn package hl cpp --target <triple> to include both runtimes for the same triple. The repository’s hxcpp simulator runner uses x86-64 (Rosetta on Apple Silicon); Ash targets Apple Silicon simulators natively.
For another desktop’s dynamic HashLink .hdll, run native packaging on that system and combine its native/<triple>/ files with the package. Cross-compiled HashLink bindings are static archives for Ash.
5. Compile the Haxe app for that platform
Register the package with haxelib dev greeter ../greeter-haxelib. Run the following commands from the greeter crate.
HashLink through Ash
Select the packaged triple when compiling Haxe bytecode, then link its static archive with Ash. Choose the build for your device or simulator:
haxe -lib greeter -D hxn_triple=aarch64-linux-android -cp haxe -main Main -hl android.hl
ash --build greeter-android --target aarch64-linux-android --native-lib libgreeter.a android.hl
haxe -lib greeter -D hxn_triple=aarch64-apple-ios-sim -cp haxe -main Main -hl ios-sim.hl
ash --build greeter-ios-sim --target aarch64-apple-ios-sim --native-lib libgreeter.a ios-sim.hl
haxe -lib greeter -D hxn_triple=aarch64-apple-ios -cp haxe -main Main -hl ios.hl
ash --build greeter-ios --target aarch64-apple-ios --native-lib libgreeter.a ios.hl
hxn.Bind copies libgreeter.a beside the bytecode. Use an Ash build with mobile AOT support and a runtime archive for the selected triple. If Ash cannot locate that runtime, add --runtime /path/to/libash_std.a to its build command.
Run the Android executable with adb, or the simulator executable in a booted iOS simulator:
adb push greeter-android /data/local/tmp/
adb shell /data/local/tmp/greeter-android
xcrun simctl spawn booted "$PWD/greeter-ios-sim"
hxcpp
hxcpp’s platform defines select its packaged library. Use the command matching your installed SDK:
haxe -lib greeter -cp haxe -main Main -cpp out/android -D android -D HXCPP_ARM64
haxe -lib greeter -cp haxe -main Main -cpp out/ios -D iphoneos -D HXCPP_ARM64
haxe -lib greeter -cp haxe -main Main -cpp out/ios-sim -D iphonesim -D HXCPP_M64
Link the resulting native library into your Android or iOS app. Mobile compilation needs Xcode or the Android NDK; creating an installable app also requires the platform’s normal application packaging and signing.