Compiler Toolchain
The commands a guest runs through process execution, the shell
(sh) and the coreutils behind it, are not native host binaries. They are
WebAssembly modules compiled ahead of time and mounted into the VM. This page
covers how that command suite is produced: which toolchains compile it, what it
links against, and how the resulting .wasm files become the guest’s commands.
For why WASM is a first-class guest and how it presents a POSIX surface at runtime, see the WASM VM page. This page is the build-side counterpart: it documents the toolchain that emits binaries carrying both the host-import layer and the WASI shim.
Target: wasm32-wasip1
Section titled “Target: wasm32-wasip1”Everything in the command suite is compiled to a single target,
wasm32-wasip1: the WASI preview 1 ABI on the 32-bit WebAssembly architecture.
Picking one target for the whole suite means a single libc, a single set of
host import declarations, and a single runtime shim can serve every command.
A guest module built for this target expects standard WASI (preopened file descriptors, clocks, randomness, file I/O) plus the extra agentOS import modules described below. Both halves are satisfied at runtime by the kernel-backed runtime; nothing in a compiled command reaches a real host syscall.
Two source languages, two compilers
Section titled “Two source languages, two compilers”The suite is heterogeneous: most tools are Rust, some are C. Each language uses
its own compiler driver, but both emit the same wasm32-wasip1 ABI and link
against the same sysroot, so the outputs are interchangeable at runtime.
- Rust coreutils are built with
cargotargetingwasm32-wasip1. Rust’s standard library already has first-class support for this target, so the coreutils crates compile with an ordinary cross-compile invocation. - C programs are built with the
wasi-sdktoolchain, a packagedclangplus sysroot tuned for WASI. C tools that have no Rust equivalent (or that are easier to carry as upstream C) go through this path.
# Rust coreutilscargo build --target wasm32-wasip1 --release
# C programs via wasi-sdk, linked against the patched libc + wasi-ext$WASI_SDK/bin/clang --target=wasm32-wasip1 \ --sysroot=$WASI_SYSROOT \ -lwasi-ext \ tool.c -o tool.wasmWhat every binary links against
Section titled “What every binary links against”Regardless of source language, each command links against the same two pieces. Together they give a single binary both the standard WASI calls and the agentOS process / user / network extensions.
- A patched
wasi-libc. The libc is the WASI standard library, modified so that the calls a normal command-line program performs resolve against the agentOS surface instead of failing or hitting unimplemented stubs. This is the same patched libc the Layer 2 shim adapts at runtime; the build side and the runtime side are two ends of the same contract. - The
wasi-extbindings. These declare the extra WebAssembly import modules (host_process,host_user,host_net, and the smallhost_sleep_msbinding) that base WASI cannot express. Linkingwasi-extinto a binary is what lets its libc emitfork/exec,getuid/getgid, andconnect/listenas ordinary-looking syscalls that the host runtime then services through the kernel. See Layer 1: custom host import modules for the runtime half.
From .wasm to a guest command
Section titled “From .wasm to a guest command”The compiler toolchain’s product is a set of .wasm files, one per command.
Those files are what the runtime mounts as the guest’s executables: when a guest
invokes ls, sh, or any other bundled tool, the kernel resolves the name to
the corresponding module, instantiates it with the host imports and the WASI
shim wired in, and runs it as a child process with real
process, user, and network semantics, all virtualized.
The same path is open to your own programs. A program you compile for
wasm32-wasip1 runs as a guest command exactly like the bundled ones; link the
wasi-ext bindings if it needs processes, users, or sockets, and leave them out
for a pure-compute tool. Heavy native binaries that are not yet available as
WASM belong in a mounted sandbox instead.
Recommendations
Section titled “Recommendations”- Use the bundled WASM coreutils and
shfor normal shell workloads; they already carry the patched libc and thewasi-extextensions. - To ship your own command, compile it for
wasm32-wasip1withcargo(Rust) or thewasi-sdkclang(C), and linkwasi-extonly if it needs the process / user / network host imports. - Keep the build and runtime contracts aligned: the patched
wasi-libcand thewasi-extimport declarations a binary is compiled against are the same ones the WASM VM runtime expects to satisfy.