summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2002-04-29 15:23:00 (GMT)
committerSteven Knight <knight@baldmt.com>2002-04-29 15:23:00 (GMT)
commitd8a61ce7bec032b17a03dbcb1f5cdaaa1e40e2f6 (patch)
tree32f207309f7cd8db461bff6966333587aaae3126
parenta2d5a170cc1f83e0b4d738e23e4a9952e17be24f (diff)
downloadSCons-d8a61ce7bec032b17a03dbcb1f5cdaaa1e40e2f6.zip
SCons-d8a61ce7bec032b17a03dbcb1f5cdaaa1e40e2f6.tar.gz
SCons-d8a61ce7bec032b17a03dbcb1f5cdaaa1e40e2f6.tar.bz2
Add 'dirs' and 'names' keyword arguments to SConscript for easier specification of subsidiary SConscript files. (Chad Austin)
-rw-r--r--src/CHANGES.txt3
-rw-r--r--src/engine/SCons/Script/SConscript.py123
-rw-r--r--test/SConscript.py37
3 files changed, 127 insertions, 36 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index f162a59..3cd3402 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -17,6 +17,9 @@ RELEASE 0.07 - Thu, 25 Apr 2002 06:24:50 -0500
- Don't create a directory Node when a file already exists there,
and vice versa.
+ - Add 'dirs' and 'names' keyword arguments to SConscript for
+ easier specification of subsidiary SConscript files.
+
From Charles Crain:
- Internal cleanup of environment passing to function Actions.
diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py
index f30652d..a6f293d 100644
--- a/src/engine/SCons/Script/SConscript.py
+++ b/src/engine/SCons/Script/SConscript.py
@@ -101,44 +101,95 @@ def Return(*vars):
else:
stack[-1].retval = tuple(retval)
-def SConscript(script, exports=[]):
- retval = ()
+# This function is responsible for converting the parameters passed to
+# SConscript() calls into a list of files and export variables. If
+# the parameters are invalid, throws SCons.Errors.UserError. Returns a
+# tuple (l, e) where l is a list of filenames and e is a list of
+# exports.
- # push:
- stack.append(Frame(exports))
- old_dir = None
- old_sys_path = sys.path
- try:
- # call:
- if script == "-":
- exec sys.stdin in stack[-1].globals
- else:
- if not isinstance(script, SCons.Node.Node):
- script = SCons.Node.FS.default_fs.File(script)
- if script.exists():
- file = open(str(script), "r")
- SCons.Node.FS.default_fs.chdir(script.dir)
- if sconscript_chdir:
- old_dir = os.getcwd()
- os.chdir(str(script.dir))
-
- # prepend the SConscript directory to sys.path so
- # that Python modules in the SConscript directory can
- # be easily imported.
- sys.path = [os.path.abspath(str(script.dir))] + sys.path
-
- exec file in stack[-1].globals
+def GetSConscriptFilenames(ls, kw):
+ files = []
+ exports = []
+
+ if len(ls) == 0:
+ try:
+ dirs = map(str, SCons.Util.argmunge(kw["dirs"]))
+ except KeyError:
+ raise SCons.Errors.UserError, \
+ "Invalid SConscript usage - no parameters"
+
+ name = kw.get('name', 'SConscript')
+
+ if kw.get('exports'):
+ exports = SCons.Util.argmunge(kw['exports'])
+
+ 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'])
+
+ 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.get('exports')))
+
+ else:
+ raise SCons.Errors.UserError, \
+ "Invalid SConscript() usage - too many arguments"
+
+ return (files, exports)
+
+def SConscript(*ls, **kw):
+ files, exports = GetSConscriptFilenames(ls, kw)
+
+ # evaluate each SConscript file
+ results = []
+ for fn in files:
+ stack.append(Frame(exports))
+ old_dir = None
+ old_sys_path = sys.path
+ try:
+ if fn == "-":
+ exec sys.stdin in stack[-1].globals
else:
- sys.stderr.write("Ignoring missing SConscript '%s'\n" % script.path)
- finally:
- # pop:
- sys.path = old_sys_path
- frame = stack.pop()
- SCons.Node.FS.default_fs.chdir(frame.prev_dir)
- if old_dir:
- os.chdir(old_dir)
-
- return frame.retval
+ f = SCons.Node.FS.default_fs.File(str(fn))
+ if f.exists():
+ file = open(str(f), "r")
+ SCons.Node.FS.default_fs.chdir(f.dir)
+ if sconscript_chdir:
+ old_dir = os.getcwd()
+ os.chdir(str(f.dir))
+
+ # prepend the SConscript directory to sys.path so
+ # that Python modules in the SConscript directory can
+ # be easily imported
+ sys.path = [os.path.abspath(str(f.dir))] + sys.path
+
+ exec file in stack[-1].globals
+ else:
+ sys.stderr.write("Ignoring missing SConscript '%s'\n" %
+ f.path)
+
+ finally:
+ sys.path = old_sys_path
+ frame = stack.pop()
+ SCons.Node.FS.default_fs.chdir(frame.prev_dir)
+ if old_dir:
+ os.chdir(old_dir)
+
+ results.append(frame.retval)
+
+ # if we only have one script, don't return a tuple
+ if len(results) == 1:
+ return results[0]
+ else:
+ return tuple(results)
def Default(*targets):
for t in targets:
diff --git a/test/SConscript.py b/test/SConscript.py
index 0062be6..22f7144 100644
--- a/test/SConscript.py
+++ b/test/SConscript.py
@@ -77,6 +77,8 @@ x7 = "SConstruct x7"
x8 = "SConstruct x8"
x9 = SConscript('SConscript6', UserList.UserList(["x7", "x8"]))
assert x9 == "SConscript6 x9"
+
+SConscript('SConscript7')
""")
test.write('SConscript', """
@@ -169,6 +171,41 @@ x9 = "SConscript6 x9"
Return("x9")
""")
+test.write('SConscript7', """
+result1 = ((1, 3), -4)
+result2 = ((2, 3), -4)
+assert result1 == SConscript('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 = ['foo', 'bar'])
+assert result2 == SConscript(dirs = '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')
+
+x1 = 3
+x2 = 2
+assert (3, 2) == SConscript(dirs = 'baz', exports = "x1 x2")
+assert (3, 2) == SConscript('baz/SConscript', 'x1', exports = 'x2')
+assert (3, 2) == SConscript('baz/SConscript', exports = 'x1 x2')
+""")
+
+fooscript = "x = %d; y = 3; Return('x y')"
+barscript = "x = -4; Return('x')"
+
+test.subdir('foo', 'bar', 'baz')
+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'], """
+Import("x1 x2")
+result = (x1, x2)
+Return("result")
+""")
+
+
wpath = test.workpath()
test.run(stdout = "SConstruct %s\nSConscript %s\n" % (wpath, wpath))