diff options
author | Steven Knight <knight@baldmt.com> | 2004-11-09 16:08:23 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2004-11-09 16:08:23 (GMT) |
commit | 7ae4d241d5e210eac9ee4c4472c6da8288e73ff1 (patch) | |
tree | f679201e2d6e48f5495027485e42e9b313404e93 /src | |
parent | 6060b498b5496281c5fbe8d188e7f8192a69247e (diff) | |
download | SCons-7ae4d241d5e210eac9ee4c4472c6da8288e73ff1.zip SCons-7ae4d241d5e210eac9ee4c4472c6da8288e73ff1.tar.gz SCons-7ae4d241d5e210eac9ee4c4472c6da8288e73ff1.tar.bz2 |
Add explicit support for Builder wrapper functions (pseudo-Builders) in the BUILDERS dictionary.
Diffstat (limited to 'src')
-rw-r--r-- | src/CHANGES.txt | 4 | ||||
-rw-r--r-- | src/engine/SCons/Builder.py | 36 | ||||
-rw-r--r-- | src/engine/SCons/BuilderTests.py | 72 | ||||
-rw-r--r-- | src/engine/SCons/Environment.py | 11 | ||||
-rw-r--r-- | src/engine/SCons/EnvironmentTests.py | 20 |
5 files changed, 74 insertions, 69 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index d9a397f..5f6968b 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -113,6 +113,10 @@ RELEASE 0.97 - XXX for another target, to avoid trying to build it again when it comes up in the target list. + - Allow a function with the right calling signature to be put directly + in an Environment's BUILDERS dictionary, making for easier creation + and use of wrappers (pseudo-Builders) that call other Builders. + From Wayne Lee: - Avoid "maximum recursion limit" errors when removing $(-$) pairs diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index d6b7597..40361d4 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -559,23 +559,15 @@ class BuilderBase: return tlist, slist - def _execute(self, env, target=None, source=_null, overwarn={}, executor_kw={}): - if source is _null: - source = target - target = None - - if(self.single_source and - SCons.Util.is_List(source) and - len(source) > 1 and - target is None): + def _execute(self, env, target, source, overwarn={}, executor_kw={}): + # We now assume that target and source are lists or None. + if self.single_source and len(source) > 1 and target is None: result = [] if target is None: target = [None]*len(source) - for k in range(len(source)): - t = self._execute(env, target[k], source[k], overwarn) - if SCons.Util.is_List(t): - result.extend(t) - else: - result.append(t) + for tgt, src in zip(target, source): + if not tgt is None: tgt = [tgt] + if not src is None: src = [src] + result.extend(self._execute(env, tgt, src, overwarn)) return result tlist, slist = self._create_nodes(env, overwarn, target, source) @@ -588,7 +580,10 @@ class BuilderBase: return tlist - def __call__(self, env, target=None, source=_null, chdir=_null, **kw): + def __call__(self, env, target=None, source=None, chdir=_null, **kw): + # We now assume that target and source are lists or None. + # The caller (typically Environment.BuilderWrapper) is + # responsible for converting any scalar values to lists. if chdir is _null: ekw = self.executor_kw else: @@ -709,11 +704,8 @@ class MultiStepBuilder(BuilderBase): self.sdict = {} self.cached_src_suffixes = {} # source suffixes keyed on id(env) - def _execute(self, env, target = None, source = _null, overwarn={}, executor_kw={}): - if source is _null: - source = target - target = None - + 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) final_sources = [] @@ -736,7 +728,7 @@ class MultiStepBuilder(BuilderBase): for snode in slist: for srcsuf in src_suffixes: if str(snode)[-len(srcsuf):] == srcsuf and sdict.has_key(srcsuf): - tgt = sdict[srcsuf]._execute(env, None, snode, overwarn) + tgt = sdict[srcsuf]._execute(env, None, [snode], overwarn) # If the subsidiary Builder returned more than one target, # then filter out any sources that this Builder isn't # capable of building. diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index 2075bf0..98e5a58 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -254,7 +254,7 @@ class BuilderTestCase(unittest.TestCase): n20 = MyNode_without_target_from_source('n20') flag = 0 try: - target = builder(env, source=n20) + target = builder(env, None, source=n20) except SCons.Errors.UserError, e: flag = 1 assert flag, "UserError should be thrown if a source node can't create a target." @@ -264,7 +264,7 @@ class BuilderTestCase(unittest.TestCase): source_factory=MyNode, prefix='p-', suffix='.s') - target = builder(env, source='n21')[0] + target = builder(env, None, source='n21')[0] assert target.name == 'p-n21.s', target builder = SCons.Builder.Builder(misspelled_action="foo", @@ -412,10 +412,10 @@ class BuilderTestCase(unittest.TestCase): tgt = builder(env, target = 'tgt2a tgt2b', source = 'src2')[0] assert tgt.path == 'libtgt2a tgt2b', \ "Target has unexpected name: %s" % tgt.path - tgt = builder(env, source = 'src3')[0] + tgt = builder(env, target = None, source = 'src3')[0] assert tgt.path == 'libsrc3', \ "Target has unexpected name: %s" % tgt.path - tgt = builder(env, source = 'lib/src4')[0] + tgt = builder(env, target = None, source = 'lib/src4')[0] assert tgt.path == os.path.join('lib', 'libsrc4'), \ "Target has unexpected name: %s" % tgt.path tgt = builder(env, target = 'lib/tgt5', source = 'lib/src5')[0] @@ -439,17 +439,17 @@ class BuilderTestCase(unittest.TestCase): '$FOO' : 'foo-', '.zzz' : my_emit}, action = '') - tgt = builder(my_env, source = 'f1')[0] + tgt = builder(my_env, target = None, source = 'f1')[0] assert tgt.path == 'default-f1', tgt.path - tgt = builder(my_env, source = 'f2.c')[0] + tgt = builder(my_env, target = None, source = 'f2.c')[0] assert tgt.path == 'default-f2', tgt.path - tgt = builder(my_env, source = 'f3.in')[0] + tgt = builder(my_env, target = None, source = 'f3.in')[0] assert tgt.path == 'out-f3', tgt.path - tgt = builder(my_env, source = 'f4.x')[0] + tgt = builder(my_env, target = None, source = 'f4.x')[0] assert tgt.path == 'y-f4', tgt.path - tgt = builder(my_env, source = 'f5.foo')[0] + tgt = builder(my_env, target = None, source = 'f5.foo')[0] assert tgt.path == 'foo-f5', tgt.path - tgt = builder(my_env, source = 'f6.zzz')[0] + tgt = builder(my_env, target = None, source = 'f6.zzz')[0] assert tgt.path == 'emit-f6', tgt.path def test_src_suffix(self): @@ -492,7 +492,7 @@ class BuilderTestCase(unittest.TestCase): b6 = SCons.Builder.Builder(action = '', src_suffix='_src.a', suffix='.b') - tgt = b6(env, source='foo_src.a') + tgt = b6(env, target=None, source='foo_src.a') assert str(tgt[0]) == 'foo.b', str(tgt[0]) b7 = SCons.Builder.Builder(action = '', @@ -501,16 +501,16 @@ class BuilderTestCase(unittest.TestCase): b8 = SCons.Builder.Builder(action = '', src_builder=b7, suffix='.c') - tgt = b8(env, source='foo_source.a') + 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') - tgt = b8(env, source=src) + tgt = b8(env, target=None, source=src) assert str(tgt[0]) == 'foo_obj.c', str(tgt[0]) b9 = SCons.Builder.Builder(action={'_src.a' : 'srcaction'}, suffix='.c') b9.add_action('_altsrc.b', 'altaction') - tgt = b9(env, source='foo_altsrc.b') + tgt = b9(env, target=None, source='foo_altsrc.b') assert str(tgt[0]) == 'foo.c', str(tgt[0]) def test_suffix(self): @@ -530,7 +530,7 @@ class BuilderTestCase(unittest.TestCase): tgt = builder(env, target = 'tgt4a tgt4b', source = 'src4')[0] assert tgt.path == 'tgt4a tgt4b.o', \ "Target has unexpected name: %s" % tgt.path - tgt = builder(env, source = 'src5')[0] + tgt = builder(env, target = None, source = 'src5')[0] assert tgt.path == 'src5.o', \ "Target has unexpected name: %s" % tgt.path @@ -551,17 +551,17 @@ class BuilderTestCase(unittest.TestCase): '$BAR' : '.new', '.zzz' : my_emit}, action='') - tgt = builder(my_env, source = 'f1')[0] + tgt = builder(my_env, target = None, source = 'f1')[0] assert tgt.path == 'f1.default', tgt.path - tgt = builder(my_env, source = 'f2.c')[0] + tgt = builder(my_env, target = None, source = 'f2.c')[0] assert tgt.path == 'f2.default', tgt.path - tgt = builder(my_env, source = 'f3.in')[0] + tgt = builder(my_env, target = None, source = 'f3.in')[0] assert tgt.path == 'f3.out', tgt.path - tgt = builder(my_env, source = 'f4.x')[0] + tgt = builder(my_env, target = None, source = 'f4.x')[0] assert tgt.path == 'f4.y', tgt.path - tgt = builder(my_env, source = 'f5.bar')[0] + tgt = builder(my_env, target = None, source = 'f5.bar')[0] assert tgt.path == 'f5.new', tgt.path - tgt = builder(my_env, source = 'f6.zzz')[0] + tgt = builder(my_env, target = None, source = 'f6.zzz')[0] assert tgt.path == 'f6.emit', tgt.path def test_single_source(self): @@ -589,7 +589,7 @@ class BuilderTestCase(unittest.TestCase): tgt.prepare() tgt.build() assert env['CNT'][0] == 2 - tgts = builder(env, infiles[2:4]) + tgts = builder(env, None, infiles[2:4]) for t in tgts: t.prepare() tgts[0].build() tgts[1].build() @@ -677,7 +677,7 @@ class BuilderTestCase(unittest.TestCase): assert str(tgt.sources[1]) == 'test2.foo', str(tgt.sources[1]) assert str(tgt.sources[2]) == 'test3.txt', str(tgt.sources[2]) - tgt = builder2(env, 'aaa.bar')[0] + tgt = builder2(env, None, 'aaa.bar')[0] assert str(tgt) == 'aaa', str(tgt) assert str(tgt.sources[0]) == 'aaa.foo', str(tgt.sources[0]) assert str(tgt.sources[0].sources[0]) == 'aaa.bar', \ @@ -1184,11 +1184,11 @@ class BuilderTestCase(unittest.TestCase): '.4b':emit4b}, target_factory=MyNode, source_factory=MyNode) - tgt = builder4(env, source='aaa.4a')[0] + tgt = builder4(env, None, source='aaa.4a')[0] assert str(tgt) == 'emit4a-aaa', str(tgt) - tgt = builder4(env, source='bbb.4b')[0] + tgt = builder4(env, None, source='bbb.4b')[0] assert str(tgt) == 'emit4b-bbb', str(tgt) - tgt = builder4(env, source='ccc.4c')[0] + tgt = builder4(env, None, source='ccc.4c')[0] assert str(tgt) == 'ccc', str(tgt) def emit4c(target, source, env): @@ -1196,7 +1196,7 @@ class BuilderTestCase(unittest.TestCase): target = map(lambda x: 'emit4c-' + x[:-3], source) return (target, source) builder4.add_emitter('.4c', emit4c) - tgt = builder4(env, source='ccc.4c')[0] + tgt = builder4(env, None, source='ccc.4c')[0] assert str(tgt) == 'emit4c-ccc', str(tgt) # Test a list of emitter functions. @@ -1241,43 +1241,43 @@ class BuilderTestCase(unittest.TestCase): env = Environment() b = SCons.Builder.Builder(action='foo', suffix='.o') - tgt = b(env, 'aaa')[0] + tgt = b(env, None, 'aaa')[0] assert str(tgt) == 'aaa.o', str(tgt) assert len(tgt.sources) == 1, map(str, tgt.sources) assert str(tgt.sources[0]) == 'aaa', map(str, tgt.sources) - tgt = b(env, 'bbb.c')[0] + tgt = b(env, None, 'bbb.c')[0] assert str(tgt) == 'bbb.o', str(tgt) assert len(tgt.sources) == 1, map(str, tgt.sources) assert str(tgt.sources[0]) == 'bbb.c', map(str, tgt.sources) - tgt = b(env, 'ccc.x.c')[0] + tgt = b(env, None, 'ccc.x.c')[0] assert str(tgt) == 'ccc.x.o', str(tgt) assert len(tgt.sources) == 1, map(str, tgt.sources) assert str(tgt.sources[0]) == 'ccc.x.c', map(str, tgt.sources) - tgt = b(env, ['d0.c', 'd1.c'])[0] + tgt = b(env, None, ['d0.c', 'd1.c'])[0] assert str(tgt) == 'd0.o', str(tgt) assert len(tgt.sources) == 2, map(str, tgt.sources) assert str(tgt.sources[0]) == 'd0.c', map(str, tgt.sources) assert str(tgt.sources[1]) == 'd1.c', map(str, tgt.sources) - tgt = b(env, source='eee')[0] + tgt = b(env, target = None, source='eee')[0] assert str(tgt) == 'eee.o', str(tgt) assert len(tgt.sources) == 1, map(str, tgt.sources) assert str(tgt.sources[0]) == 'eee', map(str, tgt.sources) - tgt = b(env, source='fff.c')[0] + tgt = b(env, target = None, source='fff.c')[0] assert str(tgt) == 'fff.o', str(tgt) assert len(tgt.sources) == 1, map(str, tgt.sources) assert str(tgt.sources[0]) == 'fff.c', map(str, tgt.sources) - tgt = b(env, source='ggg.x.c')[0] + tgt = b(env, target = None, source='ggg.x.c')[0] assert str(tgt) == 'ggg.x.o', str(tgt) assert len(tgt.sources) == 1, map(str, tgt.sources) assert str(tgt.sources[0]) == 'ggg.x.c', map(str, tgt.sources) - tgt = b(env, source=['h0.c', 'h1.c'])[0] + tgt = b(env, target = None, source=['h0.c', 'h1.c'])[0] assert str(tgt) == 'h0.o', str(tgt) assert len(tgt.sources) == 2, map(str, tgt.sources) assert str(tgt.sources[0]) == 'h0.c', map(str, tgt.sources) @@ -1285,7 +1285,7 @@ class BuilderTestCase(unittest.TestCase): w = b(env, target='i0.w', source=['i0.x'])[0] y = b(env, target='i1.y', source=['i1.z'])[0] - tgt = b(env, source=[w, y])[0] + tgt = b(env, None, source=[w, y])[0] assert str(tgt) == 'i0.o', str(tgt) assert len(tgt.sources) == 2, map(str, tgt.sources) assert str(tgt.sources[0]) == 'i0.w', map(str, tgt.sources) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index caa3b85..443c6b0 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -149,8 +149,15 @@ class BuilderWrapper: self.env = env self.builder = builder - def __call__(self, *args, **kw): - return apply(self.builder, (self.env,) + args, kw) + def __call__(self, target=None, source=_null, *args, **kw): + if source is _null: + source = target + target = None + if not target is None and not SCons.Util.is_List(target): + target = [target] + if not source is None and not SCons.Util.is_List(source): + source = [source] + return apply(self.builder, (self.env, target, source) + args, kw) # This allows a Builder to be executed directly # through the Environment to which it's attached. diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 27e7e8b..0a0f260 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -87,8 +87,10 @@ class Builder: def __init__(self, name = None): self.name = name - def __call__(self, env, **kw): + def __call__(self, env, target=None, source=None, **kw): global called_it + called_it['target'] = target + called_it['source'] = source called_it.update(kw) def execute(self, target = None, **kw): @@ -481,21 +483,21 @@ class EnvironmentTestCase(unittest.TestCase): env.Replace(BUILDERS = { 'builder1' : b1, 'builder2' : b2 }) called_it = {} - env.builder1(target = 'out1') - assert called_it['target'] == 'out1', called_it - assert not called_it.has_key('source') + env.builder1('in1') + assert called_it['target'] == None, called_it + assert called_it['source'] == ['in1'], called_it called_it = {} - env.builder2(target = 'out2', xyzzy = 1) - assert called_it['target'] == 'out2', called_it + env.builder2(source = 'in2', xyzzy = 1) + assert called_it['target'] == None, called_it + assert called_it['source'] == ['in2'], called_it assert called_it['xyzzy'] == 1, called_it - assert not called_it.has_key('source') called_it = {} env.builder1(foo = 'bar') assert called_it['foo'] == 'bar', called_it - assert not called_it.has_key('target') - assert not called_it.has_key('source') + assert called_it['target'] == None, called_it + assert called_it['source'] == None, called_it |