summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2004-11-13 21:56:57 (GMT)
committerSteven Knight <knight@baldmt.com>2004-11-13 21:56:57 (GMT)
commit09cad6ed1ffb436742adbbf6608bb094b4a236e2 (patch)
treeb6c4b1f529c82d39dab94b26fb1440980955c8fe /src/engine/SCons
parent206adf4366654b0c3fcf8c9131140f0c11ae0a5f (diff)
downloadSCons-09cad6ed1ffb436742adbbf6608bb094b4a236e2.zip
SCons-09cad6ed1ffb436742adbbf6608bb094b4a236e2.tar.gz
SCons-09cad6ed1ffb436742adbbf6608bb094b4a236e2.tar.bz2
Allow Alias Nodes to have Actions.
Diffstat (limited to 'src/engine/SCons')
-rw-r--r--src/engine/SCons/Environment.py72
-rw-r--r--src/engine/SCons/EnvironmentTests.py19
-rw-r--r--src/engine/SCons/Node/Alias.py45
-rw-r--r--src/engine/SCons/Node/AliasTests.py14
-rw-r--r--src/engine/SCons/Node/NodeTests.py13
-rw-r--r--src/engine/SCons/Node/__init__.py7
6 files changed, 124 insertions, 46 deletions
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py
index 443c6b0..ef3b2d0 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -96,6 +96,7 @@ AliasBuilder = SCons.Builder.Builder(action = alias_builder,
target_factory = SCons.Node.Alias.default_ans.Alias,
source_factory = SCons.Node.FS.default_fs.Entry,
multi = 1,
+ is_explicit = None,
name='AliasBuilder')
def our_deepcopy(x):
@@ -1036,29 +1037,56 @@ class Base:
n.add_post_action(action)
return nodes
- def Alias(self, target, *source, **kw):
- if not SCons.Util.is_List(target):
- target = [target]
- tlist = []
- for t in target:
- if not isinstance(t, SCons.Node.Alias.Alias):
- t = self.arg2nodes(self.subst(t), self.ans.Alias)[0]
- tlist.append(t)
- try:
- s = kw['source']
- except KeyError:
- try:
- s = source[0]
- except IndexError:
- s = None
- if s:
- if not SCons.Util.is_List(s):
- s = [s]
- s = filter(None, s)
- s = self.arg2nodes(s, self.fs.Entry)
+ def Alias(self, target, source=[], action=None, **kw):
+ tlist = self.arg2nodes(target, self.ans.Alias)
+ if not SCons.Util.is_List(source):
+ source = [source]
+ source = filter(None, source)
+
+ if not action:
+ if not source:
+ # There are no source files and no action, so just
+ # return a target list of classic Alias Nodes, without
+ # any builder. The externally visible effect is that
+ # this will make the wrapping Script.BuildTask class
+ # say that there's "Nothing to be done" for this Alias,
+ # instead of that it's "up to date."
+ return tlist
+
+ # No action, but there are sources. Re-call all the target
+ # builders to add the sources to each target.
+ result = []
for t in tlist:
- AliasBuilder(self, t, s)
- return tlist
+ bld = t.get_builder(AliasBuilder)
+ result.extend(bld(self, t, source))
+ return result
+
+ action = SCons.Action.Action(action)
+ nkw = self.subst_kw(kw)
+ nkw['source_factory'] = self.fs.Entry
+ nkw['multi'] = 1
+ nkw['action'] = action
+ bld = apply(SCons.Builder.Builder, (), nkw)
+
+ # Apply the Builder separately to each target so that the Aliases
+ # stay separate. If we did one "normal" Builder call with the
+ # whole target list, then all of the target Aliases would be
+ # associated under a single Executor.
+ result = []
+ for t in tlist:
+ # Calling the convert() method will cause a new Executor to be
+ # created from scratch, so we have to explicitly initialize
+ # it with the target's existing sources, plus our new ones,
+ # so nothing gets lost.
+ b = t.get_builder()
+ if b is None or b is AliasBuilder:
+ b = bld
+ else:
+ nkw['action'] = b.action + action
+ b = apply(SCons.Builder.Builder, (), nkw)
+ t.convert()
+ result.extend(b(self, t, t.sources + source))
+ return result
def AlwaysBuild(self, *targets):
tlist = []
diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py
index 0a0f260..9b84f3c 100644
--- a/src/engine/SCons/EnvironmentTests.py
+++ b/src/engine/SCons/EnvironmentTests.py
@@ -1797,6 +1797,7 @@ f5: \
tgt = env.Alias('new_alias')[0]
assert str(tgt) == 'new_alias', tgt
assert tgt.sources == [], tgt.sources
+ assert not hasattr(tgt, 'builder'), tgt.builder
tgt = env.Alias('None_alias', None)[0]
assert str(tgt) == 'None_alias', tgt
@@ -1833,6 +1834,24 @@ f5: \
assert str(t2.sources[0]) == 'asrc6', map(str, t2.sources)
assert str(t2.sources[1]) == 'asrc7', map(str, t2.sources)
+ tgt = env.Alias('add', 's1')
+ tgt = env.Alias('add', 's2')[0]
+ s = map(str, tgt.sources)
+ assert s == ['s1', 's2'], s
+ tgt = env.Alias(tgt, 's3')[0]
+ s = map(str, tgt.sources)
+ assert s == ['s1', 's2', 's3'], s
+
+ tgt = env.Alias('act', None, "action1")[0]
+ s = str(tgt.builder.action)
+ assert s == "action1", s
+ tgt = env.Alias('act', None, "action2")[0]
+ s = str(tgt.builder.action)
+ assert s == "action1\naction2", s
+ tgt = env.Alias(tgt, None, "action3")[0]
+ s = str(tgt.builder.action)
+ assert s == "action1\naction2\naction3", s
+
def test_AlwaysBuild(self):
"""Test the AlwaysBuild() method"""
env = Environment(FOO='fff', BAR='bbb')
diff --git a/src/engine/SCons/Node/Alias.py b/src/engine/SCons/Node/Alias.py
index 89127a3..c361838 100644
--- a/src/engine/SCons/Node/Alias.py
+++ b/src/engine/SCons/Node/Alias.py
@@ -39,11 +39,15 @@ import SCons.Node
import SCons.Util
class AliasNameSpace(UserDict.UserDict):
- def Alias(self, name):
- if self.has_key(name):
- raise SCons.Errors.UserError
- self[name] = SCons.Node.Alias.Alias(name)
- return self[name]
+ def Alias(self, name, **kw):
+ if isinstance(name, SCons.Node.Alias.Alias):
+ return name
+ try:
+ a = self[name]
+ except KeyError:
+ a = apply(SCons.Node.Alias.Alias, (name,), kw)
+ self[name] = a
+ return a
def lookup(self, name):
try:
@@ -59,18 +63,11 @@ class Alias(SCons.Node.Node):
def __str__(self):
return self.name
- def build(self):
- """A "builder" for aliases."""
- pass
-
+ really_build = SCons.Node.Node.build
current = SCons.Node.Node.children_are_up_to_date
- def sconsign(self):
- """An Alias is not recorded in .sconsign files"""
- pass
-
def is_under(self, dir):
- # Make Alias nodes get built regardless of
+ # Make Alias nodes get built regardless of
# what directory scons was run from. Alias nodes
# are outside the filesystem:
return 1
@@ -82,7 +79,25 @@ class Alias(SCons.Node.Node):
for kid in self.children(None):
contents = contents + kid.get_contents()
return contents
-
+
+ def sconsign(self):
+ """An Alias is not recorded in .sconsign files"""
+ pass
+
+ #
+ #
+ #
+
+ def build(self):
+ """A "builder" for aliases."""
+ pass
+
+ def convert(self):
+ try: del self.builder
+ except AttributeError: pass
+ self.reset_executor()
+ self.build = self.really_build
+
default_ans = AliasNameSpace()
SCons.Node.arg2nodes_lookups.append(default_ans.lookup)
diff --git a/src/engine/SCons/Node/AliasTests.py b/src/engine/SCons/Node/AliasTests.py
index afae46b..417cc2b 100644
--- a/src/engine/SCons/Node/AliasTests.py
+++ b/src/engine/SCons/Node/AliasTests.py
@@ -42,15 +42,11 @@ class AliasTestCase(unittest.TestCase):
"""
ans = SCons.Node.Alias.AliasNameSpace()
- a = ans.Alias('a1')
- assert a.name == 'a1', a.name
-
- try:
- ans.Alias('a1')
- except SCons.Errors.UserError:
- pass
- else:
- raise TestFailed, "did not catch expected UserError"
+ a1 = ans.Alias('a1')
+ assert a1.name == 'a1', a1.name
+
+ a2 = ans.Alias('a1')
+ assert a1 is a2, (a1, a2)
def test_lookup(self):
"""Test the lookup() method
diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py
index 657ac9b..e0956e1 100644
--- a/src/engine/SCons/Node/NodeTests.py
+++ b/src/engine/SCons/Node/NodeTests.py
@@ -390,6 +390,19 @@ class NodeTestCase(unittest.TestCase):
n1.builder_set(Builder(is_explicit=None))
assert not n1.has_explicit_builder()
+ def test_get_builder(self):
+ """Test the get_builder() method"""
+ n1 = SCons.Node.Node()
+ b = n1.get_builder()
+ assert b is None, b
+ b = n1.get_builder(777)
+ assert b == 777, b
+ n1.builder_set(888)
+ b = n1.get_builder()
+ assert b == 888, b
+ b = n1.get_builder(999)
+ assert b == 888, b
+
def test_multiple_side_effect_has_builder(self):
"""Test the multiple_side_effect_has_builder() method
"""
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py
index 36b0aed..fc3d7ec 100644
--- a/src/engine/SCons/Node/__init__.py
+++ b/src/engine/SCons/Node/__init__.py
@@ -329,6 +329,13 @@ class Node:
directories)."""
return self.has_builder() and self.builder.is_explicit
+ def get_builder(self, default_builder=None):
+ """Return the set builder, or a specified default value"""
+ try:
+ return self.builder
+ except AttributeError:
+ return default_builder
+
multiple_side_effect_has_builder = has_builder
def is_derived(self):