From: stevenknight Date: Sat, 18 Sep 2004 18:30:35 +0000 (+0000) Subject: Build targets in an associated BuildDir even if there are local targets in the source... X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=190063febac37510217d6bcf9d6dcbc7f9cd1c02;p=scons.git Build targets in an associated BuildDir even if there are local targets in the source directory. (Kevin Quick) git-svn-id: http://scons.tigris.org/svn/scons/trunk@1084 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 1965c619..d7b66937 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -109,6 +109,9 @@ RELEASE 0.97 - XXX - Fix problems with Parallel Task Exception handling. + - Build targets in an associated BuildDir even if there are targets + or subdirectories locally in the source directory. + From Christoph Wiedemann: - Add an Environment.SetDefault() method that only sets values if diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index 84eb08dc..6bd5e213 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -253,6 +253,7 @@ class Taskmaster: self.ready = None # the next task that is ready to be executed self.order = order self.message = None + self.altered = [] def _find_next_ready_node(self): """Find the next node that is ready to be built""" @@ -331,15 +332,15 @@ class Taskmaster: self.ready = node break - # If there aren't any children with builders and this - # was a top-level argument, then see if we can find any + # If this was a top-level argument and we haven't already + # done so, see if we can alter the target list to find any # corresponding targets in linked build directories: - if not derived and node in self.targets: + if node in self.targets and node not in self.altered: alt, message = node.alter_targets() if alt: self.message = message - self.candidates.pop() - self.candidates.extend(alt) + self.candidates.extend(self.order(alt)) + self.altered.append(node) continue # Add derived files that have not been built diff --git a/src/engine/SCons/TaskmasterTests.py b/src/engine/SCons/TaskmasterTests.py index a9081928..cc4ba0cd 100644 --- a/src/engine/SCons/TaskmasterTests.py +++ b/src/engine/SCons/TaskmasterTests.py @@ -421,6 +421,9 @@ class TaskmasterTestCase(unittest.TestCase): t = tm.next_task() assert t.get_target() == n7 t.executed() + t = tm.next_task() + assert t.get_target() == n6 + t.executed() n1 = Node("n1") n2 = Node("n2", [n1]) diff --git a/test/BuildDir.py b/test/BuildDir.py index 4e2871a2..0877995d 100644 --- a/test/BuildDir.py +++ b/test/BuildDir.py @@ -355,7 +355,11 @@ test.run(chdir='work2', arguments='.', stderr=None) test.fail_test(not blank_output(test.stderr())) -test.up_to_date(chdir='work2', arguments='.') +test.run(chdir='work2', arguments='.', + stdout=test.wrap_stdout("""\ +scons: building associated BuildDir targets: build +scons: `.' is up to date. +""")) test.write( ['work3', 'SConstruct'], """\ SConscriptChdir(0) @@ -377,7 +381,10 @@ test.write( ['work3', 'existing.h'], """\ """) test.run(chdir='work3', - stdout=test.wrap_stdout("scons: `.' is up to date.\n"), + stdout=test.wrap_stdout("""\ +scons: building associated BuildDir targets: build +scons: `.' is up to date. +"""), stderr="""\ existing.h:/* a header file */ non_existing.h: diff --git a/test/NodeOps.py b/test/NodeOps.py index e884400c..ae9268c0 100644 --- a/test/NodeOps.py +++ b/test/NodeOps.py @@ -57,7 +57,7 @@ if string.find(sys.platform, 'irix') > -1: test = TestSCons.TestSCons() -test.subdir('bld', 'src') +test.subdir('bld', 'src', ['src', 'subsrcdir']) sconstruct = r""" foo = Environment(SHCXXFLAGS = '%(fooflags)s', WIN32_INSERT_DEF=1) @@ -126,49 +126,75 @@ doIt() } """) -test.write(['src', 'SConscript'], r""" +sconscript = r""" import os Import('*') -# Interoperability with old Python versions. -True, False = 1, 0 +import __builtin__ +try: + __builtin__.True +except AttributeError: + __builtin__.True = 1 + __builtin__.False = 0 def mycopy(env, source, target): open(str(target[0]),'w').write(open(str(source[0]),'r').read()) + +def exists_test(node): + before = os.path.exists(str(node)) # doesn't exist yet in BuildDir + via_node = node.exists() # side effect causes copy from src + after = os.path.exists(str(node)) + node.is_derived() + node.is_pseudo_derived() + import SCons.Script + if SCons.Script.options.noexec: + if (before,via_node,after) != (False,False,False): + import sys + sys.stderr.write('BuildDir exits() populated during dryrun!\n') + sys.exit(-2) + else: + if (before,via_node,after) != (False,True,True): + import sys + sys.stderr.write('BuildDir exists() population did not occur! (%%s:%%s,%%s,%%s)\n'%%(str(node),before,via_node,after)) + sys.exit(-2) goo = Environment(CPPFLAGS = '%(fooflags)s') -Nodes.append(File('goof.in')) -before = os.path.exists('goof.in') # doesn't exist yet in BuildDir -via_node = Nodes[-1].exists() # side effect causes copy from src -after = os.path.exists('goof.in') -import SCons.Script -if SCons.Script.options.noexec: - if (before,via_node,after) != (False,False,False): - import sys - sys.stderr.write('BuildDir exits() populated during dryrun!\n') - sys.exit(-2) -else: - if (before,via_node,after) != (False,True,True): - import sys - sys.stderr.write('BuildDir exists() population did not occur!\n'%%(before,via_node,after)) - sys.exit(-2) +goof_in = File('goof.in') +if %(_E)s: + exists_test(goof_in) +Nodes.append(goof_in) Nodes.extend(goo.Command(target='goof.c', source='goof.in', action=mycopy)) +boo_src = File('subsrcdir/boo.c') +if %(_E)s: + exists_test(boo_src) +boo_objs = goo.Object(target='subsrcdir/boo%(_obj)s', source = boo_src) +Nodes.extend(boo_objs) Nodes.extend(goo.Object(target='goo%(_obj)s',source='goof.c')) -goo.Library(target = 'goo', source = 'goo%(_obj)s') -""" % locals() ) +goo.Library(target = 'goo', source = ['goo%(_obj)s'] + boo_objs) +""" test.write(['src', 'goof.in'], r""" #include +extern char *boo_sub(); + void doIt() { #ifdef FOO - printf("prog.cpp: GOO\n"); + printf("prog.cpp: %s\n", boo_sub()); #endif } """) +test.write(['src', 'subsrcdir', 'boo.c'], r""" +char * +boo_sub() +{ + return "GOO"; +} +""") + test.write('main.c', r""" void doIt(); @@ -181,23 +207,42 @@ main(int argc, char* argv[]) } """) +builddir_srcnodes = [ os.path.join('bld', 'goof.in'), + os.path.join('bld', 'subsrcdir', 'boo.c'), + ] + +sub_build_nodes = [ os.path.join('bld','subsrcdir','boo.o'), + os.path.join('bld','goo.o'), + os.path.join('bld','goof.c'), + os.path.join('bld','libgoo.a'), +] + build_nodes = ['fooprog', 'libfoo.so', 'foo.o', 'barprog', 'libbar.so', 'bar.o', 'gooprog', - os.path.join('bld','goo.o'), - os.path.join('bld','goof.c'), - os.path.join('bld','goof.in'), - ] + ] + builddir_srcnodes + sub_build_nodes + +def cleanup_test(): + "cleanup after running a test" + for F in builddir_srcnodes: + test.unlink(F) # will be repopulated during clean operation + test.run(arguments = '-c') + for F in builddir_srcnodes: + test.unlink(F) + for name in build_nodes: + test.must_not_exist(test.workpath(name)) + ### First pass, make sure everything goes quietly for name in build_nodes: - test.fail_test(os.path.exists(test.workpath(name))) + test.must_not_exist(test.workpath(name)) _E=0 test.write('SConstruct', sconstruct % locals() ) +test.write(['src', 'SConscript'], sconscript % locals() ) test.run(arguments = '.', stderr=TestSCons.noisy_ar, @@ -208,22 +253,19 @@ test.run(program = test.workpath('barprog'), stdout = "prog.cpp: BAR\n") test.run(program = test.workpath('gooprog'), stdout = "prog.cpp: GOO\n") for name in build_nodes: - test.fail_test(not os.path.exists(test.workpath(name))) + test.must_exist(test.workpath(name)) -test.unlink('bld/goof.in') # will be repopulated during clean operation -test.run(arguments = '-c') -test.unlink('bld/goof.in') -for name in build_nodes: - test.fail_test(os.path.exists(test.workpath(name))) +cleanup_test() ### Next pass: add internal Node ops that may have side effects to ### ensure that those side-effects don't interfere with building for name in build_nodes: - test.fail_test(os.path.exists(test.workpath(name))) + test.must_not_exist(test.workpath(name)) _E=1 test.write('SConstruct', sconstruct % locals() ) +test.write(['src', 'SConscript'], sconscript % locals() ) test.run(arguments = '.', stderr=TestSCons.noisy_ar, @@ -234,29 +276,26 @@ test.run(program = test.workpath('barprog'), stdout = "prog.cpp: BAR\n") test.run(program = test.workpath('gooprog'), stdout = "prog.cpp: GOO\n") for name in build_nodes: - test.fail_test(not os.path.exists(test.workpath(name))) + test.must_exist(test.workpath(name)) -test.unlink('bld/goof.in') # will be repopulated during clean operation -test.run(arguments = '-c') -test.unlink('bld/goof.in') -for name in build_nodes: - test.fail_test(os.path.exists(test.workpath(name))) +cleanup_test() ### Next pass: try a dry-run first and verify that it doesn't change ### the buildability. for name in build_nodes: - test.fail_test(os.path.exists(test.workpath(name))) + test.must_not_exist(test.workpath(name)) _E=1 test.write('SConstruct', sconstruct % locals() ) +test.write(['src', 'SConscript'], sconscript % locals() ) test.run(arguments = '-n .', stderr=TestSCons.noisy_ar, match=TestSCons.match_re_dotall) for name in build_nodes: - test.fail_test(os.path.exists(test.workpath(name))) + test.must_not_exist(test.workpath(name)) test.run(arguments = '.', stderr=TestSCons.noisy_ar, @@ -267,13 +306,52 @@ test.run(program = test.workpath('barprog'), stdout = "prog.cpp: BAR\n") test.run(program = test.workpath('gooprog'), stdout = "prog.cpp: GOO\n") for name in build_nodes: - test.fail_test(not os.path.exists(test.workpath(name))) + test.must_exist(test.workpath(name)) + +cleanup_test() + +### Next pass: do an up-build from a BuildDir src + + +for name in build_nodes: + test.must_not_exist(test.workpath(name)) + +_E=0 +test.write('SConstruct', sconstruct % locals() ) +test.write(['src', 'SConscript'], sconscript % locals() ) + +test.run(chdir='src', arguments = '-u', + stderr=TestSCons.noisy_ar, + match=TestSCons.match_re_dotall) + +for name in build_nodes: + if name in sub_build_nodes or name in builddir_srcnodes: + test.must_exist(test.workpath(name)) + else: + test.must_not_exist(test.workpath(name)) + +cleanup_test() + +### Next pass: do an up-build from a BuildDir src with Node Ops +### side-effects + +for name in build_nodes: + test.must_not_exist(test.workpath(name)) + +_E=1 +test.write('SConstruct', sconstruct % locals() ) +test.write(['src', 'SConscript'], sconscript % locals() ) + +test.run(chdir='src', arguments = '-u', + stderr=TestSCons.noisy_ar, + match=TestSCons.match_re_dotall) -test.unlink('bld/goof.in') # will be repopulated during clean operation -test.run(arguments = '-c') -test.unlink('bld/goof.in') for name in build_nodes: - test.fail_test(os.path.exists(test.workpath(name))) + if name in sub_build_nodes or name in builddir_srcnodes: + test.must_exist(test.workpath(name)) + else: + test.must_not_exist(test.workpath(name)) +cleanup_test() test.pass_test() diff --git a/test/option-u.py b/test/option-u.py index 28bab30d..9b5e88cf 100644 --- a/test/option-u.py +++ b/test/option-u.py @@ -70,7 +70,11 @@ env.Cat(target = 'dir/f2b.out', source = 'dir/f2b.in') test.write(['sub4', 'SConscript'], """ Import('env') env.Cat(target = 'f4a.out', source = 'f4a.in') -env.Cat(target = 'dir/f4b.out', source = 'dir/f4b.in') +f4b_in = File('dir/f4b.in') +f4b_in.exists() +f4b_in.is_derived() +f4b_in.is_pseudo_derived() +env.Cat(target = 'dir/f4b.out', source = f4b_in) """) test.write(['sub1', 'f1a.in'], "sub1/f1a.in") @@ -128,6 +132,7 @@ test.run(chdir = 'sub4', scons: building associated BuildDir targets: build cat(["%s"], ["%s"]) cat(["%s"], ["%s"]) +scons: `sub4' is up to date. """ % (f4b_out, f4b_in, f4a_out, f4a_in))) test.must_not_exist(test.workpath('sub1', 'sub1/f1b.out'))