summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2003-09-08 04:01:32 (GMT)
committerSteven Knight <knight@baldmt.com>2003-09-08 04:01:32 (GMT)
commit68b5dfbc87552d4cd1a9c067f6ba4523d9560bb9 (patch)
tree910dcf1998d6b72aa8eb4bdb5497177d331ea900
parent61d018dfceac6cb9717caeeea7125d7a55b4b0eb (diff)
downloadSCons-68b5dfbc87552d4cd1a9c067f6ba4523d9560bb9.zip
SCons-68b5dfbc87552d4cd1a9c067f6ba4523d9560bb9.tar.gz
SCons-68b5dfbc87552d4cd1a9c067f6ba4523d9560bb9.tar.bz2
Give the global functions corresponding Environment methods.
-rw-r--r--doc/man/scons.1204
-rw-r--r--src/CHANGES.txt3
-rw-r--r--src/engine/SCons/Environment.py43
-rw-r--r--src/engine/SCons/EnvironmentTests.py81
-rw-r--r--src/engine/SCons/Script/SConscript.py62
-rw-r--r--src/engine/SCons/Script/__init__.py6
-rw-r--r--test/Default.py58
-rw-r--r--test/FindFile.py5
-rw-r--r--test/Repository/Local.py4
-rw-r--r--test/pre-post-actions.py60
10 files changed, 389 insertions, 137 deletions
diff --git a/doc/man/scons.1 b/doc/man/scons.1
index 490975d..95696c9 100644
--- a/doc/man/scons.1
+++ b/doc/man/scons.1
@@ -891,6 +891,7 @@ variable after the Environment is constructed will not cause the tools to
be redetected.
SCons supports the following tool specifications out of the box:
+
.ES
386asm
aixc++
@@ -1089,6 +1090,7 @@ provides the following builders:
Builds a static object file
from one or more C, C++, or Fortran source files.
Source files must have one of the following extensions:
+
.ES
.asm assembly language file
.ASM assembly language file
@@ -1424,6 +1426,7 @@ env.M4(target = 'foo.c', source = 'foo.c.m4')
.IP Jar
Builds a Java archive (.jar) file
from a source tree of .class files.
+
.ES
env.Jar(target = 'foo.jar', source = 'classes')
.EE
@@ -1678,6 +1681,32 @@ method of a construction environment (see below).
.SS Other Construction Environment Methods
Additional construction environment methods include:
+.TP
+.RI AddPostAction( target ", " action )
+Arranges for the specified
+.I action
+to be performed
+after the specified
+.I target
+has been built.
+The specified action(s) may be
+an Action object, or anything that
+can be converted into an Action object
+(see below).
+
+.TP
+.RI AddPreAction( target ", " action )
+Arranges for the specified
+.I action
+to be performed
+before the specified
+.I target
+is built.
+The specified action(s) may be
+an Action object, or anything that
+can be converted into an Action object
+(see below).
+
.TP
.RI Alias( alias ", " targets )
Creates a phony target that
@@ -1697,6 +1726,24 @@ env.Alias('install', ['/usr/local/man'])
.EE
.TP
+.RI AlwaysBuild( target ", ...)"
+Marks each given
+.I target
+so that it is always assumed to be out of date,
+and will always be rebuilt if needed.
+Note, however, that
+.BR AlwaysBuild ()
+does not add its target(s) to the default target list,
+so the targets will only be built
+if they are specified on the command line,
+or are a dependent of a target specified on the command line--but
+they will
+.I always
+be built if so specified.
+Multiple targets can be passed in to a single call to
+.BR AlwaysBuild ().
+
+.TP
.RI Append( key = val ", [...])"
Appends the specified keyword arguments
to the end of construction variables in the environment.
@@ -1717,36 +1764,6 @@ env.Append(CCFLAGS = ' -g', FOO = ['foo.yyy'])
.EE
.TP
-.RI PrependENVPath( name ", " newpath ", [" envname ", " sep ])
-This appends new path elements to the given path in the
-specified external environment
-.RB ( ENV
-by default).
-This will only add
-any particular path once (leaving the first one it encounters and
-ignoring the rest, to preserve path order),
-and to help assure this,
-will normalize all paths (using
-.B os.path.normpath
-and
-.BR os.path.normcase ).
-This can also handle the
-case where the given old path variable is a list instead of a
-string, in which case a list will be returned instead of a string.
-Example:
-
-.ES
-print 'before:',env['ENV']['INCLUDE']
-include_path = '/foo/bar:/foo'
-env.PrependENVPath('INCLUDE', include_path)
-print 'after:',env['ENV']['INCLUDE']
-
-yields:
-before: /biz:/foo
-after: /foo/bar:/foo:/biz
-.EE
-
-.TP
.RI AppendENVPath( name ", " newpath ", [" envname ", " sep ])
This appends new path elements to the given path in the
specified external environment
@@ -1786,6 +1803,7 @@ The returned Builder
is intended to be passed to the
.B SourceCode
function.
+
.ES
env.SourceCode('.', env.BitKeeper())
.EE
@@ -1834,7 +1852,7 @@ for the keywords.
env2 = env.Copy()
env3 = env.Copy(CCFLAGS = '-g')
.EE
-
+.IP
Additionally, a list of tools may be specified, as in the Environment
constructor:
@@ -1843,7 +1861,6 @@ def MyTool(env): env['FOO'] = 'bar'
env4 = env.Copy(tools = ['msvc', MyTool])
.EE
-
.TP
.RI CVS( repository ", " module )
A factory function that
@@ -1883,6 +1900,44 @@ env.SourceCode('.', env.CVS('/usr/local/CVSROOT', 'foo'))
env.SourceCode('.', env.CVS('/usr/local/CVSROOT', 'foo/bar'))
.EE
+.TP
+.RI Default( targets )
+This specifies a list of default targets,
+which will be built by
+.B scons
+if no explicit targets are given on the command line.
+Multiple calls to
+.BR Default ()
+are legal,
+and add to the list of default targets.
+
+Multiple targets should be specified as
+separate arguments to the
+.BR Default ()
+method, or as a list.
+.BR Default ()
+will also accept the Node returned by any
+of a construction environment's
+builder methods.
+Examples:
+
+.ES
+env.Default('foo', 'bar', 'baz')
+env.Default(['a', 'b', 'c'])
+hello = env.Program('hello', 'hello.c')
+env.Default(hello)
+.EE
+.IP
+An argument to
+.BR Default ()
+of
+.B None
+will clear all default targets.
+Later calls to
+.BR Default ()
+will add to the (now empty) default-target list
+like normal.
+
.TP
.RI Depends( target ", " dependency )
Specifies an explicit dependency;
@@ -1912,6 +1967,21 @@ cc_dict = env.Dictionary('CC', 'CCFLAGS', 'CCCOM')
.EE
.TP
+.RI FindFile( file ", " dirs )
+Search for
+.I file
+in the path specified by
+.IR dirs .
+.I file
+may be a list of file names or a single file name. In addition to searching
+for files that exist in the filesytem, this function also searches for
+derived files that have not yet been built.
+
+.ES
+foo = env.FindFile('foo', ['dir1', 'dir2'])
+.EE
+
+.TP
.RI Ignore( target ", " dependency )
The specified dependency file(s)
will be ignored when deciding if
@@ -1947,6 +2017,15 @@ env.InstallAs(target = ['../lib/libfoo.a', '../lib/libbar.a'],
.EE
.TP
+.RI Local( targets )
+The specified
+.I targets
+will have copies made in the local tree,
+even if an already up-to-date copy
+exists in a repository.
+Returns a list of the target Node or Nodes.
+
+.TP
Perforce()
A factory function that
returns a Builder object
@@ -1956,6 +2035,7 @@ The returned Builder
is intended to be passed to the
.B SourceCode
function:
+
.ES
env.SourceCode('.', env.Perforce())
.EE
@@ -1978,24 +2058,6 @@ and
USERNAME.
.TP
-.RI AlwaysBuild( target ", ...)"
-Marks each given
-.I target
-so that it is always assumed to be out of date,
-and will always be rebuilt if needed.
-Note, however, that
-.BR AlwaysBuild ()
-does not add its target(s) to the default target list,
-so the targets will only be built
-if they are specified on the command line,
-or are a dependent of a target specified on the command line--but
-they will
-.I always
-be built if so specified.
-Multiple targets can be passed in to a single call to
-.BR AlwaysBuild ().
-
-.TP
.RI Precious( target ", ...)"
Marks each given
.I target
@@ -2026,6 +2088,36 @@ env.Prepend(CCFLAGS = '-g ', FOO = ['foo.yyy'])
.EE
.TP
+.RI PrependENVPath( name ", " newpath ", [" envname ", " sep ])
+This appends new path elements to the given path in the
+specified external environment
+.RB ( ENV
+by default).
+This will only add
+any particular path once (leaving the first one it encounters and
+ignoring the rest, to preserve path order),
+and to help assure this,
+will normalize all paths (using
+.B os.path.normpath
+and
+.BR os.path.normcase ).
+This can also handle the
+case where the given old path variable is a list instead of a
+string, in which case a list will be returned instead of a string.
+Example:
+
+.ES
+print 'before:',env['ENV']['INCLUDE']
+include_path = '/foo/bar:/foo'
+env.PrependENVPath('INCLUDE', include_path)
+print 'after:',env['ENV']['INCLUDE']
+
+yields:
+before: /biz:/foo
+after: /foo/bar:/foo:/biz
+.EE
+
+.TP
RCS()
A factory function that
returns a Builder object
@@ -2035,6 +2127,7 @@ The returned Builder
is intended to be passed to the
.B SourceCode
function:
+
.ES
env.SourceCode('.', env.RCS())
.EE
@@ -2072,6 +2165,7 @@ The returned Builder
is intended to be passed to the
.B SourceCode
function:
+
.ES
env.SourceCode('.', env.SCCS())
.EE
@@ -2157,6 +2251,7 @@ source code management files on disk.
You can avoid these extra searches
and speed up your build a little
by disabling these searches as follows:
+
.ES
env.SourceCode('.', None)
.EE
@@ -2175,6 +2270,7 @@ functions that return appropriate
Builders for various popular
source code management systems.
Canonical examples of invocation include:
+
.ES
env.SourceCode('.', env.BitKeeper('/usr/local/BKsources'))
env.SourceCode('src', env.CVS('/usr/local/CVSROOT'))
@@ -2303,6 +2399,7 @@ Alias, CFile, CXXFile, DVI, Library, Object, PDF, PostScript, and Program
are available by default.
If you initialize this variable when an
Environment is created:
+
.ES
env = Environment(BUILDERS = {'NewBuilder' : foo})
.EE
@@ -2310,12 +2407,14 @@ env = Environment(BUILDERS = {'NewBuilder' : foo})
the default Builders will no longer be available.
To use a new Builder object in addition to the default Builders,
add your new Builder object like this:
+
.ES
env = Environment()
env.Append(BUILDERS = {'NewBuilder' : foo})
.EE
.IP
or this:
+
.ES
env = Environment()
env['BUILDERS]['NewBuilder'] = foo
@@ -3235,6 +3334,7 @@ In addition, the construction environment
variables CPPPATH, LIBPATH, LIBS, PROGEMITTER, SHLIBEMITTER and LIBEMITTER
are modified. Because the build-performance is affected when using this tool,
you have to explicitly specify it at Environment creation:
+
.ES
Environment(tools=['default','qt']).
.EE
@@ -4614,6 +4714,7 @@ The specified
will have copies made in the local tree,
even if an already up-to-date copy
exists in a repository.
+Returns a list of the target Node or Nodes.
.TP
.RI ParseConfig( env ", " command ", [" function ])
@@ -4906,6 +5007,7 @@ to the directory in which each
subsidiary SConscript file lives.
This behavior may be disabled
by specifying:
+
.ES
SConscriptChdir(0)
.EE
@@ -5322,6 +5424,7 @@ the command line.
This allows white space to be enclosed
in an argument by defining
a command in a list within a list:
+
.ES
Action([['cc', '-c', '-DWHITE SPACE', '-o', '$TARGET', '$SOURCES']])
.EE
@@ -5347,6 +5450,7 @@ more than one target file or source file.
The actual target and source file name(s) may
be retrieved from their Node objects
via the built-in Python str() function:
+
.ES
target_file_name = str(target)
source_file_names = map(lambda x: str(x), source)
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 8f1f754..4d0f646 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -39,6 +39,9 @@ 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 AddPreAction(), AddPostAction(),
+ Default(), FindFile(), and Local().
+
From Bram Moolenaar:
- Split the non-SCons-specific functionality from SConf.py to a new,
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index e7407ee..074fd3c 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -577,6 +577,20 @@ class Environment:
# same-named global functions.
#######################################################################
+ def AddPreAction(self, files, action):
+ nodes = self.arg2nodes(files, self.fs.Entry)
+ action = SCons.Action.Action(action)
+ for n in nodes:
+ n.add_pre_action(action)
+ return nodes
+
+ def AddPostAction(self, files, action):
+ nodes = self.arg2nodes(files, self.fs.Entry)
+ action = SCons.Action.Action(action)
+ for n in nodes:
+ n.add_post_action(action)
+ return nodes
+
def AlwaysBuild(self, *targets):
tlist = []
for t in targets:
@@ -598,6 +612,18 @@ class Environment:
source_factory=SCons.Node.FS.default_fs.Entry)
return bld(self, target, source)
+ def Default(self, *targets):
+ global DefaultTargets
+ if DefaultTargets is None:
+ DefaultTargets = []
+ for t in targets:
+ if t is None:
+ DefaultTargets = []
+ elif isinstance(t, SCons.Node.Node):
+ DefaultTargets.append(t)
+ else:
+ DefaultTargets.extend(self.arg2nodes(t, self.fs.Entry))
+
def Depends(self, target, dependency):
"""Explicity specify that 'target's depend on 'dependency'."""
tlist = self.arg2nodes(target, self.fs.File)
@@ -609,6 +635,11 @@ class Environment:
tlist = tlist[0]
return tlist
+ def FindFile(self, file, dirs):
+ file = self.subst(file)
+ nodes = self.arg2nodes(dirs, self.fs.Dir)
+ return SCons.Node.FS.find_file(file, nodes, self.fs.File)
+
def Ignore(self, target, dependency):
"""Ignore a dependency."""
tlist = self.arg2nodes(target, self.fs.File)
@@ -653,6 +684,18 @@ class Environment:
ret = ret[0]
return ret
+ def Local(self, *targets):
+ ret = []
+ for targ in targets:
+ if isinstance(targ, SCons.Node.Node):
+ targ.set_local()
+ ret.append(targ)
+ else:
+ for t in self.arg2nodes(targ, self.fs.Entry):
+ t.set_local()
+ ret.append(t)
+ return ret
+
def Precious(self, *targets):
tlist = []
for t in targets:
diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py
index d3807f5..db05351 100644
--- a/src/engine/SCons/EnvironmentTests.py
+++ b/src/engine/SCons/EnvironmentTests.py
@@ -957,6 +957,18 @@ class EnvironmentTestCase(unittest.TestCase):
assert(env1['ENV']['PATH'] == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
+ def test_PrependENVPath(self):
+ """Test prepending to an ENV path."""
+ env1 = Environment(ENV = {'PATH': r'C:\dir\num\one;C:\dir\num\two'},
+ MYENV = {'MYPATH': r'C:\mydir\num\one;C:\mydir\num\two'})
+ # have to include the pathsep here so that the test will work on UNIX too.
+ env1.PrependENVPath('PATH',r'C:\dir\num\two',sep = ';')
+ env1.PrependENVPath('PATH',r'C:\dir\num\three',sep = ';')
+ env1.PrependENVPath('MYPATH',r'C:\mydir\num\three','MYENV',sep = ';')
+ env1.PrependENVPath('MYPATH',r'C:\mydir\num\one','MYENV',sep = ';')
+ assert(env1['ENV']['PATH'] == r'C:\dir\num\three;C:\dir\num\two;C:\dir\num\one')
+ assert(env1['MYENV']['MYPATH'] == r'C:\mydir\num\one;C:\mydir\num\three;C:\mydir\num\two')
+
def test_Replace(self):
"""Test replacing construction variables in an Environment
@@ -997,6 +1009,28 @@ class EnvironmentTestCase(unittest.TestCase):
+ def test_AddPostAction(self):
+ """Test the AddPostAction() method"""
+ env = Environment(FOO='fff', BAR='bbb')
+
+ n = env.AddPostAction('$FOO', lambda x: x)
+ assert str(n[0]) == 'fff', n[0]
+
+ n = env.AddPostAction(['ggg', '$BAR'], lambda x: x)
+ assert str(n[0]) == 'ggg', n[0]
+ assert str(n[1]) == 'bbb', n[1]
+
+ def test_AddPreAction(self):
+ """Test the AddPreAction() method"""
+ env = Environment(FOO='fff', BAR='bbb')
+
+ n = env.AddPreAction('$FOO', lambda x: x)
+ assert str(n[0]) == 'fff', n[0]
+
+ n = env.AddPreAction(['ggg', '$BAR'], lambda x: x)
+ assert str(n[0]) == 'ggg', n[0]
+ assert str(n[1]) == 'bbb', n[1]
+
def test_AlwaysBuild(self):
"""Test the AlwaysBuild() method"""
env = Environment(FOO='fff', BAR='bbb')
@@ -1045,6 +1079,25 @@ 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_Default(self):
+ """Test the Default() method"""
+ env = Environment(FOO = 'fff', BAR = 'bbb')
+
+ t = env.Default(None)
+ assert SCons.Environment.DefaultTargets == []
+
+ t = env.Default('xyz')
+ d = map(str, SCons.Environment.DefaultTargets)
+ assert d == ['xyz'], d
+
+ t = env.Default('$FOO')
+ d = map(str, SCons.Environment.DefaultTargets)
+ assert d == ['xyz', 'fff'], d
+
+ t = env.Default(None, '$BAR', 'another_file')
+ d = map(str, SCons.Environment.DefaultTargets)
+ assert d == ['bbb', 'another_file'], d
+
def test_Depends(self):
"""Test the explicit Depends method."""
env = Environment(FOO = 'xxx', BAR='yyy')
@@ -1064,6 +1117,15 @@ class EnvironmentTestCase(unittest.TestCase):
assert d.__class__.__name__ == 'File'
assert d.path == 'yyy.py'
+ def test_FindFile(self):
+ """Test the FindFile() method"""
+ env = Environment(FOO = 'fff', BAR = 'bbb')
+
+ r = env.FindFile('foo', ['no_such_directory'])
+ assert r is None, r
+
+ # XXX
+
def test_Ignore(self):
"""Test the explicit Ignore method."""
env = Environment(FOO='yyy', BAR='zzz')
@@ -1083,7 +1145,7 @@ class EnvironmentTestCase(unittest.TestCase):
assert i.path == 'zzzyyy'
def test_Install(self):
- """Test Install and InstallAs methods"""
+ """Test the Install method"""
env = Environment(FOO='iii', BAR='jjj')
tgt = env.Install('export', [ 'build/foo1', 'build/foo2' ])
@@ -1129,6 +1191,10 @@ class EnvironmentTestCase(unittest.TestCase):
match = str(e) == "Target `export/foo1' of Install() is a file, but should be a directory. Perhaps you have the Install() arguments backwards?"
assert match, e
+ def test_InstallAs(self):
+ """Test the InstallAs method"""
+ env = Environment(FOO='iii', BAR='jjj')
+
tgt = env.InstallAs(target=string.split('foo1 foo2'),
source=string.split('bar1 bar2'))
assert len(tgt) == 2, len(tgt)
@@ -1144,6 +1210,17 @@ class EnvironmentTestCase(unittest.TestCase):
assert tgt.sources[0].path == 'jjj.s'
assert tgt.builder == InstallBuilder
+ def test_Local(self):
+ """Test the Local() method."""
+ env = Environment(FOO='lll')
+
+ l = env.Local(env.fs.File('fff'))
+ assert str(l[0]) == 'fff', l[0]
+
+ l = env.Local('ggg', '$FOO')
+ assert str(l[0]) == 'ggg', l[0]
+ assert str(l[1]) == 'lll', l[1]
+
def test_Precious(self):
"""Test the Precious() method."""
env = Environment(FOO='ggg', BAR='hhh')
@@ -1207,7 +1284,7 @@ class EnvironmentTestCase(unittest.TestCase):
s = e.src_builder()
assert s is None, s
-
+
if __name__ == "__main__":
suite = unittest.makeSuite(EnvironmentTestCase, 'test_')
if not unittest.TextTestRunner().run(suite).wasSuccessful():
diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py
index 1c17ee2..276ff4e 100644
--- a/src/engine/SCons/Script/SConscript.py
+++ b/src/engine/SCons/Script/SConscript.py
@@ -56,7 +56,6 @@ import traceback
def do_nothing(text): pass
HelpFunction = do_nothing
-default_targets = None
clean_targets = {}
arguments = {}
launch_dir = os.path.abspath(os.curdir)
@@ -356,27 +355,6 @@ def annotate(node):
# leave this disabled until we find a more efficient mechanism.
#SCons.Node.Annotate = annotate
-def Default(*targets):
- global default_targets
- if default_targets is None:
- default_targets = []
- for t in targets:
- if t is None:
- default_targets = []
- elif isinstance(t, SCons.Node.Node):
- default_targets.append(t)
- else:
- default_targets.extend(SCons.Node.arg2nodes(t,
- SCons.Node.FS.default_fs.Entry))
-
-def Local(*targets):
- for targ in targets:
- if isinstance(targ, SCons.Node.Node):
- targ.set_local()
- else:
- for t in SCons.Node.arg2nodes(targ, SCons.Node.FS.default_fs.Entry):
- t.set_local()
-
def Help(text):
HelpFunction(text)
@@ -390,10 +368,6 @@ def GetBuildPath(files):
return ret[0]
return ret
-def FindFile(file, dirs):
- nodes = SCons.Node.arg2nodes(dirs, SCons.Node.FS.default_fs.Dir)
- return SCons.Node.FS.find_file(file, nodes)
-
def Export(*vars):
for var in vars:
global_exports.update(compute_exports(var))
@@ -512,16 +486,6 @@ def Clean(target, files):
except KeyError:
clean_targets[target] = nodes
-def AddPreAction(files, action):
- nodes = SCons.Node.arg2nodes(files, SCons.Node.FS.default_fs.Entry)
- for n in nodes:
- n.add_pre_action(SCons.Action.Action(action))
-
-def AddPostAction(files, action):
- nodes = SCons.Node.arg2nodes(files, SCons.Node.FS.default_fs.Entry)
- for n in nodes:
- n.add_post_action(SCons.Action.Action(action))
-
def Exit(value=0):
sys.exit(value)
@@ -553,8 +517,6 @@ def BuildDefaultGlobals():
globals = {}
globals['Action'] = SCons.Action.Action
- globals['AddPostAction'] = AddPostAction
- globals['AddPreAction'] = AddPreAction
globals['Alias'] = Alias
globals['ARGUMENTS'] = arguments
globals['BuildDir'] = BuildDir
@@ -563,7 +525,6 @@ def BuildDefaultGlobals():
globals['Clean'] = Clean
globals['Configure'] = SCons.SConf.SConf
globals['CScan'] = SCons.Defaults.CScan
- globals['Default'] = Default
globals['DefaultEnvironment'] = SCons.Defaults.DefaultEnvironment
globals['Dir'] = SCons.Node.FS.default_fs.Dir
globals['EnsurePythonVersion'] = EnsurePythonVersion
@@ -572,7 +533,6 @@ def BuildDefaultGlobals():
globals['Exit'] = Exit
globals['Export'] = Export
globals['File'] = SCons.Node.FS.default_fs.File
- globals['FindFile'] = FindFile
globals['GetBuildPath'] = GetBuildPath
globals['GetCommandHandler'] = SCons.Action.GetCommandHandler
globals['GetJobs'] = GetJobs
@@ -581,7 +541,6 @@ def BuildDefaultGlobals():
globals['Help'] = Help
globals['Import'] = Import
globals['Literal'] = SCons.Util.Literal
- globals['Local'] = Local
globals['Options'] = Options
globals['ParseConfig'] = SCons.Util.ParseConfig
globals['Platform'] = SCons.Platform.Platform
@@ -602,4 +561,25 @@ def BuildDefaultGlobals():
globals['Tool'] = SCons.Tool.Tool
globals['Value'] = SCons.Node.Python.Value
globals['WhereIs'] = SCons.Util.WhereIs
+
+ class DefaultEnvironmentCall:
+ """ """
+ def __init__(self, method_name):
+ self.method_name = method_name
+ def __call__(self, *args, **kw):
+ method = getattr(SCons.Defaults.DefaultEnvironment(),
+ self.method_name)
+ return apply(method, args, kw)
+
+ EnvironmentMethods = [
+ 'AddPostAction',
+ 'AddPreAction',
+ 'Default',
+ 'FindFile',
+ 'Local',
+ ]
+
+ for name in EnvironmentMethods:
+ globals[name] = DefaultEnvironmentCall(name)
+
return globals
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py
index 3b5c9d9..3ab4ed0 100644
--- a/src/engine/SCons/Script/__init__.py
+++ b/src/engine/SCons/Script/__init__.py
@@ -883,16 +883,16 @@ def _main(args, parser):
# or not a file, so go ahead and keep it as a default
# target and let the engine sort it out:
return 1
- default_targets = SCons.Script.SConscript.default_targets
+ default_targets = SCons.Environment.DefaultTargets
if default_targets is None:
default_targets = []
else:
default_targets = filter(check_dir, default_targets)
- SCons.Script.SConscript.default_targets = default_targets
+ SCons.Environment.DefaultTargets = default_targets
target_top = None
lookup_top = None
- targets = SCons.Script.SConscript.default_targets
+ targets = SCons.Environment.DefaultTargets
if targets is None:
targets = [SCons.Node.FS.default_fs.Dir('.')]
diff --git a/test/Default.py b/test/Default.py
index d2c438f..ae0346a 100644
--- a/test/Default.py
+++ b/test/Default.py
@@ -155,57 +155,77 @@ test.fail_test(test.read(test.workpath('eight', 'bar.out')) != "eight/bar.in\n")
-test.subdir('sub1')
+test.subdir('nine', ['nine', 'sub1'])
-test.write('SConstruct', """
+test.write(['nine', 'SConstruct'], """\
B = Builder(action = r'%s build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'xxx.out', source = 'xxx.in')
SConscript('sub1/SConscript')
""" % python)
-test.write('xxx.in', "xxx.in\n")
+test.write(['nine', 'xxx.in'], "xxx.in\n")
-test.write(['sub1', 'SConscript'], """
-B = Builder(action = r'%s build.py $TARGET $SOURCES')
+test.write(['nine', 'sub1', 'SConscript'], """
+B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'xxx.out', source = 'xxx.in')
Default('xxx.out')
""" % python)
-test.write(['sub1', 'xxx.in'], "sub1/xxx.in\n")
+test.write(['nine', 'sub1', 'xxx.in'], "sub1/xxx.in\n")
-test.run() # no arguments, use the Default
+test.run(chdir = 'nine') # no arguments, use the Default
-test.fail_test(os.path.exists(test.workpath('xxx.out')))
-test.fail_test(test.read(test.workpath('sub1', 'xxx.out')) != "sub1/xxx.in\n")
+test.fail_test(os.path.exists(test.workpath('nine', 'xxx.out')))
+test.fail_test(test.read(test.workpath('nine', 'sub1', 'xxx.out')) != "sub1/xxx.in\n")
-test.subdir('sub2')
+test.subdir('ten', ['ten', 'sub2'])
-test.write('SConstruct', """
+test.write(['ten', 'SConstruct'], """\
Default('sub2')
-B = Builder(action = r'%s build.py $TARGET $SOURCES')
+B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'xxx.out', source = 'xxx.in')
SConscript('sub2/SConscript')
""" % python)
-test.write('xxx.in', "xxx.in\n")
+test.write(['ten', 'xxx.in'], "xxx.in\n")
-test.write(['sub2', 'SConscript'], """
-B = Builder(action = r'%s build.py $TARGET $SOURCES')
+test.write(['ten', 'sub2', 'SConscript'], """
+B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
env = Environment(BUILDERS = { 'B' : B })
env.B(target = 'xxx.out', source = 'xxx.in')
""" % python)
-test.write(['sub2', 'xxx.in'], "sub2/xxx.in\n")
+test.write(['ten', 'sub2', 'xxx.in'], "sub2/xxx.in\n")
+
+test.run(chdir = 'ten') # no arguments, use the Default
+
+test.fail_test(os.path.exists(test.workpath('ten', 'xxx.out')))
+test.fail_test(test.read(test.workpath('ten', 'sub2', 'xxx.out')) != "sub2/xxx.in\n")
+
+
+test.subdir('eleven')
+
+test.write(['eleven', 'SConstruct'], """
+B = Builder(action = r'%s ../build.py $TARGET $SOURCES')
+env = Environment(BUILDERS = { 'B' : B }, XXX = 'foo.out')
+env.B(target = 'foo.out', source = 'foo.in')
+env.B(target = 'bar.out', source = 'bar.in')
+env.Default('$XXX')
+""" % python)
+
+test.write(os.path.join('eleven', 'foo.in'), "eleven/foo.in\n");
+
+test.write(os.path.join('eleven', 'bar.in'), "eleven/bar.in\n");
-test.run() # no arguments, use the Default
+test.run(chdir = 'eleven') # no arguments, use the Default
-test.fail_test(os.path.exists(test.workpath('xxx.out')))
-test.fail_test(test.read(test.workpath('sub2', 'xxx.out')) != "sub2/xxx.in\n")
+test.fail_test(test.read(test.workpath('eleven', 'foo.out')) != "eleven/foo.in\n")
+test.fail_test(os.path.exists(test.workpath('eleven', 'bar')))
diff --git a/test/FindFile.py b/test/FindFile.py
index 9c837b5..8f6cb1a 100644
--- a/test/FindFile.py
+++ b/test/FindFile.py
@@ -38,13 +38,14 @@ test.write(['bar', 'testfile1'], 'test 3\n')
test.write(['bar', 'baz', 'testfile2'], 'test 4\n')
test.write('SConstruct', """
+env = Environment(FILE = 'file', BAR = 'bar')
file1 = FindFile('testfile1', [ 'foo', '.', 'bar', 'bar/baz' ])
print open(str(file1), 'r').read()
-file2 = FindFile('testfile1', [ 'bar', 'foo', '.', 'bar/baz' ])
+file2 = env.FindFile('test${FILE}1', [ 'bar', 'foo', '.', 'bar/baz' ])
print open(str(file2), 'r').read()
file3 = FindFile('testfile2', [ 'foo', '.', 'bar', 'bar/baz' ])
print open(str(file3), 'r').read()
-file4 = FindFile('testfile2', [ 'bar/baz', 'foo', '.', 'bar' ])
+file4 = env.FindFile('testfile2', [ '$BAR/baz', 'foo', '.', 'bar' ])
print open(str(file4), 'r').read()
""")
diff --git a/test/Repository/Local.py b/test/Repository/Local.py
index 1163767..5962095 100644
--- a/test/Repository/Local.py
+++ b/test/Repository/Local.py
@@ -52,7 +52,7 @@ def copy(env, source, target):
open(target, "wb").write(open(source, "rb").read())
Build = Builder(action=copy)
-env = Environment(BUILDERS={'Build':Build})
+env = Environment(BUILDERS={'Build':Build}, BBB='bbb')
env.Build('aaa.mid', 'aaa.in')
env.Build('aaa.out', 'aaa.mid')
Local('aaa.out')
@@ -70,7 +70,7 @@ def bbb_copy(env, source, target):
Import("env")
env.Build('bbb.1', 'bbb.0')
-Local('bbb.1')
+env.Local('${BBB}.1')
env.Command('bbb.2', 'bbb.x', bbb_copy)
env.Depends('bbb.2', 'bbb.1')
""")
diff --git a/test/pre-post-actions.py b/test/pre-post-actions.py
index 91fcb3b..d5340f2 100644
--- a/test/pre-post-actions.py
+++ b/test/pre-post-actions.py
@@ -36,32 +36,22 @@ _exe = TestSCons._exe
test = TestSCons.TestSCons()
-test.write('foo.c', r"""
-#include <stdio.h>
-
-int main(void)
-{
- printf("Foo\n");
- return 0;
-}
-""")
-
test.write('SConstruct', """
import os.path
-env=Environment()
+env = Environment(XXX='bar%s')
def before(env, target, source):
f=open(str(target[0]), "wb")
f.write("Foo\\n")
f.close()
- f=open("before.txt", "wb")
- f.write("Bar\\n")
+ f=open("before.txt", "ab")
+ f.write(str(target[0]) + "\\n")
f.close()
def after(env, target, source):
fin = open(str(target[0]), "rb")
- fout = open("after%s", "wb")
+ fout = open("after_" + str(target[0]), "wb")
fout.write(fin.read())
fout.close()
fin.close()
@@ -69,12 +59,46 @@ def after(env, target, source):
foo = env.Program(source='foo.c', target='foo')
AddPreAction(foo, before)
AddPostAction('foo%s', after)
+
+bar = env.Program(source='bar.c', target='bar')
+env.AddPreAction('$XXX', before)
+env.AddPostAction('$XXX', after)
""" % (_exe, _exe))
-after_exe = test.workpath('after' + _exe)
+test.write('foo.c', r"""
+#include <stdio.h>
+
+int main(void)
+{
+ printf("foo.c\n");
+ return 0;
+}
+""")
+
+test.write('bar.c', r"""
+#include <stdio.h>
+
+int main(void)
+{
+ printf("bar.c\n");
+ return 0;
+}
+""")
+
test.run(arguments='.')
-test.fail_test(open('before.txt', 'rb').read() != "Bar\n")
-os.chmod(after_exe, os.stat(after_exe)[stat.ST_MODE] | stat.S_IXUSR)
-test.run(program=test.workpath(after_exe), stdout="Foo\n")
+
+test.run(program=test.workpath('foo'+ _exe), stdout="foo.c\n")
+test.run(program=test.workpath('bar'+ _exe), stdout="bar.c\n")
+
+test.fail_test(test.read('before.txt', 'rb') != "bar%s\nfoo%s\n" % (_exe, _exe))
+
+after_foo_exe = test.workpath('after_foo' + _exe)
+os.chmod(after_foo_exe, os.stat(after_foo_exe)[stat.ST_MODE] | stat.S_IXUSR)
+test.run(program=test.workpath(after_foo_exe), stdout="foo.c\n")
+
+after_bar_exe = test.workpath('after_bar' + _exe)
+os.chmod(after_bar_exe, os.stat(after_bar_exe)[stat.ST_MODE] | stat.S_IXUSR)
+test.run(program=test.workpath(after_bar_exe), stdout="bar.c\n")
+
test.pass_test()