Add example wasm component and runner which embeds the component
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/target
|
||||||
|
bindings.rs
|
||||||
1436
Cargo.lock
generated
Normal file
1436
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
[workspace]
|
||||||
|
|
||||||
|
members = [
|
||||||
|
"component",
|
||||||
|
"runner",
|
||||||
|
]
|
||||||
33
README.md
Normal file
33
README.md
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Wasmtime test
|
||||||
|
|
||||||
|
Example project showcasing how to run a wasm component with wasmtime, and how to build the runnable component using cargo component.
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
|
||||||
|
### component
|
||||||
|
|
||||||
|
This package includes an example wasm component, which simply calls a `hello()` function provided by the runner.
|
||||||
|
|
||||||
|
### runner
|
||||||
|
|
||||||
|
This package includes an example runtime, to run the built wasm component from the component package.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
First run `cargo component build -p component --release` to build the wasm component.
|
||||||
|
|
||||||
|
Then run `cargo run -p runner --release` to run the runner with the build wasm component from the previous step.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
If you see errors about imports missing when trying to run the compiled component, it's likely there's a dependency on std that isn't supported by the runtime linker (e.g. by calling `println!()`).
|
||||||
|
To build without std components, run the following:
|
||||||
|
|
||||||
|
`cargo component build --target wasm32-unknown-unknown --release`
|
||||||
|
|
||||||
|
Note this is only required when using std components. Preferably don't do this, and instead
|
||||||
|
use #![no_std] to not accidentally use std. Otherwise, you'll need to either use a runtime that includes std (e.g. wasmtime cli), or add the appropriate imports to the runtime linker.
|
||||||
|
|
||||||
|
To check the imports and exports for a compiled .wasm component, run the following (where component.wasm is the compiled .wasm file to inspect):
|
||||||
|
|
||||||
|
`wasm-tools component wit component.wasm`
|
||||||
13
component/Cargo.toml
Normal file
13
component/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[package]
|
||||||
|
name = "component"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
wit-bindgen-rt = { version = "0.24.0", features = ["bitflags"] }
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[package.metadata.component]
|
||||||
|
package = "component:test"
|
||||||
14
component/src/lib.rs
Normal file
14
component/src/lib.rs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#[allow(warnings)]
|
||||||
|
mod bindings;
|
||||||
|
|
||||||
|
use bindings::{hello, Guest};
|
||||||
|
|
||||||
|
struct Component;
|
||||||
|
|
||||||
|
impl Guest for Component {
|
||||||
|
fn greet() {
|
||||||
|
hello();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bindings::export!(Component with_types_in bindings);
|
||||||
6
component/wit/test.wit
Normal file
6
component/wit/test.wit
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package my:project;
|
||||||
|
|
||||||
|
world test {
|
||||||
|
import hello: func();
|
||||||
|
export greet: func();
|
||||||
|
}
|
||||||
7
runner/Cargo.toml
Normal file
7
runner/Cargo.toml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "wasmtime-test"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
wasmtime = {version = "20.0.2", features = ["component-model"]}
|
||||||
37
runner/src/main.rs
Normal file
37
runner/src/main.rs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
use wasmtime::{
|
||||||
|
component::{bindgen, Component, Linker},
|
||||||
|
Config, Engine, Store,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Defaults to 'wit' folder adjacent to cargo.toml.
|
||||||
|
// Change folder by using: bindgen!(in "other/with/folder")
|
||||||
|
bindgen!();
|
||||||
|
|
||||||
|
struct TestState {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestImports for TestState {
|
||||||
|
fn hello(&mut self) -> std::result::Result<(), wasmtime::Error> {
|
||||||
|
println!("{}", self.name);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> wasmtime::Result<()> {
|
||||||
|
let mut config = Config::new();
|
||||||
|
config.wasm_component_model(true);
|
||||||
|
let engine = Engine::new(&config)?;
|
||||||
|
let component = Component::from_file(&engine, "target/wasm32-wasi/release/component.wasm")?;
|
||||||
|
let mut linker = Linker::new(&engine);
|
||||||
|
Test::add_to_linker(&mut linker, |state: &mut TestState| state)?;
|
||||||
|
let mut store = Store::new(
|
||||||
|
&engine,
|
||||||
|
TestState {
|
||||||
|
name: "Hello World".to_string(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let (bindings, _) = Test::instantiate(&mut store, &component, &linker)?;
|
||||||
|
bindings.call_greet(&mut store)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
6
runner/wit/test.wit
Normal file
6
runner/wit/test.wit
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package my:project;
|
||||||
|
|
||||||
|
world test {
|
||||||
|
import hello: func();
|
||||||
|
export greet: func();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user