One of the most basic things you can control
is which targets SCons will build by default--that is,
when there are no targets specified on the command line.
As mentioned previously,
SCons will normally build every target
in or below the current directory
by default--that is, when you don't
explicitly specify one or more targets
on the command line.
Sometimes, however, you may want
to specify explicitly that only
certain programs, or programs in certain directories,
should be built by default.
You do this with the Default function:
env = Environment()
hello = env.Program('hello.c')
env.Program('goodbye.c')
Default(hello)
|
This SConstruct file knows how to build two programs,
hello and goodbye,
but only builds the
hello program by default:
% scons -Q
cc -o hello.o -c hello.c
cc -o hello hello.o
% scons -Q
scons: `hello' is up to date.
% scons -Q goodbye
cc -o goodbye.o -c goodbye.c
cc -o goodbye goodbye.o
|
Note that, even when you use the Default
function in your SConstruct file,
you can still explicitly specify the current directory
(.) on the command line
to tell SCons to build
everything in (or below) the current directory:
% scons -Q .
cc -o goodbye.o -c goodbye.c
cc -o goodbye goodbye.o
cc -o hello.o -c hello.c
cc -o hello hello.o
|
You can also call the Default
function more than once,
in which case each call
adds to the list of targets to be built by default:
env = Environment()
prog1 = env.Program('prog1.c')
Default(prog1)
prog2 = env.Program('prog2.c')
prog3 = env.Program('prog3.c')
Default(prog3)
|
Or you can specify more than one target
in a single call to the Default function:
env = Environment()
prog1 = env.Program('prog1.c')
prog2 = env.Program('prog2.c')
prog3 = env.Program('prog3.c')
Default(prog1, prog3)
|
Either of these last two examples
will build only the
prog1
and
prog3
programs by default:
% scons -Q
cc -o prog1.o -c prog1.c
cc -o prog1 prog1.o
cc -o prog3.o -c prog3.c
cc -o prog3 prog3.o
% scons -Q .
cc -o prog2.o -c prog2.c
cc -o prog2 prog2.o
|
You can list a directory as
an argument to Default:
env = Environment()
env.Program(['prog1/main.c', 'prog1/foo.c'])
env.Program(['prog2/main.c', 'prog2/bar.c'])
Default('prog1')
|
In which case only the target(s) in that
directory will be built by default:
% scons -Q
cc -o prog1/foo.o -c prog1/foo.c
cc -o prog1/main.o -c prog1/main.c
cc -o prog1/main prog1/main.o prog1/foo.o
% scons -Q
scons: `prog1' is up to date.
% scons -Q .
cc -o prog2/bar.o -c prog2/bar.c
cc -o prog2/main.o -c prog2/main.c
cc -o prog2/main prog2/main.o prog2/bar.o
|
Lastly, if for some reason you don't want
any targets built by default,
you can use the Python None
variable:
env = Environment()
prog1 = env.Program('prog1.c')
prog2 = env.Program('prog2.c')
Default(None)
|
Which would produce build output like:
% scons -Q
scons: *** No targets specified and no Default() targets found. Stop.
% scons -Q .
cc -o prog1.o -c prog1.c
cc -o prog1 prog1.o
cc -o prog2.o -c prog2.c
cc -o prog2 prog2.o
|
SCons supports a DEFAULT_TARGETS variable
that lets you get at the current list of default targets.
The DEFAULT_TARGETS variable has
two important differences from the COMMAND_LINE_TARGETS variable.
First, the DEFAULT_TARGETS variable is a list of
internal SCons nodes,
so you need to convert the list elements to strings
if you want to print them or look for a specific target name.
Fortunately, you can do this easily
by using the Python map function
to run the list through str:
prog1 = Program('prog1.c')
Default(prog1)
print "DEFAULT_TARGETS is", map(str, DEFAULT_TARGETS)
|
(Keep in mind that all of the manipulation of the
DEFAULT_TARGETS list takes place during the
first phase when SCons is reading up the SConscript files,
which is obvious if
we leave off the -Q flag when we run SCons:)
% scons
scons: Reading SConscript files ...
DEFAULT_TARGETS is ['prog1']
scons: done reading SConscript files.
scons: Building targets ...
cc -o prog1.o -c prog1.c
cc -o prog1 prog1.o
scons: done building targets.
|
Second,
the contents of the DEFAULT_TARGETS list change
in response to calls to the Default: function,
as you can see from the following SConstruct file:
prog1 = Program('prog1.c')
Default(prog1)
print "DEFAULT_TARGETS is now", map(str, DEFAULT_TARGETS)
prog2 = Program('prog2.c')
Default(prog2)
print "DEFAULT_TARGETS is now", map(str, DEFAULT_TARGETS)
|
Which yields the output:
% scons
scons: Reading SConscript files ...
DEFAULT_TARGETS is now ['prog1']
DEFAULT_TARGETS is now ['prog1', 'prog2']
scons: done reading SConscript files.
scons: Building targets ...
cc -o prog1.o -c prog1.c
cc -o prog1 prog1.o
cc -o prog2.o -c prog2.c
cc -o prog2 prog2.o
scons: done building targets.
|
In practice, this simply means that you
need to pay attention to the order in
which you call the Default function
and refer to the DEFAULT_TARGETS list,
to make sure that you don't examine the
list before you've added the default targets
you expect to find in it.