C
C and C++ can be used to compile WASM modules using WASI Preview 1 by using https://github.com/WebAssembly/wasi-sdk/releases (opens in a new tab).
You also have to install everything as described in Common tooling.
First download and extract wasi-sdk somewhere - in the examples we assume it is put in ~/wasi-sdk-20.0
.
The easiest way to get started once the tooling is installed is to use the golem new
command as described in the Quickstart.
If you prefer to do it manually from scratch, you first need to create a wit
directory and a main.wit
file in it describing your component's interface, and optionally adding additional dependencies in wit/deps
from the golem package (wasi-http, promise api, etc).
The following example main.wit
does not use any extra imports but defines two exported functions for your component:
package my:component;
world c-api1 {
export run: func() -> s32;
export print: func(s: string) -> ();
}
Then generate bindings from this WIT using wit-bindgen
:
wit-bindgen c --autodrop-borrows yes ./deps
This will generate some .c
, .h
and .o
files. Write a new main.c
file implementing the functions generated by wit-bindgen
:
#include <stdio.h>
#include <time.h>
#include "c_api1.h"
int32_t main(void) {
return 0;
}
int32_t c_api1_run(void) {
printf("Hello World!\n");
return 100;
}
void c_api1_print(c_api1_string_t *s) {
char* buf = malloc(s->len + 1);
memset(buf, 0, s->len + 1);
strncpy(buf, s->ptr, s->len);
time_t t = time(NULL);
struct tm tm = *localtime(&t);
printf("%s %d\n", buf, tm.tm_year + 1900);
}
and compile it to WASM using the clang
included in wasi-sdk
:
~/wasi-sdk-20.0/bin/clang --sysroot ~/wasi-sdk-20.0/share/wasi-sysroot main.c c_api1.c c_api1_component_type.o -o main.wasm
~/wasi-sdk-20.0/bin/clang++
if you are using C++ insteadThe resulting main.wasm
is a WASM module which already has the binary representation of the WIT definitions embedded (that's what is in the generated .o
).
So the only remaining step is to turn this into a WASM component using wasm-tools
:
wasm-tools component new main.wasm --adapt tier1/wasi_snapshot_preview1.wasm -o component.wasm
The resulting component.wasm
is ready to be uploaded to Golem!