Hey. Following along the instructions at https://github.com/bytecodealliance/wit-bindgen?tab=readme-ov-file#guest-tinygo
I'm not sure how to tinygo build if my-component.go is using package main, because then I can't access the wit-bindgen generated Go types in the package matching the interface name in my wit file. I'm using wit-bindgen to generate in the same directory as my-component.go, even though the example uses a subdirectory called gen. Am I supposed to generate the subpackage and install it in $GOPATH and resolve with a full repository/module url?
Got it working by treating it like a separate Go package. Derp.
We’re working on pure Go bindings for TinyGo: https://github.com/ydnar/wasm-tools-go
Currently it can generate Go bindings for imports, but not (yet) exports. It maps WIT types to their equivalent Go types where possible (e.g. enum->constants, records->structs, resources->handle types with methods).
Hi @Randy Reddig , I was trying out this binding generator, and ran into a issue. it is quite possible that it is due to WIP support for exports in wasm-tools-go, in which case I apologize to waste your time in advance:
foo.wit
interface foo {
greet: func() -> string;
}
from running wasm-tools component wit ./foo-wit -j > wit.json
{
"name": "foo",
"types": {},
"functions": {
"greet": {
"name": "greet",
"kind": "freestanding",
"params": [],
"results": [
{
"type": "string"
}
]
}
},
"package": 7
}
Then on trying to build using tinygo (using branch from here: https://github.com/dgryski/tinygo/tree/dgryski/wasi-preview-2):
tinygo build -target=wasip2 -wit-package ./foo-wit -wit-world foo-namespace:pkg/foo-world -o main.wasm -x -work main.go
error: failed to encode a component from module
Caused by:
0: failed to decode world from module
1: module was not valid
2: failed to validate exported interface `foo-namespace:pkg/foo@2.0.0`
3: type mismatch for function `greet`: expected `[] -> [I32]` but found `[I32, I32] -> []`
error: wasm-tools failed: exit status 1
On trying to use wasm-tools
to check the intermediary wasm file:
from running: wasm-tools mutate /var/folders/5r/6y6fr12x1dq6qnt74zn4_1wm0000gn/T/tinygo226195887/main -t | grep -i greet | head -1
:
(Notice the param i32 i32
, I was expecting it to be something like (param i32) (result i32)
(func $foo-namespace:pkg/foo@2.0.0#greet (;259;) (type 0) (param i32 i32)
The repo where I was trying this out is here: https://github.com/rajatjindal/foo-wasip2
is it possibly by any chance to workaround this prob or should I wait for wasm-tools-go
to have complete exports support.
Exports aren’t working yet
You can write them by hand with //export in TinyGo
with the fully-qualified namespace:package/interface#function name
thank you for your reply. I did try that, but still got same error (tried with both with init
and without it):
package foo
type Impl struct{}
//export foo-namespace:pkg/foo@2.0.0#greet
func (i *Impl) Greet() string {
return "hello from greet"
}
func init() {
instance = &Impl{}
}
adam said:
Hey. Following along the instructions at https://github.com/bytecodealliance/wit-bindgen?tab=readme-ov-file#guest-tinygo
I'm not sure how to tinygo build if my-component.go is using package main, because then I can't access the wit-bindgen generated Go types in the package matching the interface name in my wit file. I'm using wit-bindgen to generate in the same directory as my-component.go, even though the example uses a subdirectory called gen. Am I supposed to generate the subpackage and install it in $GOPATH and resolve with a full repository/module url?
In the latest release of wit-bindgen-cli
, I've included a flag to rename the package name of generated Go code to an user provided one. Hope that helps
e.g.
wit-bindgen tiny-go wasi-http/wit --world proxy --rename-package=test
I made some modification to the README and updated the example code: https://github.com/bytecodealliance/wit-bindgen/pull/921
Hopefully it should clarify things a bit :)
I think in my case I didn't have a valid golang module. Do you know why components compiled with TinyGo are 10-12 times smaller than compiled Rust components? Also, if I compiled a golang function with TinyGo that just adds two numbers, why does it need to have all the WASI imports in the component for a full fledge application?
A single line fn that just uses s32 and mod operator has all these imports. Filesystem and Stdio seem unnecessary.
package root:component;
world root {
import wasi:io/error@0.2.0;
import wasi:io/streams@0.2.0;
import wasi:cli/stdin@0.2.0;
import wasi:cli/stdout@0.2.0;
import wasi:cli/stderr@0.2.0;
import wasi:clocks/wall-clock@0.2.0;
import wasi:filesystem/types@0.2.0;
import wasi:filesystem/preopens@0.2.0;
export is-odd-or-even: func(number: s32) -> bool;
}
You’ve got it partially right. The function signature of the export needs to match what’s in the WIT.
Are you using wit-bindgen
or wit-bindgen-go
?
Rajat Jindal said:
thank you for your reply. I did try that, but still got same error (tried with both with
init
and without it):package foo type Impl struct{} //export foo-namespace:pkg/foo@2.0.0#greet func (i *Impl) Greet() string { return "hello from greet" } func init() { instance = &Impl{} }
Are you using
wit-bindgen
orwit-bindgen-go
?
I am trying out wit-bindgen-go
thank you for the pointer. i was able to fix that by changing def to:
package foo
func init() {
instance = &Impl{}
}
type Impl struct{}
func (i *Impl) Greet() string {
return "hello from greet"
}
//export foo-namespace:pkg/foo@2.0.0#greet
func GreetExported() *string {
x := instance.Greet()
return &x
}
this atleast get post the export error
i was getting earlier.
I tried implementing the export bindings for response-outparam (for inbound-http), but that seemed quite involved. I will try it again over the weekend.
Last updated: Dec 23 2024 at 12:05 UTC