Haskell.org is participating in Google Summer of Code again this year. If you're looking for a fun project to work on over the summer and want to learn something about Haskell compilation, a GHCJS-related project might just be the ticket for you. We've compiled a list of ideas to get you started:
GHCJS supports many modern Haskell features, including:
- All type system extensions supported by GHC
- Lightweight preemptive threading with blackholes, MVar, STM, asynchronous exceptions
- Weak references, CAF deallocation, StableName, StablePtr
- Unboxed arrays, emulated pointers
- Integer support through JSBN, 32 and 64 bit signed and unsigned arithmetic (
- Cabal support, GHCJS has its own package database
- synchronous and asynchronous threads.
The GHCJS command line options are still in flux. Make sure that you have the latest Cabal patch installed when you update GHCJS. You need both an updated `cabal-install` executable and `Cabal` library. Rerun `ghcjs-boot --init` to get the latest updates for the libraries. If you get `Not in scope: data constructor ‘GHCJS’`, you need to update your `Cabal` library.
First install GHC 7.8 release candidate 2 or later and check with
ghc --version that it's the
compiler in your
PATH. Next, make sure that you have all the prerequisites for your platform:
- a recent version of
happyneed to be in your
patchneed to be in your
- by default,
ghcjs-bootwill try to use the system GMP library, see
ghcjs-boot --helpfor more info.
- virus scanners often interfere with configure scripts (permission denied errors),
disable on-access scanning before running
- no extra programs need to be installed,
ghcjs-bootwill download an archive (around 100MB) with the required programs.
Run the following script to install an updated
cabal-install with GHCJS
support. Note that this will overwrite the
cabal executable in your cabal executable
installation path (typically
~/.cabal/bin), you might want to backup your current version or
append a custom program suffix with a
cabal option such as
#!/bin/sh git clone https://github.com/ghcjs/cabal.git cd cabal git checkout ghcjs cabal install ./Cabal ./cabal-install
Make sure that you're now running the new
GHCJS support must be listed under the
$ cabal install --help ... build files (default dist) -g --ghc compile with GHC --ghcjs compile with GHCJS --nhc98 compile with NHC ...
$ git clone https://github.com/ghcjs/ghcjs.git $ cabal install ./ghcjs
Check that you have the correct version of
GHCJS in your PATH:
Build the base libraries for
$ ghcjs-boot --init or $ ghcjs-boot --init --with-cabal cabal-js # if you used --program-suffix=-js earlier
$ ghcjs -o helloWorld helloWorld.hs $ node helloWorld.jsexe/all.js Hello world!
cabal install --ghcjs packageName to install a package
ghcjs-pkg to manipulate the GHCJS package database
The package database and runtime files from the shims repository are kept in the
GHCJS application data directory, typically
~/.ghcjs/. Remove this directory to reset your GHCJS installation, you
need to run
ghcjs-boot --init again.
See GHCJS introduction for more examples.
If you want to hack on GHCJS, please join our friendly community on IRC at
#ghcjs on freenode (You're also
welcome if you only use the compiler or just want to chat about it!). The channel can be quiet from time
to time, but with a little patience you should be able to find people to get you started or point you in
the right direction.
The repositories you will be interested in are:
The compiler itself, code generator, linker, test suite
- Executables (
- Main code generator (
- Optimizer (
- Linker (
- Generated runtime code (
- Executables (
lib1.jsfiles when generating a
.jsexe. Installed in
- thread scheduler, MVar implementation (
- STM implementation (
- IO system (
src/io.js) (buffered IO for
- Heap scanner for weak references and finalizers (
- package-specific dependencies (
pkg), dependencies listed in
- third party libraries (
- thread scheduler, MVar implementation (
If you've changed something that affects the code generated by GHCJS, you'll need to rebuild the base packages (reboot the compiler). Often,
a full reboot is not required. You can run a quick boot to install only the essential packages (e.g.
array, but not
-j4 flag (number of concurrent jobs) for your system:
$ ghcjs-boot --quick -j4
After a change, please run the test suite to
check that it does not break anything. Install jsshell
and node.js first to make sure that the tests run correctly (
node executables should
be in your
When the compiler has been booted, run
cabal test, or run the test program directly for more options:
$ ./dist/build/test/test --help
For example to run a specific test or tests that match a pattern:
$ ./dist/build/test/test -t pattern
New test cases, in particular if you add new features, are always welcome. The testrunner automatically picks up new tests
.hs files that start with a lowercase letter) in the existing categories.
TODO add better instructions here
- link your program with
ghcjs -debug -o test test.hs, this adds debugging information to the generated code
- get more informaton from the runtime system by enabling various tracing and logging options. See the code in the shims repository for more info. Examples:
-DGHCJS_TRACE_SCHEDULER: messages from the thread scheduler
-DGHCJS_TRACE_CALLS: print all function calls from the main loop. warning: lots of output. Requires
-debugfor name information
-DGHCJS_TRACE_STACK: print top of stack for every call in the main loop. warning: even more output
-DGHCJS_TRACE_WEAK: output related to weak references
-DGHCJS_TRACE_STM: output for software transactional memory
-DGHCJS_TRACE_GC: output garbage collector (heap scanner) related messages
- see the utility programs in
utilsin the ghcjs repository for tools for inspecting object files, quickly bisecting bugs in the optimizer etc.
names (like stack frame functions) start with
h$$, scroll up in the code to find an exported name to which they belong.
Unfortunately due to Haskell's lazy evaluation and GHCJS's tail-call optimization, the information here is far less
useful than GHC profiles for native code. Profiling support is planned, but implementation has not been started yet.
Profiling will support cost centres like in native GHC. In particular, we intend to add memory profiling support for
interactive (reactive) systems, keeping track of allocations and retention per event. If you're interested in helping
out or discussing features, please contact us in
#ghcjs on freenode.
- webkit - Bindings for WebKitGTK+ that provide a low level DOM interface.
You can use these libraries without GHCJS to build a native version of your application (it will use WebKitGTK+ to run without a browser). If you want to find out more about making GHCJS compatible Haskell applications check out the GHCJS Examples