|
| 1 | +# Copyright 2026 Ralf Anton Beier. All rights reserved. |
| 2 | +# |
| 3 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +# you may not use this file except in compliance with the License. |
| 5 | +# You may obtain a copy of the License at |
| 6 | +# |
| 7 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | + |
| 9 | +"""Loom toolchain: native binary for WebAssembly component optimization. |
| 10 | +
|
| 11 | +loom optimizes a WebAssembly component (constant folding, CSE, inlining, DCE, |
| 12 | +fused-component passes, optional Z3 verification). As of v1.x loom is |
| 13 | +distributed as native per-OS binaries (the v0.x `loom.wasm` component was |
| 14 | +dropped), so wasm_optimize runs the native binary directly instead of running |
| 15 | +loom.wasm under wasmtime. Mirrors toolchains/meld_toolchain.bzl, but loom ships |
| 16 | +tarballs (extracted) rather than a bare binary. |
| 17 | +""" |
| 18 | + |
| 19 | +load("//checksums:registry.bzl", "validate_tool_exists") |
| 20 | +load("//toolchains:tool_registry.bzl", "tool_registry") |
| 21 | + |
| 22 | +# Platforms where loom native binaries are downloaded + extracted here. loom |
| 23 | +# also ships a Windows binary (loom.exe), but that path is not wired yet |
| 24 | +# (binary-name differs); Windows gets the stub for now (see #512 follow-up). |
| 25 | +_SUPPORTED_PLATFORMS = [ |
| 26 | + "darwin_amd64", |
| 27 | + "darwin_arm64", |
| 28 | + "linux_amd64", |
| 29 | +] |
| 30 | + |
| 31 | +def _loom_toolchain_impl(ctx): |
| 32 | + """Implementation of loom_toolchain rule.""" |
| 33 | + return [platform_common.ToolchainInfo( |
| 34 | + loom = ctx.file.loom, |
| 35 | + )] |
| 36 | + |
| 37 | +loom_toolchain = rule( |
| 38 | + implementation = _loom_toolchain_impl, |
| 39 | + attrs = { |
| 40 | + "loom": attr.label( |
| 41 | + allow_single_file = True, |
| 42 | + executable = True, |
| 43 | + cfg = "exec", |
| 44 | + doc = "loom binary for component optimization", |
| 45 | + ), |
| 46 | + }, |
| 47 | + doc = "Declares a Loom toolchain for WebAssembly component optimization", |
| 48 | +) |
| 49 | + |
| 50 | +_STUB_BUILD = '''"""Loom toolchain stub: unsupported platform. |
| 51 | +
|
| 52 | +loom has no wired native binary for this host, so we register a toolchain that |
| 53 | +is marked incompatible with any target. Toolchain resolution for wasm_optimize |
| 54 | +targets fails cleanly here; builds that never touch wasm_optimize are unaffected. |
| 55 | +""" |
| 56 | +
|
| 57 | +load("@rules_wasm_component//toolchains:loom_toolchain.bzl", "loom_toolchain") |
| 58 | +
|
| 59 | +package(default_visibility = ["//visibility:public"]) |
| 60 | +
|
| 61 | +exports_files(["loom_stub"]) |
| 62 | +
|
| 63 | +loom_toolchain( |
| 64 | + name = "loom_toolchain_impl", |
| 65 | + loom = "loom_stub", |
| 66 | +) |
| 67 | +
|
| 68 | +toolchain( |
| 69 | + name = "loom_toolchain", |
| 70 | + target_compatible_with = ["@platforms//:incompatible"], |
| 71 | + toolchain = ":loom_toolchain_impl", |
| 72 | + toolchain_type = "@rules_wasm_component//toolchains:loom_toolchain_type", |
| 73 | +) |
| 74 | +''' |
| 75 | + |
| 76 | +def _loom_repository_impl(repository_ctx): |
| 77 | + """Download + extract the loom native binary and create a toolchain repo.""" |
| 78 | + platform = tool_registry.detect_platform(repository_ctx) |
| 79 | + version = repository_ctx.attr.version |
| 80 | + |
| 81 | + if platform not in _SUPPORTED_PLATFORMS or not validate_tool_exists(repository_ctx, "loom", version, platform): |
| 82 | + print("Loom: no wired native binary for platform {} (version {}); emitting stub".format(platform, version)) |
| 83 | + repository_ctx.file("loom_stub", content = "", executable = True) |
| 84 | + repository_ctx.file("BUILD.bazel", _STUB_BUILD) |
| 85 | + return |
| 86 | + |
| 87 | + print("Setting up loom {} for platform {}".format(version, platform)) |
| 88 | + |
| 89 | + # loom ships a tarball containing ./loom; tool_registry extracts it (the |
| 90 | + # 1.1.14 registry entries have no `binary: true`) and returns the binary |
| 91 | + # path. strip_prefix is "" (flat archive) — see _calculate_strip_prefix. |
| 92 | + tool_registry.download( |
| 93 | + repository_ctx, |
| 94 | + "loom", |
| 95 | + version, |
| 96 | + platform, |
| 97 | + ) |
| 98 | + |
| 99 | + repository_ctx.file("BUILD.bazel", '''"""Loom toolchain repository""" |
| 100 | +
|
| 101 | +load("@rules_wasm_component//toolchains:loom_toolchain.bzl", "loom_toolchain") |
| 102 | +
|
| 103 | +package(default_visibility = ["//visibility:public"]) |
| 104 | +
|
| 105 | +loom_toolchain( |
| 106 | + name = "loom_toolchain_impl", |
| 107 | + loom = ":loom", |
| 108 | +) |
| 109 | +
|
| 110 | +toolchain( |
| 111 | + name = "loom_toolchain", |
| 112 | + exec_compatible_with = [], |
| 113 | + target_compatible_with = [], |
| 114 | + toolchain = ":loom_toolchain_impl", |
| 115 | + toolchain_type = "@rules_wasm_component//toolchains:loom_toolchain_type", |
| 116 | +) |
| 117 | +''') |
| 118 | + |
| 119 | +loom_repository = repository_rule( |
| 120 | + implementation = _loom_repository_impl, |
| 121 | + attrs = { |
| 122 | + "version": attr.string( |
| 123 | + default = "1.1.14", |
| 124 | + doc = "Loom version to download", |
| 125 | + ), |
| 126 | + }, |
| 127 | + doc = "Downloads loom and creates a toolchain repository", |
| 128 | +) |
0 commit comments