Hello!
I want to define a custom world that I use as a service interface between different WASM apps. But I also want to give those apps access to WASI. I thought this should be enough to make it work:
world imports {
// Our custom WIT world.
import game;
// Some of the base WASI worlds for file access and more. Makes it possible to rely on `stdlib` in
// various languages.
include wasi:filesystem@0.2.0;
include wasi:io@0.2.0;
}
(where game
is an interface). But when using wasmtime
to generate the binding code for the host, I get an error saying that /
was expected instead of @
. I assume my syntax for the include
statement is wrong. But I could not find any code that showcases how to import existing worlds.
This is the code I use in Rust to create the wasmtime bindgen:
wasmtime::component::bindgen!({
path: "./wit/world.wit",
world: "world",
});
Thank yoU!
Ah, sorry! The error I got was
error: failed to resolve directory while parsing WIT for path [/home/me/code/plugin-host/wit]
Caused by:
package not found
--> /home/me/code/plugin-host/wit/world.wit:9:13
|
9 | include wasi:filesystem/filesystem@0.2.0;
| ^--------------
I fixed the other one above earlier. Do I have to clone the WASI Wit files and put them next to my world?
Yeah for now you'll need to copy the *.wit
files for WASI into your project
(it's something we hope to improve in the future though)
At the end, my world looks like this:
package ugl:plugin;
world ugl {
// Our custom WIT world.
import game;
include wasi:filesystem/imports@0.2.0;
include wasi:io/imports@0.2.0;
Do I need to exclude the WASI worlds from bindgen? It looks like a bunch of types are generated for these worlds. At the end, I plan to use the existing wasmtime_wasi library that already implement the host part.
You can use the with
keyword to point the wasi bits over to the wasmtime_wasi
crate, but you can also omit it entirely with a separate world passed to wasmtime's bindgen
I really appreciate your help! Getting started with WASI and the component model is quite hard for me tbh.
I added the with
statement:
wasmtime::component::bindgen!({
world: "ugl",
with: {
"wasi:filesystem": wasmtime_wasi::bindings::filesystem,
"wasi:io": wasmtime_wasi::bindings::io,
},
});
And it seems to work. I only get add_to_linker
function references are missing. It sounds like the codegen relies on the function being imported inside the scope. But every module exports their own add_to_linker_get_host
function. So I am not sure how I can satisfy this condition for the io
and filesystem
. It looks to me like they both expect that their respective add_to_linker
functions are in scope.
❯ cargo check
Checking ugl-plugin-api v0.1.0 (/home/me/code/plugin-host)
error[E0425]: cannot find function `add_to_linker` in module `__with_name1::error`
--> src/lib.rs:1:1
|
1 | / wasmtime::component::bindgen!({
2 | | world: "ugl",
3 | | with: {
4 | | "wasi:filesystem": wasmtime_wasi::bindings::filesystem,
5 | | "wasi:io": wasmtime_wasi::bindings::io,
6 | | },
7 | | });
| |__^ not found in `__with_name1::error`
|
= note: this error originates in the macro `wasmtime::component::bindgen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider importing one of these items
|
1 + use crate::ugl::plugin::game::add_to_linker;
|
1 + use crate::wasi::clocks::wall_clock::add_to_linker;
|
1 + use wasmtime_wasi::preview0::wasi_unstable::add_to_linker;
|
1 + use wasmtime_wasi::preview1::wasi_snapshot_preview1::add_to_linker;
|
error[E0425]: cannot find function `add_to_linker` in module `__with_name1::poll`
--> src/lib.rs:1:1
|
1 | / wasmtime::component::bindgen!({
2 | | world: "ugl",
3 | | with: {
4 | | "wasi:filesystem": wasmtime_wasi::bindings::filesystem,
5 | | "wasi:io": wasmtime_wasi::bindings::io,
6 | | },
7 | | });
| |__^ not found in `__with_name1::poll`
|
= note: this error originates in the macro `wasmtime::component::bindgen` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider importing one of these items
|
1 + use crate::ugl::plugin::game::add_to_linker;
|
1 + use crate::wasi::clocks::wall_clock::add_to_linker;
|
1 + use wasmtime_wasi::preview0::wasi_unstable::add_to_linker;
|
1 + use wasmtime_wasi::preview1::wasi_snapshot_preview1::add_to_linker;
but you can also omit it entirely with a separate world passed to wasmtime's bindgen
I do not understand this part.
Ah yes that compile error is fixed in Wasmtime 22, that was a bug in Wasmtime 21
For separating the world that would involve having a second world
in WIT which doesn't have WASI, and that's what you use for bindgen. You'd then have a "real" world which would import wasi and include
this world
Alex Crichton said:
Ah yes that compile error is fixed in Wasmtime 22, that was a bug in Wasmtime 21
My wasmtime
dependency is using the git repository's main branch directly. Using that I got the above error.
wasmtime = { git = "https://github.com/bytecodealliance/wasmtime", features = ["component-model"] }
wasmtime-wasi ="21.0.1" # {git = "https://github.com/bytecodealliance/wasmtime" }
Using the git repository wasmtime-wasi
dependency complains about non-matching types for the T in Linker<T>.
You probably need to pin all wasmtime* deps to the same revision, e.g.
wasmtime = { git = "https://github.com/bytecodealliance/wasmtime", rev = "23409ca7e184ef3b7d42fe17938caed470643d5d" }
wasmtime-wasi = { git = "https://github.com/bytecodealliance/wasmtime", rev = "23409ca7e184ef3b7d42fe17938caed470643d5d" }
Last updated: Dec 23 2024 at 13:07 UTC