...
1## WASI example
2
3This example shows how to use I/O in your WebAssembly modules using WASI
4(WebAssembly System Interface).
5
6```bash
7$ go run cat.go /test.txt
8greet filesystem
9```
10
11If you do not set the environment variable `TOOLCHAIN`, main defaults
12to use Wasm built with "tinygo". Here are the included examples:
13
14* [cargo-wasi](testdata/cargo-wasi) - Built via `cargo wasi build --release; mv ./target/wasm32-wasi/release/cat.wasm .`
15* [tinygo](testdata/tinygo) - Built via `tinygo build -o cat.wasm -scheduler=none --no-debug -target=wasi cat.go`
16* [zig](testdata/zig) - Built via `zig build-exe cat.zig -target=wasm32-wasi -OReleaseSmall`
17* [zig-cc](testdata/zig-cc) - Built via `zig cc cat.c -o cat.wasm --target=wasm32-wasi -O3`
18
19To run the same example with zig-cc:
20
21```bash
22$ TOOLCHAIN=zig-cc go run cat.go /test.txt
23greet filesystem
24```
25
26### Toolchain notes
27
28Examples here check in the resulting binary, as doing so removes a potentially
29expensive toolchain setup. This means we have to be careful how wasm is built,
30so that the repository doesn't bloat (ex more bandwidth for `git clone`).
31
32While WASI attempts to be portable, there are no specification tests and
33some compilers partially implement features. Notes about portability follow.
34
35### cargo-wasi (Rustlang)
36
37The [Rustlang source](testdata/cargo-wasi) uses [cargo-wasi][1] because the
38normal release target `wasm32-wasi` results in almost 2MB, which is too large
39to check into our source tree.
40
41Concretely, if you use `cargo build --target wasm32-wasi --release`, the binary
42`./target/wasm32-wasi/release/cat.wasm` is over 1.9MB. One explanation for this
43bloat is [`wasm32-wasi` target is not pure rust][2]. As that issue is over two
44years old, it is unlikely to change. This means the only way to create smaller
45wasm is via optimization.
46
47The [cargo-wasi][3] crate includes many optimizations in its release target,
48including `wasm-opt`, a part of [binaryen][4]. `cargo wasi build --release`
49generates 82KB of wasm, which is small enough to check in.
50
51### emscripten
52
53Emscripten is not included as we cannot create a cat program without using
54custom filesystem code. Emscripten only supports WASI I/O for
55stdin/stdout/stderr and [suggest using wasi-libc instead][5]. This is used in
56the [zig-cc](testdata/zig-cc) example.
57
58[1]: https://github.com/bytecodealliance/cargo-wasi
59
60[2]: https://github.com/rust-lang/rust/issues/73432
61
62[3]: https://github.com/bytecodealliance/cargo-wasi
63
64[4]: https://github.com/WebAssembly/binaryen
65
66[5]: https://github.com/emscripten-core/emscripten/issues/17167#issuecomment-1150252755
View as plain text