Skip to content

Commit bdaab9b

Browse files
Merge pull request #214 from seanisom/fix-c-docs
Fix c docs
2 parents d59327f + aaecec5 commit bdaab9b

File tree

3 files changed

+42
-22
lines changed

3 files changed

+42
-22
lines changed

Diff for: component-model/examples/example-host/src/async_add.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ pub async fn add(path: PathBuf, x: i32, y: i32) -> wasmtime::Result<i32> {
2121
let wasi_view = States::new();
2222
let mut store = Store::new(&engine, wasi_view);
2323
// Construct linker for linking interfaces.
24-
// For this simple adder component, no need to link additional interfaces.
25-
let linker = Linker::new(&engine);
24+
// For this simple adder component, no need to manually link additional interfaces.
25+
let mut linker = Linker::new(&engine);
26+
// Add wasi exports to linker to support io interfaces
27+
wasmtime_wasi::add_to_linker_async(&mut linker)?;
2628
let instance = Example::instantiate_async(&mut store, &component, &linker)
2729
.await
2830
.context("Failed to instantiate the example world")?;

Diff for: component-model/examples/example-host/src/sync_add.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use anyhow::Context;
33
use std::path::PathBuf;
44
use wasmtime::component::{bindgen, Component, Linker};
55
use wasmtime::{Engine, Store};
6+
use wasmtime_wasi;
67

78
bindgen!({
89
path: "add.wit",
@@ -19,8 +20,10 @@ pub fn add(path: PathBuf, x: i32, y: i32) -> wasmtime::Result<i32> {
1920
let wasi_view = States::new();
2021
let mut store = Store::new(&engine, wasi_view);
2122
// Construct linker for linking interfaces.
22-
// For this simple adder component, no need to link additional interfaces.
23-
let linker = Linker::new(&engine);
23+
// For this simple adder component, no need to manually link additional interfaces.
24+
let mut linker = Linker::new(&engine);
25+
// Add wasi exports to linker to support io interfaces
26+
wasmtime_wasi::add_to_linker_sync(&mut linker).expect("Could not add wasi to linker");
2427
let instance = Example::instantiate(&mut store, &component, &linker)
2528
.context("Failed to instantiate the example world")?;
2629
instance

Diff for: component-model/src/language-support/c.md

+33-18
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,21 @@ First, install the CLI for [`wit-bindgen`](https://github.com/bytecodealliance/w
1010

1111
The WASI SDK will install a local version of `clang` configured with a wasi-sysroot. Follow [these instructions](https://github.com/WebAssembly/wasi-sdk#use) to configure it for use. Note that you can also use your installed system or emscripten `clang` by building with `--target=wasm32-wasi` but you will need some artifacts from WASI SDK to enable and link that build target (more information is available in WASI SDK's docs).
1212

13-
Start by generating a C skeleton from `wit-bindgen` using the [sample `add.wit` file](../../examples/example-host/add.wit):
13+
Start by generating a C skeleton from `wit-bindgen` using the [sample `add.wit` file](https://github.com/bytecodealliance/component-docs/tree/main/component-model/examples/example-host/add.wit):
1414
```sh
1515
>wit-bindgen c add.wit
1616
Generating "example.c"
1717
Generating "example.h"
1818
Generating "example_component_type.o"
1919
```
2020

21-
This has generated several files - an `example.h` (based on the name of your `world`) with the prototype of the `add` function - `int32_t example_add(int32_t x, int32_t y);`, as well as some generated code in `example.c` that interfaces with the component model ABI to call your function. Additionally, `example_component_type.o` contains object code referenced in `example.c` from an `extern` that must be linked via clang.
21+
This has generated several files - an `example.h` (based on the name of your `world`) with the prototype of the `add` function (prefixed by `exports_`) - `int32_t exports_example_add(int32_t x, int32_t y);`, as well as some generated code in `example.c` that interfaces with the component model ABI to call your function. Additionally, `example_component_type.o` contains object code referenced in `example.c` from an `extern` that must be linked via clang.
2222

2323
Next, create an `add.c` that implements your function defined in `example.h`:
2424
```c
2525
#include "example.h"
2626

27-
int32_t example_add(int32_t x, int32_t y)
27+
int32_t exports_example_add(int32_t x, int32_t y)
2828
{
2929
return x + y;
3030
}
@@ -49,7 +49,7 @@ For example, modifying the above to reference `printf()` would compile:
4949
#include "example.h"
5050
#include <stdio.h>
5151

52-
int32_t example_add(int32_t x, int32_t y)
52+
int32_t exports_example_add(int32_t x, int32_t y)
5353
{
5454
int32_t result = x + y;
5555
printf("%d", result);
@@ -81,22 +81,37 @@ Finally, you can inspect the embedded wit to see your component (including any W
8181
package root:component;
8282

8383
world root {
84-
import wasi:io/[email protected].0;
85-
import wasi:io/[email protected].0;
86-
import wasi:cli/[email protected].0;
87-
import wasi:cli/[email protected].0;
88-
import wasi:cli/[email protected].0;
89-
import wasi:cli/[email protected].0;
90-
import wasi:cli/[email protected].0;
91-
import wasi:cli/[email protected].0;
92-
import wasi:cli/[email protected].0;
93-
import wasi:cli/[email protected].0;
94-
import wasi:clocks/[email protected].0;
95-
import wasi:filesystem/[email protected].0;
96-
import wasi:filesystem/[email protected].0;
84+
import wasi:io/[email protected].2;
85+
import wasi:io/[email protected].2;
86+
import wasi:cli/[email protected].2;
87+
import wasi:cli/[email protected].2;
88+
import wasi:cli/[email protected].2;
89+
import wasi:cli/[email protected].2;
90+
import wasi:cli/[email protected].2;
91+
import wasi:cli/[email protected].2;
92+
import wasi:cli/[email protected].2;
93+
import wasi:cli/[email protected].2;
94+
import wasi:clocks/[email protected].2;
95+
import wasi:filesystem/[email protected].2;
96+
import wasi:filesystem/[email protected].2;
9797

9898
export add: func(x: s32, y: s32) -> s32;
9999
}
100+
...
101+
```
102+
103+
You must use the `wasi_snapshot_preview1.wasm` from the same version of wasmtime that the host is using to ensure the WASI interface versions match. Additionally, the host must explicitly [add WASI to the linker](https://docs.wasmtime.dev/api/wasmtime_wasi/fn.add_to_linker_sync.html) to run the app. If these are not configured correctly, you may see errors like the following:
104+
```sh
105+
cargo run --release -- 1 2 add-component.wasm
106+
Compiling example-host v0.1.0 (/Users/sean/code/component-docs/component-model/examples/example-host)
107+
Finished `release` profile [optimized] target(s) in 7.85s
108+
Running `target/release/example-host 1 2 add-component.wasm`
109+
Error: Failed to instantiate the example world
110+
111+
Caused by:
112+
0: component imports instance `wasi:io/[email protected]`, but a matching implementation was not found in the linker
113+
1: instance export `error` has the wrong type
114+
2: resource implementation is missing
100115
```
101116

102117
### Running a Component from C/C++ Applications
@@ -105,4 +120,4 @@ It is not yet possible to run a Component using the `wasmtime` `c-api` - [see th
105120

106121
However, C/C++ language guest components can be composed with components written in any other language and run by their toolchains, or even composed with a C language command component and run via the `wasmtime` CLI or any other host.
107122

108-
See the [Rust Tooling guide](../language-support/rust.md#running-a-component-from-rust-applications) for instructions on how to run this component from the Rust `example-host`.
123+
See the [Rust Tooling guide](../language-support/rust.md#running-a-component-from-rust-applications) for instructions on how to run this component from the Rust `example-host` (replacing the path to `add.wasm` with your `add-component` above).

0 commit comments

Comments
 (0)