SCons provides various methods that support modifying existing values in a construction environment.
You can replace existing construction variable values
using the Replace method:
env = Environment(CCFLAGS = '-DDEFINE1')
env.Replace(CCFLAGS = '-DDEFINE2')
env.Program('foo.c')
The replacing value (-DDEFINE2 in the above example) completely replaces the value in the construction environment:
% scons -Q
cc -o foo.o -c -DDEFINE2 foo.c
cc -o foo foo.o
You can safely call Replace
for construction variables that
don't exist in the construction environment:
env = Environment()
env.Replace(NEW_VARIABLE = 'xyzzy')
print "NEW_VARIABLE =", env['NEW_VARIABLE']
In this case, the construction variable simply gets added to the construction environment:
% scons -Q
NEW_VARIABLE = xyzzy
scons: `.' is up to date.
Because the variables aren't expanded until the construction environment is actually used to build the targets, and because SCons function and method calls are order-independent, the last replacement "wins" and is used to build all targets, regardless of the order in which the calls to Replace() are interspersed with calls to builder methods:
env = Environment(CCFLAGS = '-DDEFINE1')
print "CCFLAGS =", env['CCFLAGS']
env.Program('foo.c')
env.Replace(CCFLAGS = '-DDEFINE2')
print "CCFLAGS =", env['CCFLAGS']
env.Program('bar.c')
The timing of when the replacement actually occurs relative to when the targets get built becomes apparent if we run scons without the -Q option:
% scons
scons: Reading SConscript files ...
CCFLAGS = -DDEFINE1
CCFLAGS = -DDEFINE2
scons: done reading SConscript files.
scons: Building targets ...
cc -o bar.o -c -DDEFINE2 bar.c
cc -o bar bar.o
cc -o foo.o -c -DDEFINE2 foo.c
cc -o foo foo.o
scons: done building targets.
Because the replacement occurs while
the SConscript files are being read,
the $CCFLAGS
variable has already been set to
-DDEFINE2
by the time the foo.o target is built,
even though the call to the Replace
method does not occur until later in
the SConscript file.
You can append a value to
an existing construction variable
using the Append method:
env = Environment(CCFLAGS = '-DMY_VALUE')
env.Append(CCFLAGS = ' -DLAST')
env.Program('foo.c')
SCons then supplies both the -DMY_VALUE and -DLAST flags when compiling the object file:
% scons -Q
cc -o foo.o -c -DMY_VALUE -DLAST foo.c
cc -o foo foo.o
If the construction variable doesn't already exist,
the Append method will create it:
env = Environment()
env.Append(NEW_VARIABLE = 'added')
print "NEW_VARIABLE =", env['NEW_VARIABLE']
Which yields:
% scons -Q
NEW_VARIABLE = added
scons: `.' is up to date.
You can append a value to the beginning of
an existing construction variable
using the Prepend method:
env = Environment(CCFLAGS = '-DMY_VALUE')
env.Prepend(CCFLAGS = '-DFIRST ')
env.Program('foo.c')
SCons then supplies both the -DFIRST and -DMY_VALUE flags when compiling the object file:
% scons -Q
cc -o foo.o -c -DFIRST -DMY_VALUE foo.c
cc -o foo foo.o
If the construction variable doesn't already exist,
the Prepend method will create it:
env = Environment()
env.Prepend(NEW_VARIABLE = 'added')
print "NEW_VARIABLE =", env['NEW_VARIABLE']
Which yields:
% scons -Q
NEW_VARIABLE = added
scons: `.' is up to date.