Autoconf, Automake, SWIG, Python distutils

Recently, I created a Python binding for Soothsayer and integrated it into the build system using some Autotools magic and a few custom m4 macros obtained from the Autoconf Macro Archive.

The first solution I put in place was largely based on this (very good) tutorial. In a nutshell, this is how it worked:
- configure.ac runs a few checks to determine whether SWIG and Python are available, using the AC_PROG_SWIG and AM_PATH_PYTHON macros respectively. If the user enabled the Python binding module with the --enable-python-binding, then the SWIG_ENABLE_CXX and SWIG_PYTHON macros are invoked to setup SWIG flags.
- the bindings directory contains the SWIG interface file, which needs to be parsed through the SWIG tool to generate the wrapper (a C++ source file and a Python source file).
- during a build run, Makefile.am in the bindings directory contains targets that cause SWIG to process the interface file to generate the wrapper, then compile the generated wrapper, and finally link with the wrapper object and the soothsayer shared library into a Python _soothsayer loadable extension module.
- during an install run, the generated files and library are installed into the Python extensions directory.

However, this solution had a couple of problems that I could not force myself to overlook:
- the generated sources had to be generated into the source tree, rather than in the build tree, in order for the macro defined primitives to work.
- the AC_PYTHON_DEVEL macro, required by SWIG_PYTHON, fails to detect a default Python installation on Windows/Cygwin (requiring the user to tweak the LDFLAGS when configuring the package to work around the problem).
- it does not use the recommend Python way to build Python extension modules.

For all these reasons, I decided to scrap that solution and build a new one based on the Python distutils package. The Python distutils package provides a suite of standard Distribution Utilities for Python. The goal of the Distribution Utilities (`distutils') is to make building, distributing, and installing Python modules, extensions, and applications painless and standardized.

Given that, I had to get the soothsayer build system to work with distutils. I therefore scrapped what I had and begun to build the necessary infrastructure to create a distutils extension module. As it turns out, there is really not much overhead to make distutils happy.

All the requirements are extensively laid out in the distutils documentation pages. In particular, refer to the Distributing Python Modules manual. To cut a long story short, all you have to do is provide a setup.py Python file to define some meta-data describing the extension module. The Python extension module is built and installed with `python setup.py build' and `python setup.py install'.

Since setup.py contains installation dependent meta-data, I modified my configure.ac to process a setup.py.in template located in the bindings/python source directory to produce a configured setup.py in the bindings/python build directory. I then added targets to the bidings/python/Makefile.am file using the all-local: install-exec-local: and clean-local: Automake targets. These targets simply invoke python setup.py with the appropriate distutils command. It goes without saying the all make command rules use variables substituted by Autoconf (such as $(SWIG) and $(PYTHON), for example).

Sprinkle a couple of additional rules to generate the wrapper source code using SWIG and to clean up the build directory created by distutils, and your Autotools + SWIG + Python distutils recipe is complete.

For additional details, see configure.ac, bindings/python/Makefile.am and bindings/python/setup.py.in files in Subversion.