Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 15 additions & 7 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,18 @@ use_repo(meld, "meld_toolchain")

register_toolchains("@meld_toolchain//:meld_toolchain")

# Loom toolchain for WebAssembly component optimization (native binary, v1.x).
# wasm_optimize consumes this (loom_toolchain_type); the old @loom_wasm 0.3.0
# component path was removed (#512).
loom = use_extension("//wasm:extensions.bzl", "loom")
loom.register(
name = "loom",
version = "1.1.14",
)
use_repo(loom, "loom_toolchain")

register_toolchains("@loom_toolchain//:loom_toolchain")

# spar toolchain: AADL architecture model -> WIT generation
spar = use_extension("//wasm:extensions.bzl", "spar")
spar.register(
Expand Down Expand Up @@ -331,13 +343,9 @@ wasm_component_download(
version = "0.7.0",
)

# LOOM WebAssembly optimizer (version in //checksums/tools/loom.json)
wasm_component_download(
name = "loom_wasm",
filename = "loom.wasm",
tool_name = "loom",
version = "0.3.0",
)
# LOOM: consumed via the native loom toolchain (@loom_toolchain, above).
# The old @loom_wasm 0.3.0 component download was removed — loom v1.x is
# native-only and wasm_optimize now runs the native binary directly (#512).

# WASM Tools Component toolchain for universal wasm-tools operations
register_toolchains("//toolchains:wasm_tools_component_toolchain_local")
Expand Down
50 changes: 37 additions & 13 deletions MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions test/p3/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ P2 tests verify no regression, P3 tests verify the new attribute is accepted.

load("@bazel_skylib//rules:build_test.bzl", "build_test")
load("@rules_wasm_component//rust:defs.bzl", "rust_wasm_component", "rust_wasm_component_bindgen")
load("@rules_wasm_component//wasm:defs.bzl", "wasm_optimize")
load("@rules_wasm_component//wit:defs.bzl", "wit_library")

package(default_visibility = ["//visibility:public"])
Expand Down Expand Up @@ -38,6 +39,20 @@ build_test(
targets = [":hello_p2"],
)

# ============================================================================
# Native loom optimize (covers wasm_optimize on the native loom toolchain, #512)
# ============================================================================

wasm_optimize(
name = "hello_p2_optimized",
component = ":hello_p2",
)

build_test(
name = "loom_optimize_build_test",
targets = [":hello_p2_optimized"],
)

# ============================================================================
# P3 build (experimental — async bindings via wit-bindgen crate runtime)
# ============================================================================
Expand Down
14 changes: 14 additions & 0 deletions toolchains/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ toolchain_type(
visibility = ["//visibility:public"],
)

# Toolchain type for Loom (WebAssembly component optimization)
toolchain_type(
name = "loom_toolchain_type",
visibility = ["//visibility:public"],
)

# Toolchain type for spar (AADL architecture model -> WIT generation)
toolchain_type(
name = "spar_toolchain_type",
Expand Down Expand Up @@ -349,6 +355,14 @@ bzl_library(
deps = [":tool_registry"],
)

# Bzl library for Loom toolchain implementation
bzl_library(
name = "loom_toolchain",
srcs = ["loom_toolchain.bzl"],
visibility = ["//visibility:public"],
deps = [":tool_registry"],
)

# Export .bzl files for testing
exports_files([
"tool_registry.bzl",
Expand Down
128 changes: 128 additions & 0 deletions toolchains/loom_toolchain.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Copyright 2026 Ralf Anton Beier. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0

"""Loom toolchain: native binary for WebAssembly component optimization.

loom optimizes a WebAssembly component (constant folding, CSE, inlining, DCE,
fused-component passes, optional Z3 verification). As of v1.x loom is
distributed as native per-OS binaries (the v0.x `loom.wasm` component was
dropped), so wasm_optimize runs the native binary directly instead of running
loom.wasm under wasmtime. Mirrors toolchains/meld_toolchain.bzl, but loom ships
tarballs (extracted) rather than a bare binary.
"""

load("//checksums:registry.bzl", "validate_tool_exists")
load("//toolchains:tool_registry.bzl", "tool_registry")

# Platforms where loom native binaries are downloaded + extracted here. loom
# also ships a Windows binary (loom.exe), but that path is not wired yet
# (binary-name differs); Windows gets the stub for now (see #512 follow-up).
_SUPPORTED_PLATFORMS = [
"darwin_amd64",
"darwin_arm64",
"linux_amd64",
]

def _loom_toolchain_impl(ctx):
"""Implementation of loom_toolchain rule."""
return [platform_common.ToolchainInfo(
loom = ctx.file.loom,
)]

loom_toolchain = rule(
implementation = _loom_toolchain_impl,
attrs = {
"loom": attr.label(
allow_single_file = True,
executable = True,
cfg = "exec",
doc = "loom binary for component optimization",
),
},
doc = "Declares a Loom toolchain for WebAssembly component optimization",
)

_STUB_BUILD = '''"""Loom toolchain stub: unsupported platform.

loom has no wired native binary for this host, so we register a toolchain that
is marked incompatible with any target. Toolchain resolution for wasm_optimize
targets fails cleanly here; builds that never touch wasm_optimize are unaffected.
"""

load("@rules_wasm_component//toolchains:loom_toolchain.bzl", "loom_toolchain")

package(default_visibility = ["//visibility:public"])

exports_files(["loom_stub"])

loom_toolchain(
name = "loom_toolchain_impl",
loom = "loom_stub",
)

toolchain(
name = "loom_toolchain",
target_compatible_with = ["@platforms//:incompatible"],
toolchain = ":loom_toolchain_impl",
toolchain_type = "@rules_wasm_component//toolchains:loom_toolchain_type",
)
'''

def _loom_repository_impl(repository_ctx):
"""Download + extract the loom native binary and create a toolchain repo."""
platform = tool_registry.detect_platform(repository_ctx)
version = repository_ctx.attr.version

if platform not in _SUPPORTED_PLATFORMS or not validate_tool_exists(repository_ctx, "loom", version, platform):
print("Loom: no wired native binary for platform {} (version {}); emitting stub".format(platform, version))
repository_ctx.file("loom_stub", content = "", executable = True)
repository_ctx.file("BUILD.bazel", _STUB_BUILD)
return

print("Setting up loom {} for platform {}".format(version, platform))

# loom ships a tarball containing ./loom; tool_registry extracts it (the
# 1.1.14 registry entries have no `binary: true`) and returns the binary
# path. strip_prefix is "" (flat archive) — see _calculate_strip_prefix.
tool_registry.download(
repository_ctx,
"loom",
version,
platform,
)

repository_ctx.file("BUILD.bazel", '''"""Loom toolchain repository"""

load("@rules_wasm_component//toolchains:loom_toolchain.bzl", "loom_toolchain")

package(default_visibility = ["//visibility:public"])

loom_toolchain(
name = "loom_toolchain_impl",
loom = ":loom",
)

toolchain(
name = "loom_toolchain",
exec_compatible_with = [],
target_compatible_with = [],
toolchain = ":loom_toolchain_impl",
toolchain_type = "@rules_wasm_component//toolchains:loom_toolchain_type",
)
''')

loom_repository = repository_rule(
implementation = _loom_repository_impl,
attrs = {
"version": attr.string(
default = "1.1.14",
doc = "Loom version to download",
),
},
doc = "Downloads loom and creates a toolchain repository",
)
5 changes: 5 additions & 0 deletions toolchains/tool_registry.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ _URL_PATTERNS = {
"filename": "{suffix}", # e.g., "meld-aarch64-apple-darwin"
"is_binary": True,
},
"loom": {
# loom v1.x releases are tarballs (extracted; url_suffix IS the filename)
"base": "https://github.com/{repo}/releases/download/v{version}",
"filename": "{suffix}", # e.g., "loom-v1.1.14-aarch64-apple-darwin.tar.gz"
},
"spar": {
# spar releases are tar.gz/zip archives: spar-v{version}-{triple}.{ext}
"base": "https://github.com/{repo}/releases/download/v{version}",
Expand Down
Loading