Commits

Anonymous committed 38d2eb8

Change the default behavior when no arguments are specified to building everything in (or below) the current directory.

  • Participants
  • Parent commits 2a637ae

Comments (0)

Files changed (8)

 .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 C:\ D:\
+.EE
+
+To build only specific targets,
+supply them as command-line arguments:
 
 .ES
 scons foo bar
 .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:
-
-.ES
-scons
-.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 
 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

src/engine/SCons/Script/SConscript.py

 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,

src/engine/SCons/Script/__init__.py

 
     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', """

test/no-arguments.py

 
 __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'))