Skip to content

Commit 76238d7

Browse files
refactor(pl/rust): discuss runnable command components first
1 parent 03e76d9 commit 76238d7

File tree

2 files changed

+69
-63
lines changed

2 files changed

+69
-63
lines changed

component-model/src/creating-runnable-components.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ This section contains language-specific guides on how to create runnable compone
55
At a high level there are at least two ways to create components that are more like binaries than libraries
66
(i.e. that are easy to run from a tool like `wasmtime`):
77

8-
1. Exporting the `wasi:cli/run` interface (recommended)
9-
2. Creating a "command" component
8+
1. Creating a "command" component
9+
2. Exporting the `wasi:cli/run` interface
1010

1111
This section explores how to do the above in relevant languages.
1212

component-model/src/language-support/creating-runnable-components/rust.md

Lines changed: 67 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,76 @@
11
# Creating Runnable Components (Rust)
22

3-
## Exporting the `wasi:cli/run` interface
3+
## Creating a command component
4+
5+
A _command_ is a component with a specific export that allows it to be executed directly by `wasmtime`
6+
(or other `wasi:cli` hosts). In Rust terms, it's the equivalent of an application (`bin`) package with
7+
a `main` function, instead of a library crate (`lib`) package.
8+
9+
Command components work by including a WebAssembly core export `_start` that indicates the component
10+
has a natural `main`-like starting point.
11+
12+
### 1. Create a new Rust binary project
13+
14+
To create a command with cargo, run:
15+
16+
```sh
17+
cargo new runnable-example
18+
```
19+
20+
Unlike library components, this does _not_ have the `--lib` flag (`--bin` is the default for `cargo new`).
21+
22+
The created Rust source file is called `main.rs` instead of `lib.rs`, and contains a `main` function.
23+
24+
You can write Rust in this project, just as you normally would, including importing your own or third-party crates.
25+
26+
> All the crates that make up your project are linked together at build time, and compiled to a _single_ Wasm component. In this case, all the linking is happening at the Rust level: no WITs or component composition is involved. Only if you import Wasm interfaces do WIT and composition come into play.
27+
28+
### 2. Write the relevant Rust
29+
30+
The following code can be inserted into `runnable-example/src/main.rs`:
31+
32+
```rust
33+
pub fn main() {
34+
eprintln!("Hello World!");
35+
}
36+
```
37+
38+
### 3. Build the component
39+
40+
To build the component, use `cargo`:
41+
42+
```sh
43+
cargo build --target=wasm32-wasip2
44+
```
45+
46+
The component can also be built in release mode:
47+
48+
```console
49+
cargo build --target=wasm32-wasip2 --release
50+
```
51+
52+
### 4. Run the component with `wasmtime`
53+
54+
To run your command component:
55+
56+
```sh
57+
wasmtime run ./target/wasm32-wasip2/debug/runnable-example.wasm
58+
```
59+
60+
> [!WARNING]
61+
> If your program prints to standard out or error, you may not see the printed output!
62+
>
63+
> Some versions of `wasmtime` have a bug where they don't flush output streams before exiting. To work
64+
> around this, add a `std::thread::sleep()` with a 10 millisecond delay before exiting `main`.
65+
66+
## Enabling a library component to be run via the `wasi:cli/run` interface
467

568
Any reactor (library-like) component can *also* export the [`run` interface][wasi-cli-iface-run] inside [WASI CLI][wasi-cli],
669
and signal to consumers that the library can also be run similarly to a binary.
770

71+
Unlike command components, library components have no `_start`, but by exporting the `wasi:cli/run` interface,
72+
tooling that recognizes these exports can easily execute the given WebAssembly binary (e.g. `wasmtime run`).
73+
874
[wasi-cli-iface-run]: https://github.com/WebAssembly/wasi-cli/tree/main/wit/run.wit
975
[wasi-cli]: https://github.com/WebAssembly/wasi-cli
1076

@@ -125,63 +191,3 @@ the interface and function to run (`wasi:cli/run` is detected and used automatic
125191
$ wasmtime run target/wasm32-wasip2/runnable-example.wasm
126192
Hello World!
127193
```
128-
129-
## Creating a command component
130-
131-
A _command_ is a component with a specific export that allows it to be executed directly by `wasmtime`
132-
(or other `wasi:cli` hosts). In Rust terms, it's the equivalent of an application (`bin`) package with
133-
a `main` function, instead of a library crate (`lib`) package.
134-
135-
### 1. Create a new Rust binary project
136-
137-
To create a command with cargo, run:
138-
139-
```sh
140-
cargo new runnable-example
141-
```
142-
143-
Unlike library components, this does _not_ have the `--lib` flag (`--bin` is the default for `cargo new`).
144-
145-
The created Rust source file is called `main.rs` instead of `lib.rs`, and contains a `main` function.
146-
147-
You can write Rust in this project, just as you normally would, including importing your own or third-party crates.
148-
149-
> All the crates that make up your project are linked together at build time, and compiled to a _single_ Wasm component. In this case, all the linking is happening at the Rust level: no WITs or component composition is involved. Only if you import Wasm interfaces do WIT and composition come into play.
150-
151-
### 2. Write the relevant Rust
152-
153-
The following code can be inserted into `runnable-example/src/main.rs`:
154-
155-
```rust
156-
pub fn main() {
157-
eprintln!("Hello World!");
158-
}
159-
```
160-
161-
### 3. Build the component
162-
163-
To build the component, use `cargo`:
164-
165-
```sh
166-
cargo build --target=wasm32-wasip2
167-
```
168-
169-
The component can also be built in release mode:
170-
171-
```console
172-
cargo build --target=wasm32-wasip2 --release
173-
```
174-
175-
### 4. Run the component with `wasmtime`
176-
177-
To run your command component:
178-
179-
```sh
180-
wasmtime run ./target/wasm32-wasip2/debug/runnable-example.wasm
181-
```
182-
183-
> [!WARNING]
184-
> If your program prints to standard out or error, you may not see the printed output!
185-
>
186-
> Some versions of `wasmtime` have a bug where they don't flush output streams before exiting. To work
187-
> around this, add a `std::thread::sleep()` with a 10 millisecond delay before exiting `main`.

0 commit comments

Comments
 (0)