floooh / sokol-zig

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

Targeting WASM? #8

Closed pixelpicosean closed 8 months ago

pixelpicosean commented 3 years ago

Wandering how to targeting wasm32, or is it possible?

floooh commented 3 years ago

I'm not sure actually, the sokol headers currently depend on Emscripten-specific glue APIs, while all WASM Zig demos I've seen do their own WASM-to-JS-API binding. So most likely currently it's not trivially possible to compile to WASM. It's definitely a long-term goal though, but I most likely need to add new backends to the sokol headers which don't depend on Emscripten APIs.

pfgithub commented 2 years ago

Build the zig portion with .addStaticLibrary -Dtarget=wasm32-freestanding and then build the c portion with emcc and link in the zig portion. It's nontrivial and requires emscripten but it's possible.

kassane commented 8 months ago

WiP: [Experimental]

Based on pacman.zig example (by @floooh), using v0.12.0/master (zig-pkg has git support and alldeps no need build.zig) https://github.com/kassane/sokol-zig/blob/wasm_zig-0.12.0

Download and run emsdk: https://github.com/floooh/sokol-zig/blob/a5aa949a8fe886d21187453d3441abf764348807/build.zig.zon#L2-L10

$> zig build run-clear -Dtarget=wasm32-emscripten -Doptimize=ReleaseSmall --verbose

bash /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/emsdk install latest 
Resolving SDK alias 'latest' to '3.1.51'
Resolving SDK version '3.1.51' to 'sdk-releases-4f416d92fbff66ce79901cfc8263768f1b25dd3e-64bit'
Installing SDK 'sdk-releases-4f416d92fbff66ce79901cfc8263768f1b25dd3e-64bit'..
Installing tool 'node-16.20.0-64bit'..
Downloading: /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/downloads/node-v16.20.0-linux-x64.tar.xz from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/node-v16.20.0-linux-x64.tar.xz, 22559772 Bytes
Unpacking '/home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/downloads/node-v16.20.0-linux-x64.tar.xz' to '/home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/node/16.20.0_64bit'
Done installing tool 'node-16.20.0-64bit'.
Installing tool 'releases-4f416d92fbff66ce79901cfc8263768f1b25dd3e-64bit'..
Downloading: /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/downloads/4f416d92fbff66ce79901cfc8263768f1b25dd3e-wasm-binaries.tar.xz from https://storage.googleapis.com/webassembly/emscripten-releases-builds/linux/4f416d92fbff66ce79901cfc8263768f1b25dd3e/wasm-binaries.tar.xz, 270005560 Bytes
Unpacking '/home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/downloads/4f416d92fbff66ce79901cfc8263768f1b25dd3e-wasm-binaries.tar.xz' to '/home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/upstream'
Done installing tool 'releases-4f416d92fbff66ce79901cfc8263768f1b25dd3e-64bit'.
Done installing SDK 'sdk-releases-4f416d92fbff66ce79901cfc8263768f1b25dd3e-64bit'.
bash /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/emsdk activate latest 
Resolving SDK alias 'latest' to '3.1.51'
Resolving SDK version '3.1.51' to 'sdk-releases-4f416d92fbff66ce79901cfc8263768f1b25dd3e-64bit'
Setting the following tools as active:
   node-16.20.0-64bit
   releases-4f416d92fbff66ce79901cfc8263768f1b25dd3e-64bit

Next steps:
- To conveniently access emsdk tools from the command line,
  consider adding the following directories to your PATH:
    /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245
    /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/upstream/emscripten
- This can be done for the current shell by running:
    source "/home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/emsdk_env.sh"
- Configure emsdk in your shell startup scripts by running:
    echo 'source "/home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/emsdk_env.sh"' >> $HOME/.zprofile
steps [2/9] run bash... /home/kassane/zig/0.12.0-dev.1879+e19219fa0/files/zig build-lib /home/kassane/sokol_zigwasm/src/sokol/c/sokol.c -lc -OReleaseSmall --cache-dir /home/kassane/sokol_zigwasm/zig-cache --global-cache-dir /home/kassane/.cache/zig --name sokol -static -target wasm32-emscripten -mcpu generic -isystem /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/upstream/emscripten/cache/sysroot/include -D __EMSCRIPTEN__ -L /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten --sysroot /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/upstream/emscripten/cache/sysroot --listen=- 
steps [3/9] zig build-lib sokol ReleaseSmall wasm32-emscripten... Compile C Objects [1/... /home/kassane/zig/0.12.0-dev.1879+e19219fa0/files/zig build-lib /home/kassane/sokol_zigwasm/src/examples/clear.zig -lc -OReleaseSmall --cache-dir /home/kassane/sokol_zigwasm/zig-cache --global-cache-dir /home/kassane/.cache/zig --name clear -static -target wasm32-emscripten -mcpu generic --mod sokol::/home/kassane/sokol_zigwasm/src/sokol/sokol.zig --deps sokol --sysroot /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/upstream/emscripten/cache/sysroot --listen=- 
steps [5/9] zig build-lib clear ReleaseSmall wasm32-emscripten... /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/upstream/emscripten/emcc -Os --closure 1 -ozig-out/web/clear.html -L/home/kassane/sokol_zigwasm/zig-out/lib -lclear -lsokol -sNO_FILESYSTEM=1 -sMALLOC='emmalloc' -sERROR_ON_UNDEFINED_SYMBOLS=0 -sASSERTIONS=0 -sUSE_WEBGL2=1 -sEXPORTED_FUNCTIONS=['_malloc','_free','_main'] 
shared:INFO: (Emscripten: Running sanity checks)
cache:INFO: generating system asset: symbol_lists/eb02aa377e5d2864b73689edb8276e1065be17b4.json... (this will be cached in "/home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/upstream/emscripten/cache/symbol_lists/eb02aa377e5d2864b73689edb8276e1065be17b4.json" for subsequent builds)
cache:INFO:  - ok
steps [7/9] run /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815... /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/upstream/emscripten/emrun zig-out/web/clear.html 
Now listening at http://0.0.0.0:6931/
kassane commented 8 months ago

@pixelpicosean,

Would it be possible to reopen the issue?

Because there is a PR that needs feedback. Any help if interested will be welcome.

floooh commented 8 months ago

Btw, not sure if it existed back when this issue was originally created, but the pacman.zig project has Emscripten support:

https://github.com/floooh/pacman.zig/blob/main/build.zig

...this is the version which uses sokol-zig as package manager dependency:

https://github.com/floooh/pacman.zig/blob/sokol-package/build.zig

I'll try to have a look at the PR soon-ish.

kassane commented 8 months ago

I have to admit that I did not take a look at the branch package until PR was started.

I could not get it to link with emscripten libraries, although I do not know if zig has a limit on reading library paths. Just because of zig-pkg's hashid + subdirectories, it is really long.

Regarding emcc commands: I still get undefined references (as warnings) to some functions in glsl.

floooh commented 8 months ago

I still get undefined references (as warnings) to some functions in glsl.

Can you post the warnings here? I suspect it's WebGL2 functions. The Emscripten linker step needs a -sUSE_WEBGL2=1 since GLES2 support was removed from sokol_gfx.h.

See: https://github.com/floooh/pacman.zig/blob/d3d82da497d6cf39d1b99d66d94c0ea07fe10d51/build.zig#L109

...also looks like I had to add a list of explicitly exported C functions:

https://github.com/floooh/pacman.zig/blob/d3d82da497d6cf39d1b99d66d94c0ea07fe10d51/build.zig#L110

...most of the other Emscripten-specific linker settings are about reducing the output size.

kassane commented 8 months ago

Can you post the warnings here?

No error: https://github.com/floooh/sokol-zig/blob/f5598ec4957b2546981e26b4acea170badf83e7b/build.zig#L346

steps [5/9] zig build-lib sgl-context Debug wasm32-emscripten... /home/kassane/.cache/zig/p/1220f1340cd871b444021c600661f921f96091ce0815fa43008528f4844cece7e245/upstream/emscripten/emcc -sGL_DEBUG=1 --closure 1 -o/home/kassane/sokol-zig/zig-out/web/sgl-context.html -L/home/kassane/sokol-zig/zig-out/lib -lsgl-context -lsokol -sNO_FILESYSTEM=1 -sMALLOC='emmalloc' -sASSERTIONS=0 -sERROR_ON_UNDEFINED_SYMBOLS=0 -sMALLOC='emmalloc' -sUSE_WEBGL2=1 -sEXPORTED_FUNCTIONS=['_malloc','_free','_main']
warning: undefined symbol: sgl_begin_quads (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_context_draw (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_context_make_pipeline (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_default_context (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_defaults (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_enable_texture (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_end (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_load_pipeline (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_lookat (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_make_context (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_matrix_mode_modelview (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_matrix_mode_projection (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_perspective (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_rad (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_rotate (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_set_context (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_setup (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_shutdown (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_texture (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_v2f_c3b (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: sgl_v3f_t2f (referenced by root reference (e.g. compiled C/C++ code))
emcc: warning: warnings in JS library compilation [-Wjs-compiler]
kassane commented 8 months ago

Also, tried replace addStaticLibrary to addSharedLibrary:

both: libsokol + lib{example_name}:

error: warning(link): unexpected LLD stderr:
wasm-ld: warning: creating shared libraries, with -shared, is not yet stable

libsokol (static) + lib{example_name} (dynamic):

// example config
e.linkage = .dynamic;
e.rdynamic = true;
e.root_module.pic = true; // new zig 0.12.0 change
error: wasm-ld: /home/kassane/sokol-zig/zig-cache/o/b6ca66347bfb7965597974e859270572/libsokol.a(/home/kassane/sokol-zig/zig-cache/o/000a66ff26e149800ac64c8478c51f29/sokol.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `_sg`; recompile with -fPIC
error: wasm-ld: /home/kassane/sokol-zig/zig-cache/o/b6ca66347bfb7965597974e859270572/libsokol.a(/home/kassane/sokol-zig/zig-cache/o/000a66ff26e149800ac64c8478c51f29/sokol.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `_sg`; recompile with -fPIC
error: wasm-ld: /home/kassane/sokol-zig/zig-cache/o/b6ca66347bfb7965597974e859270572/libsokol.a(/home/kassane/sokol-zig/zig-cache/o/000a66ff26e149800ac64c8478c51f29/sokol.o): relocation R_WASM_MEMORY_ADDR_LEB cannot be used against symbol `_sg`; recompile with -fPIC
error: wasm-ld: /home/kassane/sokol-zig/zig-cache/o/b6ca66347bfb7965597974e859270572/libsokol.a(/home/kassane/sokol-zig/zig-cache/o/000a66ff26e149800ac64c8478c51f29/sokol.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.346`; recompile with -fPIC
error: wasm-ld: /home/kassane/sokol-zig/zig-cache/o/b6ca66347bfb7965597974e859270572/libsokol.a(/home/kassane/sokol-zig/zig-cache/o/000a66ff26e149800ac64c8478c51f29/sokol.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L.str.16`; recompile with -fPIC
error: wasm-ld: /home/kassane/sokol-zig/zig-cache/o/b6ca66347bfb7965597974e859270572/libsokol.a(/home/kassane/sokol-zig/zig-cache/o/000a66ff26e149800ac64c8478c51f29/sokol.o): relocation R_WASM_MEMORY_ADDR_SLEB cannot be used against symbol `.L__func__._sg_gl_init_limits`; recompile with -fPIC

cc: @Luukdegram

Luukdegram commented 8 months ago

This was recently changed (https://github.com/ziglang/zig/pull/17815) meaning you need to use addExecutable in combination with exe.entry = .disabled. Read the PR for more details. Also, check the language reference and closed PR's when upgrading to a new Zig version. The language reference already includes this change.

CC @Luukdegram

Please join one of the Zig communities to ask questions or when you require help. Create a ticket on the Zig issue tracker when encountering a bug. I cannot respond to all pings in 3rd party repositories, looking for help.

kassane commented 8 months ago

This was recently changed (https://github.com/ziglang/zig/pull/17815) meaning you need to use addExecutable in combination with exe.entry = .disabled. Read the PR for more details. Also, check the language reference and closed PR's when upgrading to a new Zig version. The language reference already includes this change.

Interesting! Thanks, I'll take a look at this reference.

Please join one of the Zig communities to ask questions or when you require help. Create a ticket on the Zig issue tracker when encountering a bug. I cannot respond to all pings in 3rd party repositories, looking for help.

Sorry! I even researched it in the Zig Discord group, but I didn't find a similar question before starting any comment about.


Now, I'm reviewing the changes in the Zig build API especially involving dual target (ResolvedTarget x Target.Query)

floooh commented 8 months ago

Regarding the sgl-symbols I know what the reason is...

From looking at the PR (https://github.com/floooh/sokol-zig/pull/50/files) it looks like you added a single sokol.c 'implementation' file which includes the implementations for sokol_app.h, sokol_gfx.h, sokol_audio.h and sokol_log.h.

...and for emscripten/wasm only this gets built into a sokol-lib:

        lib.addCSourceFile(.{
            .file = .{ .path = sokol_path ++ "sokol.c" },
            .flags = &.{backend_option},
        });

...I guess this slipped in from the pacman.zig project because that's how I do it there... the reason why you see the sgl_ linker errors is because sokol.c doesn't include sokol_gl.h.

...but sokol.c shouldn't be in sokol-zig in the first place, because in the meantime I switched to per-header implementation files instead of a single sokol.c, e.g. check out all the .c files here:

https://github.com/floooh/sokol-zig/tree/master/src/sokol/c

These are gathered here in an array: https://github.com/floooh/sokol-zig/blob/1964d1e3e2612624418ce909994e582a578add6c/build.zig#L120-L129

...and built into a library like this (for macOS/iOS where they must be compiled as ObjC):

https://github.com/floooh/sokol-zig/blob/1964d1e3e2612624418ce909994e582a578add6c/build.zig#L154-L159

...each platform code block has such a comptime for-loop.

I wonder if it's best if you take the build.zig in the new zig-0.12.0 branch and start from there again. This is the most recent and "most cleaned up" version of build.zig, and this also exposes sokol as a package manager module.

kassane commented 8 months ago

Regarding the sgl-symbols I know what the reason is...

The complication at the moment is getting zig to export all the function names found in sokol. Static libraries don't export anything.

kassane commented 8 months ago

WiP

image

kassane commented 8 months ago

Finally, https://github.com/floooh/sokol-zig/commit/2edeb6f1633f17215c3d98eea40a2a4074bb5868! :tada:

floooh commented 8 months ago

Yeah just wanted to add a comment here and close the ticket.

Good stuff all around :)