New fields/flags and semantics for GHCJS

Luite Stegeman stegeman at
Tue Oct 28 20:00:50 UTC 2014

Hi all,

I've been maintaining a Cabal fork for GHCJS. The GHCJS-specific bits have
been relatively stable for a while now, and are feature complete, apart
from a few small features that I'll complete later this week.

So I think it's time to discuss merging the branch. This discussion is for
the user visible changes only, the implementation details can be discussed
later when the code has been cleaned up for the merge (1-2 weeks). I hope
that the proposed changes cover most JavaScript packaging/build
requirements, but feature requests or questions about support for specific
scenarios are welcome!

First some background:

GHCJS is a cross-compiler, installed as a package. It has its own version
number (0.1.0 currently), independent of the GHC version it was built with.
After GHCJS and its standard libraries have been installed, it does not
require GHC anymore. Cabal's custom setup type is supported by compiling
Setup.hs to JavaScript and running it with node.js.

In the Cabal branch, GHCJS is treated as a very close relative of GHC. In
various places there is support for GHCJS building native code. While this
(--native-too mode) is currently disabled in a default installation, it can
be enabled again for generating JavaScript and native code from the same
Core, for example to allow closure serialization and continuing
computations between client and server (not yet implemented!).

All Cabal features are supported, including sandboxes. "cabal test"
compiles the testsuite of a package and runs it with node.js. "cabal repl"
is implemented on the Cabal side, but there is no repl for GHCJS yet, this
is planned for the not too far future (with a terminal and browser based
front end).

The changes:

# a new implementation flag: impl(ghcjs)

A new implementation flag has been added for GHCJS, using the GHCJS version
number. Since GHCJS is a close descendant of GHC, the impl(ghc) flag is
also set when something is being built with GHCJS. For example

if impl(ghc >= 7.2) -- GHC.Generics support (compiler could be GHCJS)
if impl(ghcjs >= 0.1) -- package is being built with GHCJS

# ghcjs-options, ghcjs-shared-options, ghcjs-prof-options

These new fields behave similar to those for GHC (ghcjs-shared-options only
has effect for native-too mode). If not set, the corresponding value from
ghc-options, ghc-shared-options, ghc-prof-options is used.

(An alternative is to let ghcjs-*-options field append the options to the
corresponding ghc-*-options field, instead of replacing them)

# new js-sources field

A js-sources field is treated like the c-sources field. JS sources of all
dependencies of a an executable are collected into a big JavaScript file.
GHCJS also outputs some data about the collected files for custom
deployment scripts.

JS sources are not compiled, but are run through the C preprocessor. Since
running the same file through the preprocessor twice is problematic, and
it's very useful to be able to set some preprocessor options at link time
(for example -DGHCJS_BROWSER, which removes node.js-specific code), the
strategy is as follows:

- When a library is being installed, the js-sources are copied to the
library installation directory, but not run through the preprocessor. the
cpp options are saved in the installation dir
- When building an executable, the JS-sources are collected. Each JS source
is processed with its own saved cpp-options with the cpp-options for
building the executable appended.

# new JavaScriptFFI extension

The extension has been in GHC since 7.8, but it can't be used on
non-JavaScript code generators. This change just adds it to the list of
known extensions.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the cabal-devel mailing list