Skip to content

Commit b191454

Browse files
committed
fix: resolve C++ component toolchain integration
Complete C++ WebAssembly component toolchain implementation: • Add cpp_component extension registration to MODULE.bazel • Fix WASI SDK v25+ URL format and stripPrefix configuration • Implement proper sysroot setup for downloaded WASI SDK • Add platform transitions (wasm_transition) to C++ component rules • Reference wit-bindgen and wasm-tools from existing WASM toolchain • Fix absolute paths in clang/clang++ wrapper scripts • Resolve WIT syntax errors (reserved keyword 'result', naming conflicts) The C++ component toolchain now successfully: - Downloads WASI SDK 25.0 with correct platform-specific URLs - Generates C/C++ WIT bindings using wit-bindgen - Compiles C++ code to WebAssembly with WASI Preview 2 support - Integrates with existing WASM toolchain infrastructure
1 parent 1ea2644 commit b191454

File tree

5 files changed

+141
-46
lines changed

5 files changed

+141
-46
lines changed

MODULE.bazel

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,17 @@ use_repo(wizer, "wizer_toolchain")
106106

107107
register_toolchains("@wizer_toolchain//:wizer_toolchain_def")
108108

109+
# C++ WebAssembly components with WASI SDK
110+
cpp_component = use_extension("//wasm:extensions.bzl", "cpp_component")
111+
cpp_component.register(
112+
name = "cpp",
113+
strategy = "download",
114+
wasi_sdk_version = "25", # Match existing WASI SDK version
115+
)
116+
use_repo(cpp_component, "cpp_toolchain")
117+
118+
register_toolchains("@cpp_toolchain//:cpp_component_toolchain")
119+
109120
# Rust crates for wizer_initializer tool
110121
crate = use_extension("@rules_rust//crate_universe:extension.bzl", "crate")
111122
crate.from_cargo(

MODULE.bazel.lock

Lines changed: 36 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cpp/defs.bzl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Bazel rules for C/C++ WebAssembly components with Preview2 support"""
22

33
load("//providers:providers.bzl", "WasmComponentInfo")
4+
load("//rust:transitions.bzl", "wasm_transition")
45

56
def _cpp_component_impl(ctx):
67
"""Implementation of cpp_component rule"""
@@ -218,6 +219,7 @@ echo "Prepared C/C++ component sources in $WORK_DIR"
218219

219220
cpp_component = rule(
220221
implementation = _cpp_component_impl,
222+
cfg = wasm_transition,
221223
attrs = {
222224
"srcs": attr.label_list(
223225
allow_files = [".c", ".cpp", ".cc", ".cxx"],
@@ -336,6 +338,7 @@ def _cpp_wit_bindgen_impl(ctx):
336338

337339
cpp_wit_bindgen = rule(
338340
implementation = _cpp_wit_bindgen_impl,
341+
cfg = wasm_transition,
339342
attrs = {
340343
"wit": attr.label(
341344
allow_single_file = [".wit"],
@@ -480,6 +483,7 @@ def _cc_component_library_impl(ctx):
480483

481484
cc_component_library = rule(
482485
implementation = _cc_component_library_impl,
486+
cfg = wasm_transition,
483487
attrs = {
484488
"srcs": attr.label_list(
485489
allow_files = [".c", ".cpp", ".cc", ".cxx"],

examples/cpp_component/calculator/wit/calculator.wit

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package example:calculator@1.0.0;
22

3-
interface calculator {
3+
interface calc {
44
variant operation-type {
55
add,
66
subtract,
@@ -20,7 +20,7 @@ interface calculator {
2020
record calculation-result {
2121
success: bool,
2222
error: option<string>,
23-
result: option<f64>,
23+
value: option<f64>,
2424
}
2525

2626
record component-info {
@@ -55,5 +55,5 @@ interface calculator {
5555
}
5656

5757
world calculator {
58-
export calculator;
58+
export calc;
5959
}

toolchains/cpp_component_toolchain.bzl

Lines changed: 87 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,20 @@ def _setup_downloaded_cpp_tools(repository_ctx, platform, wasi_sdk_version):
157157

158158
# Download WASI SDK
159159
wasi_sdk_url = _get_wasi_sdk_url(platform, wasi_sdk_version)
160-
wasi_sdk_dir = "wasi-sdk-{}".format(wasi_sdk_version)
160+
161+
# Handle new WASI SDK directory format (version 25+)
162+
if int(wasi_sdk_version) >= 25:
163+
platform_map = {
164+
"linux_amd64": "x86_64-linux",
165+
"linux_arm64": "arm64-linux",
166+
"darwin_amd64": "x86_64-macos",
167+
"darwin_arm64": "arm64-macos",
168+
"windows_amd64": "x86_64-mingw",
169+
}
170+
arch_os = platform_map.get(platform, "x86_64-linux")
171+
wasi_sdk_dir = "wasi-sdk-{}.0-{}".format(wasi_sdk_version, arch_os)
172+
else:
173+
wasi_sdk_dir = "wasi-sdk-{}".format(wasi_sdk_version)
161174

162175
print("Downloading WASI SDK version {} for platform {}".format(wasi_sdk_version, platform))
163176

@@ -177,6 +190,9 @@ def _setup_downloaded_cpp_tools(repository_ctx, platform, wasi_sdk_version):
177190
# Create tool wrappers pointing to downloaded WASI SDK
178191
_create_wasi_sdk_wrappers(repository_ctx, wasi_sdk_dir)
179192

193+
# Set up sysroot symlink for the downloaded WASI SDK
194+
_setup_downloaded_sysroot(repository_ctx)
195+
180196
print("Successfully downloaded WASI SDK")
181197

182198
# Set up wit-bindgen and wasm-tools (assume system or use existing toolchain)
@@ -196,68 +212,101 @@ def _get_wasi_sdk_url(platform, version):
196212
# WASI SDK release URL format
197213
base_url = "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-{}"
198214

199-
platform_map = {
200-
"linux_amd64": "linux",
201-
"linux_arm64": "linux", # Use same binary for now
202-
"darwin_amd64": "macos",
203-
"darwin_arm64": "macos",
204-
"windows_amd64": "mingw",
205-
}
206-
207-
os_name = platform_map.get(platform, "linux")
208-
filename = "wasi-sdk-{}-{}.tar.gz".format(version, os_name)
215+
# Handle new WASI SDK filename format (version 25+)
216+
if int(version) >= 25:
217+
platform_map = {
218+
"linux_amd64": "x86_64-linux",
219+
"linux_arm64": "arm64-linux",
220+
"darwin_amd64": "x86_64-macos",
221+
"darwin_arm64": "arm64-macos",
222+
"windows_amd64": "x86_64-mingw",
223+
}
224+
arch_os = platform_map.get(platform, "x86_64-linux")
225+
filename = "wasi-sdk-{}.0-{}.tar.gz".format(version, arch_os)
226+
else:
227+
# Legacy format for older versions
228+
platform_map = {
229+
"linux_amd64": "linux",
230+
"linux_arm64": "linux",
231+
"darwin_amd64": "macos",
232+
"darwin_arm64": "macos",
233+
"windows_amd64": "mingw",
234+
}
235+
os_name = platform_map.get(platform, "linux")
236+
filename = "wasi-sdk-{}-{}.tar.gz".format(version, os_name)
209237

210238
return base_url.format(version) + "/" + filename
211239

212240
def _create_wasi_sdk_wrappers(repository_ctx, wasi_sdk_dir):
213241
"""Create wrapper scripts for WASI SDK tools"""
214242

243+
# Get absolute path to the repository root
244+
repo_root = repository_ctx.path(".")
245+
215246
# Clang wrapper with Preview2 target
216247
repository_ctx.file("clang", """#!/bin/bash
217-
exec ./bin/clang \\
248+
exec {}/bin/clang \\
218249
--target=wasm32-wasip2 \\
219-
--sysroot=./share/wasi-sysroot \\
250+
--sysroot={}/share/wasi-sysroot \\
220251
-D_WASI_EMULATED_PROCESS_CLOCKS \\
221252
-D_WASI_EMULATED_SIGNAL \\
222253
-D_WASI_EMULATED_MMAN \\
223254
"$@"
224-
""", executable = True)
255+
""".format(repo_root, repo_root), executable = True)
225256

226257
# Clang++ wrapper with Preview2 target and C++ support
227258
repository_ctx.file("clang_cpp", """#!/bin/bash
228-
exec ./bin/clang++ \\
259+
exec {}/bin/clang++ \\
229260
--target=wasm32-wasip2 \\
230-
--sysroot=./share/wasi-sysroot \\
261+
--sysroot={}/share/wasi-sysroot \\
231262
-D_WASI_EMULATED_PROCESS_CLOCKS \\
232263
-D_WASI_EMULATED_SIGNAL \\
233264
-D_WASI_EMULATED_MMAN \\
234265
-fno-exceptions \\
235266
-fno-rtti \\
236267
"$@"
237-
""", executable = True)
268+
""".format(repo_root, repo_root), executable = True)
238269

239270
# LLVM AR wrapper
240271
repository_ctx.file("llvm_ar", """#!/bin/bash
241-
exec ./bin/llvm-ar "$@"
242-
""", executable = True)
272+
exec {}/bin/llvm-ar "$@"
273+
""".format(repo_root), executable = True)
243274

244275
def _setup_component_tools(repository_ctx):
245276
"""Set up wit-bindgen and wasm-tools"""
246277

247-
# Assume these are available from system or existing toolchain
248-
for tool in ["wit_bindgen", "wasm_tools"]:
249-
validation_result = validate_system_tool(repository_ctx, tool.replace("_", "-"))
278+
# Create symlinks to the tools from the wasm toolchain
279+
# These will be resolved by Bazel's toolchain resolution system
280+
print("Using wit-bindgen and wasm-tools from configured WASM toolchain")
281+
282+
# Create placeholder scripts that will be replaced by toolchain resolution
283+
repository_ctx.file("wit_bindgen", """#!/bin/bash
284+
# This placeholder should be replaced by Bazel's toolchain resolution
285+
# with the actual wit-bindgen from @wasm_tools_toolchains
286+
echo "Error: wit-bindgen not properly resolved from WASM toolchain"
287+
exit 1
288+
""", executable = True)
250289

251-
if not validation_result["valid"]:
252-
fail(format_diagnostic_error(
253-
"E006",
254-
"{} not found".format(tool.replace("_", "-")),
255-
"Configure wasm_toolchain extension first",
256-
))
290+
repository_ctx.file("wasm_tools", """#!/bin/bash
291+
# This placeholder should be replaced by Bazel's toolchain resolution
292+
# with the actual wasm-tools from @wasm_tools_toolchains
293+
echo "Error: wasm-tools not properly resolved from WASM toolchain"
294+
exit 1
295+
""", executable = True)
257296

258-
repository_ctx.file(tool, """#!/bin/bash
259-
exec {} "$@"
260-
""".format(tool.replace("_", "-")), executable = True)
297+
def _setup_downloaded_sysroot(repository_ctx):
298+
"""Set up sysroot for downloaded WASI SDK"""
299+
300+
# Create symlink to the downloaded WASI SDK sysroot
301+
wasi_sysroot_path = repository_ctx.path("share/wasi-sysroot")
302+
if wasi_sysroot_path.exists:
303+
repository_ctx.symlink("share/wasi-sysroot", "sysroot")
304+
print("Using downloaded WASI sysroot")
305+
else:
306+
# Fallback: create minimal sysroot structure
307+
print("Warning: Downloaded WASI sysroot not found, creating minimal structure")
308+
repository_ctx.file("sysroot/include/.gitkeep", "")
309+
repository_ctx.file("sysroot/lib/.gitkeep", "")
261310

262311
def _setup_system_sysroot(repository_ctx):
263312
"""Set up system sysroot directory"""
@@ -311,15 +360,16 @@ filegroup(
311360
visibility = ["//visibility:public"],
312361
)
313362
314-
filegroup(
363+
# Reference tools from WASM toolchain instead of local files
364+
alias(
315365
name = "wit_bindgen_binary",
316-
srcs = ["wit_bindgen"],
366+
actual = "@wasm_tools_toolchains//:wit_bindgen_binary",
317367
visibility = ["//visibility:public"],
318368
)
319369
320-
filegroup(
321-
name = "wasm_tools_binary",
322-
srcs = ["wasm_tools"],
370+
alias(
371+
name = "wasm_tools_binary",
372+
actual = "@wasm_tools_toolchains//:wasm_tools_binary",
323373
visibility = ["//visibility:public"],
324374
)
325375
@@ -347,7 +397,7 @@ toolchain(
347397
toolchain = ":cpp_component_toolchain_impl",
348398
toolchain_type = "@rules_wasm_component//toolchains:cpp_component_toolchain_type",
349399
exec_compatible_with = [],
350-
target_compatible_with = [],
400+
target_compatible_with = ["@platforms//cpu:wasm32", "@platforms//os:wasi"],
351401
)
352402
353403
# Alias for toolchain registration

0 commit comments

Comments
 (0)