Introduction
------------
This is a library binding generator much like SWIG, except it infers
many interesting properties about functions (which would need to be
specified via annotations for SWIG) through source code analysis
(using the LLVM compiler framework).

In particular, it can detect output parameters, array parameters,
and some memory management functions.  It can use this information
to generate idiomatic bindings in various languages.

This is the implementation referenced in the 2009 PLDI paper
"Automatic Generation of Library Bindings Using Static Analysis"
by Tristan Ravitch, Steve Jackson, Eric Aderhold, and Ben Liblit.


Current Code Generators
-----------------------
* Python/ctypes

Contributions are welcome


Required Dependencies
---------------------
* Boost (almost any version should work)
* Guile (1.8.x or 1.9.x)
* llvm-2.4 and llvm-gcc-4.2-2.4
* gcc[1]
* perl
* Python
* binutils (objdump, objcopy)

[1] Any modern version of gcc should work, but gcc-4.4 requires
a slight tweak to compile llvm because the required version (2.4)
is so old.  This tweak is performed automatically in the build-llvm.sh
script.  This is only temporary and will not be required after the
analysis is forward-ported to llvm-2.6 when it is released.

Installation
------------
1) Acquire llvm-2.4 and llvm-gcc-4.2-2.4

If you already have both working, skip to 2.

The build-llvm.sh script will download and install the correct
versions of llvm and llvm-gcc into a local root (with
PREFIX=${PROJECT_ROOT}).  The tarballs are only downloaded if they do
not exist in ${PROJECT_ROOT}/tarballs; if you already have the
tarballs, you can place them in this directory to avoid re-downloading
them.

If you already have a working llvm and llvm-gcc (2.4) install, you do
not need to run build-llvm.sh.

2) ./waf configure --prefix=`pwd`
3) ./waf build
4) ./waf install

Usage
-----
The basic idea is to use the substitute driver program
(${PROJECT_ROOT}/bin/scc) in lieu of gcc to compile a library.  This
will compile the library as normal, but collect some information on
the side to allow us to perform a static analysis.  After this
information is gathered, we analyze it and produce an intermediate
format describing all of the functions it provides.  From there, we
feed this intermediate representation into language-specific code
generators which produce library bindings.  More details are in the
${PROJECT_ROOT}/doc subdirectory.

Assuming you have extracted and built this source package in a directory
${PROJECT_ROOT}, here is a concrete example:

export PATH=$PATH:${PROJECT_ROOT}/bin/
tar xzf gsl-1.12.tar.gz
cd gsl-1.12

--------------------------------------------------------------------------------
# Step 1
# Compile the library with the substitute driver program.  This
# step creates
#  1) The library (as normal), and
#  2) An intermediate representation of the entire library
#     suitable for interprocedural analysis
# Assume this creates a shared library called libgsl.so
CC=scc ./configure # Any other options you would normally pass
make

# Step 2
# The static analysis phase extracts the intermediate representation
# of the library (created in step 1.2) and infers interesting properties
# of function parameters.
#
# The output is a language-independent description of the interface
# provided by the library, which is annotated with all of the inferred
# properties from the static analysis.
sigdump libgsl.so -o gsl.interface

# Step 3
# Feed the interface description to a language-specific
# code generator.  The example Python generator is shown
# here.
ctypes-generator gsl.interface --module=gsl -o gsl.py
--------------------------------------------------------------------------------

Note that you do not need to use the library generated by llvm
(although you can).  Your system provided library is compatible,
provided it is the same version.


Other Notes
-----------
Parts of this application use Chris Venter's Base64 encoder/decoder libb64
available at http://libb64.sourceforge.net/ .  This is not listed as a
dependency because it is included directly in src/b64 and include/b64.

The python-ctypes code generator requires one external module:
 * decorator (http://www.phyast.pitt.edu/~micheles/python/documentation.html)
Additionally, there is one module of python helpers in $PREFIX/share/sigdump/python
that provide runtime support to the generated FFI bindings.

Adding this directory to your PYTHON_PATH should be sufficient.


Contact Information
--------------------
Please send any bug reports, comments, or contributions to
Tristan Ravitch <travitch@cs.wisc.edu>
