From d8a61ce7bec032b17a03dbcb1f5cdaaa1e40e2f6 Mon Sep 17 00:00:00 2001 From: Steven Knight Date: Mon, 29 Apr 2002 15:23:00 +0000 Subject: Add 'dirs' and 'names' keyword arguments to SConscript for easier specification of subsidiary SConscript files. (Chad Austin) --- src/CHANGES.txt | 3 + src/engine/SCons/Script/SConscript.py | 123 ++++++++++++++++++++++++---------- test/SConscript.py | 37 ++++++++++ 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)) -- cgit v0.12