SamJansen's work in progress.
This document describes moving from the traditional make(1) build system to the Python-based SCons replacement.
make(1) is not for everyone. I've had to maintain the build system for a reasonably large and complex project and using makefiles has been more and more of a headache as time has passed. I have found almost no redeeming features in make - the only thing I can say for it is that most people who wish to compile software will have it installed.
Should you use SCons too? Maybe. SCons requires that whoever has to compile the software has both Python and SCons installed. If this is an acceptable requirement, then the answer is probably "yes".
The worst thing about SCons is that it does take some time to learn. It is not hard to learn; being based on the simple but powerful programming language Python helps here, but it can be hard to make the leap from a system you already know to a new one, even if the old system is inferior, simply because of the extra time it takes to learn the new system. However, I recommend learning modern build systems that don't employ make.
SCons does a few things for free. Dependency tracking is the first one that springs to mind. Consider the following makefile and its SCons equivalent:
program: main.o sam.o johno.o gcc -o $@ $^
Program(source = ["main.c", "sam.c", "johno.c"], target = "program")
Both of these work the same at the first glance, though I believe the SConstruct file (yes, SConstruct is the name of the file that replaces your MakeFile) to be a lot more readable. However the SCons file has the following extra features:
env = Environment(CCFLAGS = '-Wall -pipe', LIBS = ['m', 'jpeg']) env.Program('sam', ["lib.c", "sam.cc"], CPPPATH = ['include', 'common/include']) env.SharedLibrary('testlib', ["source1.cc", "source2.c"])
This also sets the variable CPPPATH, which specifies which directories are to be searched for include files that are scanned during depency tracking. These are also passed to the compiler with the -I flag in the case of GCC. The flags can also be passed in the Program or Library line, constructing and Environment is usually done so multiple things can be built with the same environment.
A full list of the possible options can be found in the SCons manual.
In many cases the above will be enough: often you just want to build a directory of files into a library, shared library, or executable with a specific set of flags and dependencies. Of course, SCons lets you do a lot more, and at little to no extra cost in complexity.
It is simplicity itself to include multiple files in the build. Remember that SCons is Python-based?
import glob Library(glob.glob('*.c') + glob.glob('source_dir_2/*.cc'), 'sam')
Python's glob module does all the hard work. Again, full dependency tracking and all other features of SCons work correctly.
SCons supports hierarchical builds with the use of the SConscript directive. These scripts will be read and their information processed. No new SCons is forked for the SConscript directives, unlike the usual recursive make solution.
SConscript("dir1/") SConscript("dir2/")
This will read in the SConscript files in dir1 and dir2. It is possible to export environments to these other scripts if need be.
No page links to MakeToSCons.