Skip to content
GitHub Get Started
Reference

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.

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.

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 cargo targeting wasm32-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-sdk toolchain, a packaged clang plus sysroot tuned for WASI. C tools that have no Rust equivalent (or that are easier to carry as upstream C) go through this path.
Terminal window
# Rust coreutils
cargo 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.wasm

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-ext bindings. These declare the extra WebAssembly import modules (host_process, host_user, host_net, and the small host_sleep_ms binding) that base WASI cannot express. Linking wasi-ext into a binary is what lets its libc emit fork / exec, getuid / getgid, and connect / listen as ordinary-looking syscalls that the host runtime then services through the kernel. See Layer 1: custom host import modules for the runtime half.

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.

  • Use the bundled WASM coreutils and sh for normal shell workloads; they already carry the patched libc and the wasi-ext extensions.
  • To ship your own command, compile it for wasm32-wasip1 with cargo (Rust) or the wasi-sdk clang (C), and link wasi-ext only if it needs the process / user / network host imports.
  • Keep the build and runtime contracts aligned: the patched wasi-libc and the wasi-ext import declarations a binary is compiled against are the same ones the WASM VM runtime expects to satisfy.