bytecodealliance / bytecodealliance/wasmtime

wasmtime-wasi: `p1` cannot be used without `wasmtime/async`, requiring a C toolchain for sync-only embedders

Open
#14,288 4 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
18.6k
Forks
1.8k
Avg merge
1d 18h
Merged PRs (30d)
126

Description

### Summary

`wasmtime-wasi`'s `p1` feature cannot be enabled without also enabling `wasmtime/async`, which pulls in `wasmtime-internal-fiber` and therefore requires a working C toolchain. Embedders that use only the synchronous WASIp1 API pay that cost for a capability they never touch.

### The chain

In `wasmtime-wasi` 48.0.1:

```toml
[features]
default = ["p1", "p2"]
p0 = ["p1"]
p1 = ["dep:wiggle", "p2"]
p2 = ["wasmtime/component-model", "wasmtime/async"]
```

`p1` requires `p2`, and `p2` enables `wasmtime/async`. In `wasmtime` 48.0.1:

```toml
async = [
"dep:wasmtime-fiber",
"wasmtime-component-macro?/async",
"runtime",
]
```

And `wasmtime-internal-fiber` 48.0.1 ships `src/windows.c`, compiled through `cc` in its build script. So enabling `p1` transitively makes a pure-Rust build into one that needs a C compiler.

There is no feature combination that avoids this: `default-features = false, features = ["p1"]` still reaches `wasmtime/async` through `p2`.

### Why this is surprising

`p1`'s own module documentation describes the relationship as incidental rather than semantic:

> Support for WASIp1 is built on top of support for WASIp2 available at [the crate root](crate), but that's just an internal implementation detail.

And `p1` offers `add_to_linker_sync` alongside `add_to_linker_async`, so a fully synchronous embedder is a first-class supported use case. Our embedding uses `p1::add_to_linker_sync` and contains no `call_async` or `async_support` anywhere, yet still requires fibers.

### Concrete impact

We distribute a compiler toolchain that embeds Wasmtime to run WASIp1 guest modules. On Windows the fiber dependency turns "download our release and run it" into "download our release and also install Visual Studio Build Tools or MinGW-w64", solely to build a feature we never call. For a language toolchain trying to offer a self-contained install, that is a significant prerequisite to inherit from an unused code path.

This is not Windows-specific in principle — it is a C toolchain requirement for every sync-only embedder on every host — but Windows is where it is most visible, because a C compiler is not present by default.

### Request

Could `p1` be usable without `wasmtime/async`? Two shapes that would work, without preference between them:

- Split `p2` so `wasmtime/component-model` and `wasmtime/async` can be enabled independently, letting `p1` depend only on the former.
- Give `wasmtime-wasi` an `async` feature, default-on for compatibility, that `default-features = false` can switch off, with `add_to_linker_async` gated behind it.

If the `p1` → `p2` → `async` path is load-bearing rather than incidental, that would be useful to know too — we would then document the C toolchain as a permanent prerequisite rather than waiting on it.

### Happy to help

We have a native Windows x64 environment set up and can test a patch on both the sync path and the removal of the C-compiler requirement.

### Versions

Observed on `wasmtime-wasi` 48.0.1 and `wasmtime` 48.0.1; the same relationship holds in 46.0.3 and 47.0.4. In 36.x the coupling was even tighter — `async` was hardcoded in `[dependencies.wasmtime]` rather than feature-gated — so this has already improved, and the remaining step is the `p1` → `p2` edge.

Contributor guide

Open the contributing guide

Research direction

Start by inspecting the wasmtime-wasi and wasmtime Cargo feature definitions for the p1 → p2 → async chain, then trace how add_to_linker_sync and add_to_linker_async are gated. Verify feature resolution for a sync-only embedder without a C toolchain. Done means p1 remains usable synchronously without enabling async while existing default and async behavior remains compatible.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, wasm
Domain
build-system, developer-experience
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.