2007-10-28

SCons is not bad, not bad at all

For my personal project where I learn a language by writing five small example applications, I had ended up writing my own build tool. It was nothing much: specify the source extension, compiled file extension, and the command to execute. But then each language added some tweak that caused issues. Haskell, for instance, was the first language I wrote my example apps in that had several intermediate files that needed to be cleaned up. So then I needed to add support for specifying file extensions that could be safely deleted. And all of this was being kept in a config file that required using ConfigParser (not the nicest module in Python's stdlib to work with). I was writing too much code for a problem others have solved in separate tools for a long time.

But I hate Makefiles and that is the one build tool that I have any experience with. I have talked about replacing Python's build system with an alternative, so I figured I might as well learn a new one so as to compare against GNU Make. I considered using Bakefile, CMake, and SCons.

Bakefile was killed as a possible solution immediately based on lack of development. The mailing list has only a single new thread in October and the last release was back in February. Now being a open-source software developer I can understand having several months between releases, but I just tend to trust projects that have been updated within the last six months or at least have an active mailing list to back it up, especially when the project lacks a 1.0 release. So Bakefile was out.

CMake was a definite contender. Since it is the unofficial leader in the race in my head for a build system replacement for Python I really wanted to give CMake a try. Unfortunately I couldn't easily figure out how to create a custom build command. Since my use case is compiling several non-standard languages I needed an easy way to specify a custom build command along with a way to state what files to delete on cleanup. I just couldn't figure out how to do that in CMake.

And that left SCons. I was able to get it work with all the languages without much issue. I do have some boilerplate in several SConstruct files for tacking on file extensions of files to remove during cleanup, but it isn't bad. Plus having the build files be Python made it easy to extend it to do whatever I needed. My only complaint is that I had to hard-code the paths to the compilers since Builder commands don't seem to execute within a shell. I might just write a 'which' replacement and stick in my root SConstruct file (along with any other boilerplate I have written) and just expose the code through SCons variables. But overall I am happy with SCons for my personal use.