__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import SCons.Scanner
+import copy
+import string
+
import SCons.Node.FS
+import SCons.Scanner
import SCons.Util
-import string
-def ProgScan():
+class NullProgScanner:
+ """A do-nothing ProgScanner for Environments that have no LIBS."""
+ def scan(node, env, args = []):
+ return []
+
+null_scanner = NullProgScanner()
+
+def ProgScan(fs = SCons.Node.FS.default_fs):
"""Return a prototype Scanner instance for scanning executable
files for static-lib dependencies"""
- return SCons.Scanner.Base(scan, "ProgScan", SCons.Node.FS.default_fs.File)
+ ps = ProgScanner(scan, "ProgScan")
+ ps.fs = fs
+ return ps
-def scan(node, env, node_factory):
- """
- This scanner scans program files for static-library
- dependencies. It will search the LIBPATH environment variable
- for libraries specified in the LIBS variable, returning any
- files it finds as dependencies.
- """
-
- fs = SCons.Node.FS.default_fs
- try:
- paths = SCons.Util.scons_str2nodes(env.Dictionary("LIBPATH"),
- fs.Dir)
- except KeyError:
- paths = []
+class ProgScanner(SCons.Scanner.Base):
+ def __init__(self, *args, **kw):
+ apply(SCons.Scanner.Base.__init__, (self,) + args, kw)
+ self.hash = None
+ self.pathscanners = {}
- try:
- libs = env.Dictionary("LIBS")
+ def instance(self, env):
+ """
+ Return a unique instance of a Prog scanner object for a
+ given environment.
+ """
+ try:
+ libs = env.Dictionary('LIBS')
+ except KeyError:
+ # There are no LIBS in this environment, so just return the
+ # fake "scanner" instance that always returns a null list.
+ return null_scanner
if SCons.Util.is_String(libs):
libs = string.split(libs)
- except KeyError:
- libs = []
- try:
- prefix = env.Dictionary("LIBPREFIX")
- except KeyError:
- prefix=''
+ try:
+ dirs = tuple(SCons.Util.scons_str2nodes(env.Dictionary('LIBPATH'),
+ self.fs.Dir))
+ except:
+ dirs = ()
+
+ try:
+ prefix = env.Dictionary('LIBPREFIX')
+ except KeyError:
+ prefix = ''
- try:
- suffix = env.Dictionary("LIBSUFFIX")
- except KeyError:
- suffix=''
+ try:
+ suffix = env.Dictionary('LIBSUFFIX')
+ except KeyError:
+ suffix = ''
+ key = (dirs, tuple(libs), prefix, suffix)
+ if not self.pathscanners.has_key(key):
+ clone = copy.copy(self)
+ clone.hash = key
+ clone.argument = [self.fs, dirs, libs, prefix, suffix] # XXX reaching into object
+ self.pathscanners[key] = clone
+ return self.pathscanners[key]
+
+ def __hash__(self):
+ return hash(self.hash)
+
+def scan(node, env, args = [SCons.Node.FS.default_fs, (), [], '', '']):
+ """
+ This scanner scans program files for static-library
+ dependencies. It will search the LIBPATH environment variable
+ for libraries specified in the LIBS variable, returning any
+ files it finds as dependencies.
+ """
+ fs, libpath, libs, prefix, suffix = args
libs = map(lambda x, s=suffix, p=prefix: p + x + s, libs)
- return SCons.Node.FS.find_files(libs, paths, node_factory)
+ return SCons.Node.FS.find_files(libs, libpath, fs.File)
env = DummyEnvironment(LIBPATH=[ test.workpath("") ],
LIBS=[ 'l1', 'l2', 'l3' ])
s = SCons.Scanner.Prog.ProgScan()
- deps = s.scan('dummy', env)
+ deps = s.instance(env).scan('dummy', env)
assert deps_match(deps, ['l1.lib']), map(str, deps)
class ProgScanTestCase2(unittest.TestCase):
["", "d1", "d1/d2" ]),
LIBS=[ 'l1', 'l2', 'l3' ])
s = SCons.Scanner.Prog.ProgScan()
- deps = s.scan('dummy', env)
+ deps = s.instance(env).scan('dummy', env)
assert deps_match(deps, ['l1.lib', 'd1/l2.lib', 'd1/d2/l3.lib' ]), map(str, deps)
class ProgScanTestCase3(unittest.TestCase):
test.workpath("d1"),
LIBS='l2 l3')
s = SCons.Scanner.Prog.ProgScan()
- deps = s.scan('dummy', env)
+ deps = s.instance(env).scan('dummy', env)
assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), map(str, deps)
def suite():
test.workpath("d1"),
LIBS=u'l2 l3')
s = SCons.Scanner.Prog.ProgScan()
- deps = s.scan('dummy', env)
+ deps = s.instance(env).scan('dummy', env)
assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), map(str, deps)
suite.addTest(ProgScanTestCase4())
\n"""