
SCons: I am a convert
News, Technical, School ·Sunday November 8, 2009 @ 15:34 EST (link)
The make utility is venerable. It's also rather simplistic and somewhat crufty. The easy things are easy, but sometimes the hard things are impossible. Despite the many features added to the most common instance of the tool, make GNU make, it becomes inconvenient for all but the simplest projects. So I hunted around for something better for my UW compilers project.
At Hilton (c. 2004), I built a Perl tool—hmake, Hilton make—that leveraged the power of Perl, meaning that all hmake did was run the Perl program Makefile.pl if it was found, after minimal setup (I know CPAN distributions use Makefile.PL but uppercase PL seemed gauche and inconsistent). Makefile.pl was supposed to use the hilton::Make module and provide it a list of targets/dependencies, possibly including Perl code, which would be examined and built optimally depending on what had changed since the last build, just like make. Except hmake had Perl available to do complex target mappings (e.g. database definition files like gst_membership.cfg to perl modules like GstMembership.pm) which weren't possible with standard make. It could also do the usual install tasks etc.
SCons ("A software construction tool") (FAQ) has taken this to the next level. It is built using Python, not Perl, which is fine since I've been writing a few utilities in Python lately anyway, and the language is growing on me. It seems to be actively maintained and reasonably well documented (although apparently the (long) man page is kept more up to date); class documentation; there is also a wiki where I found several helpful nodes including one about the equivalent of make .PHONY targets, e.g., making scons run tests (replacing make test). And the source code is eminently readable; I was reading a fair amount of it figuring out how it all worked.
It is based around the concept of Builders, objects which produce target files from sources. They are very flexible, and it comes with a good number of useful defaults. I thought I would need to build flex and bison builders, but it comes with them, including analyzing the command-lines for --defines and --header-file and adding those to the target list. I did have to tweak it to understand that my scanner (.l) and parser (.y) files create C++ (.cc), not C (.c) files (I could have used use .ll and .yy, but I reject those on principle: the source is still the same type). I also added the Bison-generated location.h and position.hh files using a variant of this recipe. SCons already has an include-file scanner (no more messing around with gcc -MMD etc.), but needed to know how location.hh and position.hh were generated ("emitted" in SCons-speak) so it knew to build the parser before files that included those files.
I will not be using make in future projects unless compelled to. Call me a fan, and a devotee of scons, and kudos to the developers for a great tool.