SCons User Guide 0.93 | ||
---|---|---|
<<< Previous | Next >>> |
It is rare that all of the software in a large, complicated system needs to be built the same way. For example, different source files may need different options enabled on the command line, or different executable programs need to be linked with different libraries. SCons accomodates these different build requirements by allowing you to create and configure multiple construction environments that control how the software is built. Technically, a construction environment is an object that has a number of associated construction variables, each with a name and a value. (A construction environment also has an attached set of Builder methods, about which we'll learn more later.)
A construction environment is created by the Environment method. When you initialize a construction environment, you can set the values of the environment's construction variables to control how a program is built. For example:
env = Environment(CC = 'gcc', CCFLAGS = '-O2') env.Program('foo.c') |
This example, rather than using the default, explicitly specifies use of the GNU C compiler gcc, and further specifies that the -O2 (optimization level two) flag should be used when compiling the object file. So a run from this example would look like:
% scons -Q
gcc -O2 -c -o foo.o foo.c
gcc -o foo foo.o
The real advantage of construction environments become apparent when you realize that you can create as many different construction environments as you need, each tailored to a different way to build some piece of software or other file. If, for example, we need to build one program with the -O2 flag and another with the -g (debug) flag, we would do this like so:
opt = Environment(CCFLAGS = '-O2') dbg = Environment(CCFLAGS = '-g') opt.Program('foo', 'foo.c') dbg.Program('bar', 'bar.c') |
% scons -Q
cc -g -c -o bar.o bar.c
cc -o bar bar.o
cc -O2 -c -o foo.o foo.c
cc -o foo foo.o
We can even use multiple construction environments to build multiple versions of a single program. If you do this by simply trying to use the Program builder with both environments, though, like this:
opt = Environment(CCFLAGS = '-O2') dbg = Environment(CCFLAGS = '-g') opt.Program('foo', 'foo.c') dbg.Program('foo', 'foo.c') |
Then SCons generates the following error:
% scons -Q
scons: *** Two different environments were specified for the same target: foo.o
File "SConstruct", line 6, in ?
This is because the two Program calls have each implicitly told SCons to generate an object file named foo.o, one with a CCFLAGS value of -O2 and one with a CCFLAGS value of -g. SCons can't just decide that one of them should take precedence over the other, so it generates the error. To avoid this problem, we must explicitly specify that each environment compile foo.c to a separately-named object file using the Object call, like so:
opt = Environment(CCFLAGS = '-O2') dbg = Environment(CCFLAGS = '-g') o = opt.Object('foo-opt', 'foo.c') opt.Program(o) d = dbg.Object('foo-dbg', 'foo.c') dbg.Program(d) |
Notice that each call to the Object builder returns a value, an internal SCons object that represents the object file that will be built. We then use that object as input to the Program builder. This avoids having to specify explicitly the object file name in multiple places, and makes for a compact, readable SConstruct file. Our SCons output then looks like:
% scons -Q
cc -g -c -o foo-dbg.o foo.c
cc -o foo-dbg foo-dbg.o
cc -O2 -c -o foo-opt.o foo.c
cc -o foo-opt foo-opt.o
<<< Previous | Home | Next >>> |
The Depends Method | Copying Construction Environments |