154a290cdSNick Fitzgerald# Cross Compiling
254a290cdSNick Fitzgerald
354a290cdSNick FitzgeraldWhen contributing to Wasmtime and Cranelift you may run into issues that only
454a290cdSNick Fitzgeraldreproduce on a different architecture from your development machine. Luckily,
554a290cdSNick Fitzgerald`cargo` makes cross compilation and running tests under [QEMU] pretty easy.
654a290cdSNick Fitzgerald
754a290cdSNick Fitzgerald[QEMU]: https://www.qemu.org/
854a290cdSNick Fitzgerald
954a290cdSNick FitzgeraldThis guide will assume you are on an x86-64 with Ubuntu/Debian as your OS. The
1054a290cdSNick Fitzgeraldbasic approach (with commands, paths, and package names appropriately tweaked)
1154a290cdSNick Fitzgeraldapplies to other Linux distributions as well.
1254a290cdSNick Fitzgerald
1354a290cdSNick FitzgeraldOn Windows you can install build tools for AArch64 Windows, but targeting
1454a290cdSNick Fitzgeraldplatforms like Linux or macOS is not easy. While toolchains exist for targeting
1554a290cdSNick Fitzgeraldnon-Windows platforms you'll have to hunt yourself to find the right one.
1654a290cdSNick Fitzgerald
1754a290cdSNick FitzgeraldOn macOS you can install, through Xcode, toolchains for iOS but the main
1854a290cdSNick Fitzgerald`x86_64-apple-darwin` is really the only easy target to install. You'll need to
1954a290cdSNick Fitzgeraldhunt for toolchains if you want to compile for Linux or Windows.
2054a290cdSNick Fitzgerald
2154a290cdSNick Fitzgerald## Install Rust Targets
2254a290cdSNick Fitzgerald
2354a290cdSNick FitzgeraldFirst, use `rustup` to install Rust targets for the other architectures that
2454a290cdSNick FitzgeraldWasmtime and Cranelift support:
2554a290cdSNick Fitzgerald
2692cfda1bSVictor Adossi```console
2792cfda1bSVictor Adossirustup target add \
2854a290cdSNick Fitzgerald    s390x-unknown-linux-gnu \
2954a290cdSNick Fitzgerald    riscv64gc-unknown-linux-gnu \
3054a290cdSNick Fitzgerald    aarch64-unknown-linux-gnu
3154a290cdSNick Fitzgerald```
3254a290cdSNick Fitzgerald
3354a290cdSNick Fitzgerald## Install GCC Cross-Compilation Toolchains
3454a290cdSNick Fitzgerald
3554a290cdSNick FitzgeraldNext, you'll need to install a `gcc` for each cross-compilation target to serve
3654a290cdSNick Fitzgeraldas a linker for `rustc`.
3754a290cdSNick Fitzgerald
3892cfda1bSVictor Adossi```console
3992cfda1bSVictor Adossisudo apt install \
4054a290cdSNick Fitzgerald    gcc-s390x-linux-gnu \
4154a290cdSNick Fitzgerald    gcc-riscv64-linux-gnu \
4254a290cdSNick Fitzgerald    gcc-aarch64-linux-gnu
4354a290cdSNick Fitzgerald```
4454a290cdSNick Fitzgerald
4554a290cdSNick Fitzgerald## Install `qemu`
4654a290cdSNick Fitzgerald
4754a290cdSNick FitzgeraldYou will also need to install `qemu` to emulate the cross-compilation targets.
4854a290cdSNick Fitzgerald
4992cfda1bSVictor Adossi```console
5092cfda1bSVictor Adossisudo apt install qemu-user
5154a290cdSNick Fitzgerald```
5254a290cdSNick Fitzgerald
5354a290cdSNick Fitzgerald## Configure Cargo
5454a290cdSNick Fitzgerald
5554a290cdSNick FitzgeraldThe final bit to get out of the way is to configure `cargo` to use the
5654a290cdSNick Fitzgeraldappropriate `gcc` and `qemu` when cross-compiling and running tests for other
5754a290cdSNick Fitzgeraldarchitectures.
5854a290cdSNick Fitzgerald
59*759ccdfaSMasashi YoshimuraYou will need to set `CARGO_TARGET_<triple>_RUNNER` and `CARGO_TARGET_<triple>_LINKER` for the target.
6054a290cdSNick Fitzgerald
61*759ccdfaSMasashi Yoshimura* aarch64:
6254a290cdSNick Fitzgerald
63*759ccdfaSMasashi Yoshimura```console
64*759ccdfaSMasashi Yoshimuraexport CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_RUNNER='qemu-aarch64 -L /usr/aarch64-linux-gnu -E LD_LIBRARY_PATH=/usr/aarch64-linux-gnu/lib -E WASMTIME_TEST_NO_HOG_MEMORY=1'
65*759ccdfaSMasashi Yoshimuraexport CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER='aarch64-linux-gnu-gcc'
66*759ccdfaSMasashi Yoshimura```
6754a290cdSNick Fitzgerald
68*759ccdfaSMasashi Yoshimura* riscv64:
69*759ccdfaSMasashi Yoshimura
70*759ccdfaSMasashi Yoshimura```console
71*759ccdfaSMasashi Yoshimuraexport CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_RUNNER='qemu-riscv64 -L /usr/riscv64-linux-gnu -E LD_LIBRARY_PATH=/usr/riscv64-linux-gnu/lib -E WASMTIME_TEST_NO_HOG_MEMORY=1'
72*759ccdfaSMasashi Yoshimuraexport CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER='riscv64-linux-gnu-gcc'
73*759ccdfaSMasashi Yoshimura```
74*759ccdfaSMasashi Yoshimura
75*759ccdfaSMasashi Yoshimura* s390x:
76*759ccdfaSMasashi Yoshimura
77*759ccdfaSMasashi Yoshimura```console
78*759ccdfaSMasashi Yoshimuraexport CARGO_TARGET_S390X_UNKNOWN_LINUX_GNU_RUNNER='qemu-s390x -L /usr/s390x-linux-gnu -E LD_LIBRARY_PATH=/usr/s390x-linux-gnu/lib -E WASMTIME_TEST_NO_HOG_MEMORY=1'
79*759ccdfaSMasashi Yoshimuraexport CARGO_TARGET_S390X_UNKNOWN_LINUX_GNU_LINKER='s390x-linux-gnu-gcc'
8054a290cdSNick Fitzgerald```
8154a290cdSNick Fitzgerald
8254a290cdSNick Fitzgerald## Cross-Compile Tests and Run Them!
8354a290cdSNick Fitzgerald
8454a290cdSNick FitzgeraldNow you can use `cargo build`, `cargo run`, and `cargo test` as you normally
8554a290cdSNick Fitzgeraldwould for any crate inside the Wasmtime repository, just add the appropriate
8654a290cdSNick Fitzgerald`--target` flag!
8754a290cdSNick Fitzgerald
8854a290cdSNick FitzgeraldA few examples:
8954a290cdSNick Fitzgerald
9054a290cdSNick Fitzgerald* Build the `wasmtime` binary for `aarch64`:
9154a290cdSNick Fitzgerald
9292cfda1bSVictor Adossi  ```console
9392cfda1bSVictor Adossi  cargo build --target aarch64-unknown-linux-gnu
9454a290cdSNick Fitzgerald  ```
9554a290cdSNick Fitzgerald
9654a290cdSNick Fitzgerald* Run the tests under `riscv` emulation:
9754a290cdSNick Fitzgerald
9892cfda1bSVictor Adossi  ```console
9992cfda1bSVictor Adossi  cargo test --target riscv64gc-unknown-linux-gnu
10054a290cdSNick Fitzgerald  ```
10154a290cdSNick Fitzgerald
10254a290cdSNick Fitzgerald* Run the `wasmtime` binary under `s390x` emulation:
10354a290cdSNick Fitzgerald
10492cfda1bSVictor Adossi  ```console
10592cfda1bSVictor Adossi  cargo run --target s390x-unknown-linux-gnu -- compile example.wasm
10654a290cdSNick Fitzgerald  ```
107