From: stevenknight Date: Sun, 10 Feb 2002 07:03:00 +0000 (+0000) Subject: Create all of the directories for a target list before trying to build the targets. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=745a61c82bb3633468b03ddba75c8ee0e1cb6811;p=scons.git Create all of the directories for a target list before trying to build the targets. git-svn-id: http://scons.tigris.org/svn/scons/trunk@251 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 29f99f6a..4b4256f8 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -25,6 +25,9 @@ RELEASE 0.05 - - 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. @@ -42,6 +45,9 @@ RELEASE 0.05 - - 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. diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 130a9e2c..347a6525 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -190,8 +190,9 @@ class ListBuilder: 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: diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index 5fb273b8..3b446723 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -61,7 +61,7 @@ sys.exit(0) act_py = test.workpath('act.py') outfile = test.workpath('outfile') -outfile2 = test.workpath('outfile') +outfile2 = test.workpath('outfile2') show_string = None instanced = None @@ -259,7 +259,10 @@ class BuilderTestCase(unittest.TestCase): 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') @@ -462,19 +465,24 @@ class BuilderTestCase(unittest.TestCase): """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') @@ -483,6 +491,36 @@ class BuilderTestCase(unittest.TestCase): 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", diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 55084364..3167005d 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -562,14 +562,16 @@ class File(Entry): 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() diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index f20c2fb9..94f81fdf 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -397,6 +397,7 @@ class FSTestCase(unittest.TestCase): # 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() @@ -448,7 +449,7 @@ class FSTestCase(unittest.TestCase): 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 diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index abe5e008..4e518603 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -59,7 +59,7 @@ class ListBuilder(Builder): 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) @@ -130,11 +130,11 @@ class NodeTestCase(unittest.TestCase): 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() @@ -180,20 +180,20 @@ class NodeTestCase(unittest.TestCase): 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 diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index 1222b1e9..1d09b20b 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -82,8 +82,6 @@ class Node: # 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, @@ -185,8 +183,8 @@ class Node: """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): diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 2b907a0e..a34814ed 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -73,6 +73,7 @@ class BuildTask(SCons.Taskmaster.Task): 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)) diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index a88fe63b..558845db 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -61,6 +61,7 @@ class Task: 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): diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py index 5beb9b2d..0d7a7ad4 100644 --- a/src/engine/SCons/TaskmasterTests.py +++ b/src/engine/SCons/TaskmasterTests.py @@ -51,6 +51,9 @@ class Node: global built built = self.name + " built" + def prepare(self): + pass + def children(self): return self.kids