This repository contains a C++ ABI implementation of the WebAssembly Component Model.
- Ubuntu 24.04
- MacOS 13
- MacOS 14 (Arm)
- Windows 2019
- Windows 2022
- Bool
- S8
- U8
- S16
- U16
- S32
- U32
- S64
- U64
- F32
- F64
- Char
- Strings (UTF-8, UTF-16, Latin-1+UTF-16)
- List
- Record
- Tuple
- Variant
- Enum
- Option
- Result
- Flags
- Streams (readable/writable)
- Futures (readable/writable)
- Own
- Borrow
- lower_flat_values
- lift_flat_values
- ABI
- WasmTime
- Wamr
- WasmEdge
When expanding the canonical ABI surface, cross-check the Python reference tests in ref/component-model/design/mvp/canonical-abi/run_tests.py; new host features should mirror the behaviors exercised there.
- CMake 3.5 or higher (3.22+ recommended for presets)
- C++20 compatible compiler
- vcpkg for dependency management
- Rust toolchain with
cargo(for additional tools)
Ubuntu/Linux:
sudo apt-get install -y autoconf autoconf-archive automake build-essential ninja-buildmacOS:
brew install pkg-config autoconf autoconf-archive automake coreutils libtool cmake ninjaWindows:
- Visual Studio 2019 or 2022 with C++ support
cargo install wasm-tools wit-bindgen-cliFor header-only usage without tests or samples:
git clone https://github.com/LexisNexis-GHCPE/component-model-cpp.git
cd component-model-cpp
git submodule update --init --recursive
mkdir build && cd build
cmake .. -DBUILD_TESTING=OFF -DBUILD_SAMPLES=OFF
cmake --build .Using CMake presets with vcpkg:
git clone https://github.com/LexisNexis-GHCPE/component-model-cpp.git
cd component-model-cpp
git submodule update --init --recursive
# Configure and build
cmake --preset linux-ninja-Debug
cmake --build --preset linux-ninja-Debug
# Run tests
cd build && ctest -VVgit clone https://github.com/LexisNexis-GHCPE/component-model-cpp.git
cd component-model-cpp
git submodule update --init --recursive
# Configure and build
cmake --preset vcpkg-VS-17
cmake --build --preset VS-17-Debug
# Run tests
cd build && ctest -C Debug -VVgit clone https://github.com/LexisNexis-GHCPE/component-model-cpp.git
cd component-model-cpp
git submodule update --init --recursive
# Configure and build
cmake --preset linux-ninja-Debug
cmake --build --preset linux-ninja-Debug
# Run tests
cd build && ctest -VVIf you prefer not to use CMake presets:
mkdir build && cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build .
ctest -VV # Run tests-DBUILD_TESTING=ON/OFF- Enable/disable building tests (requires doctest, ICU)-DBUILD_SAMPLES=ON/OFF- Enable/disable building samples (requires wasi-sdk)-DCMAKE_BUILD_TYPE=Debug/Release/RelWithDebInfo/MinSizeRel- Build configuration
This library is a header only library. To use it in your project, you can:
- Copy the contents of the
includedirectory to your project. - Use
vcpkgto install the library and its dependencies.
The canonical Component Model runtime is cooperative: hosts must drive pending work by scheduling tasks explicitly. cmcpp now provides a minimal async harness in cmcpp/runtime.hpp:
Storeowns the pending task queue and exposesinvokeplustick().FuncInstis the callable signature hosts use to wrap guest functions.Thread::createbuilds a pending task with user-supplied readiness/resume callbacks.Call::from_threadreturns a cancellation-capable handle to the caller.Taskcoordinates canonical backpressure,canon_task.{return,cancel}, andcanon_yieldhelpers exposed throughcontext.hpp.canon_backpressure_{set,inc,dec}update in-flight counters; most canonical entry points now guardComponentInstance::may_leavebefore touching guest state.
Typical usage:
cmcpp::Store store;
cmcpp::FuncInst func = [](cmcpp::Store &store,
cmcpp::SupertaskPtr,
cmcpp::OnStart on_start,
cmcpp::OnResolve on_resolve) {
auto args = std::make_shared<std::vector<std::any>>(on_start());
auto gate = std::make_shared<std::atomic<bool>>(false);
auto thread = cmcpp::Thread::create(
store,
[gate]() { return gate->load(); },
[args, on_resolve](bool cancelled) {
on_resolve(cancelled ? std::nullopt : std::optional{*args});
return false; // finished
},
true,
[gate]() { gate->store(true); });
return cmcpp::Call::from_thread(thread);
};
auto call = store.invoke(func, nullptr, [] { return std::vector<std::any>{}; }, [](auto) {});
// Drive progress
store.tick();The canonical async ABI surfaces are implemented via canon_waitable_*, canon_stream_*, and canon_future_* helpers on ComponentInstance. Waitable sets can be joined to readable/writable stream ends or futures, and canon_waitable_set_poll reports readiness using the same event payload layout defined by the spec. See the doctests in test/main.cpp for end-to-end examples.
Call tick() in your host loop until all pending work completes. Cancellation is cooperative: calling Call::request_cancellation() marks the associated thread as cancelled before the next tick().
- Component Model design and specification: Official Component Model specification.
- wit-bindgen c++ host: C++ host support for the WebAssembly Interface Types (WIT) Bindgen tool.
