summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CHANGES.txt4
-rw-r--r--src/RELEASE.txt29
-rw-r--r--src/engine/SCons/Action.py13
-rw-r--r--src/engine/SCons/ActionTests.py12
-rw-r--r--src/engine/SCons/Builder.py16
-rw-r--r--src/engine/SCons/BuilderTests.py145
-rw-r--r--src/engine/SCons/Environment.py60
-rw-r--r--src/engine/SCons/EnvironmentTests.py59
-rw-r--r--src/engine/SCons/SConf.py4
-rw-r--r--src/engine/SCons/Util.py13
10 files changed, 191 insertions, 164 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 6550064..1c1829d 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -148,6 +148,10 @@ RELEASE 0.96 - XXX
- Don't blow up with stack trace when the external $PATH environment
variable isn't set.
+ - Make Builder calls return lists all the time, even if there's only
+ one target. This keeps things consistent and easier to program to
+ across platforms.
+
From Chris Murray:
- Add a .win32 attribute to force file names to expand with
diff --git a/src/RELEASE.txt b/src/RELEASE.txt
index 2228a83..0e63771 100644
--- a/src/RELEASE.txt
+++ b/src/RELEASE.txt
@@ -27,6 +27,33 @@ RELEASE 0.96 - XXX
Please note the following important changes since release 0.95:
+ - All Builder calls (both built-in like Program(), Library(),
+ etc. and customer Builders) now always return a list of target
+ Nodes. If the Builder only builds one target, the Builder
+ call will now return a list containing that target Node, not
+ the target Node itself as it used to do.
+
+ This change should be invisibile to most normal uses of the
+ return values from Builder calls. It will cause an error if the
+ SConscript file was performing some direct manipulation of the
+ returned Node value. For example, an attempt to print the name
+ of a target returned by the Object() Builder:
+
+ target = Object('foo.c')
+ # OLD WAY
+ print target
+
+ Will now need to access the first element in the list returned by
+ the Object() call:
+
+ target = Object('foo.c')
+ # NEW AY
+ print target[0]
+
+ This change was introduced to make the data type returned by Builder
+ calls consistent (always a list), regardless of platform or number
+ of returned targets.
+
- The SConsignFile() function now uses an internally-supplied
SCons.dblite module as the default DB scheme for the .sconsign file.
If you are using the SConsignFile() function without an explicitly
@@ -58,7 +85,7 @@ RELEASE 0.96 - XXX
FortranScan.add_skey('.x') => env.Append(FORTRANSUFFIXES = ['.x'])
- The internal "node_factory" keyword argument has been removed;
- the seperate and more flexible "target_factory" and "source_factory"
+ the separate and more flexible "target_factory" and "source_factory"
keywords should be used instead.
- SCons now treats file "extensions" that contain all digits (for
diff --git a/src/engine/SCons/Action.py b/src/engine/SCons/Action.py
index 6a90c76..8306791 100644
--- a/src/engine/SCons/Action.py
+++ b/src/engine/SCons/Action.py
@@ -358,6 +358,7 @@ class CommandAction(ActionBase):
# it is a path list, because that's a pretty
# common list like value to stick in an environment
# variable:
+ value = SCons.Util.flatten(value)
ENV[key] = string.join(map(str, value), os.pathsep)
elif not SCons.Util.is_String(value):
# If it isn't a string or a list, then
@@ -494,13 +495,13 @@ class FunctionAction(ActionBase):
return "unknown_python_function"
def strfunction(self, target, source, env):
- def quote(s):
- return '"' + str(s) + '"'
- def array(a, q=quote):
- return '[' + string.join(map(lambda x, q=q: q(x), a), ", ") + ']'
+ def array(a):
+ def quote(s):
+ return '"' + str(s) + '"'
+ return '[' + string.join(map(quote, a), ", ") + ']'
name = self.function_name()
- tstr = len(target) == 1 and quote(target[0]) or array(target)
- sstr = len(source) == 1 and quote(source[0]) or array(source)
+ tstr = array(target)
+ sstr = array(source)
return "%s(%s, %s)" % (name, tstr, sstr)
def __str__(self):
diff --git a/src/engine/SCons/ActionTests.py b/src/engine/SCons/ActionTests.py
index 9a89623..4c1649c 100644
--- a/src/engine/SCons/ActionTests.py
+++ b/src/engine/SCons/ActionTests.py
@@ -374,7 +374,7 @@ class ActionBaseTestCase(unittest.TestCase):
result = a("out", "in", env)
assert result == 7, result
s = sio.getvalue()
- assert s == 'execfunc("out", "in")\n', s
+ assert s == 'execfunc(["out"], ["in"])\n', s
SCons.Action.execute_actions = 0
@@ -383,7 +383,7 @@ class ActionBaseTestCase(unittest.TestCase):
result = a("out", "in", env)
assert result == 0, result
s = sio.getvalue()
- assert s == 'execfunc("out", "in")\n', s
+ assert s == 'execfunc(["out"], ["in"])\n', s
SCons.Action.print_actions_presub = 1
@@ -392,14 +392,14 @@ class ActionBaseTestCase(unittest.TestCase):
result = a("out", "in", env)
assert result == 0, result
s = sio.getvalue()
- assert s == 'execfunc("out", "in")\n', s
+ assert s == 'execfunc(["out"], ["in"])\n', s
sio = StringIO.StringIO()
sys.stdout = sio
result = a("out", "in", env, presub=1)
assert result == 0, result
s = sio.getvalue()
- assert s == 'Building out with action(s):\n execfunc(env, target, source)\nexecfunc("out", "in")\n', s
+ assert s == 'Building out with action(s):\n execfunc(env, target, source)\nexecfunc(["out"], ["in"])\n', s
a2 = SCons.Action.Action(execfunc)
@@ -408,14 +408,14 @@ class ActionBaseTestCase(unittest.TestCase):
result = a2("out", "in", env)
assert result == 0, result
s = sio.getvalue()
- assert s == 'Building out with action(s):\n execfunc(env, target, source)\nexecfunc("out", "in")\n', s
+ assert s == 'Building out with action(s):\n execfunc(env, target, source)\nexecfunc(["out"], ["in"])\n', s
sio = StringIO.StringIO()
sys.stdout = sio
result = a2("out", "in", env, presub=0)
assert result == 0, result
s = sio.getvalue()
- assert s == 'execfunc("out", "in")\n', s
+ assert s == 'execfunc(["out"], ["in"])\n', s
sio = StringIO.StringIO()
sys.stdout = sio
diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py
index 57f50c9..e6e7822 100644
--- a/src/engine/SCons/Builder.py
+++ b/src/engine/SCons/Builder.py
@@ -547,13 +547,11 @@ class BuilderBase:
if len(tlist) == 1:
builder = self
- result = tlist[0]
else:
builder = ListBuilder(self, env, tlist)
- result = tlist
_init_nodes(builder, env, overwarn.data, tlist, slist)
- return result
+ return tlist
def __call__(self, env, target = None, source = _null, **kw):
return self._execute(env, target, source, OverrideWarner(kw))
@@ -711,16 +709,14 @@ class MultiStepBuilder(BuilderBase):
final_sources.append(snode)
else:
tgt = subsidiary_builder._execute(env, None, snode, overwarn)
- # Only supply the builder with sources it is capable
- # of building.
- if SCons.Util.is_List(tgt):
+ # If the subsidiary Builder returned more than one target,
+ # then filter out any sources that this Builder isn't
+ # capable of building.
+ if len(tgt) > 1:
tgt = filter(lambda x, self=self, suf=src_suffixes:
self.splitext(SCons.Util.to_String(x))[1] in suf,
tgt)
- if not SCons.Util.is_List(tgt):
- final_sources.append(tgt)
- else:
- final_sources.extend(tgt)
+ final_sources.extend(tgt)
return BuilderBase._execute(self, env, target, final_sources, overwarn)
diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py
index 57e9f28..5a605ec 100644
--- a/src/engine/SCons/BuilderTests.py
+++ b/src/engine/SCons/BuilderTests.py
@@ -214,15 +214,15 @@ class BuilderTestCase(unittest.TestCase):
assert n1.executor, "no executor found"
assert not hasattr(n2, 'env')
- target = builder(env, target = 'n3', source = 'n4')
+ target = builder(env, target = 'n3', source = 'n4')[0]
assert target.name == 'n3'
assert target.sources[0].name == 'n4'
- target = builder(env, target = 'n4 n5', source = ['n6 n7'])
+ target = builder(env, target = 'n4 n5', source = ['n6 n7'])[0]
assert target.name == 'n4 n5'
assert target.sources[0].name == 'n6 n7'
- target = builder(env, target = ['n8 n9'], source = 'n10 n11')
+ target = builder(env, target = ['n8 n9'], source = 'n10 n11')[0]
assert target.name == 'n8 n9'
assert target.sources[0].name == 'n10 n11'
@@ -240,12 +240,12 @@ class BuilderTestCase(unittest.TestCase):
uni = unicode
target = builder(env, target = uni('n12 n13'),
- source = [uni('n14 n15')])
+ source = [uni('n14 n15')])[0]
assert target.name == uni('n12 n13')
assert target.sources[0].name == uni('n14 n15')
target = builder(env, target = [uni('n16 n17')],
- source = uni('n18 n19'))
+ source = uni('n18 n19'))[0]
assert target.name == uni('n16 n17')
assert target.sources[0].name == uni('n18 n19')
@@ -262,7 +262,7 @@ class BuilderTestCase(unittest.TestCase):
source_factory=MyNode,
prefix='p-',
suffix='.s')
- target = builder(env, source='n21')
+ target = builder(env, source='n21')[0]
assert target.name == 'p-n21.s', target
def test_mistaken_variables(self):
@@ -395,19 +395,19 @@ class BuilderTestCase(unittest.TestCase):
assert builder.get_prefix(env) == 'lib.'
builder = SCons.Builder.Builder(prefix = 'lib')
assert builder.get_prefix(env) == 'lib'
- tgt = builder(env, target = 'tgt1', source = 'src1')
+ tgt = builder(env, target = 'tgt1', source = 'src1')[0]
assert tgt.path == 'libtgt1', \
"Target has unexpected name: %s" % tgt.path
- tgt = builder(env, target = 'tgt2a tgt2b', source = 'src2')
+ 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')
+ tgt = builder(env, source = 'src3')[0]
assert tgt.path == 'libsrc3', \
"Target has unexpected name: %s" % tgt.path
- tgt = builder(env, source = 'lib/src4')
+ tgt = builder(env, 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')
+ tgt = builder(env, target = 'lib/tgt5', source = 'lib/src5')[0]
assert tgt.path == os.path.join('lib', 'libtgt5'), \
"Target has unexpected name: %s" % tgt.path
@@ -427,17 +427,17 @@ class BuilderTestCase(unittest.TestCase):
'.x' : 'y-',
'$FOO' : 'foo-',
'.zzz' : my_emit})
- tgt = builder(my_env, source = 'f1')
+ tgt = builder(my_env, source = 'f1')[0]
assert tgt.path == 'default-f1', tgt.path
- tgt = builder(my_env, source = 'f2.c')
+ tgt = builder(my_env, source = 'f2.c')[0]
assert tgt.path == 'default-f2', tgt.path
- tgt = builder(my_env, source = 'f3.in')
+ tgt = builder(my_env, source = 'f3.in')[0]
assert tgt.path == 'out-f3', tgt.path
- tgt = builder(my_env, source = 'f4.x')
+ tgt = builder(my_env, source = 'f4.x')[0]
assert tgt.path == 'y-f4', tgt.path
- tgt = builder(my_env, source = 'f5.foo')
+ tgt = builder(my_env, source = 'f5.foo')[0]
assert tgt.path == 'foo-f5', tgt.path
- tgt = builder(my_env, source = 'f6.zzz')
+ tgt = builder(my_env, source = 'f6.zzz')[0]
assert tgt.path == 'emit-f6', tgt.path
def test_src_suffix(self):
@@ -451,11 +451,11 @@ class BuilderTestCase(unittest.TestCase):
b1 = SCons.Builder.Builder(src_suffix = '.c')
assert b1.src_suffixes(env) == ['.c'], b1.src_suffixes(env)
- tgt = b1(env, target = 'tgt2', source = 'src2')
+ tgt = b1(env, target = 'tgt2', source = 'src2')[0]
assert tgt.sources[0].path == 'src2.c', \
"Source has unexpected name: %s" % tgt.sources[0].path
- tgt = b1(env, target = 'tgt3', source = 'src3a src3b')
+ tgt = b1(env, target = 'tgt3', source = 'src3a src3b')[0]
assert len(tgt.sources) == 1
assert tgt.sources[0].path == 'src3a src3b.c', \
"Unexpected tgt.sources[0] name: %s" % tgt.sources[0].path
@@ -485,13 +485,13 @@ class BuilderTestCase(unittest.TestCase):
assert builder.get_suffix(env) == '.o', builder.get_suffix(env)
builder = SCons.Builder.Builder(suffix = 'o')
assert builder.get_suffix(env) == '.o', builder.get_suffix(env)
- tgt = builder(env, target = 'tgt3', source = 'src3')
+ tgt = builder(env, target = 'tgt3', source = 'src3')[0]
assert tgt.path == 'tgt3.o', \
"Target has unexpected name: %s" % tgt.path
- tgt = builder(env, target = 'tgt4a tgt4b', source = 'src4')
+ 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')
+ tgt = builder(env, source = 'src5')[0]
assert tgt.path == 'src5.o', \
"Target has unexpected name: %s" % tgt.path
@@ -511,17 +511,17 @@ class BuilderTestCase(unittest.TestCase):
'.x' : '.y',
'$BAR' : '.new',
'.zzz' : my_emit})
- tgt = builder(my_env, source = 'f1')
+ tgt = builder(my_env, source = 'f1')[0]
assert tgt.path == 'f1.default', tgt.path
- tgt = builder(my_env, source = 'f2.c')
+ tgt = builder(my_env, source = 'f2.c')[0]
assert tgt.path == 'f2.default', tgt.path
- tgt = builder(my_env, source = 'f3.in')
+ tgt = builder(my_env, source = 'f3.in')[0]
assert tgt.path == 'f3.out', tgt.path
- tgt = builder(my_env, source = 'f4.x')
+ tgt = builder(my_env, source = 'f4.x')[0]
assert tgt.path == 'f4.y', tgt.path
- tgt = builder(my_env, source = 'f5.bar')
+ tgt = builder(my_env, source = 'f5.bar')[0]
assert tgt.path == 'f5.new', tgt.path
- tgt = builder(my_env, source = 'f6.zzz')
+ tgt = builder(my_env, source = 'f6.zzz')[0]
assert tgt.path == 'f6.emit', tgt.path
def test_single_source(self):
@@ -541,11 +541,11 @@ class BuilderTestCase(unittest.TestCase):
builder = SCons.Builder.Builder(action=SCons.Action.Action(func,None),
single_source = 1, suffix='.out')
env['CNT'] = [0]
- tgt = builder(env, target=outfiles[0], source=infiles[0])
+ tgt = builder(env, target=outfiles[0], source=infiles[0])[0]
tgt.prepare()
tgt.build()
assert env['CNT'][0] == 1, env['CNT'][0]
- tgt = builder(env, outfiles[1], infiles[1])
+ tgt = builder(env, outfiles[1], infiles[1])[0]
tgt.prepare()
tgt.build()
assert env['CNT'][0] == 2
@@ -629,14 +629,15 @@ class BuilderTestCase(unittest.TestCase):
src_builder = builder1,
src_suffix = '.foo')
- tgt = builder2(env, target='baz', source=['test.bar', 'test2.foo', 'test3.txt'])
+ tgt = builder2(env, target='baz',
+ source=['test.bar', 'test2.foo', 'test3.txt'])[0]
assert str(tgt.sources[0]) == 'test.foo', str(tgt.sources[0])
assert str(tgt.sources[0].sources[0]) == 'test.bar', \
str(tgt.sources[0].sources[0])
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')
+ tgt = builder2(env, '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', \
@@ -658,7 +659,7 @@ class BuilderTestCase(unittest.TestCase):
src_builder=builder5,
suffix='.exe',
src_suffix='.obj')
- tgt = builder6(env, 'test', 'test.i')
+ tgt = builder6(env, 'test', 'test.i')[0]
assert str(tgt) == 'test.exe', str(tgt)
assert str(tgt.sources[0]) == 'test_wrap.obj', str(tgt.sources[0])
assert str(tgt.sources[0].sources[0]) == 'test_wrap.c', \
@@ -679,14 +680,14 @@ class BuilderTestCase(unittest.TestCase):
assert isinstance(builder, SCons.Builder.CompositeBuilder)
assert isinstance(builder.action, SCons.Action.CommandGeneratorAction)
- tgt = builder(env, target='test1', source='test1.foo')
+ tgt = builder(env, target='test1', source='test1.foo')[0]
assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
assert tgt.builder.action is builder.action
- tgt = builder(env, target='test2', source='test1.bar')
+ tgt = builder(env, target='test2', source='test1.bar')[0]
assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
assert tgt.builder.action is builder.action
flag = 0
- tgt = builder(env, target='test3', source=['test2.bar', 'test1.foo'])
+ tgt = builder(env, target='test3', source=['test2.bar', 'test1.foo'])[0]
try:
tgt.build()
except SCons.Errors.UserError, e:
@@ -695,7 +696,7 @@ class BuilderTestCase(unittest.TestCase):
match = str(e) == "While building `['test3']' from `test1.foo': Cannot build multiple sources with different extensions: .bar, .foo"
assert match, e
- tgt = builder(env, target='test4', source=['test4.BAR2'])
+ tgt = builder(env, target='test4', source=['test4.BAR2'])[0]
assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
try:
tgt.build()
@@ -707,7 +708,7 @@ class BuilderTestCase(unittest.TestCase):
env['FOO_SUFFIX'] = '.BAR2'
builder.add_action('$NEW_SUFFIX', func_action)
flag = 0
- tgt = builder(env, target='test5', source=['test5.BAR2'])
+ tgt = builder(env, target='test5', source=['test5.BAR2'])[0]
try:
tgt.build()
except SCons.Errors.UserError:
@@ -726,10 +727,10 @@ class BuilderTestCase(unittest.TestCase):
assert isinstance(builder, SCons.Builder.CompositeBuilder)
assert isinstance(builder.action, SCons.Action.CommandGeneratorAction)
- tgt = builder(env, target='t1', source='t1a.ina t1b.ina')
+ tgt = builder(env, target='t1', source='t1a.ina t1b.ina')[0]
assert isinstance(tgt.builder, SCons.Builder.BuilderBase)
- tgt = builder(env, target='t2', source='t2a.foo t2b.ina')
+ tgt = builder(env, target='t2', source='t2a.foo t2b.ina')[0]
assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder), tgt.builder.__dict__
bar_bld = SCons.Builder.Builder(action = 'a-bar',
@@ -743,14 +744,14 @@ class BuilderTestCase(unittest.TestCase):
builder.add_action('.bar', 'bar')
- tgt = builder(env, target='t3-foo', source='t3a.foo t3b.ina')
+ tgt = builder(env, target='t3-foo', source='t3a.foo t3b.ina')[0]
assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder)
- tgt = builder(env, target='t3-bar', source='t3a.bar t3b.inb')
+ tgt = builder(env, target='t3-bar', source='t3a.bar t3b.inb')[0]
assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder)
flag = 0
- tgt = builder(env, target='t5', source=['test5a.foo', 'test5b.inb'])
+ tgt = builder(env, target='t5', source=['test5a.foo', 'test5b.inb'])[0]
try:
tgt.build()
except SCons.Errors.UserError, e:
@@ -760,7 +761,7 @@ class BuilderTestCase(unittest.TestCase):
assert match, e
flag = 0
- tgt = builder(env, target='t6', source=['test6a.bar', 'test6b.ina'])
+ tgt = builder(env, target='t6', source=['test6a.bar', 'test6b.ina'])[0]
try:
tgt.build()
except SCons.Errors.UserError, e:
@@ -770,7 +771,7 @@ class BuilderTestCase(unittest.TestCase):
assert match, e
flag = 0
- tgt = builder(env, target='t4', source=['test4a.ina', 'test4b.inb'])
+ tgt = builder(env, target='t4', source=['test4a.ina', 'test4b.inb'])[0]
try:
tgt.build()
except SCons.Errors.UserError, e:
@@ -780,7 +781,7 @@ class BuilderTestCase(unittest.TestCase):
assert match, e
flag = 0
- tgt = builder(env, target='t7', source=['test7'])
+ tgt = builder(env, target='t7', source=['test7'])[0]
try:
tgt.build()
except SCons.Errors.UserError, e:
@@ -790,7 +791,7 @@ class BuilderTestCase(unittest.TestCase):
assert match, e
flag = 0
- tgt = builder(env, target='t8', source=['test8.unknown'])
+ tgt = builder(env, target='t8', source=['test8.unknown'])[0]
try:
tgt.build()
except SCons.Errors.UserError, e:
@@ -809,7 +810,7 @@ class BuilderTestCase(unittest.TestCase):
env = Environment()
builder = SCons.Builder.Builder(target_scanner=tscan,
source_scanner=sscan)
- tgt = builder(env, target='foo2', source='bar')
+ tgt = builder(env, target='foo2', source='bar')[0]
assert tgt.target_scanner == tscan, tgt.target_scanner
assert tgt.source_scanner == sscan, tgt.source_scanner
@@ -820,7 +821,7 @@ class BuilderTestCase(unittest.TestCase):
src_builder = builder1,
target_scanner = tscan,
source_scanner = tscan)
- tgt = builder2(env, target='baz2', source='test.bar test2.foo test3.txt')
+ tgt = builder2(env, target='baz2', source='test.bar test2.foo test3.txt')[0]
assert tgt.target_scanner == tscan, tgt.target_scanner
assert tgt.source_scanner == tscan, tgt.source_scanner
@@ -838,7 +839,7 @@ class BuilderTestCase(unittest.TestCase):
# With no scanner specified, source_scanner and
# backup_source_scanner are None.
env1 = Environment()
- tgt = builder(env1, target='foo1.x', source='bar.y')
+ tgt = builder(env1, target='foo1.x', source='bar.y')[0]
src = tgt.sources[0]
assert tgt.target_scanner != scanner, tgt.target_scanner
assert src.source_scanner is None, src.source_scanner
@@ -848,7 +849,7 @@ class BuilderTestCase(unittest.TestCase):
# has a scanner must still set the scanner.
env2 = Environment()
env2.scanner = scanner
- tgt = builder(env2, target='foo2.x', source='bar.y')
+ tgt = builder(env2, target='foo2.x', source='bar.y')[0]
src = tgt.sources[0]
assert tgt.target_scanner != scanner, tgt.target_scanner
assert src.source_scanner is None, src.source_scanner
@@ -864,7 +865,7 @@ class BuilderTestCase(unittest.TestCase):
env=Environment(CC='cc')
builder = SCons.Builder.Builder(action=buildFunc)
- tgt = builder(env, target='foo', source='bar', foo=1, bar=2, CC='mycc')
+ tgt = builder(env, target='foo', source='bar', foo=1, bar=2, CC='mycc')[0]
tgt.build()
assert self.foo == 1, self.foo
assert self.bar == 2, self.bar
@@ -890,7 +891,7 @@ class BuilderTestCase(unittest.TestCase):
emitter=emit,
target_factory=MyNode,
source_factory=MyNode)
- tgt = builder(env, target='foo2', source='bar')
+ tgt = builder(env, target='foo2', source='bar')[0]
assert str(tgt) == 'foo2', str(tgt)
assert str(tgt.sources[0]) == 'bar', str(tgt.sources[0])
@@ -899,7 +900,7 @@ class BuilderTestCase(unittest.TestCase):
assert 'foo3' in map(str, tgt), map(str, tgt)
assert 'bar1' in map(str, tgt), map(str, tgt)
- tgt = builder(env, target='foo4', source='bar', bar=1)
+ tgt = builder(env, target='foo4', source='bar', bar=1)[0]
assert str(tgt) == 'foo4', str(tgt)
assert len(tgt.sources) == 2, len(tgt.sources)
assert 'baz' in map(str, tgt.sources), map(str, tgt.sources)
@@ -911,7 +912,7 @@ class BuilderTestCase(unittest.TestCase):
target_factory=MyNode,
source_factory=MyNode)
- tgt = builder2(env2, target='foo5', source='bar')
+ tgt = builder2(env2, target='foo5', source='bar')[0]
assert str(tgt) == 'foo5', str(tgt)
assert str(tgt.sources[0]) == 'bar', str(tgt.sources[0])
@@ -920,7 +921,7 @@ class BuilderTestCase(unittest.TestCase):
assert 'foo6' in map(str, tgt), map(str, tgt)
assert 'bar2' in map(str, tgt), map(str, tgt)
- tgt = builder2(env2, target='foo7', source='bar', bar=1)
+ tgt = builder2(env2, target='foo7', source='bar', bar=1)[0]
assert str(tgt) == 'foo7', str(tgt)
assert len(tgt.sources) == 2, len(tgt.sources)
assert 'baz' in map(str, tgt.sources), map(str, tgt.sources)
@@ -947,7 +948,7 @@ class BuilderTestCase(unittest.TestCase):
emitter=emit3,
target_factory=MyNode,
source_factory=MyNode)
- tgt = builder3(env, target=node, source='bar')
+ tgt = builder3(env, target=node, source='bar')[0]
assert tgt is new_node, tgt
assert tgt.builder is builder3, tgt.builder
assert node.builder is new_builder, node.builder
@@ -967,11 +968,11 @@ class BuilderTestCase(unittest.TestCase):
'.4b':emit4b},
target_factory=MyNode,
source_factory=MyNode)
- tgt = builder4(env, source='aaa.4a')
+ tgt = builder4(env, source='aaa.4a')[0]
assert str(tgt) == 'emit4a-aaa', str(tgt)
- tgt = builder4(env, source='bbb.4b')
+ tgt = builder4(env, source='bbb.4b')[0]
assert str(tgt) == 'emit4b-bbb', str(tgt)
- tgt = builder4(env, source='ccc.4c')
+ tgt = builder4(env, source='ccc.4c')[0]
assert str(tgt) == 'ccc', str(tgt)
def emit4c(target, source, env):
@@ -979,7 +980,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')
+ tgt = builder4(env, source='ccc.4c')[0]
assert str(tgt) == 'emit4c-ccc', str(tgt)
# Test a list of emitter functions.
@@ -1024,51 +1025,51 @@ class BuilderTestCase(unittest.TestCase):
env = Environment()
b = SCons.Builder.Builder(action='foo', suffix='.o')
- tgt = b(env, 'aaa')
+ tgt = b(env, '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')
+ tgt = b(env, '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')
+ tgt = b(env, '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'])
+ tgt = b(env, ['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')
+ tgt = b(env, 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')
+ tgt = b(env, 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')
+ tgt = b(env, 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'])
+ tgt = b(env, 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)
assert str(tgt.sources[1]) == 'h1.c', map(str, tgt.sources)
- w = b(env, target='i0.w', source=['i0.x'])
- y = b(env, target='i1.y', source=['i1.z'])
- tgt = b(env, source=[w, y])
+ 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]
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 0e79eb4..8e0c5ee 100644
--- a/src/engine/SCons/Environment.py
+++ b/src/engine/SCons/Environment.py
@@ -338,7 +338,9 @@ class Base:
if not args:
return []
- if not SCons.Util.is_List(args):
+ if SCons.Util.is_List(args):
+ args = SCons.Util.flatten(args)
+ else:
args = [args]
nodes = []
@@ -354,10 +356,16 @@ class Base:
n = self.subst(n, raw=1)
if node_factory:
n = node_factory(n)
- nodes.append(n)
+ try:
+ nodes.extend(n)
+ except TypeError:
+ nodes.append(n)
elif node_factory:
- v = self.subst(v, raw=1)
- nodes.append(node_factory(v))
+ v = node_factory(self.subst(v, raw=1))
+ try:
+ nodes.extend(v)
+ except TypeError:
+ nodes.append(v)
else:
nodes.append(v)
@@ -964,20 +972,14 @@ class Base:
s = self.arg2nodes(s, self.fs.Entry)
for t in tlist:
AliasBuilder(self, t, s)
- if len(tlist) == 1:
- tlist = tlist[0]
return tlist
def AlwaysBuild(self, *targets):
tlist = []
for t in targets:
tlist.extend(self.arg2nodes(t, self.fs.File))
-
for t in tlist:
t.set_always_build()
-
- if len(tlist) == 1:
- tlist = tlist[0]
return tlist
def BuildDir(self, build_dir, src_dir, duplicate=1):
@@ -1042,9 +1044,6 @@ class Base:
dlist = self.arg2nodes(dependency, self.fs.Entry)
for t in tlist:
t.add_dependency(dlist)
-
- if len(tlist) == 1:
- tlist = tlist[0]
return tlist
def Dir(self, name, *args, **kw):
@@ -1072,10 +1071,11 @@ class Base:
return SCons.Node.FS.find_file(file, nodes, self.fs.File)
def GetBuildPath(self, files):
- ret = map(str, self.arg2nodes(files, self.fs.Entry))
- if len(ret) == 1:
- return ret[0]
- return ret
+ result = map(str, self.arg2nodes(files, self.fs.Entry))
+ if SCons.Util.is_List(files):
+ return result
+ else:
+ return result[0]
def Ignore(self, target, dependency):
"""Ignore a dependency."""
@@ -1083,9 +1083,6 @@ class Base:
dlist = self.arg2nodes(dependency, self.fs.Entry)
for t in tlist:
t.add_ignore(dlist)
-
- if len(tlist) == 1:
- tlist = tlist[0]
return tlist
def Install(self, dir, source):
@@ -1105,21 +1102,17 @@ class Base:
for dnode in dnodes:
for src in sources:
target = self.fs.File(src.name, dnode)
- tgt.append(InstallBuilder(self, target, src))
- if len(tgt) == 1:
- tgt = tgt[0]
+ tgt.extend(InstallBuilder(self, target, src))
return tgt
def InstallAs(self, target, source):
"""Install sources as targets."""
sources = self.arg2nodes(source, self.fs.File)
targets = self.arg2nodes(target, self.fs.File)
- ret = []
+ result = []
for src, tgt in map(lambda x, y: (x, y), sources, targets):
- ret.append(InstallBuilder(self, tgt, src))
- if len(ret) == 1:
- ret = ret[0]
- return ret
+ result.extend(InstallBuilder(self, tgt, src))
+ return result
def Literal(self, string):
return SCons.Util.Literal(string)
@@ -1140,12 +1133,8 @@ class Base:
tlist = []
for t in targets:
tlist.extend(self.arg2nodes(t, self.fs.Entry))
-
for t in tlist:
t.set_precious()
-
- if len(tlist) == 1:
- tlist = tlist[0]
return tlist
def Repository(self, *dirs, **kw):
@@ -1181,18 +1170,13 @@ class Base:
self.Precious(side_effect)
for target in targets:
target.side_effects.append(side_effect)
- if len(side_effects) == 1:
- return side_effects[0]
- else:
- return side_effects
+ return side_effects
def SourceCode(self, entry, builder):
"""Arrange for a source code builder for (part of) a tree."""
entries = self.arg2nodes(entry, self.fs.Entry)
for entry in entries:
entry.set_src_builder(builder)
- if len(entries) == 1:
- return entries[0]
return entries
def SourceSignatures(self, type):
diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py
index c65fb03..1b2ceec 100644
--- a/src/engine/SCons/EnvironmentTests.py
+++ b/src/engine/SCons/EnvironmentTests.py
@@ -1733,31 +1733,31 @@ class EnvironmentTestCase(unittest.TestCase):
"""Test the Alias() method"""
env = Environment(FOO='kkk', BAR='lll', EA='export_alias')
- tgt = env.Alias('new_alias')
+ tgt = env.Alias('new_alias')[0]
assert str(tgt) == 'new_alias', tgt
assert tgt.sources == [], tgt.sources
- tgt = env.Alias('None_alias', None)
+ tgt = env.Alias('None_alias', None)[0]
assert str(tgt) == 'None_alias', tgt
assert tgt.sources == [], tgt.sources
- tgt = env.Alias('empty_list', [])
+ tgt = env.Alias('empty_list', [])[0]
assert str(tgt) == 'empty_list', tgt
assert tgt.sources == [], tgt.sources
- tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ])
+ tgt = env.Alias('export_alias', [ 'asrc1', '$FOO' ])[0]
assert str(tgt) == 'export_alias', tgt
assert len(tgt.sources) == 2, map(str, tgt.sources)
assert str(tgt.sources[0]) == 'asrc1', map(str, tgt.sources)
assert str(tgt.sources[1]) == 'kkk', map(str, tgt.sources)
- n = env.Alias(tgt, source = ['$BAR', 'asrc4'])
+ n = env.Alias(tgt, source = ['$BAR', 'asrc4'])[0]
assert n is tgt, n
assert len(tgt.sources) == 4, map(str, tgt.sources)
assert str(tgt.sources[2]) == 'lll', map(str, tgt.sources)
assert str(tgt.sources[3]) == 'asrc4', map(str, tgt.sources)
- n = env.Alias('$EA', 'asrc5')
+ n = env.Alias('$EA', 'asrc5')[0]
assert n is tgt, n
assert len(tgt.sources) == 5, map(str, tgt.sources)
assert str(tgt.sources[4]) == 'asrc5', map(str, tgt.sources)
@@ -1880,7 +1880,7 @@ class EnvironmentTestCase(unittest.TestCase):
"""Test the Command() method."""
env = Environment()
t = env.Command(target='foo.out', source=['foo1.in', 'foo2.in'],
- action='buildfoo $target $source')
+ action='buildfoo $target $source')[0]
assert not t.builder is None
assert t.builder.action.__class__.__name__ == 'CommandAction'
assert t.builder.action.cmd_list == 'buildfoo $target $source'
@@ -1889,7 +1889,7 @@ class EnvironmentTestCase(unittest.TestCase):
sub = SCons.Node.FS.default_fs.Dir('sub')
t = env.Command(target='bar.out', source='sub',
- action='buildbar $target $source')
+ action='buildbar $target $source')[0]
assert 'sub' in map(lambda x: x.path, t.sources)
def testFunc(env, target, source):
@@ -1897,7 +1897,7 @@ class EnvironmentTestCase(unittest.TestCase):
assert 'foo1.in' in map(str, source) and 'foo2.in' in map(str, source), map(str, source)
return 0
t = env.Command(target='foo.out', source=['foo1.in','foo2.in'],
- action=testFunc)
+ action=testFunc)[0]
assert not t.builder is None
assert t.builder.action.__class__.__name__ == 'FunctionAction'
t.build()
@@ -1910,7 +1910,7 @@ class EnvironmentTestCase(unittest.TestCase):
env = Environment(TEST2 = test2)
t = env.Command(target='baz.out', source='baz.in',
action='${TEST2(XYZ)}',
- XYZ='magic word')
+ XYZ='magic word')[0]
assert not t.builder is None
t.build()
assert x[0] == 'magic word', x
@@ -1951,7 +1951,8 @@ class EnvironmentTestCase(unittest.TestCase):
env.Dir('dir2')
env.File('xxx.py')
env.File('yyy.py')
- t = env.Depends(target='EnvironmentTest.py', dependency='Environment.py')
+ t = env.Depends(target='EnvironmentTest.py',
+ dependency='Environment.py')[0]
assert t.__class__.__name__ == 'Entry', t.__class__.__name__
assert t.path == 'EnvironmentTest.py'
assert len(t.depends) == 1
@@ -1959,7 +1960,7 @@ class EnvironmentTestCase(unittest.TestCase):
assert d.__class__.__name__ == 'Entry', d.__class__.__name__
assert d.path == 'Environment.py'
- t = env.Depends(target='${FOO}.py', dependency='${BAR}.py')
+ t = env.Depends(target='${FOO}.py', dependency='${BAR}.py')[0]
assert t.__class__.__name__ == 'File', t.__class__.__name__
assert t.path == 'xxx.py'
assert len(t.depends) == 1
@@ -1967,7 +1968,7 @@ class EnvironmentTestCase(unittest.TestCase):
assert d.__class__.__name__ == 'File', d.__class__.__name__
assert d.path == 'yyy.py'
- t = env.Depends(target='dir1', dependency='dir2')
+ t = env.Depends(target='dir1', dependency='dir2')[0]
assert t.__class__.__name__ == 'Dir', t.__class__.__name__
assert t.path == 'dir1'
assert len(t.depends) == 1
@@ -2061,7 +2062,7 @@ class EnvironmentTestCase(unittest.TestCase):
env.File('yyyzzz')
env.File('zzzyyy')
- t = env.Ignore(target='targ.py', dependency='dep.py')
+ t = env.Ignore(target='targ.py', dependency='dep.py')[0]
assert t.__class__.__name__ == 'Entry', t.__class__.__name__
assert t.path == 'targ.py'
assert len(t.ignore) == 1
@@ -2069,7 +2070,7 @@ class EnvironmentTestCase(unittest.TestCase):
assert i.__class__.__name__ == 'Entry', i.__class__.__name__
assert i.path == 'dep.py'
- t = env.Ignore(target='$FOO$BAR', dependency='$BAR$FOO')
+ t = env.Ignore(target='$FOO$BAR', dependency='$BAR$FOO')[0]
assert t.__class__.__name__ == 'File', t.__class__.__name__
assert t.path == 'yyyzzz'
assert len(t.ignore) == 1
@@ -2077,7 +2078,7 @@ class EnvironmentTestCase(unittest.TestCase):
assert i.__class__.__name__ == 'File', i.__class__.__name__
assert i.path == 'zzzyyy'
- t = env.Ignore(target='dir1', dependency='dir2')
+ t = env.Ignore(target='dir1', dependency='dir2')[0]
assert t.__class__.__name__ == 'Dir', t.__class__.__name__
assert t.path == 'dir1'
assert len(t.ignore) == 1
@@ -2146,7 +2147,7 @@ class EnvironmentTestCase(unittest.TestCase):
for tnode in tgt:
assert tnode.builder == InstallBuilder
- tgt = env.InstallAs(target='${FOO}.t', source='${BAR}.s')
+ tgt = env.InstallAs(target='${FOO}.t', source='${BAR}.s')[0]
assert tgt.path == 'iii.t'
assert tgt.sources[0].path == 'jjj.s'
assert tgt.builder == InstallBuilder
@@ -2282,9 +2283,9 @@ class EnvironmentTestCase(unittest.TestCase):
env.File('mylll.pdb')
env.Dir('mymmm.pdb')
- foo = env.Object('foo.obj', 'foo.cpp')
- bar = env.Object('bar.obj', 'bar.cpp')
- s = env.SideEffect('mylib.pdb', ['foo.obj', 'bar.obj'])
+ foo = env.Object('foo.obj', 'foo.cpp')[0]
+ bar = env.Object('bar.obj', 'bar.cpp')[0]
+ s = env.SideEffect('mylib.pdb', ['foo.obj', 'bar.obj'])[0]
assert s.__class__.__name__ == 'Entry', s.__class__.__name__
assert s.path == 'mylib.pdb'
assert s.side_effect
@@ -2293,9 +2294,9 @@ class EnvironmentTestCase(unittest.TestCase):
assert s.depends_on([bar])
assert s.depends_on([foo])
- fff = env.Object('fff.obj', 'fff.cpp')
- bbb = env.Object('bbb.obj', 'bbb.cpp')
- s = env.SideEffect('my${LIB}.pdb', ['${FOO}.obj', '${BAR}.obj'])
+ fff = env.Object('fff.obj', 'fff.cpp')[0]
+ bbb = env.Object('bbb.obj', 'bbb.cpp')[0]
+ s = env.SideEffect('my${LIB}.pdb', ['${FOO}.obj', '${BAR}.obj'])[0]
assert s.__class__.__name__ == 'File', s.__class__.__name__
assert s.path == 'mylll.pdb'
assert s.side_effect
@@ -2304,9 +2305,9 @@ class EnvironmentTestCase(unittest.TestCase):
assert s.depends_on([bbb])
assert s.depends_on([fff])
- ggg = env.Object('ggg.obj', 'ggg.cpp')
- ccc = env.Object('ccc.obj', 'ccc.cpp')
- s = env.SideEffect('mymmm.pdb', ['ggg.obj', 'ccc.obj'])
+ ggg = env.Object('ggg.obj', 'ggg.cpp')[0]
+ ccc = env.Object('ccc.obj', 'ccc.cpp')[0]
+ s = env.SideEffect('mymmm.pdb', ['ggg.obj', 'ccc.obj'])[0]
assert s.__class__.__name__ == 'Dir', s.__class__.__name__
assert s.path == 'mymmm.pdb'
assert s.side_effect
@@ -2318,18 +2319,18 @@ class EnvironmentTestCase(unittest.TestCase):
def test_SourceCode(self):
"""Test the SourceCode() method."""
env = Environment(FOO='mmm', BAR='nnn')
- e = env.SourceCode('foo', None)
+ e = env.SourceCode('foo', None)[0]
assert e.path == 'foo'
s = e.src_builder()
assert s is None, s
b = Builder()
- e = env.SourceCode(e, b)
+ e = env.SourceCode(e, b)[0]
assert e.path == 'foo'
s = e.src_builder()
assert s is b, s
- e = env.SourceCode('$BAR$FOO', None)
+ e = env.SourceCode('$BAR$FOO', None)[0]
assert e.path == 'nnnmmm'
s = e.src_builder()
assert s is None, s
diff --git a/src/engine/SCons/SConf.py b/src/engine/SCons/SConf.py
index 8087136..3aac882 100644
--- a/src/engine/SCons/SConf.py
+++ b/src/engine/SCons/SConf.py
@@ -268,7 +268,7 @@ class SConf:
source = self.confdir.File(f + extension)
sourceNode = self.env.SConfSourceBuilder(target=source,
source=None)
- nodesToBeBuilt.append(sourceNode)
+ nodesToBeBuilt.extend(sourceNode)
else:
source = None
@@ -335,7 +335,7 @@ class SConf:
pname = str(prog)
output = SConfFS.File(pname+'.out')
node = self.env.Command(output, prog, [ [ pname, ">", "${TARGET}"] ])
- ok = self.BuildNodes([node])
+ ok = self.BuildNodes(node)
if ok:
outputStr = output.get_contents()
return( 1, outputStr)
diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py
index 261d73c..25cea2f 100644
--- a/src/engine/SCons/Util.py
+++ b/src/engine/SCons/Util.py
@@ -953,6 +953,19 @@ else:
def is_String(e):
return type(e) is types.StringType or isinstance(e, UserString)
+def is_Scalar(e):
+ return is_String(e) or not is_List(e)
+
+def flatten(sequence, scalarp=is_Scalar, result=None):
+ if result is None:
+ result = []
+ for item in sequence:
+ if scalarp(item):
+ result.append(item)
+ else:
+ flatten(item, scalarp, result)
+ return result
+
class Proxy:
"""A simple generic Proxy class, forwarding all calls to
subject. So, for the benefit of the python newbie, what does