.EE
.TP
-.RI SConscript( script ", [" exports ", " build_dir ", " src_dir ", " duplicate ])
+.RI SConscript( scripts ", [" exports ", " build_dir ", " src_dir ", " duplicate ])
+.TP
+.RI SConscript(dirs= subdirs ", [name=" script ", " exports ", " build_dir ", " src_dir ", " duplicate ])
This tells
.B scons
to execute
-.I script
-as a SConscript (configuration) file.
+one or more subsidiary SConscript (configuration) files.
+There are two ways to call the
+.BR SConscript ()
+function.
+
+The first way you can call
+.BR SConscript ()
+is to explicitly specify one or more
+.I scripts
+as the first argument.
+A single script may be specified as a string;
+multiple scripts must be specified as a list
+(either explicitly or as created by
+a function like
+.BR Split ()).
+
+The second way you can call
+.BR SConscript ()
+is to specify a list of (sub)directory names
+as a
+.RI dirs= subdirs
+keyword argument.
+In this case,
+.B scons
+will, by default,
+execute a subsidiary configuration file named
+.B SConscript
+in each of the specified directories.
+You may specify a name other than
+.B SConscript
+by supplying an optional
+.RI name= script
+keyword argument.
The optional
.I exports
argument provides a list of variable names or a dictionary of
-named values to export to
-.IR script ". "
+named values to export to the
+.IR script(s) ". "
These variables are locally exported only to the specified
-.IR script ,
+.IR script(s) ,
and do not affect the
global pool of variables used by
the
'\"If multiple dirs are provided,
'\"each script gets a fresh export.
The subsidiary
-.I script
-file must use the
+.I script(s)
+must use the
.BR Import ()
function to import the variables.
resides should actually
be built in
.IR build_dir .
+
The optional
.I src_dir
argument specifies that the
the target files should be built
can be found in
.IR src_dir .
+
By default,
.B scons
will link or copy (depending on the platform)
foo = SConscript('sub/SConscript', exports='env')
SConscript('dir/SConscript', exports=['env', 'variable'])
SConscript('src/SConscript', build_dir='build', duplicate=0)
-SConscript('bld/SConscript', src_dir='src', exports='env')
+SConscript('bld/SConscript', src_dir='src', exports='env variable')
+SConscript(dirs=['sub1', 'sub2'])
+SConscript(dirs=['sub3', 'sub4'], name='MySConscript')
.EE
.TP
- Refactor the creation of the Program, *Object and *Library Builders
so that they're moved out of SCons.Defaults and created on demand.
+ - Don't split SConscript file names on white space.
+
+ - Document the SConscript function's "dirs" and "name" keywords.
+
+ - Remove the internal (and superfluous) SCons.Util.argmunge() function.
+
From Gary Oberbrunner:
- Report the target being built in error messages when building
Release Notes
-This is an alpha release of SCons, a tool for building software (and
+This is an beta release of SCons, a tool for building software (and
other files). SCons is implemented in Python, and its "configuration
files" are actually Python scripts, allowing you to use the full power
of a real scripting language to solve build problems. You do not,
spelling still works but has been deprecated and generates a
warning.
+ - The SConscript() function no longer splits its first argument on
+ white space into a list of SConscript file names. You must now
+ explicitly enclose the file names in a list:
+
+ SConscript(['sub1/SConscript', 'sub2/SConscript'])
+
+ Or use the Split() function (or something similar) to create a list:
+
+ SConscript(Split('sub1/SConscript sub2/SConscript'))
+
+ This makes the SConscript() function's handling of file names
+ consistent with the rest of SCons.
+
Please note the following important changes since release 0.14:
- SCons now tries to verify that Microsoft Visual Studio (including
- Visual C++) is actually installed before using it, by checking that
- the program directory exists. If SCons cannot find your copy of
- Visual Studio, it is probably because it installed itself itself in
- a default directory that we have not seen before. If this is the
+ Visual C++) is actually installed before using it, by checking
+ that the program directory exists. If SCons cannot find your copy
+ of Visual Studio, it is probably because it installed itself in a
+ default directory that we have not seen before. If this is the
case, please let us know so that we can update future versions.
SCons is developed with an extensive regression test suite, and a
rigorous development methodology for continually improving that suite.
Because of this, SCons is of sufficient quality that you can use it
- for real work. The "alpha" status of the release reflects that we
+ for real work. The "beta" status of the release reflects that we
still may change interfaces in future releases, which may require
modifications to your SConscript files. We strive to hold these
changes to a minimum.
an infinite loop.
- When using SourceSignatures('timestamp'), changes to Python
- Value() do not cause rebuilds.
+ Value() Nodes do not cause rebuilds.
- No support yet for the following planned command-line options:
-d -e -l --list-actions --list-derived --list-where
- -o --override -p -r -R --random -w --write-filenames
+ -o --override -p -r -R -w --write-filenames
-W --warn-undefined-variables
Chad Austin
Charles Crain
Steve Leblanc
+ Gary Oberbrunner
Anthony Roach
Greg Spencer
Christoph Wiedemann
def compute_exports(exports):
"""Compute a dictionary of exports given one of the parameters
to the Export() function or the exports argument to SConscript()."""
- exports = SCons.Util.argmunge(exports)
+
+ exports = SCons.Util.Split(exports)
loc, glob = get_calling_namespaces()
retval = {}
# exports.
def GetSConscriptFilenames(ls, kw):
- files = []
exports = []
if len(ls) == 0:
try:
- dirs = map(str, SCons.Util.argmunge(kw["dirs"]))
+ dirs = kw["dirs"]
except KeyError:
raise SCons.Errors.UserError, \
"Invalid SConscript usage - no parameters"
- name = kw.get('name', 'SConscript')
+ if not SCons.Util.is_List(dirs):
+ dirs = [ dirs ]
+ dirs = map(str, dirs)
- if kw.get('exports'):
- exports = SCons.Util.argmunge(kw['exports'])
+ name = kw.get('name', 'SConscript')
files = map(lambda n, name = name: os.path.join(n, name), dirs)
elif len(ls) == 1:
- files = SCons.Util.argmunge(ls[0])
- if kw.get('exports'):
- exports = SCons.Util.argmunge(kw['exports'])
+ files = ls[0]
elif len(ls) == 2:
- files = SCons.Util.argmunge(ls[0])
- exports = SCons.Util.argmunge(ls[1])
-
- if kw.get('exports'):
- exports.extend(SCons.Util.argmunge(kw['exports']))
+ files = ls[0]
+ exports = SCons.Util.Split(ls[1])
else:
+
raise SCons.Errors.UserError, \
"Invalid SConscript() usage - too many arguments"
+ if not SCons.Util.is_List(files):
+ files = [ files ]
+
+ if kw.get('exports'):
+ exports.extend(SCons.Util.Split(kw['exports']))
+
build_dir = kw.get('build_dir')
if build_dir:
if len(files) != 1:
def Import(*vars):
try:
for var in vars:
- var = SCons.Util.argmunge(var)
+ var = SCons.Util.Split(var)
for v in var:
if v == '*':
stack[-1].globals.update(global_exports)
def is_List(e):
return type(e) is types.ListType or isinstance(e, UserList.UserList)
-def argmunge(arg):
- return Split(arg)
-
def Split(arg):
"""This function converts a string or list into a list of strings
or Nodes. This makes things easier for users by allowing files to
test = TestSCons.TestSCons()
-test.write('foo.py', """
-foo = 4""")
+test.write('foo.py', "foo = 4\n")
-test.write('SConstruct', """
+
+test.write('SConstruct', """\
import os
import foo
assert x3 == "SConscript1 x3"
assert x4 == "SConscript1 x4"
-
(x3,x4) = SConscript('SConscript2', ["x1","x2"])
assert x3 == "SConscript2 x3"
assert x4 == "SConscript2 x4"
SConscript('SConscript7')
""")
-test.write('SConscript', """
+test.write('SConscript', """\
# os should not be automajically imported:
assert not globals().has_key("os")
""")
-test.write('SConscript2', """
+test.write('SConscript2', """\
Import("x1","x2")
assert x1 == "SConstruct x1"
assert x2 == "SConstruct x2"
Return("x3","x4")
""")
-test.write('SConscript3', """
+
+test.write('SConscript3', """\
Import("x1 x2")
assert x1 == "SConstruct x1"
assert x2 == "SConstruct x2"
assert x6 == "SConscript31 x6"
Export("x1 x2")
-
-
""")
-test.write('SConscript31', """
+
+test.write('SConscript31', """\
Import("x1 x2")
assert x1 == "SConscript3 x1"
assert x2 == "SConstruct x2"
""")
-test.write('SConscript4', """
+test.write('SConscript4', """\
Import("x1", "x2")
assert x1 == "SConstruct x1"
assert x2 == "SConstruct x2"
Export("x1", "x2")
""")
+
test.subdir('subdir')
-test.write(['subdir', 'SConscript'], """
+test.write(['subdir', 'SConscript'], """\
foo = 'subdir/SConscript foo'
Return('foo')
""")
-test.write('SConscript5', """
+test.write('SConscript5', """\
B = Builder(action = 'B')
def scan():
pass
""")
-test.write('SConscript6', """
+test.write('SConscript6', """\
Import("x7 x8")
assert x7 == "SConstruct x7"
assert x8 == "SConstruct x8"
Return("x9")
""")
-test.write('SConscript7', """
+
+test.write('SConscript7', """\
result1 = ((1, 3), -4)
result2 = ((2, 3), -4)
-assert result1 == SConscript('foo/SConscript bar/SConscript')
+assert result1 == SConscript(Split('foo/SConscript bar/SConscript'))
assert result1 == SConscript(['foo/SConscript', 'bar/SConscript'])
assert result1 == SConscript([File('foo/SConscript'), File('bar/SConscript')])
-assert result1 == SConscript(dirs = 'foo bar')
+assert result1 == SConscript(dirs = Split('foo bar'))
assert result1 == SConscript(dirs = ['foo', 'bar'])
-assert result2 == SConscript(dirs = 'foo bar', name = 'subscript')
+assert result2 == SConscript(dirs = Split('foo bar'), name = 'subscript')
assert result2 == SConscript(dirs = ['foo', 'bar'], name = 'subscript')
assert result1 == SConscript(dirs = ['foo', Dir('bar')])
assert result2 == SConscript(dirs = [Dir('foo'), 'bar'], name = 'subscript')
+assert 5 == SConscript('w s/SConscript')
+assert (-4, 5) == SConscript(['bar/SConscript', 'w s/SConscript'])
x1 = 3
x2 = 2
assert (3, 2) == SConscript('baz/SConscript', exports = 'x1 x2')
""")
-fooscript = "x = %d; y = 3; Return('x y')"
-barscript = "x = -4; Return('x')"
+fooscript = "x = %d; y = 3; Return('x y')\n"
+barscript = "x = -4; Return('x')\n"
-test.subdir('foo', 'bar', 'baz')
+test.subdir('foo', 'bar', 'baz', 'w s')
test.write(['foo', 'SConscript'], fooscript % 1)
test.write(['foo', 'subscript'], fooscript % 2)
test.write(['bar', 'SConscript'], barscript)
test.write(['bar', 'subscript'], barscript)
-test.write(['baz', 'SConscript'], """
+test.write(['baz', 'SConscript'], """\
Import("x1 x2")
result = (x1, x2)
Return("result")
""")
+test.write(['w s', 'SConscript'], "x = 5; Return('x')\n")
wpath = test.workpath()
test.run(arguments = ".")
+# Test white space
+test.subdir('white space')
+test.write("SConstruct", """\
+SConscript('white space/SConscript')
+""")
+
+test.write(['white space', 'SConscript'], """\
+print "`white space/SConscript'"
+""")
+
+test.run(arguments = ".",
+ stdout = test.wrap_stdout(read_str = "`white space/SConscript'\n",
+ build_str = "scons: `.' is up to date.\n"))
+
test.pass_test()