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
33 changes: 33 additions & 0 deletions examples/component_import_example/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
"""Example: adopt a prebuilt .wasm component, then validate it.

`wasm_component_import` brings an already-built component (fetched release
asset, vendored artifact, or — here — another target's output) into the build
graph as a `WasmComponentInfo`, so the downstream rules can consume it without
rebuilding from source. See rules_wasm_component#489.

To keep the example hermetic (no binary committed to the repo), `wasm` points
at an existing built component (`//examples/basic:hello_component`) as a
stand-in for a prebuilt artifact. In a real pipeline `wasm` would point at an
`http_file`-fetched release asset (e.g. a flight-control component).
"""

load("@bazel_skylib//rules:build_test.bzl", "build_test")
load("@rules_wasm_component//wasm:defs.bzl", "wasm_component_import", "wasm_validate")

wasm_component_import(
name = "adopted_component",
wasm = "//examples/basic:hello_component",
)

wasm_validate(
name = "adopted_validate",
component = ":adopted_component",
)

build_test(
name = "component_import_test",
targets = [
":adopted_component",
":adopted_validate",
],
)
5 changes: 5 additions & 0 deletions wasm/defs.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ load(
_wasm_embed_aot = "wasm_embed_aot",
_wasm_extract_aot = "wasm_extract_aot",
)
load(
"//wasm/private:wasm_component_import.bzl",
_wasm_component_import = "wasm_component_import",
)
load(
"//wasm/private:wasm_optimize.bzl",
_wasm_optimize = "wasm_optimize",
Expand Down Expand Up @@ -157,6 +161,7 @@ wasm_extract_aot = _wasm_extract_aot
ssh_keygen = _ssh_keygen

# WebAssembly optimization rules
wasm_component_import = _wasm_component_import
wasm_optimize = _wasm_optimize
binaryen_optimize = _binaryen_optimize

Expand Down
10 changes: 10 additions & 0 deletions wasm/private/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ bzl_library(
],
)

bzl_library(
name = "wasm_component_import",
srcs = ["wasm_component_import.bzl"],
visibility = [
"//docs:__pkg__",
"//wasm:__pkg__",
],
deps = ["//providers"],
)

bzl_library(
name = "wasm_optimize",
srcs = ["wasm_optimize.bzl"],
Expand Down
88 changes: 88 additions & 0 deletions wasm/private/wasm_component_import.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""wasm_component_import rule — adopt a prebuilt .wasm component into the graph.

Wraps an already-built (fetched, vendored, or released) WebAssembly component
file in a `WasmComponentInfo` so the downstream rules (`wasm_validate`,
`wasm_optimize`, `meld_fuse`, `synth_compile`, signing) can consume it without
rebuilding it from source.

Motivating use case (rules_wasm_component#489): a consumer adopts a released
component artifact — e.g. a flight-control `.wasm` fetched via `http_file` — and
runs validate / optimize / fuse / compile over it. Before this rule that
required a hand-rolled shim in every consuming repo.
"""

load("//providers:providers.bzl", "WasmComponentInfo")

def _wasm_component_import_impl(ctx):
wasm_file = ctx.file.wasm

metadata = dict(ctx.attr.metadata)
metadata.setdefault("imported", "true")
metadata.setdefault("name", ctx.label.name)

return [
DefaultInfo(files = depset([wasm_file])),
WasmComponentInfo(
wasm_file = wasm_file,
# No WIT is recovered from a prebuilt binary here; consumers that
# need typed bindings can supply it out of band. None is the
# documented "no WIT available" value.
wit_info = None,
component_type = "component",
# Optional, caller-declared interface surface. Left empty when the
# caller does not know it — downstream rules must not hard-fail on a
# stripped/opaque adopted component.
imports = ctx.attr.imports,
exports = ctx.attr.exports,
metadata = metadata,
profile = "release",
profile_variants = {},
),
]

wasm_component_import = rule(
implementation = _wasm_component_import_impl,
doc = """Adopt a prebuilt `.wasm` component as a `WasmComponentInfo` target.

Use this to bring an external/released component into a rules_wasm_component
build so `wasm_validate`, `wasm_optimize`, `meld_fuse`, `synth_compile`, and the
signing rules can consume it:

```starlark
load("@rules_wasm_component//wasm:defs.bzl", "wasm_component_import", "wasm_validate")

wasm_component_import(
name = "falcon_flight",
wasm = "@falcon_flight_wasm//file", # e.g. an http_file-fetched release asset
)

wasm_validate(
name = "falcon_validate",
component = ":falcon_flight",
)
```

`imports`/`exports` are optional and caller-declared; omit them for an opaque
component (downstream rules tolerate empty lists). `wit_info` is always `None`
for an imported binary — supply typed bindings out of band if needed.
""",
attrs = {
"wasm": attr.label(
allow_single_file = [".wasm"],
mandatory = True,
doc = "The prebuilt WebAssembly component file to adopt.",
),
"imports": attr.string_list(
default = [],
doc = "Optional, caller-declared import interface names. Empty if unknown.",
),
"exports": attr.string_list(
default = [],
doc = "Optional, caller-declared export interface names. Empty if unknown.",
),
"metadata": attr.string_dict(
default = {},
doc = "Optional extra metadata to attach to the WasmComponentInfo.",
),
},
)
Loading