rustrust-wasmwasiwasmtime

Cannot load wasm component because of missing wasi:cli import


I am trying to load a wasm-component I wrote as a plugin in my rust app. Project is made of two main parts app and add: app contains the host application, add contains the plugin. The add plugin is described by this .wit file:

package calc:operator;

world operator {
    export compute: func(x: s32, y: s32) -> s32;
    export name: func() -> string;
}

The app plugin tries to load and instantiate the .wasm component I get by build add. Here is the code:

use wasmtime::component::{bindgen, Component, Linker, ResourceTable};
use wasmtime::{Config, Engine, Store};
use wasmtime_wasi::{WasiCtx, WasiCtxBuilder, WasiView};

fn main() {
    println!("Hello, world!");

    bindgen!({ world: "operator", path: "./wit/operator.wit", async: false });

    let mut config = Config::default();
    config.async_support(true);
    let engine = Engine::new(&config).unwrap();
    let mut wasi_ctx_builder = WasiCtxBuilder::new();

    let component = Component::from_file(
        &engine,
        "/path-to-project/wasm-calc/add/target/wasm32-wasip1/release/add.wasm",
    )
    .expect("Component file not found");

    let mut store = Store::new(
        &engine,
        ComponentState {
            ctx: wasi_ctx_builder.build(),
            table: ResourceTable::new(),
        },
    );
    let linker = Linker::new(&engine);
    let instance = Operator::instantiate(&mut store, &component, &linker)
        .expect("Failed to instantiate component");

    println!("operator name: {}", instance.call_name(&mut store).unwrap());
}

struct ComponentState {
    ctx: WasiCtx,
    table: ResourceTable,
}

impl WasiView for ComponentState {
    fn table(&mut self) -> &mut ResourceTable {
        &mut self.table
    }
    fn ctx(&mut self) -> &mut WasiCtx {
        &mut self.ctx
    }
}

Here is the add component code:

#[allow(warnings)]
mod bindings;

use bindings::Guest;

struct Add;

impl Guest for Add {
    fn compute(x: i32, y: i32) -> i32 {
        x + y
    }

    fn name() -> String {
        "Add".to_string()
    }
}

bindings::export!(Add with_types_in bindings);

When I do cargo run I get this error:

Hello, world!
thread 'main' panicked at src/main.rs:40:10:
Failed to instantiate component: component imports instance `wasi:cli/environment@0.2.0`, but a matching implementation was not found in the linker

Caused by:
    0: instance export `get-environment` has the wrong type
    1: function implementation is missing

I cannot get what wasi:cli is and why is involved, component is trivial.. I am using wasmtime and wasmtime-wasi, you can have a look at the whole thing here. What am I missing?


Solution

  • I finally got that working as I stumble into this page I obviously didn't read carefully. Accordingly to doc, I added wasmtime_wasi as dependency and added this line after linker call in main.rs file:

    wasmtime_wasi::add_to_linker_sync(&mut linker);
    

    That entry loads all the wasi worlds shipped by wasmtime_wasi to the linker allowing me to instantiate component succesfully.