Let's have a brief look at how to call the tool and how to use the generated interfaces.
c2hs
C->Haskell is implemented by the executable c2hs
. It is usually
called as
c2hs
lib.h
Lib.chs
where lib.h
is the header file and Lib.chs
the Haskell
binding module, which define the C- and Haskell-side interface, respectively.
If no errors occur, the result is a pure Haskell module Lib.hs
,
which implements the Haskell API of the library.
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
-o FILE --output=FILE output result to FILE (should end in .hs)
-v --version show version information
--old-ffi[=OLDFFI] use the FFI without `Ptr a'
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)
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 -DEXTRA'
lib.h
Lib.chs
Do not forget the quotes if you have more than one option that you want to pass to the pre-processor.
Often, lib.h
will not be in the current directory, but in one of the
header file directories. Apart from the current directory, C->Haskell
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=INCLUDE
option has to be used to indicate the location, where
INCLUDE
is a colon-separated list of directories. Multiple such options
are admissible. Later paths are searched first.
C->Haskell comes with a marshalling library, called C2HS
, which is
imported by virtually all library bindings. Consequently, you will have to
tell the Haskell compiler where to find the interface files when you compile a
generated interface and you have to tell the linker where to find the library
archive of C2HS
. To simplify this usually operating and compilation
system-dependent process, C->Haskell comes with a simple configuration
manager, in the form of the executable c2hs-conf
. It can be used to
inquire information for compilation and linking and pass that information on
to the Haskell compiler. The call
c2hs-config --cflags
returns all flags that need to be given to the Haskell compiler for compilation and
c2hs-config --lib
returns all flags necessary for linking. Overall, you may want to use a call like the following to compile a generated library module:
ghc `c2hs-config --cflags` -c
Lib.hs
The backquotes cause the shell to call c2hs-config
and substitute the
call by the flags returned. This, of course, also works in a makefile.
Furthermore, c2hs-config
can also be used to locate the executable of the
tool itself, by calling
c2hs-config --c2hs
This slightly simplifies configuration management of libraries generated by
C->Haskell, as it is sufficient to know the location of c2hs-config
to
access all other components of C->Haskell.