From 1321ef0af677827deb274d698d06ffa8b73010b0 Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Wed, 5 Feb 2003 22:06:52 +0000 Subject: Change the default behavior when no arguments are specified to building everything in (or below) the current directory. --- doc/man/scons.1 | 69 +++++++++++++++++++++++++++-------- src/CHANGES.txt | 4 ++ src/RELEASE.txt | 6 +++ src/engine/SCons/Script/SConscript.py | 9 ++++- src/engine/SCons/Script/__init__.py | 2 + test/Default.py | 59 ++++++++++++++++++++++++++---- test/no-arguments.py | 12 +++--- test/option-u.py | 2 - 8 files changed, 130 insertions(+), 33 deletions(-) diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 7eac0e8..1e9086f 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -135,37 +135,62 @@ ability to define new scanners for unknown input file types. .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 @@ -2511,18 +2536,30 @@ and add to the list of default targets. 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 diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 0dea107..237aa60 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -60,6 +60,10 @@ RELEASE 0.11 - XXX 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 diff --git a/src/RELEASE.txt b/src/RELEASE.txt index ccb301c..f6fef16 100644 --- a/src/RELEASE.txt +++ b/src/RELEASE.txt @@ -72,6 +72,12 @@ RELEASE 0.10 - Thu, 16 Jan 2003 04:11:46 -0600 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 diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index 7cfb312..5c4a2b3 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -51,7 +51,7 @@ import sys def do_nothing(text): pass HelpFunction = do_nothing -default_targets = [] +default_targets = None clean_targets = {} arguments = {} launch_dir = os.path.abspath(os.curdir) @@ -204,8 +204,13 @@ def SConscript(*ls, **kw): 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, diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 8bc3da4..eed045d 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -811,6 +811,8 @@ def _main(): 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") diff --git a/test/Default.py b/test/Default.py index 1c7a638..d2c438f 100644 --- a/test/Default.py +++ b/test/Default.py @@ -24,6 +24,10 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +""" +Verify various combinations of arguments to Default() work properly. +""" + import os import sys import TestSCons @@ -32,7 +36,13 @@ python = TestSCons.python 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 @@ -42,6 +52,7 @@ file.write(contents) file.close() """) +# test.write(['one', 'SConstruct'], """ B = Builder(action = r'%s ../build.py $TARGET $SOURCES') env = Environment(BUILDERS = { 'B' : B }) @@ -85,13 +96,6 @@ Default(env.B(target = 'bar.out', source = 'bar.in')) 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") @@ -112,6 +116,45 @@ test.fail_test(test.read(test.workpath('five', 'bar.out')) != "five/bar.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', """ diff --git a/test/no-arguments.py b/test/no-arguments.py index acd590a..602ef80 100644 --- a/test/no-arguments.py +++ b/test/no-arguments.py @@ -24,6 +24,12 @@ __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 @@ -47,13 +53,9 @@ env.Build('aaa.out', 'aaa.in') 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() diff --git a/test/option-u.py b/test/option-u.py index f90e258..1f7df7a 100644 --- a/test/option-u.py +++ b/test/option-u.py @@ -44,11 +44,9 @@ file.close() """) 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')) -- cgit v0.12