Summary
Enable multiple toolchain bundles in the same workspace, allowing components targeting different WASI versions (e.g., Preview2 and Preview3) to coexist and build together.
Current State
- Single global bundle selection via
wasm_component_bundle.configure(bundle = "stable-2025-12")
- All toolchain repositories are singletons (
@wasm_tools_toolchains, @wasmtime_toolchain, etc.)
- Cannot have different components use different tool versions in the same build
Use Case
# User wants BOTH in the same workspace:
rust_wasm_component(
name = "legacy_component",
wasi_version = "preview2", # Uses wasm-tools 1.243.0, wasmtime 39.0.1
srcs = ["legacy.rs"],
)
rust_wasm_component(
name = "new_component",
wasi_version = "preview3", # Uses wasm-tools 2.0.0, wasmtime 40.0.0
srcs = ["modern.rs"],
)
# Both build in same `bazel build` invocation
Proposed Architecture
Layer 1: Constraint Definitions
# //platforms/BUILD.bazel
constraint_setting(
name = "wasi_version",
default_constraint_value = ":preview2",
)
constraint_value(name = "preview2", constraint_setting = ":wasi_version")
constraint_value(name = "preview3", constraint_setting = ":wasi_version")
Layer 2: Named Bundle Instances
# MODULE.bazel
wasm_bundle.configure(name = "preview2", bundle = "stable-2025-12")
wasm_bundle.configure(name = "preview3", bundle = "experimental-preview3")
# Creates separate repositories:
# @wasm_tools_preview2, @wasmtime_preview2, ...
# @wasm_tools_preview3, @wasmtime_preview3, ...
Layer 3: Constraint-Based Toolchain Registration
Each bundle's toolchain registered with target_compatible_with:
# Generated in @wasm_tools_preview2//:BUILD.bazel
toolchain(
name = "wasm_tools_toolchain",
target_compatible_with = ["@rules_wasm_component//platforms:preview2"],
toolchain = ":wasm_tools_toolchain_impl",
toolchain_type = "@rules_wasm_component//toolchains:wasm_tools_toolchain_type",
)
Layer 4: Rule Transitions
Rules get wasi_version attribute that triggers configuration transition:
rust_wasm_component = rule(
attrs = {
"wasi_version": attr.string(default = "preview2", values = ["preview2", "preview3"]),
},
cfg = wasi_version_transition, # Transition sets //platforms:wasi_version
toolchains = ["//toolchains:wasm_tools_toolchain_type"],
)
Architecture Diagram
MODULE.bazel
│ wasm_bundle.configure(name = "preview2", bundle = "stable-2025-12")
│ wasm_bundle.configure(name = "preview3", bundle = "experimental-p3")
▼
┌─────────────────────────────────────────────────────────────────┐
│ CONSTRAINT DEFINITIONS │
│ constraint_setting(name = "wasi_version") │
│ constraint_value(name = "preview2") │
│ constraint_value(name = "preview3") │
└─────────────────────────────────────────────────────────────────┘
│ │
▼ ▼
┌─────────────────────┐ ┌─────────────────────┐
│ @wasm_tools_preview2│ │ @wasm_tools_preview3│
│ wasm-tools 1.243.0 │ │ wasm-tools 2.0.0 │
│ target_compatible │ │ target_compatible │
│ = [":preview2"] │ │ = [":preview3"] │
└─────────────────────┘ └─────────────────────┘
│ │
└─────────────┬───────────────────────┘
▼
┌─────────────────────────────────────────────────────────────────┐
│ BUILD.bazel │
│ rust_wasm_component(name = "p2", wasi_version = "preview2") │
│ rust_wasm_component(name = "p3", wasi_version = "preview3") │
│ # Bazel toolchain resolution picks correct version! │
└─────────────────────────────────────────────────────────────────┘
Implementation Tasks
Files to Modify
| File |
Change |
platforms/BUILD.bazel |
New: constraint definitions |
wasm/extensions.bzl |
Named bundle instances |
toolchains/*_toolchain.bzl |
Add target_compatible_with to generated BUILD |
rust/defs.bzl |
Add wasi_version attr + transition |
cpp/defs.bzl |
Add wasi_version attr + transition |
go/defs.bzl |
Add wasi_version attr + transition |
js/defs.bzl |
Add wasi_version attr + transition |
Benefits
- Same BUILD file can have preview2 and preview3 components
- Bazel's toolchain resolution handles version selection automatically
- Works with caching - different configurations cached separately
- Future-proof for preview4, etc.
- Enables gradual migration between WASI versions
Impact
- Effort: Medium-High (~15-20 hours)
- Risk: Medium (touches all component rules)
- Value: High (enables WASI version migration paths)
Related
Summary
Enable multiple toolchain bundles in the same workspace, allowing components targeting different WASI versions (e.g., Preview2 and Preview3) to coexist and build together.
Current State
wasm_component_bundle.configure(bundle = "stable-2025-12")@wasm_tools_toolchains,@wasmtime_toolchain, etc.)Use Case
Proposed Architecture
Layer 1: Constraint Definitions
Layer 2: Named Bundle Instances
Layer 3: Constraint-Based Toolchain Registration
Each bundle's toolchain registered with
target_compatible_with:Layer 4: Rule Transitions
Rules get
wasi_versionattribute that triggers configuration transition:Architecture Diagram
Implementation Tasks
//platforms/BUILD.bazelwith constraint_setting and constraint_valueswasm/extensions.bzlto support named bundle instancestarget_compatible_withwasi_versionattribute to all component rules (rust, cpp, go, js)register_toolchains()to register all bundle variantsFiles to Modify
platforms/BUILD.bazelwasm/extensions.bzltoolchains/*_toolchain.bzlrust/defs.bzlcpp/defs.bzlgo/defs.bzljs/defs.bzlBenefits
Impact
Related