A batteries-included CMake toolchain for cross-compiling C/C++ code to wasm32-wasi (WebAssembly/WASI). Built on top of releases from https://github.com/WebAssembly/wasi-sdk
Add the following cmake file somewhere in your project. For this example, it is named wasi-sdk.toolchain.cmake
in a cmake/wasi-sdk
directory.
include(FetchContent)
# Fetch the WASI toolchain from Github
set(FETCHCONTENT_FULLY_DISCONNECTED_OLD ${FETCHCONTENT_FULLY_DISCONNECTED})
set(FETCHCONTENT_FULLY_DISCONNECTED OFF)
FetchContent_Declare(
wasi_sdk_toolchain
SOURCE_DIR "${CMAKE_BINARY_DIR}/_deps/wasi-sdk"
GIT_REPOSITORY https://github.com/rioam2/wasi-sdk-toolchain.git
GIT_TAG main
)
FetchContent_MakeAvailable(wasi_sdk_toolchain)
set(FETCHCONTENT_FULLY_DISCONNECTED ${FETCHCONTENT_FULLY_DISCONNECTED_OLD})
# Source toolchain file(s)
include("${wasi_sdk_toolchain_SOURCE_DIR}/wasi-sdk.toolchain.cmake")
# Initialize a specific version of the WASI toolchain
# These are example versions, set them as needed for your project
initialize_wasi_toolchain(
WIT_BINDGEN_TAG "v0.29.0" // Version of wit-bindgen for component model c++ binding generation
WASMTIME_TAG "v23.0.1" // Version of wasmtime to use for wasi-v0.2->wasip1 polyfills
WASM_TOOLS_TAG "v1.215.0" // Version of wasm-tools to use for component creation
WASI_SDK_TAG "wasi-sdk-23" // Upstream version of wasi-sdk toolchain
TARGET_TRIPLET "wasm32-wasip1" // Can be set to any of the wasi target triplets supported by wasi-sdk
ENABLE_EXPERIMENTAL_STUBS OFF // Turn on experimental stubs for unsupported libc functionality
)
FETCHCONTENT_FULLY_DISCONNECTED
is forced to off to ensure that the toolchain is always fetched and loaded, regardless of your project's configuration. It is set back to it's original value after the toolchain is loaded.
The tag in this example is set to main
. This is configurable and can be set to any tag within this repository. It is recommended to use a specific tag version to prevent breaking changes affecting your project silently.
Finally, set this CMake cache variable:
cmake ... -DCMAKE_TOOLCHAIN_FILE=path/to/wasi-sdk.toolchain.cmake
The toolchain provides a helper function to generate WebAssembly Interface Type bindings (WIT-bindings) using wit-bindgen
wit_bindgen(
INTERFACE_FILE_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/module.wit"
BINDINGS_DIR_INPUT "${CMAKE_CURRENT_SOURCE_DIR}/bindings"
GENERATED_FILES_OUTPUT wit_codegen_output_files
)
# ...
add_executable(<target> ${wit_codegen_output_files} ...)
# Create a WebAssembly Component
wasm_create_component(
COMPONENT_TARGET <name_of_wasm_component_target>
CORE_WASM_TARGET <target>
COMPONENT_TYPE "reactor"
)
This generates WIT bindings for the .wit
file provided by INTERFACE_FILE_INPUT
. The resulting bindings will be placed in the BINDINGS_DIR_INPUT
directory. Additionally, a list of the generated files will be placed in a list variable given by GENERATED_FILES_OUTPUT
. This list can be provided to a later call to add_executable
as sources/headers to link with your executable.