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