summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/SCons')
-rw-r--r--src/engine/SCons/Environment.py17
-rw-r--r--src/engine/SCons/EnvironmentTests.py11
-rw-r--r--src/engine/SCons/Node/FS.py4
-rw-r--r--src/engine/SCons/Node/FSTests.py4
-rw-r--r--src/engine/SCons/Node/__init__.py13
-rw-r--r--src/engine/SCons/Util.py40
-rw-r--r--src/engine/SCons/UtilTests.py45
7 files changed, 128 insertions, 6 deletions
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index a7e02a2..5561cce 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -11,6 +11,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import copy
import re
import types
+import SCons.Util
@@ -26,7 +27,6 @@ def InstallAs():
_cv = re.compile(r'%([_a-zA-Z]\w*|{[_a-zA-Z]\w*})')
-_self = None
@@ -109,6 +109,17 @@ class Environment:
"""
self.Dictionary.update(copy.deepcopy(kw))
+ def Depends(self, target, dependency):
+ """Explicity specify that 'target's depend on 'dependency'."""
+ tlist = SCons.Util.scons_str2nodes(target)
+ dlist = SCons.Util.scons_str2nodes(dependency)
+ for t in tlist:
+ t.add_dependency(dlist)
+
+ if len(tlist) == 1:
+ tlist = tlist[0]
+ return tlist
+
def subst(self, string):
"""Recursively interpolates construction variables from the
Environment into the specified string, returning the expanded
@@ -119,9 +130,7 @@ class Environment:
may be surrounded by curly braces to separate the name from
trailing characters.
"""
- global _self
- _self = self # XXX NOT THREAD SAFE, BUT HOW ELSE DO WE DO THIS?
- def repl(m):
+ def repl(m, _self=self):
key = m.group(1)
if key[:1] == '{' and key[-1:] == '}':
key = key[1:-1]
diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py
index 885e365..149ba74 100644
--- a/src/engine/SCons/EnvironmentTests.py
+++ b/src/engine/SCons/EnvironmentTests.py
@@ -120,6 +120,17 @@ class EnvironmentTestCase(unittest.TestCase):
env2 = Environment(AAA = 'a', BBB = 'bbb', CCC = 'c')
assert env1 != env2
+ def test_Depends(self):
+ """Test the explicit Depends method."""
+ env = Environment()
+ t = env.Depends(target='EnvironmentTest.py', dependency='Environment.py')
+ assert t.__class__.__name__ == 'File'
+ assert t.path == 'EnvironmentTest.py'
+ assert len(t.depends) == 1
+ d = t.depends[0]
+ assert d.__class__.__name__ == 'File'
+ assert d.path == 'Environment.py'
+
def test_subst(self):
"""Test substituting construction variables within strings
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index fc7b042..ee06089 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -198,6 +198,8 @@ class Dir(Node):
"""
def __init__(self, name, directory = None):
+ Node.__init__(self)
+
self.entries = PathDict()
self.entries['.'] = self
@@ -247,6 +249,8 @@ class File(Node):
"""
def __init__(self, name, directory):
+ Node.__init__(self)
+
self.abspath = os.path.join(directory.abspath, name)
if str(directory.path) == '.':
self.path = name
diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py
index f95837f..87c6ed8 100644
--- a/src/engine/SCons/Node/FSTests.py
+++ b/src/engine/SCons/Node/FSTests.py
@@ -87,7 +87,7 @@ class FSTestCase(unittest.TestCase):
built_it = None
assert not built_it
d1.path = "d" # XXX FAKE SUBCLASS ATTRIBUTE
- d1.sources = "d" # XXX FAKE SUBCLASS ATTRIBUTE
+ d1.add_source(["d"]) # XXX FAKE SUBCLASS ATTRIBUTE
d1.builder_set(Builder())
d1.build()
assert built_it
@@ -95,7 +95,7 @@ class FSTestCase(unittest.TestCase):
built_it = None
assert not built_it
f1.path = "f" # XXX FAKE SUBCLASS ATTRIBUTE
- f1.sources = "f" # XXX FAKE SUBCLASS ATTRIBUTE
+ f1.add_source(["f"]) # XXX FAKE SUBCLASS ATTRIBUTE
f1.builder_set(Builder())
f1.build()
assert built_it
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index 8e5aab1..ce8e225 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -12,6 +12,12 @@ class Node:
"""The base Node class, for entities that we know how to
build, or use to build other Nodes.
"""
+
+ def __init__(self):
+ self.depends = []
+ self.sources = []
+ self.env = None
+
def build(self):
self.builder.execute(target = self.path, source = self.sources)
@@ -30,3 +36,10 @@ class Node:
def get_signature(self):
return self.signature
+ def add_dependency(self, depend):
+ """Adds dependencies. The depends argument must be a list."""
+ self.depends.extend(depend)
+
+ def add_source(self, source):
+ """Adds sources. The source argument must be a list."""
+ self.sources.extend(source)
diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py
new file mode 100644
index 0000000..0167260
--- /dev/null
+++ b/src/engine/SCons/Util.py
@@ -0,0 +1,40 @@
+"""SCons.Util
+
+Various utility functions go here.
+
+"""
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+
+import types
+import string
+import SCons.Node.FS
+
+def scons_str2nodes(arg, fs=SCons.Node.FS.default_fs):
+ """This function converts a string or list into a list of Node instances.
+ It follows the rules outlined in the SCons design document by accepting
+ any of the following inputs:
+ - A single string containing names separated by spaces. These will be
+ split apart at the spaces.
+ - A single Node instance,
+ - A list containingg either strings or Node instances. Any strings
+ in the list are not split at spaces.
+ In all cases, the function returns a list of Node instances."""
+
+ narg = arg
+ if type(arg) is types.StringType:
+ narg = string.split(arg)
+ elif type(arg) is not types.ListType:
+ narg = [arg]
+
+ nodes = []
+ for v in narg:
+ if type(v) is types.StringType:
+ nodes.append(fs.File(v))
+ elif issubclass(v.__class__, SCons.Node.Node):
+ nodes.append(v)
+ else:
+ raise TypeError
+
+ return nodes
diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py
new file mode 100644
index 0000000..0e13047
--- /dev/null
+++ b/src/engine/SCons/UtilTests.py
@@ -0,0 +1,45 @@
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+import unittest
+import SCons.Node.FS
+from SCons.Util import scons_str2nodes
+
+
+class UtilTestCase(unittest.TestCase):
+ def test_str2nodes(self):
+ """Test the str2nodes function."""
+ nodes = scons_str2nodes("Util.py UtilTests.py")
+ assert len(nodes) == 2
+ assert isinstance(nodes[0], SCons.Node.FS.File)
+ assert isinstance(nodes[1], SCons.Node.FS.File)
+ assert nodes[0].path == "Util.py"
+ assert nodes[1].path == "UtilTests.py"
+
+ nodes = scons_str2nodes("Util.py UtilTests.py", SCons.Node.FS.FS())
+ assert len(nodes) == 2
+ assert isinstance(nodes[0], SCons.Node.FS.File)
+ assert isinstance(nodes[1], SCons.Node.FS.File)
+ assert nodes[0].path == "Util.py"
+ assert nodes[1].path == "UtilTests.py"
+
+ nodes = scons_str2nodes(["Util.py", "UtilTests.py"])
+ assert len(nodes) == 2
+ assert isinstance(nodes[0], SCons.Node.FS.File)
+ assert isinstance(nodes[1], SCons.Node.FS.File)
+ assert nodes[0].path == "Util.py"
+ assert nodes[1].path == "UtilTests.py"
+
+ n1 = SCons.Node.FS.default_fs.File("Util.py")
+ nodes = scons_str2nodes([n1, "UtilTests.py"])
+ assert len(nodes) == 2
+ assert isinstance(nodes[0], SCons.Node.FS.File)
+ assert isinstance(nodes[1], SCons.Node.FS.File)
+ assert nodes[0].path == "Util.py"
+ assert nodes[1].path == "UtilTests.py"
+
+
+if __name__ == "__main__":
+ suite = unittest.makeSuite(UtilTestCase, 'test_')
+ if not unittest.TextTestRunner().run(suite).wasSuccessful():
+ sys.exit(1)