-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
(Background: This reddit post where @andrewrk suggested I file this issue.)
I think it would be useful for Zig to allow compiling the same code both natively and to the Web.
Zig already supports the Web to some extent with the wasi and freestanding wasm targets. The difference with Emscripten is in API support: Emscripten allows common native APIs to be compiled to the Web, such as SDL2, OpenGL, OpenAL, pthreads, and so forth. A very common use case for Emscripten is to port a game engine, and that's why Unity and many others use it. As game engines begin to be written in Zig, allowing the same there as for C++ would be nice I think. (Of course, this isn't limited to games: Photoshop, Figma, AutoCAD, etc. also use Emscripten.)
What this means concretely: this gist has an example of a C program that uses GLES3 and GLFW to render, and relies on Asyncify to handle the Web event loop. That exact same program can be compiled with gcc or clang natively, or with emcc to the Web - that's the big benefit here.
The gist also has an example of a Zig program that I managed to do the same with, with some hacks. With small (I hope) improvements to Zig I think the hacks could be avoided, namely to allow setting the Emscripten target triple, and to get the full Zig stdlib compiling with that triple (hopefully simple, as the differences between the Emscripten wasm triple and the WASI wasm triple are very small). Emscripten itself would do all the rest, when the user runs it on the object files emitted from Zig (see details in that gist; there may also be more interesting Zig build system integration opportunities, but I don't know enough about that).
Why is it useful to compile the exact same code both natively and to the Web? You don't have to, of course - you can have separate codebases for the two platforms. For example, you could add a new rendering backend to your game engine to use WebGL, you can rewrite all your event handling logic to be async like the Web requires, rethink how you handle files, etc., and all the other stuff that is different on the Web. Such rewrites may have benefits, sometimes. But it makes porting harder, it makes debugging harder, and you may end up handling the mismatches between native and the Web in a sub-optimal way. Reusing the large effort put into Emscripten here can be useful.