Add 'dirs' and 'names' keyword arguments to SConscript for easier specification of...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Mon, 29 Apr 2002 15:23:00 +0000 (15:23 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Mon, 29 Apr 2002 15:23:00 +0000 (15:23 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@351 fdb21ef1-2011-0410-befe-b5e4ea1792b1

src/CHANGES.txt
src/engine/SCons/Script/SConscript.py
test/SConscript.py

index f162a59b7dd7669b3e2ffdd64fa5630f72fb41f5..3cd3402ad6767672b5fb9f855fb1a3ed2e1df11e 100644 (file)
@@ -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.
index f30652d8dfa3f0d3a6dd30605a496776279d4276..a6f293d333e228f4eabf35abd91927595381b05d 100644 (file)
@@ -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:
index 0062be63cacbd305a3156ff0baedf2488482646c..22f7144e912643f4293c82bea7209e10390041cb 100644 (file)
@@ -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))