Skip to content

Commit d058d0c

Browse files
refactor(lang/go): Revise Go language support section (#311)
* Revise Go language support section Added more details where necessary. Factored code examples out into separate files and included them. Made the "Testing the add component" section consistent with other examples involving the example host. * Move WIT example into a separate directory so it doesn't affect the tutorial build * Update component-model/src/language-support/go.md Co-authored-by: Victor Adossi <123968127+vados-cosmonic@users.noreply.github.com> * Clarify what `wit wkg build` does --------- Co-authored-by: Victor Adossi <123968127+vados-cosmonic@users.noreply.github.com>
1 parent 8d4f782 commit d058d0c

File tree

3 files changed

+95
-71
lines changed

3 files changed

+95
-71
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//go:generate go tool wit-bindgen-go generate --world adder --out internal ./docs:adder@0.1.0.wasm
2+
3+
package main
4+
5+
import (
6+
"example.com/internal/docs/adder/add"
7+
)
8+
9+
func init() {
10+
add.Exports.Add = func(x uint32, y uint32) uint32 {
11+
return x + y
12+
}
13+
}
14+
15+
// main is required for the `wasi` target, even if it isn't used.
16+
func main() {}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package docs:adder@0.1.0;
2+
3+
interface add {
4+
add: func(x: u32, y: u32) -> u32;
5+
}
6+
7+
world adder {
8+
include wasi:cli/imports@0.2.0;
9+
10+
export add;
11+
}

component-model/src/language-support/go.md

Lines changed: 68 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
The [TinyGo compiler](https://tinygo.org/) v0.34.0 and above has native support for the WebAssembly Component Model and WASI 0.2.0.
44

5-
This guide walks through building a component that implements `adder` world defined in the [`adder/world.wit` package][adder-wit].
6-
The component will implement the `adder` world, which contains `add` interface with a `add` function.
5+
This guide walks through building a component that implements
6+
the `adder` world defined in the [`adder/world.wit` package][adder-wit].
7+
The component will implement the `adder` world,
8+
which contains an `add` interface with an `add` function.
79

810
[adder-wit]: https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/tutorial/wit/adder/world.wit
911

@@ -32,9 +34,13 @@ $ wasm-tools -V
3234
wasm-tools 1.255.0 ...
3335
```
3436

35-
Optional: Install the [`wkg`][wkg] CLI tool to resolve the imports in the WIT file. The `wkg` CLI is a part of the [Wasm Component package manager](https://github.com/bytecodealliance/wasm-pkg-tools/releases)
37+
Optional: Install the [`wkg`][wkg] CLI tool to resolve the imports in the WIT file.
38+
The `wkg` CLI is a part of the [Wasm Component package manager][wasm-pkg-tools-releases].
39+
See [the wasm-pkg-tools installation instructions][wasm-pkg-tools] to install manually or using `cargo`.
3640

3741
[wkg]: https://github.com/bytecodealliance/wasm-pkg-tools/tree/main/crates/wkg
42+
[wasm-pkg-tools]: https://github.com/bytecodealliance/wasm-pkg-tools?tab=readme-ov-file#installation
43+
[wasm-pkg-tools-releases]: https://github.com/bytecodealliance/wasm-pkg-tools/releases
3844

3945
## 2. Create your Go project
4046

@@ -45,12 +51,10 @@ mkdir add && cd add
4551
go mod init example.com
4652
```
4753

48-
Ensure that the following `tool`s are installed:
54+
Install the following `tool`:
4955

50-
```
51-
tool (
52-
go.bytecodealliance.org/cmd/wit-bindgen-go
53-
)
56+
```console
57+
go get -tool go.bytecodealliance.org/cmd/wit-bindgen-go
5458
```
5559

5660
> [!NOTE]
@@ -60,41 +64,29 @@ Consider also running `go mod tidy` after adding the above tool.
6064

6165
[go-1-24-release]: https://go.dev/blog/go1.24
6266

63-
## 2. Determine which World the Component will Implement
67+
## 2. Determine which world the component will implement
6468

65-
Since we will be implementing the [`adder` world][adder-wit], we can copy the WIT to our project,
66-
under the `wit` folder (e.g. `wit/component.wit`):
69+
Since we will be implementing the [`adder` world][adder-wit], we can copy the WIT to our project.
70+
Create a subdirectory called `wit` and paste the following code
71+
into a file called `wit/component.wit`:
6772

6873
```wit
69-
package docs:adder@0.1.0;
70-
71-
interface add {
72-
add: func(x: u32, y: u32) -> u32;
73-
}
74-
75-
world adder {
76-
export add;
77-
}
74+
{{#include ../../examples/tutorial/go/adder/world2.wit}}
7875
```
7976

80-
The `wasip2` target of TinyGo assumes that the component is targeting `wasi:cli/command@0.2.0` world
81-
(part of [`wasi:cli`][wasi-cli]) so it requires the imports of `wasi:cli/imports@0.2.0`.
82-
83-
We need to include those interfaces as well in `component.wit`, by editing the `adder` world:
84-
85-
```wit
86-
world adder {
87-
include wasi:cli/imports@0.2.0;
88-
export add;
89-
}
90-
```
77+
The line `include wasi:cli/imports@0.2.0` is necessary because
78+
we are using the `wasip2` target of TinyGo.
79+
TinyGo assumes that the component targets the `wasi:cli/command@0.2.0` world
80+
(part of [`wasi:cli`][wasi-cli]),
81+
so it requires the imports of `wasi:cli/imports@0.2.0`.
9182

9283
### Using `wkg` to automatically resolve and download imports
9384

9485
Tools like [`wkg`][wkg] can be convenient to build a complete WIT package by resolving the imports.
9586

96-
Running the `wkg wit fetch` command will resolve the imports and populate your `wit` folder with all relevant
97-
imported namespaces and packages.
87+
Running the `wkg wit build` command encodes the WIT into the Component Model binary format.
88+
As a side effect, it resolves the imports
89+
and populates your `wit` folder with all relevant imported namespaces and packages.
9890

9991
```
10092
$ wkg wit build
@@ -105,8 +97,8 @@ WIT package written to docs:adder@0.1.0.wasm
10597

10698
## 3. Generate bindings for the Wasm component
10799

108-
Now that we have our WIT definitions bundled together into a WASM file,
109-
we can generate the bindings for our Wasm component, by adding a build directive:
100+
Now that we have our WIT definitions bundled together into a `.wasm` file,
101+
we can generate the bindings for our WebAssembly component, by adding a build directive:
110102

111103
```console
112104
go tool wit-bindgen-go generate --world adder --out internal ./docs:adder@0.1.0.wasm
@@ -116,7 +108,7 @@ go tool wit-bindgen-go generate --world adder --out internal ./docs:adder@0.1.0.
116108
> The `go tool` directive (added in [Golang 1.24][go-1-24-release]) installs and enables use of `wit-bindgen-go`,
117109
> part of the Bytecode Alliance suite of Golang tooling.
118110
119-
The `internal` directory will contain the generated Go code that WIT package.
111+
The `internal` directory will contain the generated Go code for that WIT package.
120112

121113
```console
122114
$ tree internal
@@ -254,50 +246,55 @@ internal
254246
39 directories, 91 files
255247
```
256248

257-
The `adder.exports.go` file contains the exported functions that need to be implemented in the Go code called `Exports`.
249+
The `add.exports.go` file contains an `Exports` struct, containing declarations for
250+
the exported functions that need to be implemented in the Go code.
258251

259252
## 4. Implement the `add` Function
260253

261-
```Go
262-
//go:generate go tool wit-bindgen-go generate --world adder --out internal ./docs:adder@0.1.0.wasm
254+
In your `add` directory, create a file called `main.go`
255+
and paste the following code into it:
263256

264-
package main
265-
266-
import (
267-
"example.com/internal/docs/adder/add"
268-
)
269-
270-
func init() {
271-
add.Exports.Add = func(x uint32, y uint32) uint32 {
272-
return x + y
273-
}
274-
}
275-
276-
// main is required for the `wasi` target, even if it isn't used.
277-
func main() {}
257+
```Go
258+
{{#include ../../examples/tutorial/go/adder/main.go}}
278259
```
279260

280-
Go's `init` functions are used to do initialization tasks that
281-
should be done before any other tasks. In this case, we are using it to export the `Add` function.
261+
Go's `init` function is used to do initialization tasks
262+
that should be done before any other tasks.
263+
In this case, we are using it to export the `Add` function.
282264

283265
## 5. Build the Component
284266

285-
We can build our component using TinyGo by specifying the wit-package to be `add.wit` and the WIT world to be `adder`.
286-
287-
Under the hood, TinyGo invokes `wasm-tools` to embed the WIT file to the module and componentize it.
267+
We can build our component using TinyGo.
268+
Under the hood, TinyGo invokes `wasm-tools`
269+
to embed the WIT file to the module and componentize it.
288270

289271
```console
290-
tinygo build -target=wasip2 -o add.wasm --wit-package docs:adder@0.1.0.wasm --wit-world adder main.go
272+
tinygo build -target=wasip2 \
273+
-o adder.wasm \
274+
--wit-package docs:adder@0.1.0.wasm \
275+
--wit-world adder main.go
291276
```
292277

293-
> **WARNING:** By default, tinygo includes all debug-related information in your .wasm file. That is desirable when prototyping or testing locally to obtain useful backtraces in case of errors (for example, with `wasmtime::WasmBacktraceDetails::Enable`). To remove debug data and optimize your binary file, build with `-no-debug`. The resulting .wasm file will be considerably smaller (up to 75% reduction in size).
278+
* The `-target=wasip2` flag specifies that the code should be compiled
279+
to WebAssembly using Preview 2 methods.
280+
* The `-o adder.wasm` flag directs the output to be saved in `add.wasm` in the current directory.
281+
* The `--wit-package` flag specifies the package name for the WIT code we are using.
282+
* The `--wit-world` flag specifies that the WIT world that defines the imports and exports
283+
for our component is `adder`.
294284

295-
We now have an add component that satisfies our `adder` world, exporting the `add` function, which
285+
We now have an `adder` component that satisfies our `adder` world, exporting the `add` function.
286+
287+
> [!WARNING]
288+
> By default, tinygo includes all debug-related information in your .wasm file.
289+
> That is desirable when prototyping or testing locally to obtain useful backtraces in case of errors
290+
> (for example, with `wasmtime::WasmBacktraceDetails::Enable`).
291+
> To remove debug data and optimize your binary file, build with `-no-debug`.
292+
> The resulting .wasm file will be considerably smaller (up to 75% reduction in size).
296293
297294
We can confirm using the `wasm-tools component wit` command:
298295

299296
```console
300-
$ wasm-tools component wit add.wasm
297+
$ wasm-tools component wit adder.wasm
301298
package root:component;
302299

303300
world root {
@@ -313,20 +310,20 @@ world root {
313310

314311
## 5. Testing the `add` Component
315312

316-
To run our add component, we need to use a host program with a WASI runtime that understands the
317-
`example` world -- we've provided an [`example-host`][example-host] that does just that.
313+
The following section requires you to have [a Rust toolchain][rust] installed.
318314

319-
The example host calls the `add` function of a passed in component providing two operands.
315+
To run our add component, we need to use a host program with a WASI runtime that understands
316+
the `example` world.
320317

321-
To use the example host, clone this repository and run the Rust program:
318+
{{#include example-host-part1.md}}
322319

323-
```console
324-
git clone git@github.com:bytecodealliance/component-docs.git
325-
cd component-docs/component-model/examples/example-host
326-
cargo run --release -- 1 2 /path/to/add.wasm
327-
```
320+
A successful run should show the following output
321+
(of course, the paths to your example host and adder component will vary):
322+
323+
{{#include example-host-part2.md}}
328324

329325
[example-host]: https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/example-host
326+
[rust]: https://www.rust-lang.org/learn/get-started
330327

331328
[!NOTE]: #
332329
[!WARNING]: #

0 commit comments

Comments
 (0)