Home

Awesome

wasm-cross

wasm-cross is a toolchain for cross compiling C and Haskell to WebAssembly, using the WebGHC and LLVM

The generated WebAssembly binary can be run on a browser using the webabi library.

It currently provides a minimal ABI, sufficient to run the Haskell code using the jsaddle library with jsaddle-wasm

Quick start

Setup nix cache

Build an example app

git clone git@github.com:WebGHC/wasm-cross.git
cd wasm-cross;

Reflex TodoMVC

nix-build release.nix -A examples.wasm.reflex-todomvc

Miso 2048

nix-build release.nix -A examples.wasm._2048

Nix based build with TemplateHaskell support

Template Haskell

For Template Haskell support the save/load-splices infrastructure is used. This was initially created to support the arm cross-compilation, but it works equally well for WebGHC.

This works by first compiling the code for x86/64 arch, and then using the splices generated by it in the wasm compilation. It needs the reflex-platform's nix wizardry to achieve this. It works well for the straightforward use cases of Template Haskell, but may break for more complicated uses.

Note: use of reflex is not required to use reflex-platform, it should work well for Miso too.

In order to support TemplateHaskell the reflex-platform and nix based build is necessary.

See the example JSaddle app and the example Reflex app

Cabal based build without TemplateHaskell support

If you dont need TemplateHaskell support, then you can use only cabal to do the builds, which works much faster as it can do builds incrementally.

The reflex-platform is used here as it provides an easier to use interface for creating a nix-shell with all the dependencies necessary for a cabal project.

Get the latest reflex-platform from https://github.com/reflex-frp/reflex-platform/

Note: reflex-dom library from v0.7 onwards already includes jsaddle-wasm dependency, so it is not necessary to modify anything.

TODO: add instructions for miso and reflex-dom < 0.7

<reflex-platform>/scripts/work-on wasm ./.

Then do the cabal configure with following options, followed by cabal build

cabal configure --configure-option=--host=wasm32-unknown-unknown-wasm --with-ghc=wasm32-unknown-unknown-wasm-ghc --with-ghc-pkg=wasm32-unknown-unknown-wasm-ghc-pkg  --with-gcc=wasm32-unknown-unknown-wasm-cc --with-ld=wasm32-unknown-unknown-wasm-ld --with-ar=wasm32-unknown-unknown-wasm-ar --with-hsc2hs=wasm32-unknown-unknown-wasm-hsc2hs
cabal build

Limitations / Known issues

  if !arch(wasm32)
    ghc-options: -threaded

Other details

The C toolchain is made up of Clang / LLVM, LLD, and a fork of musl.

The Haskell compilation is done using WebGHC, which is a fork of GHC

GHC cross compilers are built from a fork using the Nix infrastructure largely developed by John Ericson (@Ericson2314), producing a working haskellPackages.

webabi is the "kernel" to support musl's syscalls.

Notes