summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/engine/SCons/Builder.py24
-rw-r--r--src/engine/SCons/BuilderTests.py12
-rw-r--r--src/engine/SCons/Environment.py46
-rw-r--r--src/engine/SCons/EnvironmentTests.py181
-rw-r--r--src/engine/SCons/Node/FS.py37
-rw-r--r--src/engine/SCons/Node/FSTests.py2
-rw-r--r--src/engine/SCons/Node/NodeTests.py2
-rw-r--r--src/engine/SCons/Node/__init__.py3
-rw-r--r--src/engine/SCons/SConf.py5
-rw-r--r--src/engine/SCons/Scanner/C.py5
-rw-r--r--src/engine/SCons/Scanner/CTests.py77
-rw-r--r--src/engine/SCons/Scanner/D.py5
-rw-r--r--src/engine/SCons/Scanner/Dir.py12
-rw-r--r--src/engine/SCons/Scanner/DirTests.py19
-rw-r--r--src/engine/SCons/Scanner/Fortran.py12
-rw-r--r--src/engine/SCons/Scanner/FortranTests.py100
-rw-r--r--src/engine/SCons/Scanner/IDL.py5
-rw-r--r--src/engine/SCons/Scanner/IDLTests.py85
-rw-r--r--src/engine/SCons/Scanner/Prog.py6
-rw-r--r--src/engine/SCons/Scanner/ProgTests.py18
-rw-r--r--src/engine/SCons/Scanner/ScannerTests.py25
-rw-r--r--src/engine/SCons/Scanner/__init__.py39
-rw-r--r--src/engine/SCons/Script/Main.py264
-rw-r--r--src/engine/SCons/Script/SConscript.py8
-rw-r--r--src/engine/SCons/Tool/Perforce.py2
-rw-r--r--src/engine/SCons/Tool/jar.py2
-rw-r--r--src/engine/SCons/Tool/javac.py4
-rw-r--r--src/engine/SCons/Tool/javah.py6
-rw-r--r--src/engine/SCons/Tool/msvs.py6
-rw-r--r--src/engine/SCons/Tool/qt.py5
-rw-r--r--src/engine/SCons/Tool/rmic.py6
-rw-r--r--src/engine/SCons/Tool/tar.py2
-rw-r--r--src/engine/SCons/Tool/zip.py2
33 files changed, 546 insertions, 481 deletions
diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py
index 7069ef0..ec78d89 100644
--- a/src/engine/SCons/Builder.py
+++ b/src/engine/SCons/Builder.py
@@ -342,7 +342,7 @@ def _init_nodes(builder, env, overrides, executor_kw, tlist, slist):
# Now set up the relevant information in the target Nodes themselves.
for t in tlist:
- t.cwd = SCons.Node.FS.default_fs.getcwd()
+ t.cwd = env.fs.getcwd()
t.builder_set(builder)
t.env_set(env)
t.add_source(slist)
@@ -390,8 +390,8 @@ class BuilderBase:
prefix = '',
suffix = '',
src_suffix = '',
- target_factory = SCons.Node.FS.default_fs.File,
- source_factory = SCons.Node.FS.default_fs.File,
+ target_factory = None,
+ source_factory = None,
target_scanner = None,
source_scanner = None,
emitter = None,
@@ -498,8 +498,11 @@ class BuilderBase:
src_suf = self.get_src_suffix(env)
+ target_factory = env.get_factory(self.target_factory)
+ source_factory = env.get_factory(self.source_factory)
+
source = _adjustixes(source, None, src_suf)
- slist = env.arg2nodes(source, self.source_factory)
+ slist = env.arg2nodes(source, source_factory)
pre = self.get_prefix(env, slist)
suf = self.get_suffix(env, slist)
@@ -516,7 +519,7 @@ class BuilderBase:
tlist = [ t_from_s(pre, suf, splitext) ]
else:
target = _adjustixes(target, pre, suf)
- tlist = env.arg2nodes(target, self.target_factory)
+ tlist = env.arg2nodes(target, target_factory)
if self.emitter:
# The emitter is going to do str(node), but because we're
@@ -543,8 +546,8 @@ class BuilderBase:
# Have to call arg2nodes yet again, since it is legal for
# emitters to spit out strings as well as Node instances.
- slist = env.arg2nodes(source, self.source_factory)
- tlist = env.arg2nodes(target, self.target_factory)
+ slist = env.arg2nodes(source, source_factory)
+ tlist = env.arg2nodes(target, target_factory)
return tlist, slist
@@ -693,8 +696,8 @@ class MultiStepBuilder(BuilderBase):
prefix = '',
suffix = '',
src_suffix = '',
- target_factory = SCons.Node.FS.default_fs.File,
- source_factory = SCons.Node.FS.default_fs.File,
+ target_factory = None,
+ source_factory = None,
target_scanner = None,
source_scanner = None,
emitter=None,
@@ -723,7 +726,8 @@ class MultiStepBuilder(BuilderBase):
def _execute(self, env, target, source, overwarn={}, executor_kw={}):
# We now assume that target and source are lists or None.
- slist = env.arg2nodes(source, self.source_factory)
+ source_factory = env.get_factory(self.source_factory)
+ slist = env.arg2nodes(source, source_factory)
final_sources = []
sdict = self._get_sdict(env)
diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py
index 09927f1..fbf79f4 100644
--- a/src/engine/SCons/BuilderTests.py
+++ b/src/engine/SCons/BuilderTests.py
@@ -55,6 +55,9 @@ test = TestCmd.TestCmd(workdir = '')
outfile = test.workpath('outfile')
outfile2 = test.workpath('outfile2')
+infile = test.workpath('infile')
+test.write(infile, "infile\n")
+
show_string = None
scons_env = SCons.Environment.Environment()
@@ -72,6 +75,7 @@ class Environment:
global env_arg2nodes_called
env_arg2nodes_called = None
self.scanner = None
+ self.fs = SCons.Node.FS.FS()
def subst(self, s):
if not SCons.Util.is_String(s):
return s
@@ -102,6 +106,8 @@ class Environment:
a = factory(a)
list.append(a)
return list
+ def get_factory(self, factory):
+ return factory or self.fs.File
def get_scanner(self, ext):
return self.scanner
def Dictionary(self):
@@ -552,7 +558,7 @@ class BuilderTestCase(unittest.TestCase):
suffix='.c')
tgt = b8(env, target=None, source='foo_source.a')
assert str(tgt[0]) == 'foo_obj.c', str(tgt[0])
- src = SCons.Node.FS.default_fs.File('foo_source.a')
+ src = env.fs.File('foo_source.a')
tgt = b8(env, target=None, source=src)
assert str(tgt[0]) == 'foo_obj.c', str(tgt[0])
@@ -674,7 +680,7 @@ class BuilderTestCase(unittest.TestCase):
tgts = builder(env, source=[])
assert tgts == [], tgts
- tgts = builder(env, target = [outfile, outfile2], source = 'foo')
+ tgts = builder(env, target = [outfile, outfile2], source = infile)
for t in tgts:
t.prepare()
try:
@@ -698,7 +704,7 @@ class BuilderTestCase(unittest.TestCase):
return 1
builder = SCons.Builder.Builder(action = function3)
- tgts = builder(env, target = [sub1_out, sub2_out], source = 'foo')
+ tgts = builder(env, target = [sub1_out, sub2_out], source = infile)
for t in tgts:
t.prepare()
try:
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index 77ce3c2..b813cf1 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -94,7 +94,7 @@ def alias_builder(env, target, source):
AliasBuilder = SCons.Builder.Builder(action = alias_builder,
target_factory = SCons.Node.Alias.default_ans.Alias,
- source_factory = SCons.Node.FS.default_fs.Entry,
+ source_factory = SCons.Node.FS.Entry,
multi = 1,
is_explicit = None,
name='AliasBuilder')
@@ -250,7 +250,7 @@ class SubstitutionEnvironment:
"""Initialization of an underlying SubstitutionEnvironment class.
"""
if __debug__: logInstanceCreation(self, 'Environment.SubstitutionEnvironment')
- self.fs = SCons.Node.FS.default_fs
+ self.fs = SCons.Node.FS.default_fs or SCons.Node.FS.FS()
self.ans = SCons.Node.Alias.default_ans
self.lookup_list = SCons.Node.arg2nodes_lookups
self._dict = kw.copy()
@@ -483,7 +483,7 @@ class Base(SubstitutionEnvironment):
with the much simpler base class initialization.
"""
if __debug__: logInstanceCreation(self, 'Environment.Base')
- self.fs = SCons.Node.FS.default_fs
+ self.fs = SCons.Node.FS.default_fs or SCons.Node.FS.FS()
self.ans = SCons.Node.Alias.default_ans
self.lookup_list = SCons.Node.arg2nodes_lookups
self._dict = our_deepcopy(SCons.Defaults.ConstructionEnvironment)
@@ -529,6 +529,14 @@ class Base(SubstitutionEnvironment):
# These begin with lower-case letters.
#######################################################################
+ def get_builder(self, name):
+ """Fetch the builder with the specified name from the environment.
+ """
+ try:
+ return self._dict['BUILDERS'][name]
+ except KeyError:
+ return None
+
def get_calculator(self):
"__cacheable__"
try:
@@ -541,13 +549,35 @@ class Base(SubstitutionEnvironment):
c = SCons.Defaults.DefaultEnvironment().get_calculator()
return c
- def get_builder(self, name):
- """Fetch the builder with the specified name from the environment.
+ def get_factory(self, factory, default='File'):
+ """Return a factory function for creating Nodes for this
+ construction environment.
+ __cacheable__
"""
+ name = default
try:
- return self._dict['BUILDERS'][name]
- except KeyError:
- return None
+ is_node = issubclass(factory, SCons.Node.Node)
+ except TypeError:
+ # The specified factory isn't a Node itself--it's
+ # most likely None, or possibly a callable.
+ pass
+ else:
+ if is_node:
+ # The specified factory is a Node (sub)class. Try to
+ # return the FS method that corresponds to the Node's
+ # name--that is, we return self.fs.Dir if they want a Dir,
+ # self.fs.File for a File, etc.
+ try: name = factory.__name__
+ except AttributeError: pass
+ else: factory = None
+ if not factory:
+ # They passed us None, or we picked up a name from a specified
+ # class, so return the FS method. (Note that we *don't*
+ # use our own self.{Dir,File} methods because that would
+ # cause env.subst() to be called twice on the file name,
+ # interfering with files that have $$ in them.)
+ factory = getattr(self.fs, name)
+ return factory
def _gsm(self):
"__cacheable__"
diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py
index a508529..6b4bc60 100644
--- a/src/engine/SCons/EnvironmentTests.py
+++ b/src/engine/SCons/EnvironmentTests.py
@@ -794,128 +794,81 @@ class BaseTestCase(unittest.TestCase):
def test_autogenerate(dict):
"""Test autogenerating variables in a dictionary."""
- def RDirs(pathlist):
- return SCons.Node.FS.default_fs.Rsearchall(pathlist,
- clazz=SCons.Node.FS.Dir,
- must_exist=0,
- cwd=SCons.Node.FS.default_fs.Dir('xx'))
-
env = Environment(LIBS = [ 'foo', 'bar', 'baz' ],
LIBLINKPREFIX = 'foo',
- LIBLINKSUFFIX = 'bar',
- RDirs=RDirs)
+ LIBLINKSUFFIX = 'bar')
+
+ def RDirs(pathlist, fs=env.fs):
+ return fs.Rsearchall(pathlist,
+ clazz=SCons.Node.FS.Dir,
+ must_exist=0,
+ cwd=fs.Dir('xx'))
+
+ env['RDirs'] = RDirs
flags = env.subst_list('$_LIBFLAGS', 1)[0]
- assert len(flags) == 3, flags
- assert flags[0] == 'foobar', \
- flags[0]
- assert flags[1] == 'foobar', \
- flags[1]
- assert flags[2] == 'foobazbar', \
- flags[2]
-
- blat = SCons.Node.FS.default_fs.Dir('blat')
-
- env = Environment(CPPPATH = [ 'foo', '$FOO/bar', blat ],
- INCPREFIX = 'foo ',
- INCSUFFIX = 'bar',
- FOO = 'baz',
- RDirs=RDirs)
+ assert flags == ['foobar', 'foobar', 'foobazbar'], flags
+
+ blat = env.fs.Dir('blat')
+
+ env.Replace(CPPPATH = [ 'foo', '$FOO/bar', blat ],
+ INCPREFIX = 'foo ',
+ INCSUFFIX = 'bar',
+ FOO = 'baz')
flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
- assert len(flags) == 8, flags
- assert flags[0] == '$(', \
- flags[0]
- assert flags[1] == os.path.normpath('foo'), \
- flags[1]
- assert flags[2] == os.path.normpath('xx/foobar'), \
- flags[2]
- assert flags[3] == os.path.normpath('foo'), \
- flags[3]
- assert flags[4] == os.path.normpath('xx/baz/bar'), \
- flags[4]
- assert flags[5] == os.path.normpath('foo'), \
- flags[5]
- assert flags[6] == os.path.normpath('blatbar'), \
- flags[6]
- assert flags[7] == '$)', \
- flags[7]
-
- env = Environment(F77PATH = [ 'foo', '$FOO/bar', blat ],
- INCPREFIX = 'foo ',
- INCSUFFIX = 'bar',
- FOO = 'baz',
- RDirs=RDirs)
+ expect = [ '$(',
+ os.path.normpath('foo'),
+ os.path.normpath('xx/foobar'),
+ os.path.normpath('foo'),
+ os.path.normpath('xx/baz/bar'),
+ os.path.normpath('foo'),
+ os.path.normpath('blatbar'),
+ '$)',
+ ]
+ assert flags == expect, flags
+
+ env.Replace(F77PATH = [ 'foo', '$FOO/bar', blat ],
+ INCPREFIX = 'foo ',
+ INCSUFFIX = 'bar',
+ FOO = 'baz')
flags = env.subst_list('$_F77INCFLAGS', 1)[0]
- assert len(flags) == 8, flags
- assert flags[0] == '$(', \
- flags[0]
- assert flags[1] == os.path.normpath('foo'), \
- flags[1]
- assert flags[2] == os.path.normpath('xx/foobar'), \
- flags[2]
- assert flags[3] == os.path.normpath('foo'), \
- flags[3]
- assert flags[4] == os.path.normpath('xx/baz/bar'), \
- flags[4]
- assert flags[5] == os.path.normpath('foo'), \
- flags[5]
- assert flags[6] == os.path.normpath('blatbar'), \
- flags[6]
- assert flags[7] == '$)', \
- flags[7]
-
- env = Environment(CPPPATH = '', F77PATH = '', LIBPATH = '',
- RDirs=RDirs)
+ expect = [ '$(',
+ os.path.normpath('foo'),
+ os.path.normpath('xx/foobar'),
+ os.path.normpath('foo'),
+ os.path.normpath('xx/baz/bar'),
+ os.path.normpath('foo'),
+ os.path.normpath('blatbar'),
+ '$)',
+ ]
+ assert flags == expect, flags
+
+ env.Replace(CPPPATH = '', F77PATH = '', LIBPATH = '')
l = env.subst_list('$_CPPINCFLAGS')
- assert len(l[0]) == 0, l[0]
+ assert l == [[]], l
l = env.subst_list('$_F77INCFLAGS')
- assert len(l[0]) == 0, l[0]
+ assert l == [[]], l
l = env.subst_list('$_LIBDIRFLAGS')
- assert len(l[0]) == 0, l[0]
-
- SCons.Node.FS.default_fs.Repository('/rep1')
- SCons.Node.FS.default_fs.Repository('/rep2')
- env = Environment(CPPPATH = [ 'foo', '/a/b', '$FOO/bar', blat],
- INCPREFIX = '-I ',
- INCSUFFIX = 'XXX',
- FOO = 'baz',
- RDirs=RDirs)
+ assert l == [[]], l
+
+ env.fs.Repository('/rep1')
+ env.fs.Repository('/rep2')
+ env.Replace(CPPPATH = [ 'foo', '/a/b', '$FOO/bar', blat],
+ INCPREFIX = '-I ',
+ INCSUFFIX = 'XXX',
+ FOO = 'baz')
flags = env.subst_list('$_CPPINCFLAGS', 1)[0]
- assert flags[0] == '$(', \
- flags[0]
- assert flags[1] == '-I', \
- flags[1]
- assert flags[2] == os.path.normpath('xx/fooXXX'), \
- flags[2]
- assert flags[3] == '-I', \
- flags[3]
- assert flags[4] == os.path.normpath('/rep1/xx/fooXXX'), \
- flags[4]
- assert flags[5] == '-I', \
- flags[5]
- assert flags[6] == os.path.normpath('/rep2/xx/fooXXX'), \
- flags[6]
- assert flags[7] == '-I', \
- flags[7]
- assert flags[8] == os.path.normpath('/a/bXXX'), \
- flags[8]
- assert flags[9] == '-I', \
- flags[9]
- assert flags[10] == os.path.normpath('xx/baz/barXXX'), \
- flags[10]
- assert flags[11] == '-I', \
- flags[11]
- assert flags[12] == os.path.normpath('/rep1/xx/baz/barXXX'), \
- flags[12]
- assert flags[13] == '-I', \
- flags[13]
- assert flags[14] == os.path.normpath('/rep2/xx/baz/barXXX'), \
- flags[14]
- assert flags[15] == '-I', \
- flags[15]
- assert flags[16] == os.path.normpath('blatXXX'), \
- flags[16]
- assert flags[17] == '$)', \
- flags[17]
+ expect = [ '$(',
+ '-I', os.path.normpath('xx/fooXXX'),
+ '-I', os.path.normpath('/rep1/xx/fooXXX'),
+ '-I', os.path.normpath('/rep2/xx/fooXXX'),
+ '-I', os.path.normpath('/a/bXXX'),
+ '-I', os.path.normpath('xx/baz/barXXX'),
+ '-I', os.path.normpath('/rep1/xx/baz/barXXX'),
+ '-I', os.path.normpath('/rep2/xx/baz/barXXX'),
+ '-I', os.path.normpath('blatXXX'),
+ '$)'
+ ]
+ assert flags == expect, flags
def test_platform(self):
"""Test specifying a platform callable when instantiating."""
@@ -2189,7 +2142,7 @@ def generate(env):
assert 'foo1.in' in map(lambda x: x.path, t.sources)
assert 'foo2.in' in map(lambda x: x.path, t.sources)
- sub = SCons.Node.FS.default_fs.Dir('sub')
+ sub = env.fs.Dir('sub')
t = env.Command(target='bar.out', source='sub',
action='buildbar $target $source')[0]
assert 'sub' in map(lambda x: x.path, t.sources)
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index fe014f8..90bc70a 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -5,9 +5,8 @@ File system nodes.
These Nodes represent the canonical external objects that people think
of when they think of building software: files and directories.
-This initializes a "default_fs" Node with an FS at the current directory
-for its own purposes, and for use by scripts or modules looking for the
-canonical default.
+This holds a "default_fs" variable that should be initialized with an FS
+that can be used by scripts or modules looking for the canonical default.
"""
@@ -759,20 +758,20 @@ class FS(LocalFS):
The path argument must be a valid absolute path.
"""
if __debug__: logInstanceCreation(self, 'Node.FS')
- self.Top = None
- if path == None:
- self.pathTop = os.getcwd()
- else:
- self.pathTop = path
self.Root = {}
self.SConstruct_dir = None
self.CachePath = None
self.cache_force = None
self.cache_show = None
- def set_toplevel_dir(self, path):
- assert not self.Top, "You can only set the top-level path on an FS object that has not had its File, Dir, or Entry methods called yet."
- self.pathTop = path
+ if path is None:
+ self.pathTop = os.getcwd()
+ else:
+ self.pathTop = path
+
+ self.Top = self._doLookup(Dir, os.path.normpath(self.pathTop))
+ self.Top.path = '.'
+ self._cwd = self.Top
def clear_cache(self):
"__cache_reset__"
@@ -780,15 +779,8 @@ class FS(LocalFS):
def set_SConstruct_dir(self, dir):
self.SConstruct_dir = dir
-
- def __setTopLevelDir(self):
- if not self.Top:
- self.Top = self._doLookup(Dir, os.path.normpath(self.pathTop))
- self.Top.path = '.'
- self._cwd = self.Top
-
+
def getcwd(self):
- self.__setTopLevelDir()
return self._cwd
def __checkClass(self, node, klass):
@@ -912,7 +904,6 @@ class FS(LocalFS):
If directory is None, and name is a relative path,
then the same applies.
"""
- self.__setTopLevelDir()
if name and name[0] == '#':
directory = self.Top
name = name[1:]
@@ -930,7 +921,6 @@ class FS(LocalFS):
If change_os_dir is true, we will also change the "real" cwd
to match.
"""
- self.__setTopLevelDir()
curr=self._cwd
try:
if not dir is None:
@@ -990,7 +980,6 @@ class FS(LocalFS):
"""Link the supplied build directory to the source directory
for purposes of building files."""
- self.__setTopLevelDir()
if not isinstance(src_dir, SCons.Node.Node):
src_dir = self.Dir(src_dir)
if not isinstance(build_dir, SCons.Node.Node):
@@ -1010,7 +999,6 @@ class FS(LocalFS):
for d in dirs:
if not isinstance(d, SCons.Node.Node):
d = self.Dir(d)
- self.__setTopLevelDir()
self.Top.addRepository(d)
def do_Rsearch(self, path, dir, func, clazz=_classEntry):
@@ -1150,7 +1138,6 @@ class FS(LocalFS):
message = fmt % string.join(map(str, targets))
return targets, message
-
class Dir(Base):
"""A class for directories in a file system.
"""
@@ -1914,7 +1901,7 @@ class File(Base):
File, this is a TypeError..."""
raise TypeError, "Tried to lookup File '%s' as a Dir." % self.path
-default_fs = FS()
+default_fs = None
def find_file(filename, paths, verbose=None):
"""
diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py
index 94e9790..e2c787e 100644
--- a/src/engine/SCons/Node/FSTests.py
+++ b/src/engine/SCons/Node/FSTests.py
@@ -972,7 +972,7 @@ class FSTestCase(_tempdirTestCase):
# the reading of files in text mode. This tests that
# get_contents() returns the binary contents.
test.write("binary_file", "Foo\x1aBar")
- f1 = SCons.Node.FS.default_fs.File(test.workpath("binary_file"))
+ f1 = fs.File(test.workpath("binary_file"))
assert f1.get_contents() == "Foo\x1aBar", f1.get_contents()
def nonexistent(method, s):
diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py
index 5f03377..67ac05f 100644
--- a/src/engine/SCons/Node/NodeTests.py
+++ b/src/engine/SCons/Node/NodeTests.py
@@ -141,6 +141,8 @@ class Environment:
self._dict.update(dict)
def get_calculator(self):
return SCons.Sig.default_calc
+ def get_factory(self, factory):
+ return factory or MyNode
def get_scanner(self, scanner_key):
return self._dict['SCANNERS'][0]
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index db80985..bc10e21 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -424,7 +424,8 @@ class Node:
here is a significant performance boost.
__cacheable__
"""
- return self.builder.source_factory(path)
+ env = self.get_build_env()
+ return env.get_factory(self.builder.source_factory)(path)
def get_scanner(self, env, kw={}):
return env.get_scanner(self.scanner_key())
diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py
index 7bd9c1a..b89ca4a 100644
--- a/src/engine/SCons/SConf.py
+++ b/src/engine/SCons/SConf.py
@@ -76,7 +76,7 @@ def SetProgressDisplay(display):
global progress_display
progress_display = display
-SConfFS=SCons.Node.FS.default_fs
+SConfFS = None
_ac_build_counter = 0 # incremented, whenever TryBuild is called
_ac_config_logs = {} # all config.log files created in this build
@@ -338,7 +338,8 @@ class SConf:
"""
global SConfFS
if not SConfFS:
- SConfFS = SCons.Node.FS.FS(SCons.Node.FS.default_fs.pathTop)
+ SConfFS = SCons.Node.FS.default_fs or \
+ SCons.Node.FS.FS(env.fs.pathTop)
if not sconf_global is None:
raise (SCons.Errors.UserError,
"Only one SConf object may be active at one time")
diff --git a/src/engine/SCons/Scanner/C.py b/src/engine/SCons/Scanner/C.py
index 62a6842..276570e 100644
--- a/src/engine/SCons/Scanner/C.py
+++ b/src/engine/SCons/Scanner/C.py
@@ -32,12 +32,11 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import SCons.Node.FS
import SCons.Scanner
-def CScanner(fs = SCons.Node.FS.default_fs):
+def CScanner():
"""Return a prototype Scanner instance for scanning source files
that use the C pre-processor"""
cs = SCons.Scanner.ClassicCPP("CScanner",
"$CPPSUFFIXES",
"CPPPATH",
- '^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")',
- fs = fs)
+ '^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")')
return cs
diff --git a/src/engine/SCons/Scanner/CTests.py b/src/engine/SCons/Scanner/CTests.py
index fd17ee1..138b788 100644
--- a/src/engine/SCons/Scanner/CTests.py
+++ b/src/engine/SCons/Scanner/CTests.py
@@ -174,6 +174,7 @@ class DummyEnvironment(UserDict.UserDict):
def __init__(self, **kw):
UserDict.UserDict.__init__(self)
self.data.update(kw)
+ self.fs = SCons.Node.FS.FS(test.workpath(''))
def Dictionary(self, *args):
return self.data
@@ -196,6 +197,15 @@ class DummyEnvironment(UserDict.UserDict):
def get_calculator(self):
return None
+ def get_factory(self, factory):
+ return factory or self.fs.File
+
+ def Dir(self, filename):
+ return self.fs.Dir(test.workpath(filename))
+
+ def File(self, filename):
+ return self.fs.File(test.workpath(filename))
+
if os.path.normcase('foo') == os.path.normcase('FOO'):
my_normpath = os.path.normcase
else:
@@ -207,9 +217,6 @@ def deps_match(self, deps, headers):
expect = map(my_normpath, headers)
self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
-def make_node(filename, fs=SCons.Node.FS.default_fs):
- return fs.File(test.workpath(filename))
-
# define some tests:
class CScannerTestCase1(unittest.TestCase):
@@ -217,36 +224,36 @@ class CScannerTestCase1(unittest.TestCase):
env = DummyEnvironment(CPPPATH=[])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
- deps = s(make_node('f1.cpp'), env, path)
+ deps = s(env.File('f1.cpp'), env, path)
headers = ['f1.h', 'f2.h']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class CScannerTestCase2(unittest.TestCase):
def runTest(self):
env = DummyEnvironment(CPPPATH=[test.workpath("d1")])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
- deps = s(make_node('f1.cpp'), env, path)
+ deps = s(env.File('f1.cpp'), env, path)
headers = ['f1.h', 'd1/f2.h']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class CScannerTestCase3(unittest.TestCase):
def runTest(self):
env = DummyEnvironment(CPPPATH=[test.workpath("d1")])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
- deps = s(make_node('f2.cpp'), env, path)
+ deps = s(env.File('f2.cpp'), env, path)
headers = ['d1/f1.h', 'f1.h', 'd1/d2/f1.h']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class CScannerTestCase4(unittest.TestCase):
def runTest(self):
env = DummyEnvironment(CPPPATH=[test.workpath("d1"), test.workpath("d1/d2")])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
- deps = s(make_node('f2.cpp'), env, path)
+ deps = s(env.File('f2.cpp'), env, path)
headers = ['d1/f1.h', 'f1.h', 'd1/d2/f1.h', 'd1/d2/f4.h']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class CScannerTestCase5(unittest.TestCase):
def runTest(self):
@@ -254,7 +261,7 @@ class CScannerTestCase5(unittest.TestCase):
s = SCons.Scanner.C.CScanner()
path = s.path(env)
- n = make_node('f3.cpp')
+ n = env.File('f3.cpp')
def my_rexists(s=n):
s.rexists_called = 1
return s.old_rexists()
@@ -269,7 +276,7 @@ class CScannerTestCase5(unittest.TestCase):
headers = ['f1.h', 'f2.h', 'f3-test.h',
'd1/f1.h', 'd1/f2.h', 'd1/f3-test.h']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class CScannerTestCase6(unittest.TestCase):
def runTest(self):
@@ -278,25 +285,24 @@ class CScannerTestCase6(unittest.TestCase):
s = SCons.Scanner.C.CScanner()
path1 = s.path(env1)
path2 = s.path(env2)
- deps1 = s(make_node('f1.cpp'), env1, path1)
- deps2 = s(make_node('f1.cpp'), env2, path2)
+ deps1 = s(env1.File('f1.cpp'), env1, path1)
+ deps2 = s(env2.File('f1.cpp'), env2, path2)
headers1 = ['f1.h', 'd1/f2.h']
headers2 = ['f1.h', 'd1/d2/f2.h']
- deps_match(self, deps1, map(test.workpath, headers1))
- deps_match(self, deps2, map(test.workpath, headers2))
+ deps_match(self, deps1, headers1)
+ deps_match(self, deps2, headers2)
class CScannerTestCase8(unittest.TestCase):
def runTest(self):
- fs = SCons.Node.FS.FS(test.workpath(''))
env = DummyEnvironment(CPPPATH=["include"])
- s = SCons.Scanner.C.CScanner(fs = fs)
+ s = SCons.Scanner.C.CScanner()
path = s.path(env)
- deps1 = s(fs.File('fa.cpp'), env, path)
- fs.chdir(fs.Dir('subdir'))
- dir = fs.getcwd()
- fs.chdir(fs.Dir('..'))
+ deps1 = s(env.File('fa.cpp'), env, path)
+ env.fs.chdir(env.Dir('subdir'))
+ dir = env.fs.getcwd()
+ env.fs.chdir(env.Dir(''))
path = s.path(env, dir)
- deps2 = s(fs.File('#fa.cpp'), env, path)
+ deps2 = s(env.File('#fa.cpp'), env, path)
headers1 = ['include/fa.h', 'include/fb.h']
headers2 = ['subdir/include/fa.h', 'subdir/include/fb.h']
deps_match(self, deps1, headers1)
@@ -315,7 +321,8 @@ class CScannerTestCase9(unittest.TestCase):
test.write('fa.h','\n')
fs = SCons.Node.FS.FS(test.workpath(''))
env = DummyEnvironment(CPPPATH=[])
- s = SCons.Scanner.C.CScanner(fs=fs)
+ env.fs = fs
+ s = SCons.Scanner.C.CScanner()
path = s.path(env)
deps = s(fs.File('fa.cpp'), env, path)
@@ -330,7 +337,8 @@ class CScannerTestCase10(unittest.TestCase):
fs = SCons.Node.FS.FS(test.workpath(''))
fs.chdir(fs.Dir('include'))
env = DummyEnvironment(CPPPATH=[])
- s = SCons.Scanner.C.CScanner(fs=fs)
+ env.fs = fs
+ s = SCons.Scanner.C.CScanner()
path = s.path(env)
test.write('include/fa.cpp', test.read('fa.cpp'))
fs.chdir(fs.Dir('..'))
@@ -349,10 +357,12 @@ class CScannerTestCase11(unittest.TestCase):
f1=fs.File('include2/jjj.h')
f1.builder=1
env = DummyEnvironment(CPPPATH=['include', 'include2'])
- s = SCons.Scanner.C.CScanner(fs=fs)
+ env.fs = fs
+ s = SCons.Scanner.C.CScanner()
path = s.path(env)
deps = s(fs.File('src/fff.c'), env, path)
- deps_match(self, deps, [ test.workpath('repository/include/iii.h'), 'include2/jjj.h' ])
+ deps_match(self, deps, [ test.workpath('repository/include/iii.h'),
+ 'include2/jjj.h' ])
os.chdir(test.workpath(''))
class CScannerTestCase12(unittest.TestCase):
@@ -363,7 +373,8 @@ class CScannerTestCase12(unittest.TestCase):
fs.BuildDir('build2', 'src', 0)
fs.Repository(test.workpath('repository'))
env = DummyEnvironment(CPPPATH=[])
- s = SCons.Scanner.C.CScanner(fs = fs)
+ env.fs = fs
+ s = SCons.Scanner.C.CScanner()
path = s.path(env)
deps1 = s(fs.File('build1/aaa.c'), env, path)
deps_match(self, deps1, [ 'build1/bbb.h' ])
@@ -383,18 +394,18 @@ class CScannerTestCase13(unittest.TestCase):
env = SubstEnvironment(CPPPATH=["blah"])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
- deps = s(make_node('f1.cpp'), env, path)
+ deps = s(env.File('f1.cpp'), env, path)
headers = ['f1.h', 'd1/f2.h']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class CScannerTestCase14(unittest.TestCase):
def runTest(self):
env = DummyEnvironment(CPPPATH=[])
s = SCons.Scanner.C.CScanner()
path = s.path(env)
- deps = s(make_node('f5.c'), env, path)
+ deps = s(env.File('f5.c'), env, path)
headers = ['f5a.h', 'f5b.h']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class CScannerTestCase15(unittest.TestCase):
def runTest(self):
diff --git a/src/engine/SCons/Scanner/D.py b/src/engine/SCons/Scanner/D.py
index cd93a69..2ea2614 100644
--- a/src/engine/SCons/Scanner/D.py
+++ b/src/engine/SCons/Scanner/D.py
@@ -36,13 +36,12 @@ import string
import SCons.Scanner
-def DScanner(fs = SCons.Node.FS.default_fs):
+def DScanner():
"""Return a prototype Scanner instance for scanning D source files"""
ds = D(name = "DScanner",
suffixes = '$DSUFFIXES',
path_variable = 'DPATH',
- regex = 'import\s+([^\;]*)\;',
- fs = fs)
+ regex = 'import\s+([^\;]*)\;')
return ds
class D(SCons.Scanner.Classic):
diff --git a/src/engine/SCons/Scanner/Dir.py b/src/engine/SCons/Scanner/Dir.py
index 6161059..ae20749 100644
--- a/src/engine/SCons/Scanner/Dir.py
+++ b/src/engine/SCons/Scanner/Dir.py
@@ -28,14 +28,16 @@ import string
import SCons.Node.FS
import SCons.Scanner
-def DirScanner(fs = SCons.Node.FS.default_fs, **kw):
+def DirScanner(**kw):
"""Return a prototype Scanner instance for scanning
directories for on-disk files"""
- def only_dirs(nodes, fs=fs):
- return filter(lambda n: isinstance(n.disambiguate(), SCons.Node.FS.Dir), nodes)
- kw['node_factory'] = fs.Entry
+ def only_dirs(nodes):
+ return filter(lambda n: isinstance(n.disambiguate(),
+ SCons.Node.FS.Dir),
+ nodes)
+ kw['node_factory'] = SCons.Node.FS.Entry
kw['recursive'] = only_dirs
- ds = apply(SCons.Scanner.Base, [scan, "DirScanner"], kw)
+ ds = apply(SCons.Scanner.Base, (scan, "DirScanner"), kw)
return ds
skip_entry = {
diff --git a/src/engine/SCons/Scanner/DirTests.py b/src/engine/SCons/Scanner/DirTests.py
index e735ca2..257e76b 100644
--- a/src/engine/SCons/Scanner/DirTests.py
+++ b/src/engine/SCons/Scanner/DirTests.py
@@ -47,24 +47,35 @@ test.write(['dir', 'sub', '.sconsign'], "dir/.sconsign\n")
test.write(['dir', 'sub', '.sconsign.dblite'], "dir/.sconsign.dblite\n")
class DummyNode:
- def __init__(self, name):
+ def __init__(self, name, fs):
self.name = name
self.abspath = test.workpath(name)
- self.fs = SCons.Node.FS.default_fs
+ self.fs = fs
def __str__(self):
return self.name
def Entry(self, name):
return self.fs.Entry(name)
+class DummyEnvironment:
+ def __init__(self):
+ self.fs = SCons.Node.FS.FS()
+ def Entry(self, name):
+ node = DummyNode(name, self.fs)
+ return node
+ def get_factory(self, factory):
+ return factory or self.fs.Entry
+
class DirScannerTestCase1(unittest.TestCase):
def runTest(self):
+ env = DummyEnvironment()
+
s = SCons.Scanner.Dir.DirScanner()
- deps = s(DummyNode('dir'), {}, ())
+ deps = s(env.Entry('dir'), env, ())
sss = map(str, deps)
assert sss == ['f1', 'f2', 'sub'], sss
- deps = s(DummyNode('dir/sub'), {}, ())
+ deps = s(env.Entry('dir/sub'), env, ())
sss = map(str, deps)
assert sss == ['f3', 'f4'], sss
diff --git a/src/engine/SCons/Scanner/Fortran.py b/src/engine/SCons/Scanner/Fortran.py
index 4da0914..66bec0c 100644
--- a/src/engine/SCons/Scanner/Fortran.py
+++ b/src/engine/SCons/Scanner/Fortran.py
@@ -55,13 +55,12 @@ class F90Scanner(SCons.Scanner.Classic):
"""
def __init__(self, name, suffixes, path_variable, use_regex,
- incl_regex, fs=SCons.Node.FS.default_fs, *args, **kw):
+ incl_regex, *args, **kw):
self.cre_use = re.compile(use_regex, re.M)
self.cre_incl = re.compile(incl_regex, re.M)
- self.fs = fs
- def _scan(node, env, path, self=self, fs=fs):
+ def _scan(node, env, path, self=self):
node = node.rfile()
if not node.exists():
@@ -70,7 +69,7 @@ class F90Scanner(SCons.Scanner.Classic):
return self.scan(node, env, path)
kw['function'] = _scan
- kw['path_function'] = SCons.Scanner.FindPathDirs(path_variable, fs)
+ kw['path_function'] = SCons.Scanner.FindPathDirs(path_variable)
kw['recursive'] = 1
kw['skeys'] = suffixes
kw['name'] = name
@@ -117,7 +116,7 @@ class F90Scanner(SCons.Scanner.Classic):
nodes = map(lambda pair: pair[1], nodes)
return nodes
-def FortranScan(path_variable="FORTRANPATH", fs=SCons.Node.FS.default_fs):
+def FortranScan(path_variable="FORTRANPATH"):
"""Return a prototype Scanner instance for scanning source files
for Fortran USE & INCLUDE statements"""
@@ -275,6 +274,5 @@ def FortranScan(path_variable="FORTRANPATH", fs=SCons.Node.FS.default_fs):
"$FORTRANSUFFIXES",
path_variable,
use_regex,
- include_regex,
- fs = fs)
+ include_regex)
return scanner
diff --git a/src/engine/SCons/Scanner/FortranTests.py b/src/engine/SCons/Scanner/FortranTests.py
index 4c82522..141f375 100644
--- a/src/engine/SCons/Scanner/FortranTests.py
+++ b/src/engine/SCons/Scanner/FortranTests.py
@@ -210,6 +210,7 @@ test.write(['modules', 'use.mod'], "\n")
class DummyEnvironment:
def __init__(self, listCppPath):
self.path = listCppPath
+ self.fs = SCons.Node.FS.FS(test.workpath(''))
def Dictionary(self, *args):
if not args:
@@ -244,14 +245,20 @@ class DummyEnvironment:
def get_calculator(self):
return None
+ def get_factory(self, factory):
+ return factory or self.fs.File
+
+ def Dir(self, filename):
+ return self.fs.Dir(test.workpath(filename))
+
+ def File(self, filename):
+ return self.fs.File(test.workpath(filename))
+
def deps_match(self, deps, headers):
scanned = map(os.path.normpath, map(str, deps))
expect = map(os.path.normpath, headers)
self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
-def make_node(filename, fs=SCons.Node.FS.default_fs):
- return fs.File(test.workpath(filename))
-
# define some tests:
class FortranScannerTestCase1(unittest.TestCase):
@@ -261,10 +268,9 @@ class FortranScannerTestCase1(unittest.TestCase):
env = DummyEnvironment([])
s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- fs = SCons.Node.FS.FS(original)
- deps = s(make_node('fff1.f', fs), env, path)
+ deps = s(env.File('fff1.f'), env, path)
headers = ['f1.f', 'f2.f']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
test.unlink('f1.f')
test.unlink('f2.f')
@@ -275,10 +281,9 @@ class FortranScannerTestCase2(unittest.TestCase):
env = DummyEnvironment([test.workpath("d1")])
s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- fs = SCons.Node.FS.FS(original)
- deps = s(make_node('fff1.f', fs), env, path)
+ deps = s(env.File('fff1.f'), env, path)
headers = ['f1.f', 'f2.f']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
test.unlink('f1.f')
test.unlink('f2.f')
@@ -287,10 +292,9 @@ class FortranScannerTestCase3(unittest.TestCase):
env = DummyEnvironment([test.workpath("d1")])
s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- fs = SCons.Node.FS.FS(original)
- deps = s(make_node('fff1.f', fs), env, path)
+ deps = s(env.File('fff1.f'), env, path)
headers = ['d1/f1.f', 'd1/f2.f']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class FortranScannerTestCase4(unittest.TestCase):
def runTest(self):
@@ -298,10 +302,9 @@ class FortranScannerTestCase4(unittest.TestCase):
env = DummyEnvironment([test.workpath("d1")])
s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- fs = SCons.Node.FS.FS(original)
- deps = s(make_node('fff1.f', fs), env, path)
+ deps = s(env.File('fff1.f'), env, path)
headers = ['d1/f1.f', 'd1/f2.f']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
test.write(['d1', 'f2.f'], "\n")
class FortranScannerTestCase5(unittest.TestCase):
@@ -309,10 +312,9 @@ class FortranScannerTestCase5(unittest.TestCase):
env = DummyEnvironment([test.workpath("d1")])
s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- fs = SCons.Node.FS.FS(original)
- deps = s(make_node('fff2.f', fs), env, path)
+ deps = s(env.File('fff2.f'), env, path)
headers = ['d1/f2.f', 'd1/d2/f2.f', 'd1/f2.f']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class FortranScannerTestCase6(unittest.TestCase):
def runTest(self):
@@ -320,10 +322,9 @@ class FortranScannerTestCase6(unittest.TestCase):
env = DummyEnvironment([test.workpath("d1")])
s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- fs = SCons.Node.FS.FS(original)
- deps = s(make_node('fff2.f', fs), env, path)
+ deps = s(env.File('fff2.f'), env, path)
headers = ['d1/f2.f', 'd1/d2/f2.f', 'f2.f']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
test.unlink('f2.f')
class FortranScannerTestCase7(unittest.TestCase):
@@ -331,10 +332,9 @@ class FortranScannerTestCase7(unittest.TestCase):
env = DummyEnvironment([test.workpath("d1/d2"), test.workpath("d1")])
s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- fs = SCons.Node.FS.FS(original)
- deps = s(make_node('fff2.f', fs), env, path)
+ deps = s(env.File('fff2.f'), env, path)
headers = ['d1/f2.f', 'd1/d2/f2.f', 'd1/d2/f2.f']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class FortranScannerTestCase8(unittest.TestCase):
def runTest(self):
@@ -342,10 +342,9 @@ class FortranScannerTestCase8(unittest.TestCase):
env = DummyEnvironment([test.workpath("d1/d2"), test.workpath("d1")])
s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- fs = SCons.Node.FS.FS(original)
- deps = s(make_node('fff2.f', fs), env, path)
+ deps = s(env.File('fff2.f'), env, path)
headers = ['d1/f2.f', 'd1/d2/f2.f', 'f2.f']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
test.unlink('f2.f')
class FortranScannerTestCase9(unittest.TestCase):
@@ -355,7 +354,7 @@ class FortranScannerTestCase9(unittest.TestCase):
s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- n = make_node('fff3.f')
+ n = env.File('fff3.f')
def my_rexists(s=n):
s.rexists_called = 1
return s.old_rexists()
@@ -369,21 +368,20 @@ class FortranScannerTestCase9(unittest.TestCase):
assert n.rexists_called
headers = ['d1/f3.f', 'f3.f']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
test.unlink('f3.f')
class FortranScannerTestCase10(unittest.TestCase):
def runTest(self):
- fs = SCons.Node.FS.FS(test.workpath(''))
env = DummyEnvironment(["include"])
- s = SCons.Scanner.Fortran.FortranScan(fs = fs)
+ s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- deps1 = s(fs.File('fff4.f'), env, path)
- fs.chdir(fs.Dir('subdir'))
- dir = fs.getcwd()
- fs.chdir(fs.Dir('..'))
+ deps1 = s(env.File('fff4.f'), env, path)
+ env.fs.chdir(env.Dir('subdir'))
+ dir = env.fs.getcwd()
+ env.fs.chdir(env.Dir(''))
path = s.path(env, dir)
- deps2 = s(fs.File('#fff4.f'), env, path)
+ deps2 = s(env.File('#fff4.f'), env, path)
headers1 = ['include/f4.f']
headers2 = ['subdir/include/f4.f']
deps_match(self, deps1, headers1)
@@ -399,11 +397,10 @@ class FortranScannerTestCase11(unittest.TestCase):
to = TestOut()
to.out = None
SCons.Warnings._warningOut = to
- fs = SCons.Node.FS.FS(test.workpath(''))
env = DummyEnvironment([])
- s = SCons.Scanner.Fortran.FortranScan(fs=fs)
+ s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- deps = s(fs.File('fff5.f'), env, path)
+ deps = s(env.File('fff5.f'), env, path)
# Did we catch the warning from not finding not_there.f?
assert to.out
@@ -412,14 +409,13 @@ class FortranScannerTestCase11(unittest.TestCase):
class FortranScannerTestCase12(unittest.TestCase):
def runTest(self):
- fs = SCons.Node.FS.FS(test.workpath(''))
- fs.chdir(fs.Dir('include'))
env = DummyEnvironment([])
- s = SCons.Scanner.Fortran.FortranScan(fs=fs)
+ env.fs.chdir(env.Dir('include'))
+ s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
test.write('include/fff4.f', test.read('fff4.f'))
- deps = s(fs.File('#include/fff4.f'), env, path)
- fs.chdir(fs.Dir('..'))
+ deps = s(env.File('#include/fff4.f'), env, path)
+ env.fs.chdir(env.Dir(''))
deps_match(self, deps, ['include/f4.f'])
test.unlink('include/fff4.f')
@@ -434,7 +430,8 @@ class FortranScannerTestCase13(unittest.TestCase):
f1=fs.File('include2/jjj.f')
f1.builder=1
env = DummyEnvironment(['include','include2'])
- s = SCons.Scanner.Fortran.FortranScan(fs=fs)
+ env.fs = fs
+ s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
deps = s(fs.File('src/fff.f'), env, path)
deps_match(self, deps, [test.workpath('repository/include/iii.f'), 'include2/jjj.f'])
@@ -448,7 +445,8 @@ class FortranScannerTestCase14(unittest.TestCase):
fs.BuildDir('build2', 'src', 0)
fs.Repository(test.workpath('repository'))
env = DummyEnvironment([])
- s = SCons.Scanner.Fortran.FortranScan(fs = fs)
+ env.fs = fs
+ s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
deps1 = s(fs.File('build1/aaa.f'), env, path)
deps_match(self, deps1, [ 'build1/bbb.f' ])
@@ -469,10 +467,9 @@ class FortranScannerTestCase15(unittest.TestCase):
env = SubstEnvironment(["junk"])
s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- fs = SCons.Node.FS.FS(original)
- deps = s(make_node('fff1.f', fs), env, path)
+ deps = s(env.File('fff1.f'), env, path)
headers = ['d1/f1.f', 'd1/f2.f']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
test.write(['d1', 'f2.f'], "\n")
class FortranScannerTestCase16(unittest.TestCase):
@@ -490,8 +487,7 @@ class FortranScannerTestCase16(unittest.TestCase):
env = DummyEnvironment([test.workpath('modules')])
s = SCons.Scanner.Fortran.FortranScan()
path = s.path(env)
- fs = SCons.Node.FS.FS(original)
- deps = s(make_node('fff90a.f90', fs), env, path)
+ deps = s(env.File('fff90a.f90'), env, path)
headers = ['f1.f', 'f2.f', 'f3.f', 'f4.f', 'f5.f', 'f6.f', 'f7.f', 'f8.f', 'f9.f']
modules = ['mod01.mod', 'mod02.mod', 'mod03.mod', 'mod04.mod', 'mod05.mod',
'mod06.mod', 'mod07.mod', 'mod08.mod', 'mod09.mod', 'mod10.mod',
@@ -499,7 +495,7 @@ class FortranScannerTestCase16(unittest.TestCase):
'mod16.mod', 'mod17.mod', 'mod18.mod', 'mod19.mod', 'mod20.mod',
'mod21.mod', 'mod22.mod', 'mod23.mod', 'mod24.mod', 'mod25.mod', 'modules/use.mod']
deps_expected = headers + modules
- deps_match(self, deps, map(test.workpath, deps_expected))
+ deps_match(self, deps, deps_expected)
test.unlink('f1.f')
test.unlink('f2.f')
test.unlink('f3.f')
diff --git a/src/engine/SCons/Scanner/IDL.py b/src/engine/SCons/Scanner/IDL.py
index 8c4f68d..b0fd8ed 100644
--- a/src/engine/SCons/Scanner/IDL.py
+++ b/src/engine/SCons/Scanner/IDL.py
@@ -33,11 +33,10 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import SCons.Node.FS
import SCons.Scanner
-def IDLScan(fs = SCons.Node.FS.default_fs):
+def IDLScan():
"""Return a prototype Scanner instance for scanning IDL source files"""
cs = SCons.Scanner.ClassicCPP("IDLScan",
"$IDLSUFFIXES",
"CPPPATH",
- '^[ \t]*(?:#[ \t]*include|[ \t]*import)[ \t]+(<|")([^>"]+)(>|")',
- fs = fs)
+ '^[ \t]*(?:#[ \t]*include|[ \t]*import)[ \t]+(<|")([^>"]+)(>|")')
return cs
diff --git a/src/engine/SCons/Scanner/IDLTests.py b/src/engine/SCons/Scanner/IDLTests.py
index db842c3..d1a0941 100644
--- a/src/engine/SCons/Scanner/IDLTests.py
+++ b/src/engine/SCons/Scanner/IDLTests.py
@@ -189,6 +189,7 @@ test.write([ 'repository', 'src', 'ddd.idl'], "\n")
class DummyEnvironment:
def __init__(self, listCppPath):
self.path = listCppPath
+ self.fs = SCons.Node.FS.FS(test.workpath(''))
def Dictionary(self, *args):
if not args:
@@ -221,6 +222,15 @@ class DummyEnvironment:
def get_calculator(self):
return None
+ def get_factory(self, factory):
+ return factory or self.fs.File
+
+ def Dir(self, filename):
+ return self.fs.Dir(test.workpath(filename))
+
+ def File(self, filename):
+ return self.fs.File(test.workpath(filename))
+
global my_normpath
my_normpath = os.path.normpath
@@ -232,9 +242,6 @@ def deps_match(self, deps, headers):
expect = map(my_normpath, headers)
self.failUnless(scanned == expect, "expect %s != scanned %s" % (expect, scanned))
-def make_node(filename, fs=SCons.Node.FS.default_fs):
- return fs.File(test.workpath(filename))
-
# define some tests:
class IDLScannerTestCase1(unittest.TestCase):
@@ -242,36 +249,36 @@ class IDLScannerTestCase1(unittest.TestCase):
env = DummyEnvironment([])
s = SCons.Scanner.IDL.IDLScan()
path = s.path(env)
- deps = s(make_node('t1.idl'), env, path)
+ deps = s(env.File('t1.idl'), env, path)
headers = ['f1.idl', 'f3.idl', 'f2.idl']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class IDLScannerTestCase2(unittest.TestCase):
def runTest(self):
env = DummyEnvironment([test.workpath("d1")])
s = SCons.Scanner.IDL.IDLScan()
path = s.path(env)
- deps = s(make_node('t1.idl'), env, path)
+ deps = s(env.File('t1.idl'), env, path)
headers = ['f1.idl', 'f3.idl', 'd1/f2.idl']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class IDLScannerTestCase3(unittest.TestCase):
def runTest(self):
env = DummyEnvironment([test.workpath("d1")])
s = SCons.Scanner.IDL.IDLScan()
path = s.path(env)
- deps = s(make_node('t2.idl'), env, path)
+ deps = s(env.File('t2.idl'), env, path)
headers = ['d1/f1.idl', 'f1.idl', 'd1/d2/f1.idl', 'f3.idl']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class IDLScannerTestCase4(unittest.TestCase):
def runTest(self):
env = DummyEnvironment([test.workpath("d1"), test.workpath("d1/d2")])
s = SCons.Scanner.IDL.IDLScan()
path = s.path(env)
- deps = s(make_node('t2.idl'), env, path)
+ deps = s(env.File('t2.idl'), env, path)
headers = ['d1/f1.idl', 'f1.idl', 'd1/d2/f1.idl', 'f3.idl']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class IDLScannerTestCase5(unittest.TestCase):
def runTest(self):
@@ -279,7 +286,7 @@ class IDLScannerTestCase5(unittest.TestCase):
s = SCons.Scanner.IDL.IDLScan()
path = s.path(env)
- n = make_node('t3.idl')
+ n = env.File('t3.idl')
def my_rexists(s=n):
s.rexists_called = 1
return s.old_rexists()
@@ -295,7 +302,7 @@ class IDLScannerTestCase5(unittest.TestCase):
headers = ['d1/f1.idl', 'd1/f2.idl',
'f1.idl', 'f2.idl', 'f3-test.idl',
'd1/f1.idl', 'd1/f2.idl', 'd1/f3-test.idl']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
class IDLScannerTestCase6(unittest.TestCase):
def runTest(self):
@@ -304,25 +311,24 @@ class IDLScannerTestCase6(unittest.TestCase):
s = SCons.Scanner.IDL.IDLScan()
path1 = s.path(env1)
path2 = s.path(env2)
- deps1 = s(make_node('t1.idl'), env1, path1)
- deps2 = s(make_node('t1.idl'), env2, path2)
+ deps1 = s(env1.File('t1.idl'), env1, path1)
+ deps2 = s(env2.File('t1.idl'), env2, path2)
headers1 = ['f1.idl', 'f3.idl', 'd1/f2.idl']
headers2 = ['f1.idl', 'f3.idl', 'd1/d2/f2.idl']
- deps_match(self, deps1, map(test.workpath, headers1))
- deps_match(self, deps2, map(test.workpath, headers2))
+ deps_match(self, deps1, headers1)
+ deps_match(self, deps2, headers2)
class IDLScannerTestCase7(unittest.TestCase):
def runTest(self):
- fs = SCons.Node.FS.FS(test.workpath(''))
env = DummyEnvironment(["include"])
- s = SCons.Scanner.IDL.IDLScan(fs = fs)
+ s = SCons.Scanner.IDL.IDLScan()
path = s.path(env)
- deps1 = s(fs.File('t4.idl'), env, path)
- fs.chdir(fs.Dir('subdir'))
- dir = fs.getcwd()
- fs.chdir(fs.Dir('..'))
+ deps1 = s(env.File('t4.idl'), env, path)
+ env.fs.chdir(env.Dir('subdir'))
+ dir = env.fs.getcwd()
+ env.fs.chdir(env.Dir(''))
path = s.path(env, dir)
- deps2 = s(fs.File('#t4.idl'), env, path)
+ deps2 = s(env.File('#t4.idl'), env, path)
headers1 = ['include/fa.idl', 'include/fb.idl']
headers2 = ['subdir/include/fa.idl', 'subdir/include/fb.idl']
deps_match(self, deps1, headers1)
@@ -339,11 +345,10 @@ class IDLScannerTestCase8(unittest.TestCase):
to.out = None
SCons.Warnings._warningOut = to
test.write('fa.idl','\n')
- fs = SCons.Node.FS.FS(test.workpath(''))
env = DummyEnvironment([])
- s = SCons.Scanner.IDL.IDLScan(fs=fs)
+ s = SCons.Scanner.IDL.IDLScan()
path = s.path(env)
- deps = s(fs.File('t4.idl'), env, path)
+ deps = s(env.File('t4.idl'), env, path)
# Did we catch the warning associated with not finding fb.idl?
assert to.out
@@ -353,14 +358,13 @@ class IDLScannerTestCase8(unittest.TestCase):
class IDLScannerTestCase9(unittest.TestCase):
def runTest(self):
- fs = SCons.Node.FS.FS(test.workpath(''))
- fs.chdir(fs.Dir('include'))
env = DummyEnvironment([])
- s = SCons.Scanner.IDL.IDLScan(fs=fs)
+ env.fs.chdir(env.Dir('include'))
+ s = SCons.Scanner.IDL.IDLScan()
path = s.path(env)
test.write('include/t4.idl', test.read('t4.idl'))
- deps = s(fs.File('#include/t4.idl'), env, path)
- fs.chdir(fs.Dir('..'))
+ deps = s(env.File('#include/t4.idl'), env, path)
+ env.fs.chdir(env.Dir(''))
deps_match(self, deps, [ 'include/fa.idl', 'include/fb.idl' ])
test.unlink('include/t4.idl')
@@ -372,13 +376,15 @@ class IDLScannerTestCase10(unittest.TestCase):
# Create a derived file in a directory that does not exist yet.
# This was a bug at one time.
- f1=fs.File('include2/jjj.idl')
- f1.builder=1
env = DummyEnvironment(['include', 'include2'])
- s = SCons.Scanner.IDL.IDLScan(fs=fs)
+ env.fs = fs
+ f1 = fs.File('include2/jjj.idl')
+ f1.builder = 1
+ s = SCons.Scanner.IDL.IDLScan()
path = s.path(env)
deps = s(fs.File('src/fff.c'), env, path)
- deps_match(self, deps, [ test.workpath('repository/include/iii.idl'), 'include2/jjj.idl' ])
+ deps_match(self, deps, [ test.workpath('repository/include/iii.idl'),
+ 'include2/jjj.idl' ])
os.chdir(test.workpath(''))
class IDLScannerTestCase11(unittest.TestCase):
@@ -389,7 +395,8 @@ class IDLScannerTestCase11(unittest.TestCase):
fs.BuildDir('build2', 'src', 0)
fs.Repository(test.workpath('repository'))
env = DummyEnvironment([])
- s = SCons.Scanner.IDL.IDLScan(fs = fs)
+ env.fs = fs
+ s = SCons.Scanner.IDL.IDLScan()
path = s.path(env)
deps1 = s(fs.File('build1/aaa.c'), env, path)
deps_match(self, deps1, [ 'build1/bbb.idl' ])
@@ -409,9 +416,9 @@ class IDLScannerTestCase12(unittest.TestCase):
env = SubstEnvironment(["blah"])
s = SCons.Scanner.IDL.IDLScan()
path = s.path(env)
- deps = s(make_node('t1.idl'), env, path)
+ deps = s(env.File('t1.idl'), env, path)
headers = ['f1.idl', 'f3.idl', 'd1/f2.idl']
- deps_match(self, deps, map(test.workpath, headers))
+ deps_match(self, deps, headers)
def suite():
diff --git a/src/engine/SCons/Scanner/Prog.py b/src/engine/SCons/Scanner/Prog.py
index 206c6de..54db9a8 100644
--- a/src/engine/SCons/Scanner/Prog.py
+++ b/src/engine/SCons/Scanner/Prog.py
@@ -33,14 +33,14 @@ import SCons.Util
# global, set by --debug=findlibs
print_find_libs = None
-def ProgramScanner(fs = SCons.Node.FS.default_fs, **kw):
+def ProgramScanner(**kw):
"""Return a prototype Scanner instance for scanning executable
files for static-lib dependencies"""
- kw['path_function'] = SCons.Scanner.FindPathDirs('LIBPATH', fs)
+ kw['path_function'] = SCons.Scanner.FindPathDirs('LIBPATH')
ps = apply(SCons.Scanner.Base, [scan, "ProgramScanner"], kw)
return ps
-def scan(node, env, libpath = (), fs = SCons.Node.FS.default_fs):
+def scan(node, env, libpath = ()):
"""
This scanner scans program files for static-library
dependencies. It will search the LIBPATH environment variable
diff --git a/src/engine/SCons/Scanner/ProgTests.py b/src/engine/SCons/Scanner/ProgTests.py
index ec25f24..bac10b7 100644
--- a/src/engine/SCons/Scanner/ProgTests.py
+++ b/src/engine/SCons/Scanner/ProgTests.py
@@ -49,6 +49,7 @@ class DummyEnvironment:
def __init__(self, **kw):
self._dict = {'LIBSUFFIXES' : '.lib'}
self._dict.update(kw)
+ self.fs = SCons.Node.FS.FS(test.workpath(''))
def Dictionary(self, *args):
if not args:
@@ -83,6 +84,15 @@ class DummyEnvironment:
path = [path]
return map(self.subst, path)
+ def get_factory(self, factory):
+ return factory or self.fs.File
+
+ def Dir(self, filename):
+ return self.fs.Dir(test.workpath(filename))
+
+ def File(self, filename):
+ return self.fs.File(test.workpath(filename))
+
class DummyNode:
def __init__(self, name):
self.name = name
@@ -95,9 +105,7 @@ def deps_match(deps, libs):
deps=map(str, deps)
deps.sort()
libs.sort()
- return map(os.path.normpath, deps) == \
- map(os.path.normpath,
- map(test.workpath, libs))
+ return map(os.path.normpath, deps) == map(os.path.normpath, libs)
# define some tests:
@@ -117,7 +125,7 @@ class ProgramScannerTestCase1(unittest.TestCase):
deps = s(DummyNode('dummy'), env, path)
assert deps_match(deps, ['l1.lib']), map(str, deps)
- f1 = SCons.Node.FS.default_fs.File(test.workpath('f1'))
+ f1 = env.fs.File(test.workpath('f1'))
env = DummyEnvironment(LIBPATH=[ test.workpath("") ],
LIBS=[f1])
s = SCons.Scanner.Prog.ProgramScanner()
@@ -125,7 +133,7 @@ class ProgramScannerTestCase1(unittest.TestCase):
deps = s(DummyNode('dummy'), env, path)
assert deps[0] is f1, deps
- f2 = SCons.Node.FS.default_fs.File(test.workpath('f1'))
+ f2 = env.fs.File(test.workpath('f1'))
env = DummyEnvironment(LIBPATH=[ test.workpath("") ],
LIBS=f2)
s = SCons.Scanner.Prog.ProgramScanner()
diff --git a/src/engine/SCons/Scanner/ScannerTests.py b/src/engine/SCons/Scanner/ScannerTests.py
index ef836bc..0d0ccec 100644
--- a/src/engine/SCons/Scanner/ScannerTests.py
+++ b/src/engine/SCons/Scanner/ScannerTests.py
@@ -30,10 +30,19 @@ import SCons.Sig
import SCons.Scanner
+class DummyFS:
+ def __init__(self, search_result=[]):
+ self.search_result = search_result
+ def File(self, name):
+ return DummyNode(name)
+ def Rsearchall(self, nodes, must_exist=0, clazz=None, cwd=dir):
+ return self.search_result + nodes
+
class DummyEnvironment(UserDict.UserDict):
def __init__(self, dict=None, **kw):
UserDict.UserDict.__init__(self, dict)
self.data.update(kw)
+ self.fs = DummyFS()
def subst(self, strSubst):
if strSubst[0] == '$':
return self.data[strSubst[1:]]
@@ -48,6 +57,8 @@ class DummyEnvironment(UserDict.UserDict):
return map(self.subst, path)
def get_calculator(self):
return SCons.Sig.default_calc
+ def get_factory(self, factory):
+ return factory or self.fs.File
class DummyNode:
def __init__(self, name):
@@ -56,18 +67,15 @@ class DummyNode:
return 1
def __str__(self):
return self.name
-
+
class FindPathDirsTestCase(unittest.TestCase):
def test_FindPathDirs(self):
"""Test the FindPathDirs callable class"""
- class FS:
- def Rsearchall(self, nodes, must_exist=0, clazz=None, cwd=dir):
- return ['xxx'] + nodes
-
env = DummyEnvironment(LIBPATH = [ 'foo' ])
+ env.fs = DummyFS(['xxx'])
- fpd = SCons.Scanner.FindPathDirs('LIBPATH', FS())
+ fpd = SCons.Scanner.FindPathDirs('LIBPATH')
result = fpd(env, dir)
assert str(result) == "('xxx', 'foo')", result
@@ -308,11 +316,12 @@ class SelectorTestCase(unittest.TestCase):
s2 = SCons.Scanner.Base(s2func)
selector = SCons.Scanner.Selector({'.x' : s1, '.y' : s2})
nx = self.skey_node('.x')
- selector(nx, None, [])
+ env = DummyEnvironment()
+ selector(nx, env, [])
assert called == ['s1func', nx], called
del called[:]
ny = self.skey_node('.y')
- selector(ny, None, [])
+ selector(ny, env, [])
assert called == ['s2func', ny], called
def test_select(self):
diff --git a/src/engine/SCons/Scanner/__init__.py b/src/engine/SCons/Scanner/__init__.py
index 247eafb..504b6df 100644
--- a/src/engine/SCons/Scanner/__init__.py
+++ b/src/engine/SCons/Scanner/__init__.py
@@ -75,11 +75,10 @@ def Binder(path):
class FindPathDirs:
- """A class to bind a specific *PATH variable name and the fs object
- to a function that will return all of the *path directories."""
- def __init__(self, variable, fs):
+ """A class to bind a specific *PATH variable name to a function that
+ will return all of the *path directories."""
+ def __init__(self, variable):
self.variable = variable
- self.fs = fs
def __call__(self, env, dir, target=None, source=None, argument=None):
# The goal is that we've made caching this unnecessary
# because the caching takes place at higher layers.
@@ -89,10 +88,10 @@ class FindPathDirs:
return ()
path = env.subst_path(path, target=target, source=source)
- path_tuple = tuple(self.fs.Rsearchall(path,
- must_exist = 0, #kwq!
- clazz = SCons.Node.FS.Dir,
- cwd = dir))
+ path_tuple = tuple(env.fs.Rsearchall(path,
+ must_exist = 0, #kwq!
+ clazz = SCons.Node.FS.Dir,
+ cwd = dir))
return Binder(path_tuple)
class Base:
@@ -110,7 +109,7 @@ class Base:
skeys = [],
path_function = None,
node_class = SCons.Node.FS.Entry,
- node_factory = SCons.Node.FS.default_fs.File,
+ node_factory = None,
scan_check = None,
recursive = None):
"""
@@ -155,13 +154,12 @@ class Base:
(the canonical example being only recursively scanning
subdirectories within a directory).
- The scanner function's first argument will be the a Node that
- should be scanned for dependencies, the second argument will
- be an Environment object, the third argument will be the tuple
- of paths returned by the path_function, and the fourth
- argument will be the value passed into 'argument', and the
- returned list should contain the Nodes for all the direct
- dependencies of the file.
+ The scanner function's first argument will be a Node that should
+ be scanned for dependencies, the second argument will be an
+ Environment object, the third argument will be the tuple of paths
+ returned by the path_function, and the fourth argument will be
+ the value passed into 'argument', and the returned list should
+ contain the Nodes for all the direct dependencies of the file.
Examples:
@@ -218,10 +216,11 @@ class Base:
kw = {}
if hasattr(node, 'dir'):
kw['directory'] = node.dir
+ node_factory = env.get_factory(self.node_factory)
nodes = []
for l in list:
if self.node_class and not isinstance(l, self.node_class):
- l = apply(self.node_factory, (l,), kw)
+ l = apply(node_factory, (l,), kw)
nodes.append(l)
return nodes
@@ -315,11 +314,9 @@ class Classic(Current):
include file in group 0.
"""
- def __init__(self, name, suffixes, path_variable, regex,
- fs=SCons.Node.FS.default_fs, *args, **kw):
+ def __init__(self, name, suffixes, path_variable, regex, *args, **kw):
self.cre = re.compile(regex, re.M)
- self.fs = fs
def _scan(node, env, path=(), self=self):
node = node.rfile()
@@ -328,7 +325,7 @@ class Classic(Current):
return self.scan(node, path)
kw['function'] = _scan
- kw['path_function'] = FindPathDirs(path_variable, fs)
+ kw['path_function'] = FindPathDirs(path_variable)
kw['recursive'] = 1
kw['skeys'] = suffixes
kw['name'] = name
diff --git a/src/engine/SCons/Script/Main.py b/src/engine/SCons/Script/Main.py
index d018d15..fd2a914 100644
--- a/src/engine/SCons/Script/Main.py
+++ b/src/engine/SCons/Script/Main.py
@@ -241,7 +241,6 @@ class QuestionTask(SCons.Taskmaster.Task):
# Global variables
keep_going_on_error = 0
-count_stats = None
print_dtree = 0
print_explanations = 0
print_includes = 0
@@ -251,7 +250,6 @@ print_stacktrace = 0
print_stree = 0
print_time = 0
print_tree = 0
-memory_stats = None
ignore_errors = 0
sconscript_time = 0
command_time = 0
@@ -260,6 +258,62 @@ profiling = 0
repositories = []
num_jobs = 1 # this is modifed by SConscript.SetJobs()
+#
+class Stats:
+ def __init__(self):
+ self.stats = []
+ self.labels = []
+ self.append = self.do_nothing
+ self.print_stats = self.do_nothing
+ def enable(self, outfp):
+ self.outfp = outfp
+ self.append = self.do_append
+ self.print_stats = self.do_print
+ def do_nothing(self, *args, **kw):
+ pass
+
+class CountStats(Stats):
+ def do_append(self, label):
+ self.labels.append(label)
+ self.stats.append(SCons.Debug.fetchLoggedInstances())
+ def do_print(self):
+ stats_table = {}
+ for s in self.stats:
+ for n in map(lambda t: t[0], s):
+ stats_table[n] = [0, 0, 0, 0]
+ i = 0
+ for s in self.stats:
+ for n, c in s:
+ stats_table[n][i] = c
+ i = i + 1
+ keys = stats_table.keys()
+ keys.sort()
+ self.outfp.write("Object counts:\n")
+ pre = [" "]
+ post = [" %s\n"]
+ l = len(self.stats)
+ fmt1 = string.join(pre + [' %7s']*l + post, '')
+ fmt2 = string.join(pre + [' %7d']*l + post, '')
+ self.labels.append(("", "Class"))
+ self.outfp.write(fmt1 % tuple(map(lambda x: x[0], self.labels)))
+ self.outfp.write(fmt1 % tuple(map(lambda x: x[1], self.labels)))
+ for k in keys:
+ r = stats_table[k]
+ self.outfp.write(fmt2 % (r[0], r[1], r[2], r[3], k))
+
+count_stats = CountStats()
+
+class MemStats(Stats):
+ def do_append(self, label):
+ self.labels.append(label)
+ self.stats.append(SCons.Debug.memory())
+ def do_print(self):
+ fmt = 'Memory %-32s %12d\n'
+ for label, stats in map(None, self.labels, self.stats):
+ self.outfp.write(fmt % (label, stats))
+
+memory_stats = MemStats()
+
# utility functions
def get_all_children(node): return node.all_children()
@@ -406,15 +460,13 @@ def _SConstruct_exists(dirname=''):
return None
def _set_globals(options):
- global repositories, keep_going_on_error, ignore_errors
+ global keep_going_on_error, ignore_errors
global count_stats, print_dtree
global print_explanations, print_includes, print_memoizer
global print_objects, print_stacktrace, print_stree
global print_time, print_tree
- global memory_outf, memory_stats
+ global memory_stats
- if options.repository:
- repositories.extend(options.repository)
keep_going_on_error = options.keep_going
try:
debug_values = options.debug
@@ -424,7 +476,7 @@ def _set_globals(options):
pass
else:
if "count" in debug_values:
- count_stats = []
+ count_stats.enable(sys.stdout)
if "dtree" in debug_values:
print_dtree = 1
if "explain" in debug_values:
@@ -436,8 +488,7 @@ def _set_globals(options):
if "memoizer" in debug_values:
print_memoizer = 1
if "memory" in debug_values:
- memory_stats = []
- memory_outf = sys.stdout
+ memory_stats.enable(sys.stdout)
if "objects" in debug_values:
print_objects = 1
if "presub" in debug_values:
@@ -795,50 +846,28 @@ class SConscriptSettableOptions:
def _main(args, parser):
- targets = []
- fs = SCons.Node.FS.default_fs
-
- # Enable deprecated warnings by default.
+ # Here's where everything really happens.
+
+ # First order of business: set up default warnings and and then
+ # handle the user's warning options, so we can warn about anything
+ # that happens appropriately.
+ default_warnings = [ SCons.Warnings.CorruptSConsignWarning,
+ SCons.Warnings.DeprecatedWarning,
+ SCons.Warnings.DuplicateEnvironmentWarning,
+ SCons.Warnings.MissingSConscriptWarning,
+ SCons.Warnings.NoParallelSupportWarning,
+ SCons.Warnings.MisleadingKeywordsWarning, ]
+ for warning in default_warnings:
+ SCons.Warnings.enableWarningClass(warning)
SCons.Warnings._warningOut = _scons_internal_warning
- SCons.Warnings.enableWarningClass(SCons.Warnings.CorruptSConsignWarning)
- SCons.Warnings.enableWarningClass(SCons.Warnings.DeprecatedWarning)
- SCons.Warnings.enableWarningClass(SCons.Warnings.DuplicateEnvironmentWarning)
- SCons.Warnings.enableWarningClass(SCons.Warnings.MissingSConscriptWarning)
- SCons.Warnings.enableWarningClass(SCons.Warnings.NoParallelSupportWarning)
- # This is good for newbies, and hopefully most everyone else too.
- SCons.Warnings.enableWarningClass(SCons.Warnings.MisleadingKeywordsWarning)
-
- global ssoptions
- ssoptions = SConscriptSettableOptions(options)
-
- _set_globals(options)
- SCons.Node.implicit_cache = options.implicit_cache
- SCons.Node.implicit_deps_changed = options.implicit_deps_changed
- SCons.Node.implicit_deps_unchanged = options.implicit_deps_unchanged
if options.warn:
_setup_warn(options.warn)
- if options.noexec:
- SCons.SConf.dryrun = 1
- SCons.Action.execute_actions = None
- CleanTask.execute = CleanTask.show
- if options.question:
- SCons.SConf.dryrun = 1
- SCons.SConf.SetCacheMode(options.config)
- SCons.SConf.SetProgressDisplay(progress_display)
- if options.no_progress or options.silent:
- progress_display.set_mode(0)
- if options.silent:
- display.set_mode(0)
- if options.silent:
- SCons.Action.print_actions = None
- if options.cache_disable:
- def disable(self): pass
- fs.CacheDir = disable
- if options.cache_force:
- fs.cache_force = 1
- if options.cache_show:
- fs.cache_show = 1
+ # Next, we want to create the FS object that represents the outside
+ # world's file system, as that's central to a lot of initialization.
+ # To do this, however, we need to be in the directory from which we
+ # want to start everything, which means first handling any relevant
+ # options that might cause us to chdir somewhere (-C, -D, -U, -u).
if options.directory:
cdir = _create_path(options.directory)
try:
@@ -846,14 +875,11 @@ def _main(args, parser):
except OSError:
sys.stderr.write("Could not change directory to %s\n" % cdir)
- xmit_args = []
- for a in args:
- if '=' in a:
- xmit_args.append(a)
- else:
- targets.append(a)
- SCons.Script._Add_Arguments(xmit_args)
- SCons.Script._Add_Targets(targets)
+ # The SConstruct file may be in a repository, so initialize those
+ # before we start the search up our path for one.
+ global repositories
+ if options.repository:
+ repositories.extend(options.repository)
target_top = None
if options.climb_up:
@@ -869,8 +895,17 @@ def _main(args, parser):
display("scons: Entering directory `%s'" % script_dir)
os.chdir(script_dir)
- fs.set_toplevel_dir(os.getcwd())
+ # Now that we're in the top-level SConstruct directory, go ahead
+ # and initialize the FS object that represents the file system,
+ # and make it the build engine default.
+ fs = SCons.Node.FS.default_fs = SCons.Node.FS.FS()
+
+ for rep in repositories:
+ fs.Repository(rep)
+ # Now that we have the FS object, the next order of business is to
+ # check for an SConstruct file (or other specified config file).
+ # If there isn't one, we can bail before doing any more work.
scripts = []
if options.file:
scripts.extend(options.file)
@@ -879,15 +914,13 @@ def _main(args, parser):
if sfile:
scripts.append(sfile)
- if options.help_msg:
- if not scripts:
+ if not scripts:
+ if options.help_msg:
# There's no SConstruct, but they specified -h.
# Give them the options usage now, before we fail
# trying to read a non-existent SConstruct file.
parser.print_help()
sys.exit(0)
-
- if not scripts:
raise SCons.Errors.UserError, "No SConstruct file found."
if scripts[0] == "-":
@@ -896,6 +929,54 @@ def _main(args, parser):
d = fs.File(scripts[0]).dir
fs.set_SConstruct_dir(d)
+ # Now that we have the FS object and it's intialized, set up (most
+ # of) the rest of the options.
+ global ssoptions
+ ssoptions = SConscriptSettableOptions(options)
+
+ _set_globals(options)
+ SCons.Node.implicit_cache = options.implicit_cache
+ SCons.Node.implicit_deps_changed = options.implicit_deps_changed
+ SCons.Node.implicit_deps_unchanged = options.implicit_deps_unchanged
+ if options.noexec:
+ SCons.SConf.dryrun = 1
+ SCons.Action.execute_actions = None
+ CleanTask.execute = CleanTask.show
+ if options.question:
+ SCons.SConf.dryrun = 1
+ SCons.SConf.SetCacheMode(options.config)
+ SCons.SConf.SetProgressDisplay(progress_display)
+
+ if options.no_progress or options.silent:
+ progress_display.set_mode(0)
+ if options.silent:
+ display.set_mode(0)
+ if options.silent:
+ SCons.Action.print_actions = None
+ if options.cache_disable:
+ def disable(self): pass
+ fs.CacheDir = disable
+ if options.cache_force:
+ fs.cache_force = 1
+ if options.cache_show:
+ fs.cache_show = 1
+
+ if options.include_dir:
+ sys.path = options.include_dir + sys.path
+
+ # That should cover (most of) the options. Next, set up the variables
+ # that hold command-line arguments, so the SConscript files that we
+ # read and execute have access to them.
+ targets = []
+ xmit_args = []
+ for a in args:
+ if '=' in a:
+ xmit_args.append(a)
+ else:
+ targets.append(a)
+ SCons.Script._Add_Targets(targets)
+ SCons.Script._Add_Arguments(xmit_args)
+
class Unbuffered:
def __init__(self, file):
self.file = file
@@ -907,15 +988,8 @@ def _main(args, parser):
sys.stdout = Unbuffered(sys.stdout)
- if options.include_dir:
- sys.path = options.include_dir + sys.path
-
- global repositories
- for rep in repositories:
- fs.Repository(rep)
-
- if not memory_stats is None: memory_stats.append(SCons.Debug.memory())
- if not count_stats is None: count_stats.append(SCons.Debug.fetchLoggedInstances())
+ memory_stats.append('before reading SConscript files:')
+ count_stats.append(('pre-', 'read'))
progress_display("scons: Reading SConscript files ...")
@@ -944,8 +1018,8 @@ def _main(args, parser):
# file system nodes.
SCons.Node.FS.save_strings(1)
- if not memory_stats is None: memory_stats.append(SCons.Debug.memory())
- if not count_stats is None: count_stats.append(SCons.Debug.fetchLoggedInstances())
+ memory_stats.append('after reading SConscript files:')
+ count_stats.append(('post-', 'read'))
fs.chdir(fs.Top)
@@ -1084,8 +1158,8 @@ def _main(args, parser):
"\tignoring -j or num_jobs option.\n"
SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg)
- if not memory_stats is None: memory_stats.append(SCons.Debug.memory())
- if not count_stats is None: count_stats.append(SCons.Debug.fetchLoggedInstances())
+ memory_stats.append('before building targets:')
+ count_stats.append(('pre-', 'build'))
try:
jobs.run()
@@ -1097,37 +1171,11 @@ def _main(args, parser):
if not options.noexec:
SCons.SConsign.write()
- if not memory_stats is None:
- memory_stats.append(SCons.Debug.memory())
- when = [
- 'before reading SConscript files',
- 'after reading SConscript files',
- 'before building targets',
- 'after building targets',
- ]
- for i in xrange(len(when)):
- memory_outf.write('Memory %-32s %12d\n' % (when[i]+':', memory_stats[i]))
-
- if not count_stats is None:
- count_stats.append(SCons.Debug.fetchLoggedInstances())
- stats_table = {}
- for cs in count_stats:
- for n in map(lambda t: t[0], cs):
- stats_table[n] = [0, 0, 0, 0]
- i = 0
- for cs in count_stats:
- for n, c in cs:
- stats_table[n][i] = c
- i = i + 1
- keys = stats_table.keys()
- keys.sort()
- print "Object counts:"
- fmt = " %7s %7s %7s %7s %s"
- print fmt % ("pre-", "post-", "pre-", "post-", "")
- print fmt % ("read", "read", "build", "build", "Class")
- for k in keys:
- r = stats_table[k]
- print " %7d %7d %7d %7d %s" % (r[0], r[1], r[2], r[3], k)
+ memory_stats.append('after building targets:')
+ memory_stats.print_stats()
+
+ count_stats.append(('post-', 'build'))
+ count_stats.print_stats()
if print_objects:
SCons.Debug.listLoggedInstances('*')
@@ -1139,8 +1187,8 @@ def _main(args, parser):
# Dump any development debug info that may have been enabled.
# These are purely for internal debugging during development, so
- # there's no need to control the with --debug= options, they're
- # controlled by changing the source code.)
+ # there's no need to control them with --debug= options; they're
+ # controlled by changing the source code.
SCons.Debug.dump_caller_counts()
SCons.Taskmaster.dump_stats()
diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py
index 07dfd55..7ca9993 100644
--- a/src/engine/SCons/Script/SConscript.py
+++ b/src/engine/SCons/Script/SConscript.py
@@ -117,16 +117,16 @@ def compute_exports(exports):
class Frame:
"""A frame on the SConstruct/SConscript call stack"""
- def __init__(self, exports, sconscript):
+ def __init__(self, fs, exports, sconscript):
self.globals = BuildDefaultGlobals()
self.retval = None
- self.prev_dir = SCons.Node.FS.default_fs.getcwd()
+ self.prev_dir = fs.getcwd()
self.exports = compute_exports(exports) # exports from the calling SConscript
# make sure the sconscript attr is a Node.
if isinstance(sconscript, SCons.Node.Node):
self.sconscript = sconscript
else:
- self.sconscript = SCons.Node.FS.default_fs.File(str(sconscript))
+ self.sconscript = fs.File(str(sconscript))
# the SConstruct/SConscript call stack:
call_stack = []
@@ -158,7 +158,7 @@ def _SConscript(fs, *files, **kw):
# evaluate each SConscript file
results = []
for fn in files:
- call_stack.append(Frame(exports,fn))
+ call_stack.append(Frame(fs, exports, fn))
old_sys_path = sys.path
try:
SCons.Script.sconscript_reading = 1
diff --git a/src/engine/SCons/Tool/Perforce.py b/src/engine/SCons/Tool/Perforce.py
index 22c75e9..37115e9 100644
--- a/src/engine/SCons/Tool/Perforce.py
+++ b/src/engine/SCons/Tool/Perforce.py
@@ -75,7 +75,7 @@ def generate(env):
# calling getcwd() for itself, which is odd. If no PWD variable
# is present, p4 WILL call getcwd, but this seems to cause problems
# with good ol' Win32's tilde-mangling for long file names.
- environ['PWD'] = SCons.Node.FS.default_fs.Dir('#').get_abspath()
+ environ['PWD'] = env.Dir('#').get_abspath()
for var in _import_env:
v = os.environ.get(var)
diff --git a/src/engine/SCons/Tool/jar.py b/src/engine/SCons/Tool/jar.py
index a721d96..b069990 100644
--- a/src/engine/SCons/Tool/jar.py
+++ b/src/engine/SCons/Tool/jar.py
@@ -82,7 +82,7 @@ def jarChdir(target, source, env, for_signature):
JarAction = SCons.Action.Action('$JARCOM', '$JARCOMSTR')
JarBuilder = SCons.Builder.Builder(action = JarAction,
- source_factory = SCons.Node.FS.default_fs.Entry,
+ source_factory = SCons.Node.FS.Entry,
suffix = '$JARSUFFIX')
def generate(env):
diff --git a/src/engine/SCons/Tool/javac.py b/src/engine/SCons/Tool/javac.py
index 8741c23..44a4bd0 100644
--- a/src/engine/SCons/Tool/javac.py
+++ b/src/engine/SCons/Tool/javac.py
@@ -99,8 +99,8 @@ JavaAction = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR')
JavaBuilder = SCons.Builder.Builder(action = JavaAction,
emitter = emit_java_classes,
- target_factory = SCons.Node.FS.default_fs.Dir,
- source_factory = SCons.Node.FS.default_fs.Dir)
+ target_factory = SCons.Node.FS.Dir,
+ source_factory = SCons.Node.FS.Dir)
def generate(env):
"""Add Builders and construction variables for javac to an Environment."""
diff --git a/src/engine/SCons/Tool/javah.py b/src/engine/SCons/Tool/javah.py
index 4d5749a..26fcc53 100644
--- a/src/engine/SCons/Tool/javah.py
+++ b/src/engine/SCons/Tool/javah.py
@@ -59,7 +59,7 @@ def emit_java_headers(target, source, env):
classdir = s.attributes.java_classdir
except AttributeError:
classdir = '.'
- classdir = SCons.Node.FS.default_fs.Dir(classdir).rdir()
+ classdir = env.Dir(classdir).rdir()
if str(classdir) == '.':
c_ = None
else:
@@ -111,8 +111,8 @@ JavaHAction = SCons.Action.Action('$JAVAHCOM', '$JAVAHCOMSTR')
JavaHBuilder = SCons.Builder.Builder(action = JavaHAction,
emitter = emit_java_headers,
src_suffix = '$JAVACLASSSUFFIX',
- target_factory = SCons.Node.FS.default_fs.Entry,
- source_factory = SCons.Node.FS.default_fs.File)
+ target_factory = SCons.Node.FS.Entry,
+ source_factory = SCons.Node.FS.File)
def generate(env):
"""Add Builders and construction variables for javah to an Environment."""
diff --git a/src/engine/SCons/Tool/msvs.py b/src/engine/SCons/Tool/msvs.py
index 04e09f5..e03eb8d 100644
--- a/src/engine/SCons/Tool/msvs.py
+++ b/src/engine/SCons/Tool/msvs.py
@@ -1049,8 +1049,8 @@ def projectEmitter(target, source, env):
suff = env.subst('$MSVSPROJECTSUFFIX')
target[0] = base + suff
- dspfile = SCons.Node.FS.default_fs.File(target[0]).srcnode()
- dswfile = SCons.Node.FS.default_fs.File(SCons.Util.splitext(str(dspfile))[0] + env.subst('$MSVSSOLUTIONSUFFIX'))
+ dspfile = env.File(target[0]).srcnode()
+ dswfile = env.File(SCons.Util.splitext(str(dspfile))[0] + env.subst('$MSVSSOLUTIONSUFFIX'))
# XXX Need to find a way to abstract this; the build engine
# shouldn't depend on anything in SCons.Script.
@@ -1060,7 +1060,7 @@ def projectEmitter(target, source, env):
source[0].attributes.sconstruct = stack[0].sconscript
bdswpath = SCons.Util.splitext(str(target[0]))[0] + env.subst('$MSVSSOLUTIONSUFFIX')
- bdswfile = SCons.Node.FS.default_fs.File(bdswpath)
+ bdswfile = env.File(bdswpath)
# only make these side effects if they're
# not the same file.
diff --git a/src/engine/SCons/Tool/qt.py b/src/engine/SCons/Tool/qt.py
index bc2d41b..04b6215 100644
--- a/src/engine/SCons/Tool/qt.py
+++ b/src/engine/SCons/Tool/qt.py
@@ -107,7 +107,6 @@ class _Automoc:
debug = 0
# some shortcuts used in the scanner
- FS = SCons.Node.FS.default_fs
splitext = SCons.Util.splitext
objBuilder = getattr(env, self.objBuilderName)
@@ -147,9 +146,7 @@ class _Automoc:
# try to find the header file in the corresponding source
# directory
hname = splitext(cpp.name)[0] + h_ext
- h = find_file(hname,
- (cpp.get_dir(),),
- FS.File)
+ h = find_file(hname, (cpp.get_dir(),), env.File)
if h:
if debug:
print "scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp))
diff --git a/src/engine/SCons/Tool/rmic.py b/src/engine/SCons/Tool/rmic.py
index c5c4854..4b48e0b 100644
--- a/src/engine/SCons/Tool/rmic.py
+++ b/src/engine/SCons/Tool/rmic.py
@@ -58,7 +58,7 @@ def emit_rmic_classes(target, source, env):
classdir = s.attributes.java_classdir
except AttributeError:
classdir = '.'
- classdir = SCons.Node.FS.default_fs.Dir(classdir).rdir()
+ classdir = env.Dir(classdir).rdir()
if str(classdir) == '.':
c_ = None
else:
@@ -95,8 +95,8 @@ RMICAction = SCons.Action.Action('$RMICCOM', '$RMICCOMSTR')
RMICBuilder = SCons.Builder.Builder(action = RMICAction,
emitter = emit_rmic_classes,
src_suffix = '$JAVACLASSSUFFIX',
- target_factory = SCons.Node.FS.default_fs.Dir,
- source_factory = SCons.Node.FS.default_fs.File)
+ target_factory = SCons.Node.FS.Dir,
+ source_factory = SCons.Node.FS.File)
def generate(env):
"""Add Builders and construction variables for rmic to an Environment."""
diff --git a/src/engine/SCons/Tool/tar.py b/src/engine/SCons/Tool/tar.py
index 079865e..58b7554 100644
--- a/src/engine/SCons/Tool/tar.py
+++ b/src/engine/SCons/Tool/tar.py
@@ -44,7 +44,7 @@ tars = ['tar', 'gtar']
TarAction = SCons.Action.Action('$TARCOM', '$TARCOMSTR')
TarBuilder = SCons.Builder.Builder(action = TarAction,
- source_factory = SCons.Node.FS.default_fs.Entry,
+ source_factory = SCons.Node.FS.Entry,
source_scanner = SCons.Defaults.DirScanner,
suffix = '$TARSUFFIX',
multi = 1)
diff --git a/src/engine/SCons/Tool/zip.py b/src/engine/SCons/Tool/zip.py
index b67528b..fe9ce32 100644
--- a/src/engine/SCons/Tool/zip.py
+++ b/src/engine/SCons/Tool/zip.py
@@ -69,7 +69,7 @@ else:
zipAction = SCons.Action.Action(zip, varlist=['ZIPCOMPRESSION'])
ZipBuilder = SCons.Builder.Builder(action = SCons.Action.Action('$ZIPCOM', '$ZIPCOMSTR'),
- source_factory = SCons.Node.FS.default_fs.Entry,
+ source_factory = SCons.Node.FS.Entry,
source_scanner = SCons.Defaults.DirScanner,
suffix = '$ZIPSUFFIX',
multi = 1)