Yet Another FFI Binding Auto-generation Utility

HSFFIG (HaSkell FFI Generator)

This file contains very brief and informal introduction in the
Haskell FFI binding autogeneration utility, hsffig. As of today,
06/25/2005, the utility is in its very early stage; a lot of things 
will change in the future, so it is not worth the effort to document
everything now.

The utility is built on the simple principle: given a C include
file (.h) for a library, generate a Haskell module (or a collection 
of modules) containing FFI bindings for the library. No configuration files,
no manually written wrappers, nothing else. Maximum, a single include
file needs to be written manually, containing only few #include directives.

It is assumed that GNU C compiler is used. The utility has not been tested
with compilers from other vendors. Also the utility is significantly
biased towards GHC as the Haskell compiler to use, and although it may work
with Hugs as well, this has not been tested yet.

1. Generation of Haskell bindings from an include file

The `hsffig' utility works as a filter consuming output of the C preprocessor,
which in turn consumes the include file(s).

For example,

gcc -E -dD db.h | hsffig > DB_H.hsc

The hsffig utility produces a .hsc file (see GHC documentation). The file contains
FFI declarations for functions whose prototypes were found in the include file,
for most of the constants defined in the file (via #define and enumerations), and
also declarations to access fields of structures and unions defined in the include file.

The .hsc file will contain definition of a single module whose name is derived
from the include file name by throwing away directory (as basename(1) does),
uppercasing the remaining filename, and replacement of dots with underscores.

This .hsc file needs to be converted to compilable Haskell with the `hsc2hs' utility
(included with GHC). To work around the cases when C structures are declared 
anonymously, special hsc2hs template must be used: template-hsffig.h (included
with hsffig source distribution). See also [1].

For example,

hsc2hs -t template-hsffig.h DB_H.hsc -o DB_H.hs

2. Inclusion of multiple header files

If inclusion of more than a single file is necessary, it is recommended to
manually create an include file, containing #include directives for all the
files to be included. This results in creation of a single module. If for some
reason these include files cannot be included at once, hsffig may be run for each
file independently (producing a .hsc file for each .h file). However it is not 
recommended to import those modules together (similarly to the situation with .h
files: if they cannot be #include'd together without conflicts, most likely
the resulting modules will conflict if imported together).

3. Splitting large modules.

For certain include files, amount of autogenerated Haskell code may be
large enough to become non-compilable due to lack of computer resources.
In this situation, one large module may be split into many modules of much smaller
size. This does not affect the way the autogenerated binding is imported: the module
whose name is derived from the include file name as shown before is to be imported.
The rest will be chased automatically if using ghc --make.

The `splitter' utility serves this purpose. To use it, hsc2hs must be instructed
to save its Haskell output in a file with name not ending with .hs:

hsc2hs -t template-hsffig.h DB_H.hsc -o DB_H.hs_unsplit

and then, the splitter comes into action:

splitter DB_H.hs_unsplit

As a result, many smaller Haskell modules will be created (currently, a module for
all functions, a module for all #define'd constants, a module for all enumerations,
a separate module for each C structure, a module providing combinators to access
C structure fields).

4. Binding Declarations Generated.

Please refer to the hsffig Tutorial: http://haskell.org/hawiki/HsffigTutorial
which contains the detailed description of import declarations generated.

5. A Working Example

Binding to the Sleepycat's Berkeley DB database library was autogenerated, and
a program from the database tutorial was compiled with it. The example worked.

The `bdb' subdirectory contains source code of the example program, and the binding
may be autogenerated by executing `make' in the `bdb' directory.


[1] http://www.haskell.org//pipermail/glasgow-haskell-users/2005-June/008619.html

