Let's have a brief look at how to call the tool and how to use the generated interfaces.
C➔Haskell is implemented by the executable c2hs. The simplest form of usage is
c2hsLib
.chs
where Lib
.chs
is the Haskell
binding module defining the Haskell interface to a C library together with
the required marshalling code. If c2hs is invoked in this manner, the
binding module must contain a cpp #include
directive to
determine the C-side interface of the library. Alternatively, a C header
file can be specified on the command line, as in
c2hslib
.h
Lib
.chs
However, the latter option is only preserved for backwards compatibility and not recommended. If no errors occur, c2hs generates three files:
a pure Haskell module Lib
.hs
,
which implements the Haskell API of the library
a C header file Lib
.h
which some Haskell systems need to compile the generated Haskell code.
a c2hs interface file
Lib
.chi
that is used by
other binding modules that import
Lib
.hs
using an import
hook (see the section called “Import Hooks”the section on import hooks for details).
The executable c2hs has a couple more options:
Usage: c2hs [ option... ] [header-file] binding-file -C CPPOPTS --cppopts=CPPOPTS pass CPPOPTS to the C preprocessor -c CPP --cpp=CPP use executable CPP to invoke C preprocessor -d TYPE --dump=TYPE dump internal information (for debugging) -h, -? --help brief help (the present message) -i INCLUDE --include=INCLUDE include paths for .chi files -k --keep keep pre-processed C header -l --copy-library copy `C2HS' library module in -o FILE --output=FILE output result to FILE (should end in .hs) -p PLATFORM --platform=PLATFORM platform to use for cross compilation -t PATH --output-dir=PATH place generated files in PATH -v --version show version information --numeric-version show version number The header file must be a C header file matching the given binding file. The dump TYPE can be trace -- trace compiler phases genbind -- trace binding generation ctrav -- trace C declaration traversal chs -- dump the binding file (adds `.dump' to the name) PLATFORM can be x86_64-linux, i686-linux, m68k-palmos
The most useful of these is probably --cppopts=
(or
-C
). If the C header file needs any special options
(like -D
or -I
) to go through the C
pre-processor, here is the place to pass them. A call may look like this:
c2hs --cppopts='-I/some/obscure/dir' --cppopts=-DEXTRA' Lib
.chs
If you have more than one option that you want to pass to the pre-processor
it is best to use multiple --cppopts=
flags. That way
there is no need to worry about quoting.
Often, lib
.h
will not be in
the current directory, but in one of the header file directories. c2hs
leaves locating the header file to the standard C preprocessor, which
usually looks in two places for the header: first, in the standard include
directory of the used system, this is usually /usr/include
and
/usr/local/include
; and second, it will look in every directory
that is mentioned in a -IDIR
option passed to the
pre-processor via --cppopts
.
If the compiled binding module contains import hooks, C➔Haskell needs to
find the .chi
(C➔Haskell interface files) produced while compiling
the corresponding binding modules. By default, they will be searched for in
the current working directory. If they are located elsewhere, the
--include=
option has
to be used to indicate the location, where
INCLUDE
INCLUDE
is a colon-separated list of
directories. Multiple such options are admissible. Paths specified later
are searched first.
C➔Haskell comes with a marshalling library, called C2HS
,
which needs to be explicitly imported into Haskell binding modules. The
library contains functions that users might use explicitly, but also
functions that C➔Haskell will generate for some classes of bindings. The
library takes the form of a single Haskell module, which c2hs places in
the same directory as the generated binding whenever it is given the
--copy-library
(or -l
) option.