1# Cross Compiling 2 3When contributing to Wasmtime and Cranelift you may run into issues that only 4reproduce on a different architecture from your development machine. Luckily, 5`cargo` makes cross compilation and running tests under [QEMU] pretty easy. 6 7[QEMU]: https://www.qemu.org/ 8 9This guide will assume you are on an x86-64 with Ubuntu/Debian as your OS. The 10basic approach (with commands, paths, and package names appropriately tweaked) 11applies to other Linux distributions as well. 12 13On Windows you can install build tools for AArch64 Windows, but targeting 14platforms like Linux or macOS is not easy. While toolchains exist for targeting 15non-Windows platforms you'll have to hunt yourself to find the right one. 16 17On macOS you can install, through Xcode, toolchains for iOS but the main 18`x86_64-apple-darwin` is really the only easy target to install. You'll need to 19hunt for toolchains if you want to compile for Linux or Windows. 20 21## Install Rust Targets 22 23First, use `rustup` to install Rust targets for the other architectures that 24Wasmtime and Cranelift support: 25 26```console 27rustup target add \ 28 s390x-unknown-linux-gnu \ 29 riscv64gc-unknown-linux-gnu \ 30 aarch64-unknown-linux-gnu 31``` 32 33## Install GCC Cross-Compilation Toolchains 34 35Next, you'll need to install a `gcc` for each cross-compilation target to serve 36as a linker for `rustc`. 37 38```console 39sudo apt install \ 40 gcc-s390x-linux-gnu \ 41 gcc-riscv64-linux-gnu \ 42 gcc-aarch64-linux-gnu 43``` 44 45## Install `qemu` 46 47You will also need to install `qemu` to emulate the cross-compilation targets. 48 49```console 50sudo apt install qemu-user 51``` 52 53## Configure Cargo 54 55The final bit to get out of the way is to configure `cargo` to use the 56appropriate `gcc` and `qemu` when cross-compiling and running tests for other 57architectures. 58 59You will need to set `CARGO_TARGET_<triple>_RUNNER` and `CARGO_TARGET_<triple>_LINKER` for the target. 60 61* aarch64: 62 63```console 64export 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' 65export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER='aarch64-linux-gnu-gcc' 66``` 67 68* riscv64: 69 70```console 71export 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' 72export CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER='riscv64-linux-gnu-gcc' 73``` 74 75* s390x: 76 77```console 78export 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' 79export CARGO_TARGET_S390X_UNKNOWN_LINUX_GNU_LINKER='s390x-linux-gnu-gcc' 80``` 81 82## Cross-Compile Tests and Run Them! 83 84Now you can use `cargo build`, `cargo run`, and `cargo test` as you normally 85would for any crate inside the Wasmtime repository, just add the appropriate 86`--target` flag! 87 88A few examples: 89 90* Build the `wasmtime` binary for `aarch64`: 91 92 ```console 93 cargo build --target aarch64-unknown-linux-gnu 94 ``` 95 96* Run the tests under `riscv` emulation: 97 98 ```console 99 cargo test --target riscv64gc-unknown-linux-gnu 100 ``` 101 102* Run the `wasmtime` binary under `s390x` emulation: 103 104 ```console 105 cargo run --target s390x-unknown-linux-gnu -- compile example.wasm 106 ``` 107