It’s not much of a secret that I loathe autotools and have been seeking to banish that festering pile of rancid crocks from my life. I took another step in that direction over the last four days, and have some interesting statistics to report.
I have been muttering dark threats against the autotools-based build system in GPSD for years. All the usual reasons applied – it’s brittle, clunky, slow, and a huge maintainance headache. There was one piece of it in particular, the place where the generated makefile calls setup.py to make some Python extension modules, that was just hideously bug-prone.
But one of my lieutenants doesn’t like Python. That, and too much other stuff to do, kept shooting autotools through the head just far enough down the priority list that it didn’t get done. Until we had an embedded user show up (Thomas Zerucha from my post on bookend consistency) and complain that our autotools build takes nine eternities to run on the little ARM device he’s targeting.
That did it. Out came the notional .45. Die, you monster! *BANG*
It’s now about a week later; I have a success story and some interesting statistics to report. But first, let us set the scene. GPSD is a mid-sized project at about 41KLOC of C and Python in 120 or so sourcefiles. Our build products are eight binaries, five Python scripts, a moderately complex Python extension module, and sixteen man pages. The build system is also the framework for our regression-test suite, a large and important component that goes far towards explaining GPSD’s exceptionally low defect rate.
The autotools build system is a bit over 2100 lines of stuff. That’s just counting Makefile.am, configure.ac, and autogen.sh; if I counted all the auxiliary scripts and crap autotools leaves lying around (aclocal.m4, anyone?) it would balloon up to 14K.
It took me about 6 man-days of concentrated effort to convert this to an SCons recipe. Most of that effort and time was spent comprehending what the autotools build is actually doing; replicating it in SCons once I understood it was relatively easy and actually kind of fun. I guess I should explain that…
An SCons recipe is a Python script which evaluates to a set of production rules making targets from sources. The rules can be, and usually are, chained together; you tell the system to make a target and it fires the minimum set of rules to achieve that. This is familiar territory to anyone who’s ever written a makefile.
One thing that makes SCons tremendously more powerful than a makefile is that you get to use a full programming language to generate the production rules. And not just a lame macro language like autotools, either. One of my devs spotted an opportunity: where I had a utility production that sequentially invoked fifteen variant splint(1) commands, he turned into a data table that the recipe walks through using a Python loop, generating a production rule on each tick. The table is far easier to understand and modify than the code it replaced.
2129 or so lines of autotools code turned into 1057 lines of SCons recipe. That’s a full factor of two shrinkage, but it actually understates the gain in readability. Where the autotools builder is written in an incongruent mixture of three quite dissimilar languages (shell, m4 macros, and make notation), the SCons recipe is just Python calling rule-generator functions. It’s a refreshing change being able to look at a build recipe that size without feeling like you’re inexorably losing sanity points thereby.
But the real surprise was the build time. Pretty consistently the SCons build completes almost three times as fast as the autotools build. On my 2GHz Intel Core Duo, wall time drops from 50-odd seconds for configure/make to about 20 for scons.
Not all is perfection yet. There’s one minor component (the Qt client library) that scons can’t build yet, because it requires idiosyncratic build tools of its own that are stapled into the autotools build in ways I don’t understand yet. The real problem is, as as usual, that any random autotools build can be expected to be a nigh-incomprehensible mess.
A more serious issue is that I haven’t figured how to do out-of-directory builds in SCons. That’s a fragile and difficult feature in autotools; we haven’t got it quite right, last I heard (I don’t need or use VPATH myself). But at least it’s theoretically possible, and our Mac-port guy is probably going to become difficult if I have to tell him he can’t have it.
This is my second scons conversion. The first, for Battle For Wesnoth, went pretty well too. Thomas just checked in and loves the speed increase. I’m feeling happy about having tremendously reduced GPSD’s long-term maintainance burden.
Say it with me…no, yell it good and loud: “AUTOTOOLS MUST DIE!”. SCons is not the only competitor to replace it, but it’s the one I recommend.