Tuesday, May 12, 2009

SCons

I spent some of today looking at SCons as a build tool for (initially) my C++ code. After trying things out on some toy code I moved over to my main codebase that contains 10,000+ lines of code spread across 50+ files.

To date my build system has consisted of calling, from the command line, the MSVC++ executables on pre-established workspace/solution files. This becomes a real nuisance when I need to add new code to the project as it involves GUI manipulation to add each file to the project (true, I could edit the project files directly, but I don't know the specifics of the formats well enough to be confident my changes would be correct). Plus, I have to do this for multiple versions of MSVC++ that I still need to support. I tend not to use the MSVC++ IDEs to create and edit my source files and I have, more than once, added files to the filesystem and forgotten to add them to the project. So, one thing I wanted of SCons was to not have to update the build script if I added a new set of code to the source tree.

I wasn't able to locate a SCons function to do this for me directly. It seems the only source aggregation routines available in SCons work in a single directory. However, since SCons' build scripts are written in Python it was simple enough to create what I wanted. Here is the function I created (with help from Programming Python, 3rd Ed) to get a list of all source files in a source tree:


import os
def getSourceFiles(root_dir, source_file_extensions):
source_files = []
for (dirname, dirshere, fileshere) in os.walk(root_dir):
for filename in fileshere:
if os.path.splitext(filename)[1] in source_file_extensions:
source_files.append(os.path.join(dirname, filename)

return source_files


With this routine I can now compile a library of C and C++ code spread throughout a directory tree using the following SCons build script:


source_files = getSourceFiles('src', ['.cpp', '.c'])
Library('libname', source_files)


Nary a hard coded filename in sight.

An added advantage of SCons over MSVC++ is related to source files with the same name but in different directories. MSVC++ by default will try to generate the same object file for all source files with the same name, regardless of where they appear in the source tree. Manual intervention is required to have different files generate different object files. In contrast, SCons' default operation is to reflect the source directory tree in the build output.

So, after half a day of use, SCons is impressing me. However, I have only tested my build script on one computer (a Mac). Tomorrow I need to test on a Windows box and configure the script to selectively use VC6 or VC8.

0 comments: