This is now possible by building a cross compiler for js-unknown-ghjs
using `pkgsCross.ghcjs.buildPackages.haskell.compiler.ghcHEAD`.
To allow this, the following things needed to be done:
* Disable dependencies that wouldn't work:
- Don't pull in ncurses for terminfo
- Don't pull in libffi
- Don't pull in libiconv
- Don't enable the LLVM backend
- Enable gmp-less native-bignum backend
* Use emscripten instead of a C compiler. The way this works is inspired
by emscriptenPackages, but avoids the following flaws:
- Instead of using a custom configurePhase, just set
`configureScript = "emconfigure ./configure";` which is much simpler.
- Create writable EM_CACHE before configuring, as configure scripts
want to compile test programs.
Additionally, we need to disable the targetCC check, as it is not
applicable with emscripten which never appears as part of stdenv.
* Use generic $configureScript in installPhase to be able to work with
our emconfigure trick.
Note that the corresponding Haskell package set does not work yet. Cabal
doesn't seem to like GHC 9.7 yet and the generic-builder is clueless
about the JS backend.
Since #200337 gobject-introspection propagates itself via
depsTargetTargetPropagated, so one doesn't have to add it to every
derivation twice. The problem is that gobject-introspection still is in
a lot of buildInputs and will thus propagate itself again for target,
breaking evaluation unnecessarily if gobject-introspection doesn't
evaluate on whatever the target platform turns out to be.
temurin-bin and openjdk19 caused such a situation via gtk3 which GHC's
JavaScript backend depends on. To fix evaluation of those packages in
pkgsCross.ghcjs.buildPackages, we'll just disable the features pulling
in gtk3 until this is fixed properly.
gmp is part of buildInputs _and_ depsTargetTarget, so we need to check
the host and target platform to be correct. In practice this doesn't
change much though, as gmp.meta.platforms is _quite_ liberal.
For the GHC JavaScript backend, we'll use emscripten in place of
targetCC. To avoid having too much special logic for this, we'll make
the emscripten derivation look like the result of wrapCC as far as GHC
is concerned, i.e. we need targetPrefix and bintools.
For bintools, we'll just reexpose emscripten, as it has emar, the only
relevant bintools. That the other ones are missing doesn't matter in
practice, as the GHC build system won't attempt to use them.
targetPrefix can immediately be (ab)used to make sure GHC will correctly
call emcc etc. instead of plain cc.