Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sokol binaries for wasm #3

Open
thePHTest opened this issue Oct 18, 2022 · 7 comments
Open

Sokol binaries for wasm #3

thePHTest opened this issue Oct 18, 2022 · 7 comments

Comments

@thePHTest
Copy link

I am starting to look into adding a build_clibs_wasm.cmd/sh script and get at least the microui example program working for web.
Are there any significant barriers to achieve this? It's my first foray into web assembly so it might take me a bit. Odin's wasm usage isn't as battle tested as other platforms at the moment either.

@floooh
Copy link
Owner

floooh commented Oct 19, 2022

The sokol headers are using Emscripten specific functions and features (for instance the EM_JS macro to embed Javascript functions into C source code).

In Zig I was able to compile by using a combination of the Zig compiler and the Emscripten SDK (which is needed to provide a 'sysroot', and the linker), see here:

https://github.com/floooh/pacman.zig#experimental-web-support

...last time I checked this didn't work anymore though because of some breaking changes in the Emscripten SDK, it may be that Zig needs to update to the latest LLVM version before it works again, not sure.

@thePHTest
Copy link
Author

thePHTest commented Oct 20, 2022

Ah interesting. Odin has the build flag -target:js_wasm32 to compile for wasm. I believe there is some extra work that will need to be done to setup the Odin runtime on startup as the default allocators with wasm are the nil allocator for that build target. I'll have to see if I need to do anything in particular to expose these EM_JS functions via Odin as well.

If there is anywhere you can point me to to grab an emscripten build command for sokol libs that would be great. Otherwise, I'll see what I can piece together.

@floooh
Copy link
Owner

floooh commented Oct 21, 2022

Quick and dirty build_clibs_wasm.sh (see https://github.com/floooh/sokol-odin/blob/main/build_clibs_linux.sh for reference):

set -e

build_lib_wasm_release() {
    src=$1
    dst=$2
    backend=$3
    echo $dst
    emcc -c -O2 -DNDEBUG -DIMPL -D$backend c/$src.c
    emar rcs $dst.a $src.o
}

build_lib_wasm_debug() {
    src=$1
    dst=$2
    backend=$3
    echo $dst
    emcc -c -g -DIMPL -D$backend c/$src.c
    emar rcs $dst.a $src.o
}

# wasm + GL + Release
build_lib_wasm_release sokol_gfx sokol/gfx/sokol_gfx_wasm_gl_release SOKOL_GLES3

# wasm + GL + Debug
build_lib_wasm_debug sokol_gfx sokol/gfx/sokol_gfx_wasm_gl_debug SOKOL_GLES3

rm *.o

Expects a 'global' install of the Emscripten SDK so that emcc and emar are in the path. I only tested compilation, not if the resulting link libraries actually work :)

@floooh
Copy link
Owner

floooh commented Oct 21, 2022

PS: the tricky part will be the linking though... but let me know how it goes :)

@colinbellino
Copy link

colinbellino commented Mar 26, 2024

Very hesitant to restart the conversation here since this issue is more than one year old at that point, so let me know if this is not the right place.

I'm trying to do a similar test with odin & sokol, so i'm very curious if you managed to get it to work for you @thePHTest?

The script (build_clibs_wasm.sh) that @floooh provided worked correctly, at least from what i can see, so thanks for that :) But as you said the linking seemed to be the tricky part and since i'm a little out of my depth here, i was wondering if you had some pointers or insight about that step? (or would this fall on the Odin part of things)

To make discussing this easier, i've setup an example project of what i'm trying to do (one of the sokol odin example). I've changed some of the sokol-odin bindings to import the newly compiled files when the OS is .JS.
Then i compile the project on the -target mentioned above: odin build src/ -out=main.wasm --target:js_wasm32 -debug, here again no errors that i could see.
But when i run the server, WebAssembly.instantiate() fails with the error below, so i am guessing i forgot or missed something obvious?

runtime.js:1699 Uncaught (in promise) TypeError: WebAssembly.instantiate(): Import #1 module="sokol_gfx_wasm_gl_debug.a" error: module is not an object or function

Any help would be very much appreciated!

Edit: I have now researched the subject a little more and have found this project that is doing something similar with raylib, and it made me realise what i am doing in the project above might not be correct.

@tyzor
Copy link

tyzor commented Jan 8, 2025

What options are there for removing emscripten requirements from the sokol bindings? It seems like the EM_JS macros are the major hurdle and I see there was another discussion about it (floooh/sokol#617)

@floooh
Copy link
Owner

floooh commented Jan 8, 2025

What options are there for removing emscripten requirements from the sokol bindings?

Yeah, that's not realistic option, it's not just the EM_JS magic, but all the other things provided by the Emscripten SDK and especially the Emscripten link step (like automatically creating a JS file for the 'web API glue' in the link step and running additional optimization via wasm-opt/binaryen and Closure). Doing all this stuff without Emscripten basically comes down to emulating Emscripten or switching to an alternative toolchain like https://github.com/schellingb/wajic (which is similar but much more bare bones).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants