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
-
If you're using linux, a nix binary cache is available at https://nixcache.webghc.org with a public key of:
hydra.webghc.org-1:knW30Yb8EXYxmUZKEl0Vc6t2BDjAUQ5kfC1BKJ9qEG8= -
When using reflex-platform you may want to add its cache as well: https://nixcache.reflex-frp.org
ryantrinkle.com-1:JJiAKaRv9mWgpVAz8dwewnZe0AzzEAzPkagE9SP5NWI=
git clone [email protected]: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
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
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/
- For a JSaddle app, add the
jsaddle-wasmin your executable's cabal file, and put the-threadedoption inif !arch(wasm32)block.
Note:
reflex-domlibrary from v0.7 onwards already includesjsaddle-wasmdependency, so it is not necessary to modify anything.
TODO: add instructions for
misoandreflex-dom< 0.7
- Use the
work-onscript from reflex-platform to obtain a shell withWebGHC
<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- The
-threadedoption is not supported withWebGHC. You will have to put to modify the cabal file to exclude this option like this:
if !arch(wasm32)
ghc-options: -threaded
- The
-Werroroption is known to cause compilation failure as it converts theclangwarnings to errors. This is a temporary issue, as it should be possible to get rid ofclangwarnings altogether.
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.
-
We have forked
nixpkgsjust to support thewasm32-unknown-unknown-wasmcompilation target, as this support cannot be provided by overlays. All other changes needed to nixpkgs, which cannot be done by overlays, have already been upstreamed.The choice of target triple is still under debate, with
wasm32-unknown-unknownorwasm32-unknown-unknown-webghcbeing other candidates. -
The
wasm-crosscontains some code fornodejssupport, but unfortunately it has not been maintained. If there is interest in running the executables outside the browser environment, then this could be resurrected with a little effort.