Nim: Add Emscripten compiler support

Created on 21 Aug 2018  路  7Comments  路  Source: nim-lang/Nim

Nim has already been demonstrated to work with the LLVM/Emscripten compiler with a little bit of configuration (here's an example) and I'm getting the impression that there's a lot of interest in using Emscripten nowadays (especially given the increasing relevance of WASM), so I think it would be best to just add Emscripten as a new compiler in extcomp. Those that are familiar with Emscripten will know that it is an extended form of LLVM/Clang with support for exporting code to WebAssembly and asm.js, (also I think it also supports vanilla JS/ECMA if you do -O0 but I had a hard time trying to find where I originally read that in the past).

Some notes:

  • when defined(emscripten) is already used in the compiler
  • clang should probably be defined as well when using Emscripten.
  • Possibly treat "asm.js" and "WebAssembly" as CPU ISAs? e.g. --cpu:wasm
  • Should we throw in EM_ASM etc. macro wrappers in the standard library or is letting everyone do this via {.emit.} manually good enough?
  • Using the config mentioned at the top doesn't work on Windows because whenever Nim invokes the compiler it suffixes an .exe at the end when emcc is a .bat on Windows.
  • The WebAssembly backend has dynlib support (never tested it myself) and the asm.js one does not (you could probably emulate dynlib-like semantics in asm.js but IMO that shouldn't be within our purview.)
Feature

Most helpful comment

I'm confused by the politics of what is going on in that space

Clang only produces the wasm binary. Emscripten adds tons of arguably unnecessary from Nim perspective JS and HTML glue to make it work.

One advantage of emscripten is that it can compile Nim exception handling code by means of JS glue. To make it work with pure clang this should be handled by either the next wasm spec, or by new Nim error handling model.

To summarize, emscripten better be used for building (compiling, linking, asset packing, etc) C/C++ projects, and not for compiling C/C++ files. It offers many benefits to existing C/C++ projects that need to be "ported" to web. Nim on the other hand has the means to implement the wasm-compatible codegen almost completely within its library code, so it would be a much cleaner approach. Thus for new projects I would strongly recommend to look towards clang+wasm, and not misguide newcomers to some bulky legacy stuff. IMO.

All 7 comments

Isn't asm.js effectively dead? Wouldn't it be easier to simply support WebAsm only?

@dom96 I imagine someone will still be using asm.js for something in the future. Nim has --cpu: options for a number of "dead" ISAs like the 68k and the DEC Alpha, so I mean, it can't really hurt.

Let's better not.

  • Nim already supports emscripten just fine.
  • Emscripten has clang interface, why add another clang?
  • Apart from compilation to asmjs/wasm emscripten does so much more (glue, fs emulation, libc emulation) that might not be needed and is hard to control.

Instead let's better support pure clang+wasm32/64 target. Yay!

Side note: @awr1, jsbind should solve all of your issues, including windows problem.

Emscripten has clang interface, why add another clang?

@yglukhov We already support things like llvm-gcc and the Nintendo Switch gcc as seperate compilers, so adding compiler "variations" as serperate entries in extcomp is not unheard of.

~What do you mean by pure clang+wasm32/64 target? Do you mean doing --cpu:wasm32 which would switch the target compiler to emcc or do you mean something entirely different?~ I see now that Clang has an official WASM backend which I didn't know existed... interesting to say the least. I'm confused by the politics of what is going on in that space, are they trying to merge Emscripten and Clang or is it something completely different?

I think we can discuss this further when a pull request arrives. Please bring it on.

I'm confused by the politics of what is going on in that space

Clang only produces the wasm binary. Emscripten adds tons of arguably unnecessary from Nim perspective JS and HTML glue to make it work.

One advantage of emscripten is that it can compile Nim exception handling code by means of JS glue. To make it work with pure clang this should be handled by either the next wasm spec, or by new Nim error handling model.

To summarize, emscripten better be used for building (compiling, linking, asset packing, etc) C/C++ projects, and not for compiling C/C++ files. It offers many benefits to existing C/C++ projects that need to be "ported" to web. Nim on the other hand has the means to implement the wasm-compatible codegen almost completely within its library code, so it would be a much cleaner approach. Thus for new projects I would strongly recommend to look towards clang+wasm, and not misguide newcomers to some bulky legacy stuff. IMO.

I have just gotten pretty far with this. Indeed, there are a number of issues which makes compilation with emcc a pain (particularly on Windows). But I was able to compile my game (which uses SDL2) fairly easily. Of course running it is a whole other adventure, currently I am getting segfaults very quickly in the runtime of the code.

Still, for reference, here is my config:

@if not emscripten:
  -d:ssl
@else:
  --nimcache:"./emscripten"
  --dynlibOverride:SDL2
  --dynlibOverride:SDL2_image
  --passL:"-s USE_SDL=2 -s USE_SDL_IMAGE=2 -s TOTAL_MEMORY=536870912 -s SAFE_HEAP=1 -s WARN_UNALIGNED=1 --use-preload-plugins --preload-file out --preload-file fonts"
  --genScript
  --os:linux
  --cc:clang
  --clang.exe:emcc
  --gc:refc
@end

And a really quick script I wrote to workaround a few bugs:

  • @ not being liked by emcc in paths
  • packages using {.compile.} not being referenced correctly in the compile_.sh script

Here it is: https://gist.github.com/dom96/d085e571f092d1515fece0c4c3f43847

So my next step will likely be compiling a simpler program, probably a simple gamelight test to see if it also segfaults. But I'm guessing that tracking down the source of these segfaults will be non-trivial, which is a real shame :/

Was this page helpful?
0 / 5 - 0 ratings

Related issues

juancarlospaco picture juancarlospaco  路  3Comments

zzz125 picture zzz125  路  4Comments

timotheecour picture timotheecour  路  3Comments

koki-koba picture koki-koba  路  3Comments

Tronic picture Tronic  路  3Comments