Welcome to the new Golem Cloud Docs! 👋
Documentation
Experimental Languages
Zig
Building Components

Building Golem Components in Zig

Building Golem components written in Zig involves a few steps.

If the project was created with golem-cli new, it already has a build.zig file that incorporates all the necessary steps to build the component, so it is enough to run:

$ zig build

In details, building the component requires the following steps:

Generate the C bindings from the WIT files

const bindgen = b.addSystemCommand(&.{ "wit-bindgen", "c", "--autodrop-borrows", "yes", "./wit", "--out-dir", "src/bindings" });

Use the WASM32/WASI target

const wasm = b.addExecutable(.{ .name = "main", .root_source_file = b.path("src/main.zig"), .target = b.resolveTargetQuery(.{
    .cpu_arch = .wasm32,
    .os_tag = .wasi,
}), .optimize = optimize });

Include the generated C bindings

const binding_root = "src/bindings";
var binding_root_dir = try std.fs.cwd().openDir(binding_root, .{ .iterate = true});
defer binding_root_dir.close();
var it = try binding_root_dir.walk(b.allocator);
while (try it.next()) |entry| {
    switch (entry.kind) {
        .file => {
            const path = b.pathJoin(&.{ binding_root, entry.path });
            if (std.mem.endsWith(u8, entry.basename, ".c")) {
                wasm.addCSourceFile(.{ .file = b.path(path), .flags = &.{} });
            } else if (std.mem.endsWith(u8, entry.basename, ".o")) {
                wasm.addObjectFile(b.path(path));
            }
        },
        else => continue,
    }
}
 
wasm.addIncludePath(b.path(binding_root));
wasm.linkLibC();
 
wasm.step.dependOn(&bindgen.step);

Package it into a WASM component

The resulting WASM file is a WebAssembly module, not a component. To be able to use it as a Golem component, use wasm-tools to package the module as a component:

const adapter = b.option([]const u8, "adapter", "Path to the Golem Tier1 WASI adapter") orelse "adapters/tier1/wasi_snapshot_preview1.wasm";
const out = try std.fmt.allocPrint(b.allocator, "zig-out/bin/{s}", .{wasm.out_filename});
const component = b.addSystemCommand(&.{ "wasm-tools", "component", "new", out, "-o", "zig-out/bin/component.wasm", "--adapt", adapter });
component.step.dependOn(&wasm.step);
 
b.installArtifact(wasm);
b.getInstallStep().dependOn(&component.step);

Note that the adapters/tier1/wasi_snapshot_preview1.wasm file is placed in the project's directory when using golem-cli new to create the new project.

If needed, it can be manually downloaded from https://github.com/golemcloud/golem-wit/blob/main/adapters/tier1/wasi_snapshot_preview1.wasm (opens in a new tab)