Welcome to the new Golem Cloud Docs! 👋

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
💡
Use ~/wasi-sdk-20.0/bin/clang++ if you are using C++ instead

The 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!