C and C++ without Emscripten

16.1 Bare Clang to wasm32

// tiny.c: no libc
__attribute__((export_name("add")))
int add(int a, int b) { return a + b; }

__attribute__((import_module("env"), import_name("log_int")))
void log_int(int);

__attribute__((export_name("run")))
void run(void) { log_int(add(40, 2)); }
clang --target=wasm32 -O3 -nostdlib -Wl,--no-entry -Wl,--export-dynamic -o tiny.wasm tiny.c
wasm-opt -Oz tiny.wasm -o tiny.min.wasm

16.2 wasi-sdk (C/C++ with libc, for WASI)

wasm2c (WABT) converts Wasm back to C for sandboxed native libraries (as used by Firefox's RLBox).

// hello.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
    printf("Hello, WASI! args=%d\n", argc);
    FILE* f = fopen("/data/out.txt", "w");
    if (f) { fputs("written from wasm\n", f); fclose(f); }
    return 0;
}
$WASI_SDK/bin/clang --target=wasm32-wasip1 -O2 hello.c -o hello.wasm
wasmtime run --dir ./data::/data hello.wasm arg1 arg2
$WASI_SDK/bin/clang --target=wasm32-wasip2 -O2 hello.c -o hello-p2.wasm   # component output (WASI 0.2)