jhc(1) jhc haskell compiler


jhc [OPTION ..] Main.hs -o main


Building Projects

Jhc does its own dependency chasing to track down source files, you need only provide it with the file containing your 'main' function on the command line. For instance, if you had a program 'HelloWorld.hs', the following would compile it to an executable named 'hello'.

; jhc HelloWorld.hs -o hello

Jhc searches for modules in its search path, which defaults to the current directory. Modules are searched for based on their names. For instance, the module Data.Foo will be searched for in 'Data/Foo.hs' and 'Data.Foo.hs'. The search path may be modifed with the '-i' command line option, or by setting the 'JHC_PATH' environment variable.

Using Libraries

jhc libraries are distributed as files with an 'hl' suffix, such as 'base-1.0.hl'. In order to use a haskell library you simply need to place the file in a directory that jhc will search for it. For instance, $HOME/lib/jhc. You may set the environment variable JHC_LIBRARY_PATH to specify alternate locations to search for libraries or specify directory to search with the -L command line option. -L- will clear the search path.

You can then use libraries with the '-p' command line option, for instance if you had a library 'mylibrary-1.0.hl' in your search path, the following would use it.

; jhc -p mylibrary MyProgram.hs -o myprogram

You can list all available libraries by passing the --list-libraries option to jhc. If you include '-v' for verbose output, you will get detailed information about the libraries in a YAML format suitable for processing by external tools.

Environment Variables

Jhc's behavior is modified by several enviornment variables.

JHC_OPTS : this is read and appended to the command line of jhc invocations.

JHC_PATH : This specifies the path to search for modules.

JHC_LIBRARY_PATH : This specifies the path to search for libraries.

JHC_CACHE : This specified the directory jhc will use to cache values. having a valid cache is essential for jhc performance. It defaults to ~/.jhc/cache.

Building Haskell Libraries

Libraries are built by passing jhc a file describing the library via the --build-hl option. The library file format is a stadard YAML file.

; jhc --build-hl mylibrary.yaml

Library File Format

The library file is a YAML document, jhc will recognize several fields and ignore unknown ones.

Name : The name of your library

Version : The version of your library, The version number is used to differentiate different versions of the library passed to the '-p' command line option but is not otherwise special to jhc.

Exposed-Modules : A list of modules to be included in the library and exposed to users of the library as its public interface. This may include modules that are part of another library, they will be re-exported by the current library.

Hidden-Modules : A list of modules that the library may use internally but that should not be exposed to the user. Jhc may optimize based on this information. If this list is not exhaustive jhc will still build your library, but it will print out a warning.

Extensions : A list of extensions which should be enabled during compilation of this module. When possible, jhc will match ghc extensions to their closest jhc counterparts.

Options : Extra command line options to jhc for this library build.

Build-Depends : libraries to include, in the same format as passed to the '-p' command line option

Hs-Source-Dirs : Directory to search for Haskell source files in, this differs from the '-i' command line option in that the directory in this field is relative to the directory the library description .yaml file is located while the '-i' option is always relative to the current working directory.

Include-Dirs : directories to be included in the preprocessor search path as if via '-I'. The directories are interpreted relative to the directory that contains the yaml file.

C-Sources : C files that should be linked into programs that utilize this library.

Include-Sources : files that should be made available for inclusion when compiling the generated C code but don't need to be linked into the executable.

example library files can be seen in lib/jhc/jhc.yaml and lib/base/base.yaml

Dependency Information

Jhc can output dependency information describing how source files and libraries depend on each other while compiling code. The dependency information is generated when the --deps name.yaml option is passed to jhc. It is presented in the standard YAML format and its fields are as described below.

  • LibraryDeps: the libraries that are dependend on. It is a hash of library ids to the specific filename of the library used.
  • LibraryDesc: if building a library, this field contains the name of the library description file used.
  • ModuleDeps: a hash of module names to the list of modules that are directly dependend on by said module.
  • ModuleSouce: a hash of module name to the haskell source file used.

An example tool to processs the deps.yaml file and spit out appropriate Makefile rules is included as 'utils/deps_to_make.prl'.


Usage: jhc [OPTION...] Main.hs
  -V                --version                 print version info and exit
                    --version-context         print version context info and exit
                    --help                    print help information and exit
                    --info                    show compiler configuration information and exit
                    --purge-cache             clean out jhc compilation cache
  -v                --verbose                 chatty output on stderr
  -z                                          Increase verbosity of statistics
  -d [no-]flag                                dump specified data during compilation
  -f [no-]flag                                set or clear compilation options
  -X ExtensionName                            enable the given language extension
  -o FILE           --output=FILE             output to FILE
  -i DIR            --include=DIR             where to look for source files
  -I DIR                                      add to preprocessor include path
  -D NAME=VALUE                               add new definitions to set in preprocessor
                    --optc=option             extra options to pass to c compiler
  -c                                          just compile the modules, caching the results.
  -C                                          compile to C code
  -E                                          preprocess the input and print result to stdout
  -k                --keepgoing               keep going on errors
                    --cross                   enable cross-compilation, choose target with the -m flag
                    --stop=parse/typecheck/c  stop after the given pass, parse/typecheck/c
                    --width=COLUMNS           width of screen for debugging output
                    --main=Main.main          main entry point
  -m arch           --arch=arch               target architecture options
                    --entry=<expr>            main entry point, showable expression
                    --show-ho=file.ho         Show ho file
                    --noauto                  Don't automatically load base and haskell98 packages
  -p package                                  Load given haskell library package
  -L path                                     Look for haskell libraries in the given directory
                    --build-hl=desc.yaml      Build hakell library from given library description file
                    --annotate-source=<dir>   Write preprocessed and annotated source code to the directory specified
                    --deps=<file.yaml>        Write dependency information to file specified
                    --interactive             run interactivly                                                             ( for debugging only)
                    --ignore-cache            Ignore existing compilation cache entries.
                    --readonly-cache          Do not write new information to the compilation cache.
                    --no-cache                Do not use or update the cache.
                    --cache-dir=JHC_CACHE     Use a global cache located in the directory passed as an argument.
                    --stale=Module            Treat these modules as stale, even if they exist in the cache
                    --list-libraries          List of installed libraries
                    --tdir=dir/               specify the directory where all intermediate files/dumps will be placed.
valid -d arguments: 'help' for more info
    all-types, aspats, atom, bindgroups, boxy-steps, c, class, class-summary, core, core-afterlift
    core-beforelift, core-initial, core-mangled, core-mini, core-pass, core-steps, datatable
    datatable-builtin, dcons, decls, defs, derived, e-alias, e-info, e-size, e-verbose, exports, grin
    grin-datalog, grin-final, grin-graph, grin-initial, grin-normalized, grin-posteval, grin-preeval
    imports, ini, instance, kind, kind-steps, optimization-stats, parsed, preprocessed, program
    progress, renamed, rules, rules-spec, scc-modules, sigenv, srcsigs, stats, steps, tags, the
    types, verbose, veryverbose
valid -f arguments: 'help' for more info
    bang-patterns, boehm, controlled, cpp, debug, default, defaulting, exists, ffi, forall, full-int
    glasgow-exts, global-optimize, inline-pragmas, jgc, lint, m4, monomorphism-restriction, negate
    prelude, profile, raw, rules, standalone, type-analysis, type-families, unboxed-tuples
    unboxed-values, user-kinds, wrapper

Code Options

Various options affecting how jhc interprets and compiles code can be controlled with the '-f' flag, the following options are availible, you can negate any particular one by prepending 'no-' to it.

Code options

bang-patterns - bang patterns
cpp pass haskell source through c preprocessor
exists - exists keyword for existential types recognized
ffi support foreign function declarations
forall - forall keyword for rank-n types and explicit quantification
m4 pass haskell source through m4 preprocessor
prelude implicitly import Prelude
type-families type/data family support
unboxed-tuples allow unboxed tuple syntax to be recognized
unboxed-values allow unboxed value syntax
user-kinds user defined kinds


defaulting perform defaulting of ambiguous types
monomorphism-restriction enforce monomorphism restriction


lint perform lots of extra type checks

Optimization Options

global-optimize perform whole program E optimization
inline-pragmas use inline pragmas
rules use rules
type-analysis perform a basic points-to analysis on types right after method generation

Code Generation

boehm use Boehm garbage collector
debug enable debugging code in generated executable
full-int extend Int and Word to 32 bits on a 32 bit machine (rather than 30)
jgc use the jgc garbage collector
profile enable profiling code in generated executable
raw just evaluate main to WHNF and nothing else.
standalone compile to a standalone executable
wrapper wrap main in exception handler

Default settings

default inline-pragmas rules wrapper defaulting type-analysis monomorphism-restriction global-optimize full-int prelude
glasgow-exts forall ffi unboxed-tuples

Dumping Debugging Information

You can have jhc print out a variety of things while running as Controlled by the '-d' flag. The following is a list of possible parameters you can pass to '-d'.

Front End

defs Show all defined names in a module
derived show generated derived instances
exports show which names are exported from each module
imports show in scope names for each module
ini all ini configuration options
parsed parsed code
preprocessed code after preprocessing/deliting
renamed code after uniqueness renaming
scc-modules show strongly connected modules in dependency order

Type Checker

all-types show unified type table, after everything has been typechecked
aspats show as patterns
bindgroups show bindgroups
boxy-steps show step by step what the type inferencer is doing
class detailed information on each class
class-summary summary of all classes
dcons data constructors
decls processed declarations
instance show instances
kind show results of kind inference for each module
kind-steps show steps of kind inference
program impl expls, the whole shebang.
sigenv initial signature environment
srcsigs processed signatures from source code
types display unified type table containing all defined names

Intermediate code

core show intermediate core code
core-afterlift show final core before writing ho file
core-beforelift show core before lambda lifting
core-initial show core right after E.FromHs conversion
core-mangled de-typed core right before it is converted to grin
core-mini show details even when optimizing individual functions
core-pass show each iteration of code while transforming
core-steps show what happens in each pass
datatable show data table of constructors
datatable-builtin show data table entries for some built in types
e-alias show expanded aliases
e-info show info tags on all bound variables
e-size print the size of E after each pass
e-verbose print very verbose version of E code always
optimization-stats show combined stats of optimization passes
rules show all user rules and catalysts
rules-spec show specialization rules

Grin code

grin dump all grin to the screen
grin-datalog print out grin information in a format suitable for loading into a database
grin-final final grin before conversion to C
grin-graph print dot file of final grin code to outputname_grin.dot
grin-initial grin right after conversion from core
grin-normalized grin right after first normalization
grin-posteval show grin code just before eval/apply inlining
grin-preeval show grin code just before eval/apply inlining
steps show interpreter go
tags list of all tags and their types

Backend code

c don't delete C source file after compilation


atom dump atom table on exit


progress show basic progress indicators
stats show extra information about stuff
verbose progress
veryverbose progress stats


John Meacham.