Next Previous Contents

2. Usage of C->Haskell

Let's have a brief look at how to call the tool and how to use the generated interfaces.

2.1 Usage of 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.

2.2 Compilation of a Generated Haskell API

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.


Next Previous Contents