Skip to content

rioam2/wasi-sdk-toolchain

Repository files navigation

wasi-sdk-toolchain

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

Getting started

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

Using wit-bindgen to create a component

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.

About

🔌 Batteries-included CMake toolchain for cross-compiling C/C++ code to wasm32-wasi.

Resources

License

Stars

Watchers

Forks