# Building This section describes everything required to build and run Wasmtime. ## Prerequisites Before we can actually build Wasmtime, we'll need to make sure these things are installed first. ### Git Submodules The Wasmtime repository contains a number of git submodules. To build Wasmtime and most other crates in the repository, you have to ensure that those are initialized with this command: ```shell git submodule update --init ``` ### The Rust Toolchain [Install the Rust toolchain here.](https://www.rust-lang.org/tools/install) This includes `rustup`, `cargo`, `rustc`, etc... ### `libclang` (optional) The `wasmtime-fuzzing` crate transitively depends on `bindgen`, which requires that your system has a `libclang` installed. Therefore, if you want to hack on Wasmtime's fuzzing infrastructure, you'll need `libclang`. [Details on how to get `libclang` and make it available for `bindgen` are here.](https://rust-lang.github.io/rust-bindgen/requirements.html#clang) ## Building the `wasmtime` CLI To make an unoptimized, debug build of the `wasmtime` CLI tool, go to the root of the repository and run this command: ```shell cargo build ``` The built executable will be located at `target/debug/wasmtime`. To make an optimized build, run this command in the root of the repository: ```shell cargo build --release ``` The built executable will be located at `target/release/wasmtime`. You can also build and run a local `wasmtime` CLI by replacing `cargo build` with `cargo run`. ## Building the Wasmtime C API To build the C API of Wasmtime you can run: ```shell cargo build --release --manifest-path crates/c-api/Cargo.toml ``` This will place the shared library inside of `target/release`. On Linux it will be called `libwasmtime.{a,so}`, on macOS it will be called `libwasmtime.{a,dylib}`, and on Windows it will be called `wasmtime.{lib,dll,dll.lib}`. ## Building Other Wasmtime Crates You can build any of the Wasmtime crates by appending `-p wasmtime-whatever` to the `cargo build` invocation. For example, to build the `wasmtime-jit` crate, execute this command: ```shell cargo build -p wasmtime-jit ``` Alternatively, you can `cd` into the crate's directory, and run `cargo build` there, without needing to supply the `-p` flag: ```shell cd crates/jit/ 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.