.B scons
is normally executed in a top-level directory containing a
.I SConstruct
-file, specifying the target or targets to be built as
-command-line arguments. The command
+file, optionally specifying
+as command-line arguments
+the target file or files to be built.
+
+By default, the command
+
+.ES
+scons
+.EE
+
+will build all target files in or below the current directory.
+Explicit default targets
+(to be built when no targets are specified on the command line)
+may be defined the SConscript file(s)
+using the
+.B Default()
+function, described below.
+
+Even when
+.B Default()
+targets are specified in the SConscript file(s),
+all target files in or below the current directory
+may be built by explicitly specifying
+the current directory (.)
+as a command-line target:
.ES
scons .
.EE
-will build all target files in or below the current directory
-.RI ( . ")."
+Building all target files,
+including any files outside of the current directory,
+may be specified by supplying a command-line target
+of the root directory (on POSIX systems):
.ES
scons /
.EE
-will build all target files in or below the root directory (i.e.,
-all files). Specific targets may be supplied:
+or the path name(s) of the volume(s) in which all the targets
+should be built (on Windows systems):
.ES
-scons foo bar
+scons C:\ D:\
.EE
-Targets may be omitted from the command line,
-in which case the targets specified
-in the SConscript file(s) as
-.B Default
-targets will be built:
+To build only specific targets,
+supply them as command-line arguments:
.ES
-scons
+scons foo bar
.EE
+in which case only the specified targets will be built
+(along with any derived files on which they depend).
+
Specifying "cleanup" targets in SConscript files is not
necessary. The
.B -c
Multiple targets should be specified as
separate arguments to the
.BR Default ()
-method or as a list.
+method, or as a list.
.BR Default ()
-will also accept the return value of any of the construction environment
+will also accept the Node returned by any
+of a construction environment's
builder methods.
Examples:
.ES
Default('foo', 'bar', 'baz')
Default(['a', 'b', 'c'])
-Default(env.Program('hello', 'hello.c'))
+hello = env.Program('hello', 'hello.c')
+Default(hello)
.EE
+An argument to
+.BR Default ()
+of
+.B None
+will clear all default targets.
+Later calls to
+.BR Default ()
+will add to the (now empty) default-target list
+like normal.
+
.TP
.RI Dir( name ", [" directory ])
This returns an object that represents a given directory
between builds, with related options --cache-disable, --cache-force,
and --cache-show.
+ - Change the default behavior when no targets are specified to build
+ everything in the current directory and below (like Make). This
+ can be disabled by specifying Default(None) in an SConscript.
+
From Steve Leblanc:
- Fix the output of -c -n when directories are involved, so it
If you have defined a strfunction() for a Python function Action,
you will need to add a third "env" argument to your function call.
+ - The default behavior when no targets are specified has been changed
+ to be like Make: everything in the current directory and below will
+ be built. This can be disabled by specifying "Default(None)" in an
+ SConscript, in which case there will be no default targets and
+ SCons will print an appropriate error message.
+
Please note the following important changes since release 0.09:
- The Scanner interface has been changed to make it easier to
def do_nothing(text): pass
HelpFunction = do_nothing
-default_targets = []
+default_targets = None
clean_targets = {}
arguments = {}
launch_dir = os.path.abspath(os.curdir)
return tuple(results)
def Default(*targets):
+ global default_targets
+ if default_targets is None:
+ default_targets = []
for t in targets:
- if isinstance(t, SCons.Node.Node):
+ if t is None:
+ default_targets = []
+ elif isinstance(t, SCons.Node.Node):
default_targets.append(t)
else:
default_targets.extend(SCons.Node.arg2nodes(t,
if not targets:
targets = SCons.Script.SConscript.default_targets
+ if targets is None:
+ targets = [SCons.Node.FS.default_fs.Dir('.')]
if not targets:
sys.stderr.write("scons: *** No targets specified and no Default() targets found. Stop.\n")
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+"""
+Verify various combinations of arguments to Default() work properly.
+"""
+
import os
import sys
import TestSCons
test = TestSCons.TestSCons()
-test.subdir('one', 'two', 'three', 'four', 'five')
+for dir in ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']:
+
+ test.subdir(dir)
+
+ test.write(os.path.join(dir, 'foo.in'), dir + "/foo.in\n");
+
+ test.write(os.path.join(dir, 'bar.in'), dir + "/bar.in\n");
test.write('build.py', r"""
import sys
file.close()
""")
+#
test.write(['one', 'SConstruct'], """
B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
for dir in ['one', 'two', 'three', 'four', 'five']:
- foo_in = os.path.join(dir, 'foo.in')
- bar_in = os.path.join(dir, 'bar.in')
-
- test.write(foo_in, dir + "/foo.in\n");
-
- test.write(bar_in, dir + "/bar.in\n");
-
test.run(chdir = dir) # no arguments, use the Default
test.fail_test(test.read(test.workpath('one', 'foo.out')) != "one/foo.in\n")
+# Test how a None Default() argument works to disable/reset default targets.
+test.write(['six', 'SConstruct'], """\
+B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+env = Environment(BUILDERS = { 'B' : B })
+foo = env.B(target = 'foo.out', source = 'foo.in')
+bar = env.B(target = 'bar.out', source = 'bar.in')
+Default(None)
+""" % python)
+
+test.run(chdir = 'six', status = 2, stderr =
+"scons: *** No targets specified and no Default() targets found. Stop.\n")
+
+test.write(['seven', 'SConstruct'], """\
+B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+env = Environment(BUILDERS = { 'B' : B })
+foo = env.B(target = 'foo.out', source = 'foo.in')
+bar = env.B(target = 'bar.out', source = 'bar.in')
+Default(foo, bar, None)
+""" % python)
+
+test.run(chdir = 'seven', status = 2, stderr =
+"scons: *** No targets specified and no Default() targets found. Stop.\n")
+
+test.write(['eight', 'SConstruct'], """\
+B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+env = Environment(BUILDERS = { 'B' : B })
+foo = env.B(target = 'foo.out', source = 'foo.in')
+bar = env.B(target = 'bar.out', source = 'bar.in')
+Default(foo, None, bar)
+""" % python)
+
+test.run(chdir = 'eight') # no arguments, use the Default
+
+test.fail_test(os.path.exists(test.workpath('eight', 'foo.out')))
+test.fail_test(test.read(test.workpath('eight', 'bar.out')) != "eight/bar.in\n")
+
+
+
+
test.subdir('sub1')
test.write('SConstruct', """
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+"""
+Verify that we use a default target of the current directory when there
+are no command-line arguments (and, implicitly, no Default() in the
+SConstruct).
+"""
+
import os.path
import TestSCons
test.write('aaa.in', "aaa.in\n")
#
-test.run(arguments = '.')
+test.run()
test.fail_test(test.read('aaa.out') != "aaa.in\n")
-#
-test.run(status = 2, stderr =
-"scons: *** No targets specified and no Default() targets found. Stop.\n")
-
#
test.pass_test()
""")
test.write('SConstruct', """
-import SCons.Defaults
env = Environment()
env['BUILDERS']['B'] = Builder(action=r'%s build.py $TARGET $SOURCES')
env.B(target = 'sub1/foo.out', source = 'sub1/foo.in')
-Default('.')
Export('env')
SConscript('sub2/SConscript')
env.Alias('baz', env.B(target = 'sub3/baz.out', source = 'sub3/baz.in'))