ziglua icon indicating copy to clipboard operation
ziglua copied to clipboard

Linking fails with Emscripten

Open Interrupt opened this issue 1 year ago • 9 comments

When making a web build for Emscripten, and linking ziglua with the Emscripten system headers, linking fails with an error like:

/Users/ccuddigan/.cache/zig/p/1220f93ada1fa077ab096bf88a5b159ad421dbf6a478edec78ddb186d0c21d3476d9/src/lauxlib.h:246:3: error: unknown type name 'FILE'
  FILE *f;  /* stream (NULL for incompletely created streams) */

This might be because -DLUA_USE_POSIX is passed in build.zig for all unknown targets, and the WASM case isn't handled.

Interrupt avatar Jun 11 '24 22:06 Interrupt

Dug more into this, that unknown type name was due to the Zig library not having the correct headers - the Lua library did have the right ones but the Zig library was including some of Lua's C files directly and calling into them which makes sense.

The next issue I found though is harder to work around:

warning: undefined symbol: _longjmp (referenced by root reference (e.g. compiled C/C++ code))
warning: undefined symbol: _setjmp (referenced by root reference (e.g. compiled C/C++ code))

In POSIX mode it can't seem to find _longjmp / _setjmp, in non-POSIX it complains about a similar missing longjmp / setjmp.

It's possible to work around this by modifying ziglua's build.zig file to turn off Lua error handling, but that does not seem to be ideal.

Turning off the error handling can be done by adding the following to the Lua build flags:

-DLUAI_THROW(L,c)={return;}
-DLUAI_TRY(L,c,a)=a
-Dluai_jmpbuf=int

Interrupt avatar Jun 15 '24 00:06 Interrupt

I pushed a 0.3.0 release to ziglua earlier today and then I was thinking about this issue. Thanks for digging into it a bit more!

Yeah I was thinking about how there are functions not available in wasm. We may need a new build option to enable/disable things :)

natecraddock avatar Jun 15 '24 01:06 natecraddock

Thinking about this more, maybe what is needed is a way to modify the Lua build flags by the upstream builder pulling in the ziglua dependency. The sokol-zig project does something like this when linking against emscripten, there's an emLinkStep function that among other things takes an array of extra argument flags to use in the form of extra_args: []const []const u8 = &.{},

Interrupt avatar Jun 15 '24 06:06 Interrupt

Is this the only thing you needed to get it working with emscripten? https://github.com/Interrupt/ziglua/commit/3d7532ec73202bddfbeba1933d43fe427ca6d80d

natecraddock avatar Jun 19 '24 16:06 natecraddock

Yes, but that is a super hacky solution! It turns off all of the debug printing amongst other stuff.

Interrupt avatar Jul 02 '24 19:07 Interrupt

@Interrupt In case it's useful: I got one of the examples running in a browser w/ Luau by lifting a bunch of build code from sokol-zig and switching both compilation (unlike sokol-zig) and linking (like sokol-zig) to invoke emcc directly. https://github.com/natecraddock/ziglua/pull/95

edit: Lua 5.x seems to work too now

luchak avatar Sep 16 '24 06:09 luchak

@luchak could you share your emscripten build stuff to see how you did it?

Interrupt avatar Apr 08 '25 19:04 Interrupt

@Interrupt I believe it was created over here. It didn't refer back to this PR so you may have missed it.

nii236 avatar May 20 '25 03:05 nii236

There are now helper libraries for wrapping the emcc compiler like the one under zig-gamedev/zemscripten - this could be a drop in to help get Lua building and running for the wasm32-emscripten target now. Example build for Lua here:

https://codeberg.org/ruka/zig-lua-sandbox/src/branch/main/deps/lua/build.zig

Interrupt avatar Oct 15 '25 17:10 Interrupt