From 220c8f5c8b3c06a5aaf36175f28d07d638c72120 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Tue, 27 Jan 2026 06:30:55 +0100 Subject: [PATCH 1/5] fix(moonbit): register toolchain and fix component build pipeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three issues prevented moonbit_wasm_component from building: 1. MoonBit toolchain was never registered - MODULE.bazel declared bazel_dep(name = "rules_moonbit") but never called use_extension or register_toolchains, causing Bazel to use the stub toolchain 2. MOON_HOME not set - moon build couldn't find moonbitlang/core standard library inside the Bazel sandbox 3. Missing sandbox inputs - moonbit_all_files wasn't included in action inputs, so the toolchain binaries (moonc, etc.) weren't available in the sandbox Also adds --encoding utf16 to wasm-tools component embed (required for MoonBit string encoding) and updates rules_moonbit to the commit with chmod + core bundle fixes. Verified: calculator component builds and exports correct WIT: export add: func(a: s32, b: s32) -> s32 export subtract: func(a: s32, b: s32) -> s32 export multiply: func(a: s32, b: s32) -> s32 export divide: func(a: s32, b: s32) -> s32 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- MODULE.bazel | 15 +++++++++++---- moonbit/private/moonbit_wasm_component.bzl | 13 +++++++++++-- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 08bde69a..e118f405 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -23,13 +23,14 @@ bazel_dep(name = "rules_cc", version = "0.2.14") bazel_dep(name = "rules_go", version = "0.59.0") # MoonBit language support for WebAssembly components -# Required for moonbit_wasm_cli and moonbit_wasm_binary rules -# Note: rules_moonbit is not yet in BCR - uses git_override -bazel_dep(name = "rules_moonbit", version = "0.1.0") +# Dev dependency: rules_moonbit is not yet in BCR. Downstream users who want +# MoonBit support must add their own bazel_dep + git_override for rules_moonbit. +# The moonbit/ rules are available but only resolve when rules_moonbit is present. +bazel_dep(name = "rules_moonbit", version = "0.1.0", dev_dependency = True) git_override( module_name = "rules_moonbit", remote = "https://github.com/pulseengine/rules_moonbit.git", - commit = "b5bbfe8ef1f87b42c77f168640817f67ed8758a3", + commit = "e95c912e55094b90b6c02a6052c0a284b142e6b8", # includes chmod + bundle + dev_dependency fix ) # OCI image signing capabilities @@ -241,6 +242,12 @@ use_repo(componentize_py, "componentize_py_toolchain") register_toolchains("@componentize_py_toolchain//:componentize_py_toolchain") +# MoonBit hermetic toolchain for WebAssembly component builds (dev only) +moonbit = use_extension("@rules_moonbit//moonbit:extensions.bzl", "moonbit_toolchain_extension", dev_dependency = True) +use_repo(moonbit, "moonbit_toolchain") + +register_toolchains("@moonbit_toolchain//:moonbit_toolchain", dev_dependency = True) + # File Operations Component toolchain for universal file handling register_toolchains("//toolchains:file_ops_toolchain_target") diff --git a/moonbit/private/moonbit_wasm_component.bzl b/moonbit/private/moonbit_wasm_component.bzl index 11958693..2273b28f 100644 --- a/moonbit/private/moonbit_wasm_component.bzl +++ b/moonbit/private/moonbit_wasm_component.bzl @@ -46,6 +46,7 @@ def _moonbit_wasm_component_impl(ctx): moonbit_toolchain = ctx.toolchains["@rules_moonbit//moonbit:moonbit_toolchain_type"] moon = moonbit_toolchain.moonbit.moon_executable + moonbit_all_files = moonbit_toolchain.moonbit.all_files wit_file = ctx.file.wit srcs = ctx.files.srcs @@ -70,6 +71,12 @@ WIT_FILE="$(pwd)/{wit_file}" OUTPUT="$(pwd)/{output}" ORIG_DIR="$(pwd)" +# Set MOON_HOME so moon build can find the core library +# MOON path: /path/to/external/moonbit_toolchain/bin/moon +# MOON_HOME: /path/to/external/moonbit_toolchain/.moon +TOOLCHAIN_ROOT=$(dirname $(dirname "$MOON")) +export MOON_HOME="$TOOLCHAIN_ROOT/.moon" + # Create temporary project directory PROJECT_DIR=$(mktemp -d) cleanup() {{ rm -rf "$PROJECT_DIR"; }} @@ -94,7 +101,7 @@ if [ -d "$STUB_DIR" ]; then fi # Step 3: Compile with MoonBit -"$MOON" build --target wasm --release 2>&1 || {{ +"$MOON" build --target wasm 2>&1 || {{ echo "MoonBit compilation failed" >&2 exit 1 }} @@ -107,7 +114,9 @@ if [ -z "$CORE_WASM" ]; then fi # Step 4: Embed WIT metadata +# Use --encoding utf16 for MoonBit string encoding "$WASM_TOOLS" component embed \\ + --encoding utf16 \\ --world {world} \\ "$WIT_FILE" \\ "$CORE_WASM" \\ @@ -135,7 +144,7 @@ echo "Created component: $OUTPUT" ctx.actions.run_shell( command = script, - inputs = [wit_file, wit_bindgen, moon, wasm_tools] + srcs, + inputs = [wit_file, wit_bindgen, moon, wasm_tools] + srcs + moonbit_all_files.to_list(), outputs = [component_wasm], mnemonic = "MoonbitWasmComponent", progress_message = "Building MoonBit WASM component %s" % ctx.label, From e6ab140534b3d0c646074a1775ef8fcac762b6e3 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Wed, 28 Jan 2026 06:05:33 +0100 Subject: [PATCH 2/5] fix: import CcToolchainConfigInfo for Bazel 9 compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add explicit import of CcToolchainConfigInfo from @rules_cc in both wasi_sdk_toolchain.bzl (generated template) and wasm_cc_toolchain.bzl. Bazel 9 removed CcToolchainConfigInfo as a global built-in, so `provides = [CcToolchainConfigInfo]` evaluates to `provides = [None]` without the import, causing rule definition failures. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- toolchains/wasi_sdk_toolchain.bzl | 1 + toolchains/wasm_cc_toolchain.bzl | 1 + 2 files changed, 2 insertions(+) diff --git a/toolchains/wasi_sdk_toolchain.bzl b/toolchains/wasi_sdk_toolchain.bzl index 41814f04..dbff1394 100644 --- a/toolchains/wasi_sdk_toolchain.bzl +++ b/toolchains/wasi_sdk_toolchain.bzl @@ -298,6 +298,7 @@ load( "flag_set", "tool_path", ) +load("@rules_cc//cc/toolchains:cc_toolchain_config_info.bzl", "CcToolchainConfigInfo") def _wasm_cc_toolchain_config_impl(ctx): """C++ toolchain config for WASM using WASI SDK""" diff --git a/toolchains/wasm_cc_toolchain.bzl b/toolchains/wasm_cc_toolchain.bzl index 98a2e9ef..dcdfe6e5 100644 --- a/toolchains/wasm_cc_toolchain.bzl +++ b/toolchains/wasm_cc_toolchain.bzl @@ -9,6 +9,7 @@ load( "flag_set", "tool_path", ) +load("@rules_cc//cc/toolchains:cc_toolchain_config_info.bzl", "CcToolchainConfigInfo") def _wasm_cc_toolchain_config_impl(ctx): """C++ toolchain config for WASM using WASI SDK""" From 14a7bb233edb3a864b4965cbcd3063e1de55e016 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Wed, 28 Jan 2026 06:20:44 +0100 Subject: [PATCH 3/5] fix: import cc_common from rules_cc for Bazel 9 compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Bazel 9, cc_common is no longer a global built-in - it must be explicitly imported from @rules_cc//cc/common:cc_common.bzl. Also switch cc_toolchain_config_lib imports from @bazel_tools to @rules_cc to match the canonical pattern from rules_cc examples. This fixes the "struct has no field create_cc_toolchain_config_info" error when building with Bazel 9. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- toolchains/wasi_sdk_toolchain.bzl | 3 ++- toolchains/wasm_cc_toolchain.bzl | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/toolchains/wasi_sdk_toolchain.bzl b/toolchains/wasi_sdk_toolchain.bzl index dbff1394..24f24d36 100644 --- a/toolchains/wasi_sdk_toolchain.bzl +++ b/toolchains/wasi_sdk_toolchain.bzl @@ -292,12 +292,13 @@ alias( # Create cc_toolchain_config.bzl with proper path resolution cc_config_content = ''' load( - "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", + "@rules_cc//cc:cc_toolchain_config_lib.bzl", "feature", "flag_group", "flag_set", "tool_path", ) +load("@rules_cc//cc/common:cc_common.bzl", "cc_common") load("@rules_cc//cc/toolchains:cc_toolchain_config_info.bzl", "CcToolchainConfigInfo") def _wasm_cc_toolchain_config_impl(ctx): diff --git a/toolchains/wasm_cc_toolchain.bzl b/toolchains/wasm_cc_toolchain.bzl index dcdfe6e5..154f36a9 100644 --- a/toolchains/wasm_cc_toolchain.bzl +++ b/toolchains/wasm_cc_toolchain.bzl @@ -1,7 +1,7 @@ """Minimal C++ toolchain for WASM builds""" load( - "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", + "@rules_cc//cc:cc_toolchain_config_lib.bzl", "env_entry", "env_set", "feature", @@ -9,6 +9,7 @@ load( "flag_set", "tool_path", ) +load("@rules_cc//cc/common:cc_common.bzl", "cc_common") load("@rules_cc//cc/toolchains:cc_toolchain_config_info.bzl", "CcToolchainConfigInfo") def _wasm_cc_toolchain_config_impl(ctx): From 392f591b18693f00938ca783481231502290c993 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Wed, 28 Jan 2026 06:28:19 +0100 Subject: [PATCH 4/5] fix: add CcInfo and cc_common imports for Bazel 9 compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bazel 9 removed CcInfo and cc_common from the built-in globals. Add explicit imports from @rules_cc for all files that use them: - cpp/defs.bzl: CcInfo + cc_common - cpp/private/cpp_wasm_binary.bzl: CcInfo - rust/private/rust_wasm_component_bindgen.bzl: CcInfo - test/cpp/cpp_component_tests.bzl: CcInfo These imports are backward-compatible with Bazel 8. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- cpp/defs.bzl | 2 ++ cpp/private/cpp_wasm_binary.bzl | 1 + rust/private/rust_wasm_component_bindgen.bzl | 1 + test/cpp/cpp_component_tests.bzl | 1 + 4 files changed, 5 insertions(+) diff --git a/cpp/defs.bzl b/cpp/defs.bzl index 5e5f0f20..b67bca23 100644 --- a/cpp/defs.bzl +++ b/cpp/defs.bzl @@ -68,6 +68,8 @@ Example usage: ) """ +load("@rules_cc//cc/common:cc_common.bzl", "cc_common") +load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") load("//providers:providers.bzl", "WasmComponentInfo") load("//rust:transitions.bzl", "wasm_transition") load("//tools/bazel_helpers:file_ops_actions.bzl", "setup_cpp_workspace_action") diff --git a/cpp/private/cpp_wasm_binary.bzl b/cpp/private/cpp_wasm_binary.bzl index 3c4309a3..65e1fb91 100644 --- a/cpp/private/cpp_wasm_binary.bzl +++ b/cpp/private/cpp_wasm_binary.bzl @@ -29,6 +29,7 @@ Example usage: # Run with: wasmtime run bazel-bin/examples/hello.wasm """ +load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") load("//providers:providers.bzl", "WasmComponentInfo") load("//rust:transitions.bzl", "wasm_transition") load("//tools/bazel_helpers:file_ops_actions.bzl", "setup_cpp_workspace_action") diff --git a/rust/private/rust_wasm_component_bindgen.bzl b/rust/private/rust_wasm_component_bindgen.bzl index 5a834b91..1a3cb933 100644 --- a/rust/private/rust_wasm_component_bindgen.bzl +++ b/rust/private/rust_wasm_component_bindgen.bzl @@ -1,5 +1,6 @@ """Rust WASM component with WIT bindgen integration""" +load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") load("@rules_rust//rust:defs.bzl", "rust_common", "rust_library") load("//wit:defs.bzl", "symmetric_wit_bindgen", "wit_bindgen") load("//toolchains:tool_versions.bzl", "get_tool_version") diff --git a/test/cpp/cpp_component_tests.bzl b/test/cpp/cpp_component_tests.bzl index 5eb361ca..40d0539c 100644 --- a/test/cpp/cpp_component_tests.bzl +++ b/test/cpp/cpp_component_tests.bzl @@ -8,6 +8,7 @@ This module provides comprehensive testing for WASI SDK + clang integration: """ load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts") +load("@rules_cc//cc/common:cc_info.bzl", "CcInfo") load("@rules_wasm_component//providers:providers.bzl", "WasmComponentInfo") def _cpp_component_analysis_test_impl(ctx): From c41d716cd6e30cc28f76056768c7ed5d48cd2318 Mon Sep 17 00:00:00 2001 From: Ralf Anton Beier Date: Thu, 29 Jan 2026 06:38:20 +0100 Subject: [PATCH 5/5] fix(go): add configurable interp_timeout for TinyGo Go 1.25+ FIPS crypto MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Go 1.25 introduced FIPS 140-3 crypto compliance with complex init() code in crypto/internal/fips140/nistec/p256.go. TinyGo's interpreter evaluates init() functions at compile time, and this complex P256 table generation exceeds the default 3-minute timeout on some systems (particularly macOS). Changes: - Add `interp_timeout` attribute to go_wasm_component rule (default: 10m) - Pass `-interp-timeout` flag to TinyGo build command - Update rule documentation with FIPS crypto note and example Users can increase the timeout for crypto-heavy components: go_wasm_component( name = "my_component", interp_timeout = "15m", # For crypto-heavy code ) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- go/defs.bzl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/go/defs.bzl b/go/defs.bzl index 1ea730ee..d2570d8a 100644 --- a/go/defs.bzl +++ b/go/defs.bzl @@ -549,6 +549,7 @@ def _compile_tinygo_module(ctx, tinygo, go_binary, wasm_opt_binary, wasm_tools, tinygo_args = [ "build", "-target=wasip2", + "-interp-timeout=" + ctx.attr.interp_timeout, # Configurable timeout for Go 1.25+ FIPS crypto init "-o", wasm_module.path, ] @@ -854,6 +855,10 @@ go_wasm_component = rule( default = False, doc = "Validate that the component exports match the WIT specification", ), + "interp_timeout": attr.string( + default = "10m", + doc = "TinyGo interpreter timeout for init() evaluation. Increase if crypto packages cause timeouts (Go 1.25+ FIPS 140 issue).", + ), "_wasi_adapter": attr.label( default = "//toolchains:wasi_snapshot_preview1.command.wasm", allow_single_file = [".wasm"], @@ -875,6 +880,10 @@ This rule provides state-of-the-art Go support for WebAssembly Component Model: - WIT binding generation support - Zero shell script dependencies +Note: Go 1.25+ introduced FIPS 140-3 crypto with complex init() code that may +cause TinyGo interpreter timeouts. The default interp_timeout of 10m should +handle most cases. Increase if needed for crypto-heavy components. + Example: go_wasm_component( name = "http_downloader", @@ -883,6 +892,7 @@ Example: wit = "//wit:http_interfaces", world = "http-client", optimization = "release", + interp_timeout = "15m", # Increase for crypto-heavy components ) """, )