floooh / sokol-zig

Zig bindings for the sokol headers (https://github.com/floooh/sokol)
zlib License
375 stars 48 forks source link

[Help] Build targeting emscripten fails due to cImport of stb_image.h #62

Closed trace-andreason closed 6 months ago

trace-andreason commented 6 months ago

I'm working on this repo https://github.com/trace-andreason/zig-learn-opengl-in-sokol where I'm going through the examples in the sokol learn openGL repo https://github.com/zeromake/learnopengl-examples and converting them over to zig. I can't figure out how to get the examples that need image files for textures to build using the emscripten target. Its complaining about not being able to find stdio.h.

I've looked through your other repos, and I see that files are never loaded due to issues with zig and wasm. I'm new to basically everything involved here so I'm not sure if there is anything I can do to get this working. I've posted the full verbose build output below.

I guess my question is, is loading images for textures just not possible right now? Should I just move on? Thanks in advanced for the help!

zig build run-texture -Dtarget=wasm32-emscripten --verbose
/opt/homebrew/Cellar/zig/0.12.0/bin/zig build-lib -cflags -DIMPL -DSOKOL_GLES3 -- /Users/twork/.cache/zig/p/12204b76dc14c74da9d61d01b5bd7a4fbfd0614aa7cc0a7428de0742129203ca5008/src/sokol/c/sokol_log.c -cflags -DIMPL -DSOKOL_GLES3 -- /Users/twork/.cache/zig/p/12204b76dc14c74da9d61d01b5bd7a4fbfd0614aa7cc0a7428de0742129203ca5008/src/sokol/c/sokol_app.c -cflags -DIMPL -DSOKOL_GLES3 -- /Users/twork/.cache/zig/p/12204b76dc14c74da9d61d01b5bd7a4fbfd0614aa7cc0a7428de0742129203ca5008/src/sokol/c/sokol_gfx.c -cflags -DIMPL -DSOKOL_GLES3 -- /Users/twork/.cache/zig/p/12204b76dc14c74da9d61d01b5bd7a4fbfd0614aa7cc0a7428de0742129203ca5008/src/sokol/c/sokol_time.c -cflags -DIMPL -DSOKOL_GLES3 -- /Users/twork/.cache/zig/p/12204b76dc14c74da9d61d01b5bd7a4fbfd0614aa7cc0a7428de0742129203ca5008/src/sokol/c/sokol_audio.c -cflags -DIMPL -DSOKOL_GLES3 -- /Users/twork/.cache/zig/p/12204b76dc14c74da9d61d01b5bd7a4fbfd0614aa7cc0a7428de0742129203ca5008/src/sokol/c/sokol_gl.c -cflags -DIMPL -DSOKOL_GLES3 -- /Users/twork/.cache/zig/p/12204b76dc14c74da9d61d01b5bd7a4fbfd0614aa7cc0a7428de0742129203ca5008/src/sokol/c/sokol_debugtext.c -cflags -DIMPL -DSOKOL_GLES3 -- /Users/twork/.cache/zig/p/12204b76dc14c74da9d61d01b5bd7a4fbfd0614aa7cc0a7428de0742129203ca5008/src/sokol/c/sokol_shape.c -cflags -DIMPL -DSOKOL_GLES3 -- /Users/twork/.cache/zig/p/12204b76dc14c74da9d61d01b5bd7a4fbfd0614aa7cc0a7428de0742129203ca5008/src/sokol/c/sokol_glue.c -ODebug -target wasm32-emscripten -mcpu baseline -isystem /Users/twork/.cache/zig/p/122034cf4aca9f97fea3c34f3e9fe92e56f08e2160efe3c95d7ec89260e621426a81/upstream/emscripten/cache/sysroot/include -Mroot -lc --cache-dir /Users/twork/Documents/zig/test/zig-cache --global-cache-dir /Users/twork/.cache/zig --name sokol -static --listen=-
/opt/homebrew/Cellar/zig/0.12.0/bin/zig build-lib /Users/twork/Documents/zig/test/src/stb_image.c -ODebug -target wasm32-emscripten -mcpu baseline -I /Users/twork/Documents/zig/test/src --dep sokol -Mroot=/Users/twork/Documents/zig/test/src/1-6-textures/1-texture.zig -I /Users/twork/Documents/zig/test/zig-cache/o/bab42bbbea71a70c78c338ea9331fb6e -Msokol=/Users/twork/.cache/zig/p/12204b76dc14c74da9d61d01b5bd7a4fbfd0614aa7cc0a7428de0742129203ca5008/src/sokol/sokol.zig -lc --cache-dir /Users/twork/Documents/zig/test/zig-cache --global-cache-dir /Users/twork/.cache/zig --name texture -static --listen=-
run-texture
└─ run /Users/twork/.cache/zig/p/122034cf4aca9f97fea3c34f3e9fe92e56f08e2160efe3c95d7ec89260e621426a81/upstream/emscripten/emrun
   └─ emcc
      └─ zig build-lib texture Debug wasm32-emscripten 4 errors
/Users/twork/Documents/zig/test/src/stb_image.c:2:23: error: extra tokens at end of #include directive
/Users/twork/Documents/zig/test/src/stb_image.h:370:10: error: 'stdio.h' file not found
#include <stdio.h>
         ^~~~~~~~~~
/Users/twork/Documents/zig/test/src/stb_image.c:2:10: note: in file included from /Users/twork/Documents/zig/test/src/stb_image.c:2:
src/1-6-textures/1-texture.zig:10:11: error: C import failed
const c = @cImport({
          ^~~~~~~~
referenced by:
    loadImage: src/1-6-textures/1-texture.zig:63:18
    init: src/1-6-textures/1-texture.zig:26:5
    remaining reference traces hidden; use '-freference-trace' to see all reference traces
/Users/twork/Documents/zig/test/src/stb_image.h:370:10: error: 'stdio.h' file not found
#include <stdio.h>
         ^
error: the following command failed with 4 compilation errors:
/opt/homebrew/Cellar/zig/0.12.0/bin/zig build-lib /Users/twork/Documents/zig/test/src/stb_image.c -ODebug -target wasm32-emscripten -mcpu baseline -I /Users/twork/Documents/zig/test/src --dep sokol -Mroot=/Users/twork/Documents/zig/test/src/1-6-textures/1-texture.zig -I /Users/twork/Documents/zig/test/zig-cache/o/bab42bbbea71a70c78c338ea9331fb6e -Msokol=/Users/twork/.cache/zig/p/12204b76dc14c74da9d61d01b5bd7a4fbfd0614aa7cc0a7428de0742129203ca5008/src/sokol/sokol.zig -lc --cache-dir /Users/twork/Documents/zig/test/zig-cache --global-cache-dir /Users/twork/.cache/zig --name texture -static --listen=-
Build Summary: 2/6 steps succeeded; 1 failed (disable with --summary none)
run-texture transitive failure
└─ run /Users/twork/.cache/zig/p/122034cf4aca9f97fea3c34f3e9fe92e56f08e2160efe3c95d7ec89260e621426a81/upstream/emscripten/emrun transitive failure
   └─ emcc transitive failure
      └─ zig build-lib texture Debug wasm32-emscripten 4 errors
error: the following build command failed with exit code 1:
/Users/twork/Documents/zig/test/zig-cache/o/d5acdff3f8d287c7642b9d7180ca1cb8/build /opt/homebrew/Cellar/zig/0.12.0/bin/zig /Users/twork/Documents/zig/test /Users/twork/Documents/zig/test/zig-cache /Users/twork/.cache/zig --seed 0xb5aabee1 -Zc15ddec284e8ad70 run-texture -Dtarget=wasm32-emscripten --verbose
floooh commented 6 months ago

Yeah, there's an issue that the Emscripten compiler cannot automatically find its own system header files. That's why there is this code block in the buildLibSokol() build.zig function:

https://github.com/floooh/sokol-zig/blob/b4451848b187e171052ae6011beaeb35a8c2ba0b/build.zig#L173-L176

You basically need to do something similar when compiling your own C code into a library in your build.zig. Off the top of my head, untested:

const emsdk = dep_sokol.builder.dependency("emsdk", .{});
const emsdk_path = emsdk.path("").getPath(b);
const emsdk_sysroot = b.pathJoin(&.{ emsdk_path, "upstream", "emscripten", "cache", "sysroot" });
const include_path = b.pathJoin(&.{ emsdk_sysroot, "include" });
lib.addSystemIncludePath(.{ .path = include_path });
floooh commented 6 months ago

PS: note that sokol_fetch.h is currently not part of the bindings, but maybe you can 'cheat' with Zig's @embedFile (e.g. instead of loading the texture data via HTTP, just embed it in the WASM blob).

trace-andreason commented 6 months ago

damn, worked like a charm. Yeah, now I need to work out how to get my textures copied over to the web build, or just embed the files like you suggested. Thank you so much for the help!

What is the purpose of sokol_fetch? I assumed that it wasn't part of the bindings because it wasn't necessary, but sounds like that isn't the case. Is it just to provide an abstraction for fitting IO into the event loop in a cross platform way? Am I actually going to need sokol_fetch to load an image without going the embedFile route?

floooh commented 6 months ago

sokol_fetch.h is basically an asynchronous file loader that works both on native platforms (by loading from the filesystem) and web (by loading data via XmlHttpRequest (or at some point in the future, the fetch API).

Other language bindings don't have proper web support yet, so including sokol_fetch.h in the bindings didn't make much sense. With the Zig bindings it might make sense though.

floooh commented 6 months ago

PS:

Yeah, there's an issue that the Emscripten compiler cannot automatically find its own system header files.

What I wrote here is actually incorrect ;)

It's actually the Zig compiler which compiles the C code to WASM of course, so it kinda makes sense that it's necessary to add the path to the Emscripten SDK in order to find the right system headers. I remember that in the past there was a confusion because I had already passed the Emscripten sysroot directory to Zig, and it didn't quite make sense that a separate include directory inside the sysroot had to be passed as well. But AFAIK there is no concept of a 'cross-compilation sysroot' in the Zig build system anymore, I might be wrong though.