Skip to content

Commit b0def76

Browse files
refactor(lang/go): update go lang docs
Signed-off-by: Victor Adossi <vadossi@cosmonic.com>
1 parent bf164cd commit b0def76

1 file changed

Lines changed: 208 additions & 48 deletions

File tree

  • component-model/src/language-support

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

Lines changed: 208 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -9,103 +9,262 @@ The component will implement the `adder` world, which contains `add` interface w
99

1010
## 1. Install the tools
1111

12-
Follow the [TinyGo installation instructions](https://tinygo.org/getting-started/) to install the TinyGo compiler. Additionally, install the `wasm-tools` CLI tool from the [wasm-tools repository](https://github.com/bytecodealliance/wasm-tools/releases).
12+
Follow the [TinyGo installation instructions](https://tinygo.org/getting-started/) to install the TinyGo compiler.
13+
14+
Additionally, install the `wasm-tools` CLI tool from the [wasm-tools repository](https://github.com/bytecodealliance/wasm-tools/releases).
15+
16+
> [!WARNING]
17+
> Due to some upstream issues, only `wasm-tools` versions 1.225.0 or earlier can be used with `wit-bindgen-go`
18+
>
19+
> If using the Rust toolchain to install `wasm-tools`, it can be installed like so:
20+
> `cargo install --locked wasm-tools@1.225.0 --force`
1321
1422
To verify the installation, run the following commands:
1523

16-
```console
24+
```
1725
$ tinygo version
1826
tinygo version 0.34.0 ...
1927
$ wasm-tools -V
20-
wasm-tools 1.219.1 ...
28+
wasm-tools 1.255.0 ...
2129
```
2230

23-
Optional: Install the `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)
31+
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)
2432

25-
## 2. Determine which World the Component will Implement
33+
[wkg]: https://github.com/bytecodealliance/wasm-pkg-tools/tree/main/crates/wkg
2634

27-
The `wasip2` target of TinyGo assumes that the component is targeting `wasi:cli/command@0.2.0` world so it requires the imports of `wasi:cli/imports@0.2.0`. We need to include them in the `add.wit`.
35+
## 2. Create your Go project
2836

29-
Tools like `wkg` can be convenient to build a complete WIT package by resolving the imports.
37+
Now, create your Go project:
38+
39+
```console
40+
mkdir add && cd add
41+
go mod init example.com
42+
```
43+
44+
Ensure that the following `tool`s are installed:
45+
46+
```
47+
tool (
48+
go.bytecodealliance.org/cmd/wit-bindgen-go
49+
)
50+
```
51+
52+
> [!NOTE]
53+
> `go tool` was introduced in [Golang 1.24][go-1-24-release] and can be used to manage tooling in Go projects.
54+
55+
Consider also running `go mod tidy` after adding the above tool.
56+
57+
[go-1-24-release]: https://go.dev/blog/go1.24
58+
59+
## 2. Determine which World the Component will Implement
60+
61+
Since we will be implementing the [`adder` world][adder-wit], we can copy the WIT to our project,
62+
under the `wit` folder (e.g. `wit/component.wit`):
3063

3164
```wit
32-
# wit/add.wit
3365
package docs:adder@0.1.0;
66+
67+
interface add {
68+
add: func(x: u32, y: u32) -> u32;
69+
}
70+
71+
world adder {
72+
export add;
73+
}
74+
```
75+
76+
The `wasip2` target of TinyGo assumes that the component is targeting `wasi:cli/command@0.2.0` world
77+
(part of [`wasi:cli`][wasi-cli]) so it requires the imports of `wasi:cli/imports@0.2.0`.
78+
79+
We need to include those interfaces as well in `component.wit`, by editing the `adder` world:
80+
81+
```wit
3482
world adder {
3583
include wasi:cli/imports@0.2.0;
36-
export add: func(x: s32, y: s32) -> s32;
84+
export add;
3785
}
3886
```
3987

40-
Running the `wkg wit build` command will resolve the imports and generate the complete WIT file encoded as a Wasm component.
88+
### Using `wkg` to automatically resolve and download imports
4189

42-
```console
90+
Tools like [`wkg`][wkg] can be convenient to build a complete WIT package by resolving the imports.
91+
92+
Running the `wkg wit fetch` command will resolve the imports and populate your `wit` folder with all relevant
93+
imported namespaces and packages.
94+
95+
```
4396
$ wkg wit build
4497
WIT package written to docs:adder@0.1.0.wasm
4598
```
4699

47-
Now, create your Go project:
100+
[wasi-cli]: https://github.com/WebAssembly/wasi-cli
48101

49-
```console
50-
$ mkdir add && cd add
51-
$ go mod init example.com
52-
```
102+
## 3. Generate bindings for the Wasm component
53103

54-
Next, we can generate the bindings for the Wasm component:
104+
Now that we have our WIT definitions bundled together into a WASM file,
105+
we can generate the bindings for our Wasm component, by adding a build directive:
55106

56107
```console
57-
$ go get go.bytecodealliance.org/cmd/wit-bindgen-go
58-
$ go run go.bytecodealliance.org/cmd/wit-bindgen-go generate -o internal/ ./docs:adder@0.1.0.wasm
108+
go tool wit-bindgen-go generate --world adder --out internal ./docs:adder@0.1.0.wasm
59109
```
60110

111+
> [!NOTE]
112+
> The `go tool` directive (added in [Golang 1.24][go-1-24-release]) installs and enables use of `wit-bindgen-go`,
113+
> part of the Bytecode Alliance suite of Golang tooling.
114+
61115
The `internal` directory will contain the generated Go code that WIT package.
62116

63117
```console
64118
$ tree internal
65119
internal
66120
├── docs
67-
│ └── adder
68-
│ └── adder
69-
│ ├── adder.exports.go
70-
│ ├── adder.wasm.go
71-
│ ├── adder.wit
72-
│ ├── adder.wit.go
73-
│ └── empty.s
121+
│   └── adder
122+
│   ├── add
123+
│   │   ├── add.exports.go
124+
│   │   ├── add.wasm.go
125+
│   │   ├── add.wit.go
126+
│   │   └── empty.s
127+
│   └── adder
128+
│   └── adder.wit.go
74129
└── wasi
75130
├── cli
76-
│ └── stdout
77-
│ ├── empty.s
78-
│ ├── stdout.wasm.go
79-
│ └── stdout.wit.go
131+
│   ├── environment
132+
│   │   ├── empty.s
133+
│   │   ├── environment.wasm.go
134+
│   │   └── environment.wit.go
135+
│   ├── exit
136+
│   │   ├── empty.s
137+
│   │   ├── exit.wasm.go
138+
│   │   └── exit.wit.go
139+
│   ├── stderr
140+
│   │   ├── empty.s
141+
│   │   ├── stderr.wasm.go
142+
│   │   └── stderr.wit.go
143+
│   ├── stdin
144+
│   │   ├── empty.s
145+
│   │   ├── stdin.wasm.go
146+
│   │   └── stdin.wit.go
147+
│   ├── stdout
148+
│   │   ├── empty.s
149+
│   │   ├── stdout.wasm.go
150+
│   │   └── stdout.wit.go
151+
│   ├── terminal-input
152+
│   │   ├── empty.s
153+
│   │   ├── terminal-input.wasm.go
154+
│   │   └── terminal-input.wit.go
155+
│   ├── terminal-output
156+
│   │   ├── empty.s
157+
│   │   ├── terminal-output.wasm.go
158+
│   │   └── terminal-output.wit.go
159+
│   ├── terminal-stderr
160+
│   │   ├── empty.s
161+
│   │   ├── terminal-stderr.wasm.go
162+
│   │   └── terminal-stderr.wit.go
163+
│   ├── terminal-stdin
164+
│   │   ├── empty.s
165+
│   │   ├── terminal-stdin.wasm.go
166+
│   │   └── terminal-stdin.wit.go
167+
│   └── terminal-stdout
168+
│   ├── empty.s
169+
│   ├── terminal-stdout.wasm.go
170+
│   └── terminal-stdout.wit.go
171+
├── clocks
172+
│   ├── monotonic-clock
173+
│   │   ├── empty.s
174+
│   │   ├── monotonic-clock.wasm.go
175+
│   │   └── monotonic-clock.wit.go
176+
│   └── wall-clock
177+
│   ├── empty.s
178+
│   ├── wall-clock.wasm.go
179+
│   └── wall-clock.wit.go
180+
├── filesystem
181+
│   ├── preopens
182+
│   │   ├── empty.s
183+
│   │   ├── preopens.wasm.go
184+
│   │   └── preopens.wit.go
185+
│   └── types
186+
│   ├── abi.go
187+
│   ├── empty.s
188+
│   ├── types.wasm.go
189+
│   └── types.wit.go
80190
├── io
81-
│ ├── error
82-
│ │ ├── empty.s
83-
│ │ ├── error.wit.go
84-
│ │ └── ioerror.wasm.go
85-
│ └── streams
86-
│ ├── empty.s
87-
│ ├── streams.wasm.go
88-
│ └── streams.wit.go
89-
└── random
90-
└── random
191+
│   ├── error
192+
│   │   ├── empty.s
193+
│   │   ├── error.wasm.go
194+
│   │   └── error.wit.go
195+
│   ├── poll
196+
│   │   ├── empty.s
197+
│   │   ├── poll.wasm.go
198+
│   │   └── poll.wit.go
199+
│   └── streams
200+
│   ├── empty.s
201+
│   ├── streams.wasm.go
202+
│   └── streams.wit.go
203+
├── random
204+
│   ├── insecure
205+
│   │   ├── empty.s
206+
│   │   ├── insecure.wasm.go
207+
│   │   └── insecure.wit.go
208+
│   ├── insecure-seed
209+
│   │   ├── empty.s
210+
│   │   ├── insecure-seed.wasm.go
211+
│   │   └── insecure-seed.wit.go
212+
│   └── random
213+
│   ├── empty.s
214+
│   ├── random.wasm.go
215+
│   └── random.wit.go
216+
└── sockets
217+
├── instance-network
218+
│   ├── empty.s
219+
│   ├── instance-network.wasm.go
220+
│   └── instance-network.wit.go
221+
├── ip-name-lookup
222+
│   ├── abi.go
223+
│   ├── empty.s
224+
│   ├── ip-name-lookup.wasm.go
225+
│   └── ip-name-lookup.wit.go
226+
├── network
227+
│   ├── abi.go
228+
│   ├── empty.s
229+
│   ├── network.wasm.go
230+
│   └── network.wit.go
231+
├── tcp
232+
│   ├── abi.go
233+
│   ├── empty.s
234+
│   ├── tcp.wasm.go
235+
│   └── tcp.wit.go
236+
├── tcp-create-socket
237+
│   ├── empty.s
238+
│   ├── tcp-create-socket.wasm.go
239+
│   └── tcp-create-socket.wit.go
240+
├── udp
241+
│   ├── abi.go
242+
│   ├── empty.s
243+
│   ├── udp.wasm.go
244+
│   └── udp.wit.go
245+
└── udp-create-socket
91246
├── empty.s
92-
├── random.wasm.go
93-
└── random.wit.go
247+
├── udp-create-socket.wasm.go
248+
└── udp-create-socket.wit.go
249+
250+
39 directories, 91 files
94251
```
95252

96253
The `adder.exports.go` file contains the exported functions that need to be implemented in the Go code called `Exports`.
97254

98-
## 3. Implement the `add` Function
255+
## 4. Implement the `add` Function
99256

100257
```Go
258+
//go:generate go tool wit-bindgen-go generate --world adder --out internal ./docs:adder@0.1.0.wasm
259+
101260
package main
102261

103262
import (
104-
"example.com/internal/docs/adder/adder"
263+
"example.com/internal/docs/adder/add"
105264
)
106265

107266
func init() {
108-
adder.Exports.Add = func(x int32, y int32) int32 {
267+
add.Exports.Add = func(x uint32, y uint32) uint32 {
109268
return x + y
110269
}
111270
}
@@ -117,18 +276,19 @@ func main() {}
117276
Go's `init` functions are used to do initialization tasks that
118277
should be done before any other tasks. In this case, we are using it to export the `Add` function.
119278

120-
## 4. Build the Component
279+
## 5. Build the Component
121280

122281
We can build our component using TinyGo by specifying the wit-package to be `add.wit` and the WIT world to be `adder`.
123282

124283
Under the hood, TinyGo invokes `wasm-tools` to embed the WIT file to the module and componentize it.
125284

126285
```console
127-
$ tinygo build -target=wasip2 -o add.wasm --wit-package docs:adder@0.1.0.wasm --wit-world adder main.go
286+
tinygo build -target=wasip2 -o add.wasm --wit-package docs:adder@0.1.0.wasm --wit-world adder main.go
128287
```
129288

130289
We now have an add component that satisfies our `adder` world, exporting the `add` function, which
131-
we can confirm using the `wasm-tools component wit` command:
290+
291+
We can confirm using the `wasm-tools component wit` command:
132292

133293
```console
134294
$ wasm-tools component wit add.wasm

0 commit comments

Comments
 (0)