- More performance optimizations: cache #include lines from files,
eliminate unnecessary calls.
+ - If a prefix or suffix contains white space, treat the resulting
+ concatenation as separate arguments.
+
- Fix irregularities in the way we fetch DevStudio information from
the Windows registry, and in our registry error handling.
- Make writing .sconsign files more robust by first trying to write
to a temp file that we rename.
+ - Create all of the directories for a list of targets before trying
+ to build any of the targets.
+
From Anthony Roach:
- Make the scons script return an error code on failures.
if hasattr(self, 'status'):
return self.status
for t in self.tlist:
- # unlink all targets before building any
- t.remove()
+ # unlink all targets and make all directories
+ # before building anything
+ t.prepare()
kw['target'] = self.tlist[0]
self.status = apply(self.builder.execute, (), kw)
for t in self.tlist:
act_py = test.workpath('act.py')
outfile = test.workpath('outfile')
-outfile2 = test.workpath('outfile')
+outfile2 = test.workpath('outfile2')
show_string = None
instanced = None
return 1
builder = MyBuilder(action = function1, name = "function1")
- r = builder.execute(target = [outfile, outfile2])
+ try:
+ r = builder.execute(target = [outfile, outfile2])
+ except SCons.Errors.BuildError:
+ pass
assert r == 1
assert count == 1
c = test.read(outfile, 'r')
"""Testing ListBuilder class."""
global count
count = 0
- def function2(**kw):
+ def function2(tlist = [outfile, outfile2], **kw):
global count
count = count + 1
if not type(kw['target']) is type([]):
kw['target'] = [ kw['target'] ]
for t in kw['target']:
open(t, 'w').write("function2\n")
+ for t in tlist:
+ if not t in kw['target']:
+ open(t, 'w').write("function2\n")
return 1
builder = SCons.Builder.Builder(action = function2, name = "function2")
tgts = builder(env, target = [outfile, outfile2], source = 'foo')
- r = tgts[0].builder.execute(target = tgts[0])
- assert r == 1, r
+ try:
+ r = tgts[0].builder.execute(target = tgts)
+ except SCons.Errors.BuildError:
+ pass
c = test.read(outfile, 'r')
assert c == "function2\n", c
c = test.read(outfile2, 'r')
assert r == 1, r
assert count == 1, count
+ sub1_out = test.workpath('sub1', 'out')
+ sub2_out = test.workpath('sub2', 'out')
+
+ count = 0
+ def function3(tlist = [sub1_out, sub2_out], **kw):
+ global count
+ count = count + 1
+ if not type(kw['target']) is type([]):
+ kw['target'] = [ kw['target'] ]
+ for t in kw['target']:
+ open(t, 'w').write("function3\n")
+ for t in tlist:
+ if not t in kw['target']:
+ open(t, 'w').write("function3\n")
+ return 1
+
+ builder = SCons.Builder.Builder(action = function3, name = "function3")
+ tgts = builder(env, target = [sub1_out, sub2_out], source = 'foo')
+ try:
+ r = tgts[0].builder.execute(target = tgts)
+ except:
+ pass
+ assert r == 1, r
+ c = test.read(sub1_out, 'r')
+ assert c == "function3\n", c
+ c = test.read(sub2_out, 'r')
+ assert c == "function3\n", c
+ assert os.path.exists(test.workpath('sub1'))
+ assert os.path.exists(test.workpath('sub2'))
+
def test_MultiStepBuilder(self):
"""Testing MultiStepBuilder class."""
builder1 = SCons.Builder.Builder(name = "builder1",
pass
def build(self):
- self.__createDir()
Entry.build(self)
self.exists_flag = self.exists()
- def remove(self):
- """Remove this file."""
+ def prepare(self):
+ """Prepare for this file to be created."""
if self.exists():
- os.unlink(self.path)
+ if not self.precious:
+ os.unlink(self.path)
+ else:
+ self.__createDir()
default_fs = FS()
# Test building a file whose directory is not there yet...
f1 = fs.File(test.workpath("foo/bar/baz/ack"))
assert not f1.dir.exists()
+ f1.prepare()
f1.build()
assert f1.dir.exists()
test.write("remove_me", "\n")
assert os.path.exists(test.workpath("remove_me"))
f1 = fs.File(test.workpath("remove_me"))
- f1.remove()
+ f1.prepare()
assert not os.path.exists(test.workpath("remove_me"))
#XXX test current() for directories
if hasattr(self, 'status'):
return self.status
for n in self.nodes:
- n.remove()
+ n.prepare()
kw['target'] = self.nodes[0]
self.status = apply(Builder.execute, (self,), kw)
class MyNode(SCons.Node.Node):
def __init__(self, **kw):
apply(SCons.Node.Node.__init__, (self,), kw)
- self.remove_count = 0
+ self.prepare_count = 0
def __str__(self):
return self.path
- def remove(self):
- self.remove_count= self.remove_count+ 1
+ def prepare(self):
+ self.prepare_count = self.prepare_count+ 1
# Make sure it doesn't blow up if no builder is set.
node = MyNode()
node.build()
fff.build()
assert built_it
ggg.build()
- assert ggg.remove_count== 1, ggg.remove_count
+ assert ggg.prepare_count== 1, ggg.prepare_count
assert type(built_target) == type(MyNode()), type(built_target)
assert str(built_target) == "fff", str(built_target)
assert built_source == ["hhh", "iii"], built_source
delattr(lb, 'status')
- fff.remove_count = 0
- ggg.remove_count = 0
+ fff.prepare_count = 0
+ ggg.prepare_count = 0
built_it = None
ggg.build()
#assert built_it
fff.build()
- assert fff.remove_count== 1, fff.remove_count
+ assert fff.prepare_count== 1, fff.prepare_count
assert type(built_target) == type(MyNode()), type(built_target)
assert str(built_target) == "fff", str(built_target)
assert built_source == ["hhh", "iii"], built_source
# there will already be an associated status.
stat = self.builder.status
except AttributeError:
- if not self.precious:
- self.remove()
try:
stat = self.builder.execute(env = self.env.Dictionary(),
target = self,
"""Set the Node's precious value."""
self.precious = precious
- def remove(self):
- """Remove this Node's external object: no-op by default."""
+ def prepare(self):
+ """Prepare for this Node to be created: no-op by default."""
pass
def add_dependency(self, depend):
print 'scons: "%s" is up to date.' % str(self.targets[0])
else:
try:
+ self.targets[0].prepare()
self.targets[0].build()
except BuildError, e:
sys.stderr.write("scons: *** [%s] %s\n" % (e.node, e.errstr))
def execute(self):
if self.targets[0].get_state() != SCons.Node.up_to_date:
+ self.targets[0].prepare()
self.targets[0].build()
def get_target(self):
global built
built = self.name + " built"
+ def prepare(self):
+ pass
+
def children(self):
return self.kids