More Environment method conversions:
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Mon, 13 Oct 2003 13:20:28 +0000 (13:20 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Mon, 13 Oct 2003 13:20:28 +0000 (13:20 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@819 fdb21ef1-2011-0410-befe-b5e4ea1792b1

12 files changed:
doc/man/scons.1
src/CHANGES.txt
src/engine/SCons/Action.py
src/engine/SCons/ActionTests.py
src/engine/SCons/Defaults.py
src/engine/SCons/Environment.py
src/engine/SCons/EnvironmentTests.py
src/engine/SCons/Script/SConscript.py
test/Alias.py
test/Configure.py
test/Scanner.py
test/Value.py

index 633f3175d897c49ce74b1077e8dbfe7d832bdeec..9b11f6bee3983c7882868519848366801c09e851 100644 (file)
@@ -1897,20 +1897,24 @@ can be converted into an Action object
 
 '\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 .TP
-.RI Alias( alias )
+.RI Alias( alias ", [" targets ])
 .TP
-.RI env.Alias( alias ", " targets )
-Creates a phony target that
-expands to one or more other targets.
+.RI env.Alias( alias ", [" targets ])
+Creates one or more phony targets that
+expand to one or more other targets.
 Returns the Node object representing the alias,
 which exists outside of any file system.
 This Node object, or the alias name,
 may be used as a dependency of any other target,
-including another alias. Alias can be called multiple times for the same
+including another alias.
+.B Alias
+can be called multiple times for the same
 alias to add additional targets to the alias.
 
 .ES
 Alias('install')
+Alias('install', '/usr/bin')
+Alias(['install', 'install-lib'], '/usr/local/lib')
 
 env.Alias('install', ['/usr/local/bin', '/usr/local/lib'])
 env.Alias('install', ['/usr/local/man'])
@@ -2256,6 +2260,16 @@ env.Command('baz.out', 'baz.in',
             rename ])
 .EE
 
+'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.TP
+.RI Configure( env ", [" custom_tests ", " conf_dir ", " log_file ])
+.TP
+.RI env.Configure([ custom_tests ", " conf_dir ", " log_file ])
+Creates a Configure object for integrated
+functionality similar to GNU autoconf.
+See the section "Configure Contexts,"
+below, for a complete explanation of the arguments and behavior.
+
 '\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 .TP
 .RI env.Copy([ key = val ", ...])"
@@ -2590,6 +2604,25 @@ options from a SConscript file. See
 .IR SetOption () 
 for a description of the options available.
 
+'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+'\".TP
+'\".RI GlobalBuilders( flag )
+'\"When
+'\".B flag
+'\"is non-zero,
+'\"adds the names of the default builders
+'\"(Program, Library, etc.)
+'\"to the global name space
+'\"so they can be called without an explicit construction environment.
+'\"(This is the default.)
+'\"When
+'\".B
+'\"flag is zero,
+'\"the names of the default builders are removed
+'\"from the global name space
+'\"so that an explicit construction environment is required
+'\"to call all builders.
+
 '\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 .TP
 .RI Help( text )
@@ -2963,6 +2996,17 @@ Return("foo")
 Return(["foo", "bar"])
 .EE
 
+'\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+.TP 
+.RI Scanner( function ", [" argument ", " keys ", " path_function ", " node_class ", " node_factory ", " scan_check ", " recursive ])
+.TP 
+.RI env.Scanner( function ", [" argument ", " keys ", " path_function ", " node_class ", " node_factory ", " scan_check ", " recursive ])
+Creates a Scanner object for
+the specified
+.IR function .
+See the section "Scanner Objects,"
+below, for a complete explanation of the arguments and behavior.
+
 '\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 .TP
 env.SCCS()
@@ -3122,16 +3166,19 @@ SConscript(dirs=['sub3', 'sub4'], name='MySConscript')
 '\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 .TP
 .RI SConscriptChdir( value )
+.TP
+.RI env.SConscriptChdir( value )
 By default,
 .B scons
 changes its working directory
 to the directory in which each
 subsidiary SConscript file lives.
 This behavior may be disabled
-by specifying:
+by specifying either:
 
 .ES
 SConscriptChdir(0)
+env.SConscriptChdir(0)
 .EE
 .IP
 in which case
@@ -3148,9 +3195,10 @@ SConscriptChdir()
 multiple times:
 
 .ES
+env = Environment()
 SConscriptChdir(0)
 SConscript('foo/SConscript')   # will not chdir to foo
-SConscriptChdir(1)
+env.SConscriptChdir(1)
 SConscript('bar/SConscript')   # will chdir to bar
 .EE
 
@@ -3468,6 +3516,8 @@ env.Tool('gcc')
 '\"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 .TP
 .RI Value( value )
+.TP
+.RI env.Value( value )
 Returns a Node object representing the specified Python value.  Value
 nodes can be used as dependencies of targets.  If the result of
 calling
@@ -4993,7 +5043,7 @@ method:
 env2 = env.Copy(CC="cl.exe")
 .EE
 
-.SS Configure contexts
+.SS Configure Contexts
 
 .B scons
 supports
@@ -5011,6 +5061,8 @@ The following methods can be used to perform checks:
 
 .TP
 .RI Configure( env ", [" custom_tests ", " conf_dir ", " log_file ])
+.TP
+.RI env.Configure([ custom_tests ", " conf_dir ", " log_file ])
 This creates a configure context, which can be used to perform checks.
 .I env
 specifies the environment for building the tests.
index 17069034c2d88b245886d3a716e5fd9d7265adf2..1ab7499c6c4fb66c298c19cc7a3c6d91fbc7b6c5 100644 (file)
@@ -80,13 +80,14 @@ RELEASE X.XX - XXX
   - Support arbitrary expansion of construction variables within
     file and directory arguments to Builder calls and Environment methods.
 
-  - Add Environment-method versions of the following global
-    functions: Action(), AddPostAction(), AddPreAction(), Builder(),
-    BuildDir(), CacheDir(), Clean(), Default(), EnsurePythonVersion(),
-    EnsureSConsVersion(), Environment(), Exit(), Export(), FindFile(),
-    GetBuildPath(), GetOption(), Help(), Import(), Literal(),
-    Local(), Platform(), Repository(), SConsignFile(), SetOption(),
-    SourceSignatures(), Split(), TargetSignatures(), Tool().
+  - Add Environment-method versions of the following global functions:
+    Action(), AddPostAction(), AddPreAction(), Alias(), Builder(),
+    BuildDir(), CacheDir(), Clean(), Configure(), Default(),
+    EnsurePythonVersion(), EnsureSConsVersion(), Environment(),
+    Exit(), Export(), FindFile(), GetBuildPath(), GetOption(), Help(),
+    Import(), Literal(), Local(), Platform(), Repository(), Scanner(),
+    SConscriptChdir(), SConsignFile(), SetOption(), SourceSignatures(),
+    Split(), TargetSignatures(), Tool(), Value().
 
   - Add the following global functions that correspond to the same-named
     Environment methods:  AlwaysBuild(), Command(), Depends(), Ignore(),
@@ -115,6 +116,8 @@ RELEASE X.XX - XXX
   - Allow the Environment.WhereIs() method to take explicit path and
     pathext arguments (like the underlying SCons.Util.WhereIs() function).
 
+  - Remove the long-obsolete {Get,Set}CommandHandler() functions.
+
   From Clark McGrew:
 
   - Generalize the action for .tex files so that it will decide whether
index c9186a443d83fd26b86ddb50267d1cfe065b9697..633bb064eefab23707a3e1979645c0b2ffbbda14 100644 (file)
@@ -53,12 +53,6 @@ def rfile(n):
     except AttributeError:
         return n
 
-def SetCommandHandler(func, escape = lambda x: x):
-    raise SCons.Errors.UserError("SetCommandHandler() is no longer supported, use the SPAWN and ESCAPE construction variables.")
-
-def GetCommandHandler():
-    raise SCons.Errors.UserError("GetCommandHandler() is no longer supported, use the SPAWN construction variable.")
-
 def _actionAppend(act1, act2):
     # This function knows how to slap two actions together.
     # Mainly, it handles ListActions by concatenating into
index be1435763acd722009c7203df4f6ad87148692b1..53aa00aef6922040b85f098ae988f7b66dff58bc 100644 (file)
@@ -616,13 +616,6 @@ class CommandActionTestCase(unittest.TestCase):
             def is_literal(self):
                 return 1
 
-        try:
-            SCons.Action.SetCommandHandler(func)
-        except SCons.Errors.UserError:
-            pass
-        else:
-            assert 0, "should have gotten user error"
-            
         a = SCons.Action.CommandAction(["xyzzy"])
         a([], [], Environment(SPAWN = func))
         assert t.executed == [ 'xyzzy' ]
index 798abb377553462f77b6fcca658c3abf841f2072..aaa1abaab14afa1ef46092bf6407d82c039307a9 100644 (file)
@@ -46,8 +46,6 @@ import types
 import SCons.Action
 import SCons.Builder
 import SCons.Environment
-import SCons.Node.Alias
-import SCons.Node.FS
 import SCons.Scanner.C
 import SCons.Scanner.Fortran
 import SCons.Scanner.Prog
@@ -69,15 +67,6 @@ def DefaultEnvironment(*args, **kw):
         _default_env._calc_module = SCons.Sig.default_module
     return _default_env
 
-
-def alias_builder(env, target, source):
-    pass
-
-Alias = SCons.Builder.Builder(action = alias_builder,
-                              target_factory = SCons.Node.Alias.default_ans.Alias,
-                              source_factory = SCons.Node.FS.default_fs.Entry,
-                              multi = 1)
-
 CScan = SCons.Scanner.C.CScan()
 
 FortranScan = SCons.Scanner.Fortran.FortranScan()
@@ -264,7 +253,7 @@ class NullCmdGenerator:
         return self.cmd
 
 ConstructionEnvironment = {
-    'BUILDERS'   : { 'Alias' : Alias },
+    'BUILDERS'   : {},
     'SCANNERS'   : [CScan, FortranScan],
     'PDFPREFIX'  : '',
     'PDFSUFFIX'  : '.pdf',
index 36be2e4d013336c0bb8429d5c2d1077f622d3856..f8ff6c35f49b1a2a7c4be978e27a356f31796bbe 100644 (file)
@@ -48,7 +48,9 @@ import SCons.Builder
 import SCons.Defaults
 import SCons.Errors
 import SCons.Node
+import SCons.Node.Alias
 import SCons.Node.FS
+import SCons.Node.Python
 import SCons.Platform
 import SCons.Sig
 import SCons.Sig.MD5
@@ -87,6 +89,14 @@ installAction = SCons.Action.Action(installFunc, installString)
 
 InstallBuilder = SCons.Builder.Builder(action=installAction)
 
+def alias_builder(env, target, source):
+    pass
+
+AliasBuilder = SCons.Builder.Builder(action = alias_builder,
+                                     target_factory = SCons.Node.Alias.default_ans.Alias,
+                                     source_factory = SCons.Node.FS.default_fs.Entry,
+                                     multi = 1)
+
 def our_deepcopy(x):
    """deepcopy lists and dictionaries, and just copy the reference
    for everything else."""
@@ -201,6 +211,7 @@ class Base:
                  options=None,
                  **kw):
         self.fs = SCons.Node.FS.default_fs
+        self.ans = SCons.Node.Alias.default_ans
         self.lookup_list = SCons.Node.arg2nodes_lookups
         self._dict = our_deepcopy(SCons.Defaults.ConstructionEnvironment)
 
@@ -374,6 +385,7 @@ class Base:
             mode = SCons.Util.SUBST_CMD
         nkw = {}
         for k, v in kw.items():
+            k = SCons.Util.scons_subst(k, self, mode, target, source)
             if SCons.Util.is_String(v):
                 v = SCons.Util.scons_subst(v, self, mode, target, source)
             nkw[k] = v
@@ -705,6 +717,32 @@ class Base:
             n.add_post_action(action)
         return nodes
 
+    def Alias(self, target, *source, **kw):
+        if not SCons.Util.is_List(target):
+            target = [target]
+        tlist = []
+        for t in target:
+            if not isinstance(t, SCons.Node.Alias.Alias):
+                t = self.arg2nodes(self.subst(t), self.ans.Alias)[0]
+            tlist.append(t)
+        try:
+            s = kw['source']
+        except KeyError:
+            try:
+                s = source[0]
+            except IndexError:
+                s = None
+        if s:
+            if not SCons.Util.is_List(s):
+                s = [s]
+            s = filter(None, s)
+            s = self.arg2nodes(s, self.fs.Entry)
+            for t in tlist:
+                AliasBuilder(self, t, s)
+        if len(tlist) == 1:
+            tlist = tlist[0]
+        return tlist
+
     def AlwaysBuild(self, *targets):
         tlist = []
         for t in targets:
@@ -734,7 +772,7 @@ class Base:
 
         if not isinstance(target, SCons.Node.Node):
             target = self.subst(target)
-            target = SCons.Node.FS.default_fs.Entry(target, create=1)
+            target = self.fs.Entry(target, create=1)
     
         if not SCons.Util.is_List(files):
             files = [files]
@@ -751,13 +789,24 @@ class Base:
         except KeyError:
             CleanTargets[target] = nodes
 
+    def Configure(self, *args, **kw):
+        nargs = [self]
+        if args:
+            nargs = nargs + self.subst_list(args)[0]
+        nkw = self.subst_kw(kw)
+        try:
+            nkw['custom_tests'] = self.subst_kw(nkw['custom_tests'])
+        except KeyError:
+            pass
+        return apply(SCons.SConf.SConf, nargs, nkw)
+
     def Command(self, target, source, action):
         """Builds the supplied target files from the supplied
         source files using the supplied action.  Action may
         be any type that the Builder constructor will accept
         for an action."""
         bld = SCons.Builder.Builder(action=action,
-                                    source_factory=SCons.Node.FS.default_fs.Entry)
+                                    source_factory=self.fs.Entry)
         return bld(self, target, source)
 
     def Default(self, *targets):
@@ -834,7 +883,7 @@ class Base:
         tgt = []
         for dnode in dnodes:
             for src in sources:
-                target = SCons.Node.FS.default_fs.File(src.name, dnode)
+                target = self.fs.File(src.name, dnode)
                 tgt.append(InstallBuilder(self, target, src))
         if len(tgt) == 1:
             tgt = tgt[0]
@@ -882,6 +931,15 @@ class Base:
         dirs = self.arg2nodes(list(dirs), self.fs.Dir)
         apply(self.fs.Repository, dirs, kw)
 
+    def Scanner(self, *args, **kw):
+        nargs = []
+        for arg in args:
+            if SCons.Util.is_String(arg):
+                arg = self.subst(arg)
+            nargs.append(arg)
+        nkw = self.subst_kw(kw)
+        return apply(SCons.Scanner.Base, nargs, nkw)
+
     def SConsignFile(self, name=".sconsign.dbm"):
         name = self.subst(name)
         if not os.path.isabs(name):
@@ -957,6 +1015,11 @@ class Base:
         else:
             raise SCons.Errors.UserError, "Unknown target signature type '%s'"%type
 
+    def Value(self, value):
+        """
+        """
+        return SCons.Node.Python.Value(value)
+
 # The entry point that will be used by the external world
 # to refer to a construction environment.  This allows the wrapper
 # interface to extend a construction environment for its own purposes
index 360eb4c0b6f8fc5af5ed94653290164cbb297c97..49d6ac72017d9d435b2459a0999e51f1ae0c25bb 100644 (file)
@@ -308,6 +308,36 @@ class EnvironmentTestCase(unittest.TestCase):
         assert lst[0][0] == 'test', lst[0][0]
         assert lst[0][1] == 'baz', lst[0][1]
 
+        # Test not calling callables in the Environment
+        if 0:
+            # This will take some serious surgery to subst() and
+            # subst_list(), so just leave these tests out until we can
+            # do that.
+            def bar(arg):
+                pass
+
+            env = Environment(BAR=bar, FOO='$BAR')
+
+            subst = env.subst('$BAR', call=None)
+            assert subst is bar, subst
+
+            subst = env.subst('$FOO', call=None)
+            assert subst is bar, subst
+
+            subst = env.subst_list('$BAR', call=None)
+            assert subst is bar, subst
+
+            subst = env.subst_list('$FOO', call=None)
+            assert subst is bar, subst
+
+    def test_subst_kw(self):
+       """Test substituting construction variables within dictionaries"""
+       env = Environment(AAA = 'a', BBB = 'b')
+        kw = env.subst_kw({'$AAA' : 'aaa', 'bbb' : '$BBB'})
+        assert len(kw) == 2, kw
+        assert kw['a'] == 'aaa', kw['a']
+        assert kw['bbb'] == 'b', kw['bbb']
+
     def test_Builder_calls(self):
         """Test Builder calls through different environments
         """
@@ -1191,6 +1221,49 @@ class EnvironmentTestCase(unittest.TestCase):
         assert str(n[0]) == 'ggg', n[0]
         assert str(n[1]) == 'bbb', n[1]
 
+    def test_Alias(self):
+        """Test the Alias() method"""
+        env = Environment(FOO='kkk', BAR='lll', EA='export_alias')
+
+        tgt = env.Alias('new_alias')
+        assert str(tgt) == 'new_alias', tgt
+        assert tgt.sources == [], tgt.sources
+
+        tgt = env.Alias('None_alias', None)
+        assert str(tgt) == 'None_alias', tgt
+        assert tgt.sources == [], tgt.sources
+
+        tgt = env.Alias('empty_list', [])
+        assert str(tgt) == 'empty_list', tgt
+        assert tgt.sources == [], tgt.sources
+
+        tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ])
+        assert str(tgt) == 'export_alias', tgt
+        assert len(tgt.sources) == 2, map(str, tgt.sources)
+        assert str(tgt.sources[0]) == 'asrc1', map(str, tgt.sources)
+        assert str(tgt.sources[1]) == 'kkk', map(str, tgt.sources)
+
+        n = env.Alias(tgt, source = ['$BAR', 'asrc4'])
+        assert n is tgt, n
+        assert len(tgt.sources) == 4, map(str, tgt.sources)
+        assert str(tgt.sources[2]) == 'lll', map(str, tgt.sources)
+        assert str(tgt.sources[3]) == 'asrc4', map(str, tgt.sources)
+
+        n = env.Alias('$EA', 'asrc5')
+        assert n is tgt, n
+        assert len(tgt.sources) == 5, map(str, tgt.sources)
+        assert str(tgt.sources[4]) == 'asrc5', map(str, tgt.sources)
+
+        t1, t2 = env.Alias(['t1', 't2'], ['asrc6', 'asrc7'])
+        assert str(t1) == 't1', t1
+        assert str(t2) == 't2', t2
+        assert len(t1.sources) == 2, map(str, t1.sources)
+        assert str(t1.sources[0]) == 'asrc6', map(str, t1.sources)
+        assert str(t1.sources[1]) == 'asrc7', map(str, t1.sources)
+        assert len(t2.sources) == 2, map(str, t2.sources)
+        assert str(t2.sources[0]) == 'asrc6', map(str, t2.sources)
+        assert str(t2.sources[1]) == 'asrc7', map(str, t2.sources)
+
     def test_AlwaysBuild(self):
         """Test the AlwaysBuild() method"""
         env = Environment(FOO='fff', BAR='bbb')
@@ -1323,6 +1396,32 @@ class EnvironmentTestCase(unittest.TestCase):
         assert 'foo1.in' in map(lambda x: x.path, t.sources)
         assert 'foo2.in' in map(lambda x: x.path, t.sources)
 
+    def test_Configure(self):
+        """Test the Configure() method"""
+        # Configure() will write to a local temporary file.
+        test = TestCmd.TestCmd(workdir = '')
+        save = os.getcwd()
+
+        try:
+            os.chdir(test.workpath())
+
+            env = Environment(FOO = 'xyzzy')
+
+            def func(arg):
+                pass
+
+            c = env.Configure()
+            assert not c is None, c
+            c.Finish()
+
+            c = env.Configure(custom_tests = {'foo' : func, '$FOO' : func})
+            assert not c is None, c
+            assert hasattr(c, 'foo')
+            assert hasattr(c, 'xyzzy')
+            c.Finish()
+        finally:
+            os.chdir(save)
+
     def test_Default(self):
         """Test the Default() method"""
         env = Environment(FOO = 'fff', BAR = 'bbb')
@@ -1592,6 +1691,26 @@ class EnvironmentTestCase(unittest.TestCase):
         expect = ['/tmp/foo', '/tmp/rrr', '/tmp/sss/foo']
         assert env.fs.list == expect, env.fs.list
 
+    def test_Scanner(self):
+        """Test the Scanner() method"""
+        def scan(node, env, target, arg):
+            pass
+
+        env = Environment(FOO = scan)
+
+        s = env.Scanner('foo')
+        assert not s is None, s
+
+        s = env.Scanner(function = 'foo')
+        assert not s is None, s
+
+        if 0:
+            s = env.Scanner('$FOO')
+            assert not s is None, s
+
+            s = env.Scanner(function = '$FOO')
+            assert not s is None, s
+
     def test_SConsignFile(self):
         """Test the SConsignFile() method"""
         import SCons.Sig
@@ -1750,6 +1869,23 @@ class EnvironmentTestCase(unittest.TestCase):
         env.TargetSignatures('$C')
         assert env._build_signature == 0, env._build_signature
 
+    def test_Value(self):
+        """Test creating a Value() object
+        """
+        env = Environment()
+        v1 = env.Value('a')
+        assert v1.value == 'a', v1.value
+
+        value2 = 'a'
+        v2 = env.Value(value2)
+        assert v2.value == value2, v2.value
+        assert v2.value is value2, v2.value
+
+        assert not v1 is v2
+        assert v1.value == v2.value
+
+
+
     def test_Environment_global_variable(type):
         """Test setting Environment variable to an Environment.Base subclass"""
         class MyEnv(SCons.Environment.Base):
index aed43f5fb578e177681e504ab0af375d5c0762a6..92cd68dd8f55a5932914fb243395b798a20a1d4a 100644 (file)
@@ -39,13 +39,12 @@ import SCons.Errors
 import SCons.Node
 import SCons.Node.Alias
 import SCons.Node.FS
-import SCons.Node.Python
+import SCons.Options
 import SCons.Platform
 import SCons.SConf
 import SCons.Script
 import SCons.Tool
 import SCons.Util
-import SCons.Options
 
 import os
 import os.path
@@ -68,10 +67,6 @@ global_exports = {}
 # chdir flag
 sconscript_chdir = 1
 
-def SConscriptChdir(flag):
-    global sconscript_chdir
-    sconscript_chdir = flag
-
 def _scons_add_args(alist):
     global arguments
     for arg in alist:
@@ -365,17 +360,17 @@ class SConsEnvironment(SCons.Environment.Base):
                 src_dir, fname = os.path.split(str(files[0]))
             else:
                 if not isinstance(src_dir, SCons.Node.Node):
-                    src_dir = SCons.Node.FS.default_fs.Dir(src_dir)
+                    src_dir = self.fs.Dir(src_dir)
                 fn = files[0]
                 if not isinstance(fn, SCons.Node.Node):
-                    fn = SCons.Node.FS.default_fs.File(fn)
+                    fn = self.fs.File(fn)
                 if fn.is_under(src_dir):
                     # Get path relative to the source directory.
                     fname = fn.get_path(src_dir)
                 else:
                     # Fast way to only get the terminal path component of a Node.
                     fname = fn.get_path(fn.dir)
-            SCons.Node.FS.default_fs.BuildDir(build_dir, src_dir, duplicate)
+            self.fs.BuildDir(build_dir, src_dir, duplicate)
             files = [os.path.join(str(build_dir), fname)]
 
         return (files, exports)
@@ -446,6 +441,10 @@ class SConsEnvironment(SCons.Environment.Base):
 
         return apply(_SConscript, [self.fs,] + files, {'exports' : exports})
 
+    def SConscriptChdir(self, flag):
+        global sconscript_chdir
+        sconscript_chdir = flag
+
     def SetOption(self, name, value):
         name = self.subst(name)
         SCons.Script.ssoptions.set(name, value)
@@ -455,6 +454,9 @@ class SConsEnvironment(SCons.Environment.Base):
 #
 SCons.Environment.Environment = SConsEnvironment
 
+def Options(files=None, args=arguments):
+    return SCons.Options.Options(files, args)
+
 def SetBuildSignatureType(type):
     SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
                         "The SetBuildSignatureType() function has been deprecated;\n" +\
@@ -467,10 +469,6 @@ def SetContentSignatureType(type):
                         "\tuse the SourceSignatures() function instead.")
     SCons.Defaults.DefaultEnvironment().SourceSignatures(type)
 
-class Options(SCons.Options.Options):
-    def __init__(self, files=None, args=arguments):
-        SCons.Options.Options.__init__(self, files, args)
-
 def GetJobs():
     SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning,
                         "The GetJobs() function has been deprecated;\n" +\
@@ -490,13 +488,6 @@ def ParseConfig(env, command, function=None):
                         "\tuse the env.ParseConfig() method instead.")
     return env.ParseConfig(command, function)
 
-
-def Alias(name):
-    alias = SCons.Node.Alias.default_ans.lookup(name)
-    if alias is None:
-        alias = SCons.Node.Alias.default_ans.Alias(name)
-    return alias
-
 #
 _DefaultEnvironmentProxy = None
 
@@ -557,12 +548,14 @@ GlobalDefaultEnvironmentFunctions = [
     'Help',
     'Import',
     'SConscript',
+    'SConscriptChdir',
     'SetOption',
 
     # Methods from the Environment.Base class.
     'Action',
     'AddPostAction',
     'AddPreAction',
+    'Alias',
     'AlwaysBuild',
     'BuildDir',
     'Builder',
@@ -583,13 +576,17 @@ GlobalDefaultEnvironmentFunctions = [
     'Local',
     'Precious',
     'Repository',
+    'Scanner',
     'SConsignFile',
     'SideEffect',
     'SourceCode',
     'SourceSignatures',
     'Split',
     'TargetSignatures',
+    'Value',
+]
 
+GlobalDefaultBuilders = [
     # Supported builders.
     'CFile',
     'CXXFile',
@@ -616,7 +613,7 @@ GlobalDefaultEnvironmentFunctions = [
     'Zip',
 ]
 
-for name in GlobalDefaultEnvironmentFunctions:
+for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders:
     GlobalDict[name] = DefaultEnvironmentCall(name)
 
 def BuildDefaultGlobals():
@@ -626,23 +623,17 @@ def BuildDefaultGlobals():
     """
 
     globals = {}
+    globals['ARGUMENTS']         = arguments
+    globals['Configure']         = SCons.SConf.SConf
+    globals['Options']           = Options
     globals['Platform']          = SCons.Platform.Platform
+    globals['Return']            = Return
     globals['Tool']              = SCons.Tool.Tool
     globals['WhereIs']           = SCons.Util.WhereIs
 
     # Functions we're in the process of converting to Environment methods.
-    globals['Alias']             = Alias
-    globals['ARGUMENTS']         = arguments
-    globals['Configure']         = SCons.SConf.SConf
     globals['CScan']             = SCons.Defaults.CScan
     globals['DefaultEnvironment'] = SCons.Defaults.DefaultEnvironment
-    globals['GetCommandHandler'] = SCons.Action.GetCommandHandler
-    globals['Options']           = Options
-    globals['Return']            = Return
-    globals['SConscriptChdir']   = SConscriptChdir
-    globals['Scanner']           = SCons.Scanner.Base
-    globals['SetCommandHandler'] = SCons.Action.SetCommandHandler
-    globals['Value']             = SCons.Node.Python.Value
 
     # Deprecated functions, leave these here for now.
     globals['GetJobs']           = GetJobs
index ea9465269ebedbc33af3794c2c8ba25d8072ba0d..2a14c024b6cad505fb87573f9f73cb532ddd9799 100644 (file)
@@ -54,7 +54,7 @@ SConscript('sub2/SConscript', "env")
 foo = Alias('foo')
 foo2 = env.Alias('foo', ['f2.out', 'sub1'])
 assert foo == foo2
-bar = env.Alias('bar', ['sub2', 'f3.out'])
+bar = Alias('bar', ['sub2', 'f3.out'])
 env.Alias('blat', ['sub2', 'f3.out'])
 env.Alias('blat', ['f2.out', 'sub1'])
 env.Depends('f1.out', 'bar')
index 3bad08607a043f481dd4ee8f242379db450b5b5f..917046906636a75d486d7eb9742f508156576fd9 100644 (file)
@@ -116,7 +116,7 @@ Checking for C++ header file vector... yes
 env = Environment()
 import os
 env['ENV']['PATH'] = os.environ['PATH']
-conf = Configure(env)
+conf = env.Configure()
 r1 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error
 r2 = conf.CheckLib( 'no_c_library_SAFFDG' )   # leads to link error
 env = conf.Finish()
@@ -182,11 +182,11 @@ Checking for C header file no_std_c_header.h... no
     
 
     test.write( 'SConstruct', """
-env = Environment()
+env = Environment(LOGFILE='build/config.log')
 import os
 env['ENV']['PATH'] = os.environ['PATH']
 BuildDir( 'build', '.' )
-conf = Configure(env, conf_dir='build/config.tests', log_file='build/config.log')
+conf = env.Configure(conf_dir='build/config.tests', log_file='$LOGFILE')
 r1 = conf.CheckCHeader( 'math.h' )
 r2 = conf.CheckCHeader( 'no_std_c_header.h' ) # leads to compile error
 env = conf.Finish()
@@ -243,11 +243,15 @@ def CustomTest(context):
   context.Result(ret)
   return ret
 
-env = Environment()
+env = Environment(FOO='fff')
 env.Append( CPPPATH='local' )
 import os
 env['ENV']['PATH'] = os.environ['PATH']
-conf = Configure( env, custom_tests = {'CustomTest' : CustomTest} )
+conf = Configure( env, custom_tests = {'CustomTest' : CustomTest,
+                                       '$FOO' : CustomTest} )
+if hasattr(conf, 'fff'):
+  conf.Message('$FOO should not have been expanded!')
+  Exit(1)
 if not conf.CheckCHeader( 'math.h' ):
   Exit(1)
 if conf.CheckCHeader( 'no_std_c_header.h' ):
index 42ef18dc534ef8edc00e34816e3fb59f6bc4476a..b11805e0c8f08560cc14d58da857724806928b77 100644 (file)
@@ -70,15 +70,29 @@ kscan = Scanner(name = 'kfile',
                 function = kfile_scan,
                 argument = None,
                 skeys = ['.k'])
+
+env = Environment(K2SCAN=kfile_scan)
+
+k2scan = env.Scanner(name = 'k2',
+                     # We'd like to do the following, but it will take
+                     # some major surgery to subst() and subst_list(),
+                     # so comment it out for now.
+                     # function = '$K2SCAN',
+                     function = kfile_scan,
+                     argument = None,
+                     skeys = ['.k2'])
+
 scanners = Environment().Dictionary('SCANNERS')
-env = Environment(SCANNERS = scanners + [kscan])
+env = Environment(SCANNERS = scanners + [kscan, k2scan])
 
 env.Command('foo', 'foo.k', r'%s build.py $SOURCES $TARGET')
 
+env.Command('junk', 'junk.k2', r'%s build.py $SOURCES $TARGET')
+
 bar_in = File('bar.in')
 env.Command('bar', bar_in, r'%s build.py $SOURCES  $TARGET')
 bar_in.source_scanner = kscan
-""" % (python, python))
+""" % (python, python, python))
 
 test.write('foo.k', 
 """foo.k 1 line 1
@@ -94,6 +108,13 @@ bar.in 1 line 3
 include zzz
 """)
 
+test.write('junk.k2', 
+"""include yyy
+junk.k2 1 line 2
+junk.k2 1 line 3
+include zzz
+""")
+
 test.write('xxx', "xxx 1\n")
 
 test.write('yyy', "yyy 1\n")
@@ -106,6 +127,8 @@ test.fail_test(test.read('foo') != "foo.k 1 line 1\nxxx 1\nyyy 1\nfoo.k 1 line 4
 
 test.fail_test(test.read('bar') != "yyy 1\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n")
 
+test.fail_test(test.read('junk') != "yyy 1\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n")
+
 test.up_to_date(arguments = '.')
 
 test.write('xxx', "xxx 2\n")
@@ -116,6 +139,8 @@ test.fail_test(test.read('foo') != "foo.k 1 line 1\nxxx 2\nyyy 1\nfoo.k 1 line 4
 
 test.fail_test(test.read('bar') != "yyy 1\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n")
 
+test.fail_test(test.read('junk') != "yyy 1\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n")
+
 test.write('yyy', "yyy 2\n")
 
 test.run(arguments = '.')
@@ -124,6 +149,8 @@ test.fail_test(test.read('foo') != "foo.k 1 line 1\nxxx 2\nyyy 2\nfoo.k 1 line 4
 
 test.fail_test(test.read('bar') != "yyy 2\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 1\n")
 
+test.fail_test(test.read('junk') != "yyy 2\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 1\n")
+
 test.write('zzz', "zzz 2\n")
 
 test.run(arguments = '.')
@@ -132,6 +159,8 @@ test.fail_test(test.read('foo') != "foo.k 1 line 1\nxxx 2\nyyy 2\nfoo.k 1 line 4
 
 test.fail_test(test.read('bar') != "yyy 2\nbar.in 1 line 2\nbar.in 1 line 3\nzzz 2\n")
 
+test.fail_test(test.read('junk') != "yyy 2\njunk.k2 1 line 2\njunk.k2 1 line 3\nzzz 2\n")
+
 test.up_to_date(arguments = 'foo')
 
 test.pass_test()
index 11fb72a32d92b361a714b6d96ff79e57b27f5ab2..5f723bf4de050b5d6657827fdecef29a57475c25 100644 (file)
@@ -54,7 +54,7 @@ def create(target, source, env):
 env = Environment()
 env['BUILDERS']['B'] = Builder(action = create)
 env.B('f1.out', Value(P))
-env.B('f2.out', Value(L))
+env.B('f2.out', env.Value(L))
 env.B('f3.out', Value(C))
 """ % source_signature)