Docs: Expand cross compiling section into its own page (#5284)
And fill out everything needed for all non-x64 targets supported by Wasmtime and Cranelift.
This commit is contained in:
@@ -55,6 +55,7 @@
|
|||||||
- [Testing](./contributing-testing.md)
|
- [Testing](./contributing-testing.md)
|
||||||
- [Fuzzing](./contributing-fuzzing.md)
|
- [Fuzzing](./contributing-fuzzing.md)
|
||||||
- [CI](./contributing-ci.md)
|
- [CI](./contributing-ci.md)
|
||||||
|
- [Cross Compiling](./contributing-cross-compiling.md)
|
||||||
- [Coding Guidelines](./contributing-coding-guidelines.md)
|
- [Coding Guidelines](./contributing-coding-guidelines.md)
|
||||||
- [Development Process](./contributing-development-process.md)
|
- [Development Process](./contributing-development-process.md)
|
||||||
- [Release Process](./contributing-release-process.md)
|
- [Release Process](./contributing-release-process.md)
|
||||||
|
|||||||
@@ -82,115 +82,3 @@ there, without needing to supply the `-p` flag:
|
|||||||
cd crates/jit/
|
cd crates/jit/
|
||||||
cargo build
|
cargo build
|
||||||
```
|
```
|
||||||
|
|
||||||
## Cross Compiling Wasmtime
|
|
||||||
|
|
||||||
By default `cargo build` will build Wasmtime for the platform you're running the
|
|
||||||
build on. You might, however, want to build Wasmtime for a different platform!
|
|
||||||
Let's say for example that you want to build Wasmtime for
|
|
||||||
`aarch64-unknown-linux-gnu`. First you'll want to acquire the Rust standard
|
|
||||||
library for this target:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
rustup target add aarch64-unknown-linux-gnu
|
|
||||||
```
|
|
||||||
|
|
||||||
Next you need to install a native C toolchain which has a C compiler, runtime
|
|
||||||
libraries, and linker for the desired target. This is unfortunately not very
|
|
||||||
easy to acquire on most platforms:
|
|
||||||
|
|
||||||
* On Windows you can install build tools for AArch64 Windows, but targeting
|
|
||||||
platforms like Linux or macOS is not easy. While toolchains exist for
|
|
||||||
targeting non-Windows platforms you'll have to hunt yourself to find the right
|
|
||||||
one.
|
|
||||||
|
|
||||||
* On macOS you can install, through Xcode, toolchains for iOS but the main
|
|
||||||
`x86_64-apple-darwin` is really the only easy target to install. You'll need
|
|
||||||
to hunt for toolchains if you want to compile for Linux or Windows.
|
|
||||||
|
|
||||||
* On Linux you can relatively easily compile for other Linux architectures most
|
|
||||||
of the time. For example on Debian-based distributions you can install the
|
|
||||||
`gcc-aarch64-linux-gnu` package which should come with the C compiler, runtime
|
|
||||||
libraries, and linker all in one (assuming you don't explicitly request
|
|
||||||
disabling recommended packages). Other Linux distributions may have
|
|
||||||
differently named toolchains. Compiling for macOS from Linux will require
|
|
||||||
finding your own toolchain. Compiling for Windows MSVC will require finding
|
|
||||||
your own toolchain, but compiling for MinGW can work easily enough if you
|
|
||||||
install the MinGW toolchain via your package manager.
|
|
||||||
|
|
||||||
For now we'll assume you're on Linux compiling for a different Linux
|
|
||||||
architecture. Once you've got the native toolchain, you'll want to find the C
|
|
||||||
compiler that came with it. On Debian, for example, this is called
|
|
||||||
`aarch64-linux-gnu-gcc`. Next up you'll need to configure two environment
|
|
||||||
variables to configure the Rust build:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
|
|
||||||
export CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
|
|
||||||
```
|
|
||||||
|
|
||||||
The first environment variable tells Cargo to tell rustc what the correct linker
|
|
||||||
for your target is. The second configures the [`cc` Rust
|
|
||||||
crate](https://crates.io/crates/cc) for C code compiled as part of the build.
|
|
||||||
|
|
||||||
Finally you can execute.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
cargo build --target aarch64-unknown-linux-gnu --release
|
|
||||||
```
|
|
||||||
|
|
||||||
The built executable will be located at
|
|
||||||
`target/aarch64-unknown-linux-gnu/release/wasmtime`. Note that you can
|
|
||||||
cross-compile the C API in the same manner as the CLI too.
|
|
||||||
|
|
||||||
Note that if you are using these invocations regularly, you can avoid the need
|
|
||||||
to set environment variables by adding some configuration to your persistent
|
|
||||||
Cargo configuration. In the file `~/.cargo/config.toml` (in your home
|
|
||||||
directory), add the section:
|
|
||||||
|
|
||||||
```plain
|
|
||||||
[target.aarch64-unknown-linux-gnu]
|
|
||||||
linker = 'aarch64-linux-gnu-gcc'
|
|
||||||
```
|
|
||||||
|
|
||||||
Then the above `cargo build --target aarch64-unknown-linux-gnu` command should
|
|
||||||
work without setting any extra environment variables beforehand.
|
|
||||||
|
|
||||||
## Running a Cross-Compiled Wasmtime in qemu (emulation)
|
|
||||||
|
|
||||||
Once you have cross-compiled a binary, it is possible to run it on an emulator
|
|
||||||
if you do not have access to (or do not wish to use) hardware with the given
|
|
||||||
architecture. This can be done using an emulator such as `qemu`. The `qemu`
|
|
||||||
user-space emulation support allows running, for example, a Linux/aarch64
|
|
||||||
binary on a Linux/x86-64 host, as long as you have the system libraries for
|
|
||||||
aarch64 as well.
|
|
||||||
|
|
||||||
To try this out, first install `qemu`, making sure that the user-space emulator
|
|
||||||
option for your target architecture is enabled. On Debian-based Linux
|
|
||||||
distributions (including Ubuntu), this is in the `qemu-user` package, for
|
|
||||||
example.
|
|
||||||
|
|
||||||
Next, make sure that you have system libraries for the target. You will already
|
|
||||||
have these present if you cross-compiled as described above.
|
|
||||||
|
|
||||||
Finally, you can run the `wasmtime` binary under `qemu`; the following example
|
|
||||||
is for an `aarch64` target. Adjust the library paths as appropriate; these are
|
|
||||||
correct for Ubuntu/Debian's cross-compilation packages.
|
|
||||||
|
|
||||||
```shell
|
|
||||||
qemu-aarch64 \
|
|
||||||
-L /usr/aarch64-linux-gnu \
|
|
||||||
-E LD_LIBRARY_PATH=/usr/aarch64-linux-gnu/lib \
|
|
||||||
target/aarch64-unknown-linux-gnu/release/wasmtime [ARGS]
|
|
||||||
```
|
|
||||||
|
|
||||||
You can add this to your persistent Cargo configuration as well. Extending the
|
|
||||||
above example in `~/.cargo/config.toml`, you can add:
|
|
||||||
|
|
||||||
```plain
|
|
||||||
[target.aarch64-unknown-linux-gnu]
|
|
||||||
linker = 'aarch64-linux-gnu-gcc'
|
|
||||||
runner = "qemu-aarch64 -L /usr/aarch64-linux-gnu -E LD_LIBRARY_PATH=/usr/aarch64-linux-gnu/lib"
|
|
||||||
```
|
|
||||||
|
|
||||||
Then a simple `cargo test --target aarch64-unknown-linux-gnu` should work.
|
|
||||||
|
|||||||
100
docs/contributing-cross-compiling.md
Normal file
100
docs/contributing-cross-compiling.md
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# Cross Compiling
|
||||||
|
|
||||||
|
When contributing to Wasmtime and Cranelift you may run into issues that only
|
||||||
|
reproduce on a different architecture from your development machine. Luckily,
|
||||||
|
`cargo` makes cross compilation and running tests under [QEMU] pretty easy.
|
||||||
|
|
||||||
|
[QEMU]: https://www.qemu.org/
|
||||||
|
|
||||||
|
This guide will assume you are on an x86-64 with Ubuntu/Debian as your OS. The
|
||||||
|
basic approach (with commands, paths, and package names appropriately tweaked)
|
||||||
|
applies to other Linux distributions as well.
|
||||||
|
|
||||||
|
On Windows you can install build tools for AArch64 Windows, but targeting
|
||||||
|
platforms like Linux or macOS is not easy. While toolchains exist for targeting
|
||||||
|
non-Windows platforms you'll have to hunt yourself to find the right one.
|
||||||
|
|
||||||
|
On macOS you can install, through Xcode, toolchains for iOS but the main
|
||||||
|
`x86_64-apple-darwin` is really the only easy target to install. You'll need to
|
||||||
|
hunt for toolchains if you want to compile for Linux or Windows.
|
||||||
|
|
||||||
|
## Install Rust Targets
|
||||||
|
|
||||||
|
First, use `rustup` to install Rust targets for the other architectures that
|
||||||
|
Wasmtime and Cranelift support:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ rustup target add \
|
||||||
|
s390x-unknown-linux-gnu \
|
||||||
|
riscv64gc-unknown-linux-gnu \
|
||||||
|
aarch64-unknown-linux-gnu
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install GCC Cross-Compilation Toolchains
|
||||||
|
|
||||||
|
Next, you'll need to install a `gcc` for each cross-compilation target to serve
|
||||||
|
as a linker for `rustc`.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ sudo apt install \
|
||||||
|
gcc-s390x-linux-gnu \
|
||||||
|
gcc-riscv64-linux-gnu \
|
||||||
|
gcc-aarch64-linux-gnu
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install `qemu`
|
||||||
|
|
||||||
|
You will also need to install `qemu` to emulate the cross-compilation targets.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ sudo apt install qemu-user
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configure Cargo
|
||||||
|
|
||||||
|
The final bit to get out of the way is to configure `cargo` to use the
|
||||||
|
appropriate `gcc` and `qemu` when cross-compiling and running tests for other
|
||||||
|
architectures.
|
||||||
|
|
||||||
|
Add this to `.cargo/config.toml` in the Wasmtime repository (or create that file
|
||||||
|
if none already exists).
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[target.aarch64-unknown-linux-gnu]
|
||||||
|
linker = "aarch64-linux-gnu-gcc"
|
||||||
|
runner = "qemu-aarch64 -L /usr/aarch64-linux-gnu -E LD_LIBRARY_PATH=/usr/aarch64-linux-gnu/lib -E WASMTIME_TEST_NO_HOG_MEMORY=1"
|
||||||
|
|
||||||
|
[target.riscv64gc-unknown-linux-gnu]
|
||||||
|
linker = "riscv64-linux-gnu-gcc"
|
||||||
|
runner = "qemu-riscv64 -L /usr/riscv64-linux-gnu -E LD_LIBRARY_PATH=/usr/riscv64-linux-gnu/lib -E WASMTIME_TEST_NO_HOG_MEMORY=1"
|
||||||
|
|
||||||
|
[target.s390x-unknown-linux-gnu]
|
||||||
|
linker = "s390x-linux-gnu-gcc"
|
||||||
|
runner = "qemu-s390x -L /usr/s390x-linux-gnu -E LD_LIBRARY_PATH=/usr/s390x-linux-gnu/lib -E WASMTIME_TEST_NO_HOG_MEMORY=1"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cross-Compile Tests and Run Them!
|
||||||
|
|
||||||
|
Now you can use `cargo build`, `cargo run`, and `cargo test` as you normally
|
||||||
|
would for any crate inside the Wasmtime repository, just add the appropriate
|
||||||
|
`--target` flag!
|
||||||
|
|
||||||
|
A few examples:
|
||||||
|
|
||||||
|
* Build the `wasmtime` binary for `aarch64`:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ cargo build --target aarch64-unknown-linux-gnu
|
||||||
|
```
|
||||||
|
|
||||||
|
* Run the tests under `riscv` emulation:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ cargo test --target riscv64gc-unknown-linux-gnu
|
||||||
|
```
|
||||||
|
|
||||||
|
* Run the `wasmtime` binary under `s390x` emulation:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ cargo run --target s390x-unknown-linux-gnu -- compile example.wasm
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user