Can't build a wasm version of a project based on sokol-zig

Hello,

I’m in the throes of learning Zig (but really loving it!) and the build system, and I’m currently struggling with getting a wasm build completed of a simple sokol-zig test project.

I’m working out of my own zig init’d project directory, and I added sokol-zig with zig fetch. Everything is fine if I build natively, but trying to build for wasm results in this error:

$ zig build -Dtarget=wasm32-emscripten  -Doptimize=ReleaseSmall
install
└─ install sokoltest
   └─ zig build-exe sokoltest ReleaseSmall wasm32-emscripten failure
error: error: unable to find or provide libc for target 'wasm32-emscripten-musl'

I know it’s calling down into the sokol-zig build.zig because if I set the target to wasm32-freestanding instead I get the following error:

 zig build -Dtarget=wasm32-freestanding
error: Please build with 'zig build -Dtarget=wasm32-emscripten
thread 1116791 panic: unhandled error
/Users/zach/.cache/zig/p/12200f54d3d37b99ecde3987c1fdc744d87b40595cc32e8943db82635498f14c0db0/build.zig:177:13: 0x10484c5af in buildLibSokol (build)
            return error.Wasm32EmscriptenExpected;
            ^
[snip]

It also ran through the process of installing the Emscripten tools, a step which is also defined in the sokol-zig build.zig file.

If I clone sokol-zig separately and run zig build -Dtarget=wasm32-emscripten, it builds all the sokol wasm examples just fine.

It seems to me that what I need for my project to build ('wasm32-emscripten-musl?) is available on the system, but the build is unable to find it.

Here is the sokol-zig build.zig file: sokol-zig/build.zig at master · floooh/sokol-zig · GitHub

Here is mine:

const std = @import("std");
const Build = std.Build;
const OptimizeMode = std.builtin.OptimizeMode;

pub fn build(b: *Build) !void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});
    const dep_sokol = b.dependency("sokol", .{
        .target = target,
        .optimize = optimize,
    });
    const sokoltest = b.addExecutable(.{
        .name = "sokoltest",
        .target = target,
        .optimize = optimize,
        .root_source_file = b.path("src/main.zig"),
    });
    sokoltest.root_module.addImport("sokol", dep_sokol.module("sokol"));
    b.installArtifact(sokoltest);
    const run = b.addRunArtifact(sokoltest);
    b.step("run", "Run sokoltest").dependOn(&run.step);
}

Could someone with experience around this type of issue kindly provide some guidance? I apologize in advance if this is an obvious question, but I can’t seem to find an answer so I figured I would ask here! I’m happy to provide any additional information if necessary.

Thanks!

To target Emscripten you will unfortunately need to install Emscripten and use the emcc binary as a linker. Zig doesn’t ship with the Emscripten build tools or the Emscripten libc.

The build.zig in this project from @Sze is a good example.

Edit: I just glanced at sokol-zig and it seems like they have their own way to do this by depending on the emcc-core repo and providing functions like emLinkStep. I’m not familiar enough with that project to offer specific advice on how to use their method, but either way you have to build a static library and link with Emscripten, you can’t just build an executable with the Zig build system.

1 Like

Thank you kindly for the reply. Part of what is confusing to me here is that the sokol-zig build.zig actually installs the emcc binary and related tools the first time you try to target wasm (this was my first attempt):

❯ zig build -Dtarget=wasm32-emscripten
Resolving SDK alias 'latest' to '3.1.61'
Resolving SDK version '3.1.61' to 'sdk-releases-28e4a74b579b4157bda5fc34f23c7d3905a8bd6c-64bit'
Installing SDK 'sdk-releases-28e4a74b579b4157bda5fc34f23c7d3905a8bd6c-64bit'..
Installing tool 'node-18.20.3-64bit'..
Downloading: /Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/downloads/node-v18.20.3-darwin-arm64.tar.gz from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/node-v18.20.3-darwin-arm64.tar.gz
################################################################################################################################################################################### 100.0%
Unpacking '/Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/downloads/node-v18.20.3-darwin-arm64.tar.gz' to '/Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/node/18.20.3_64bit'
Done installing tool 'node-18.20.3-64bit'.
Installing tool 'python-3.9.2-64bit'..
Downloading: /Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/downloads/python-3.9.2-1-macos-arm64.tar.gz from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/python-3.9.2-1-macos-arm64.tar.gz
################################################################################################################################################################################### 100.0%
Unpacking '/Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/downloads/python-3.9.2-1-macos-arm64.tar.gz' to '/Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/python/3.9.2_64bit'
Done installing tool 'python-3.9.2-64bit'.
Installing tool 'releases-28e4a74b579b4157bda5fc34f23c7d3905a8bd6c-64bit'..
Downloading: /Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/downloads/28e4a74b579b4157bda5fc34f23c7d3905a8bd6c-wasm-binaries-arm64.tar.xz from https://storage.googleapis.com/webassembly/emscripten-releases-builds/mac/28e4a74b579b4157bda5fc34f23c7d3905a8bd6c/wasm-binaries-arm64.tar.xz
################################################################################################################################################################################### 100.0%
Unpacking '/Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/downloads/28e4a74b579b4157bda5fc34f23c7d3905a8bd6c-wasm-binaries-arm64.tar.xz' to '/Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/upstream'
Done installing tool 'releases-28e4a74b579b4157bda5fc34f23c7d3905a8bd6c-64bit'.
Done installing SDK 'sdk-releases-28e4a74b579b4157bda5fc34f23c7d3905a8bd6c-64bit'.
Resolving SDK alias 'latest' to '3.1.61'
Resolving SDK version '3.1.61' to 'sdk-releases-28e4a74b579b4157bda5fc34f23c7d3905a8bd6c-64bit'
Setting the following tools as active:
   node-18.20.3-64bit
   python-3.9.2-64bit
   releases-28e4a74b579b4157bda5fc34f23c7d3905a8bd6c-64bit

Next steps:
- To conveniently access emsdk tools from the command line,
  consider adding the following directories to your PATH:
    /Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e
    /Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/node/18.20.3_64bit/bin
    /Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/upstream/emscripten
- This can be done for the current shell by running:
    source "/Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/emsdk_env.sh"
- Configure emsdk in your shell startup scripts by running:
    echo 'source "/Users/zach/.cache/zig/p/12200ba39d83227f5de08287b043b011a2eb855cdb077f4b165edce30564ba73400e/emsdk_env.sh"' >> $HOME/.zprofile
install
└─ install sokoltest
   └─ zig build-exe sokoltest Debug wasm32-emscripten failure
error: error: unable to find or provide libc for target 'wasm32-emscripten-musl'

I can source the script under the “Next Steps” output above, and everything (including emcc) is added to my path.

I was initially thinking that maybe I had to try to recreate some of the steps from sokol’s build.zig in my own, but when I realized the build was already calling down into sokol’s build, I assumed that maybe I would be stepping on sokol’s logic with my own.

That’s where I also got confused - I didn’t know if I had to do anything special in my build.zig to make this work, but it sounds like that might be the case. I will try to get something like that working next.

Thanks!

Edit: thanks for the followup, I submitted this before I saw your edit!

I think you need to copy what this example (which also uses sokol-zig) does:

This did the trick, thank you for taking a look!

1 Like