From: stevenknight Date: Sat, 9 Aug 2003 03:30:48 +0000 (+0000) Subject: Multi-level build dir with Object() and duplicate=0. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=4b5d312b2aec42c09dd42c6736f1923a656b2d38;p=scons.git Multi-level build dir with Object() and duplicate=0. git-svn-id: http://scons.tigris.org/svn/scons/trunk@762 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 74b537c4..9e9e7747 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -86,6 +86,10 @@ RELEASE 0.XX - XXX - Make how we build .rpm packages not depend on the installation locations from the distutils being used. + - When deducing a target Node, create it directly from the first + source Node, not by trying to create the right string to pass to + arg2nodes(). + From Gary Oberbrunner: - Report the target being built in error messages when building diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index b7bc1a30..be1608dd 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -349,19 +349,17 @@ class BuilderBase: src_suf = self.get_src_suffix(env) source = adjustixes(source, None, src_suf) + slist = SCons.Node.arg2nodes(source, self.source_factory) + if target is None: - s = source[0] - if isinstance(s, SCons.Node.Node): - s = str(s) - dir, s = os.path.split(s) - target = pre + self.splitext(s)[0] + suf - if dir: - target = [ os.path.join(dir, target) ] + try: + t_from_s = slist[0].target_from_source + except AttributeError: + raise UserError("Do not know how to create a target from source `%s'" % slist[0]) + tlist = [ t_from_s(pre, suf, self.splitext) ] else: target = adjustixes(target, pre, suf) - - slist = SCons.Node.arg2nodes(source, self.source_factory) - tlist = SCons.Node.arg2nodes(target, self.target_factory) + tlist = SCons.Node.arg2nodes(target, self.target_factory) if self.emitter: # The emitter is going to do str(node), but because we're diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index a7c2f121..f8d22ede 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -111,7 +111,7 @@ class Environment: env = Environment() -class MyNode: +class MyNode_without_target_from_source: def __init__(self, name): self.name = name self.sources = [] @@ -140,6 +140,10 @@ class MyNode: def get_executor(self, create=1): return self.executor +class MyNode(MyNode_without_target_from_source): + def target_from_source(self, prefix, suffix, stripext): + return MyNode(prefix + stripext(str(self))[0] + suffix) + class BuilderTestCase(unittest.TestCase): def test__nonzero__(self): @@ -215,6 +219,21 @@ class BuilderTestCase(unittest.TestCase): assert target.name == uni('n16 n17') assert target.sources[0].name == uni('n18 n19') + n20 = MyNode_without_target_from_source('n20') + flag = 0 + try: + target = builder(env, source=n20) + except SCons.Errors.UserError, e: + flag = 1 + assert flag, "UserError should be thrown if a source node can't create a target." + + builder = SCons.Builder.Builder(action="foo", + node_factory=MyNode, + prefix='p-', + suffix='.s') + target = builder(env, source='n21') + assert target.name == 'p-n21.s', target + def test_action(self): """Test Builder creation diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index d12a504d..249c8c6a 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -1455,6 +1455,10 @@ class File(Base): return dir, os.path.join(dir, bsig) return None, None + def target_from_source(self, prefix, suffix, splitext=SCons.Util.splitext): + return self.dir.File(prefix + splitext(self.name)[0] + suffix) + + default_fs = FS() diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index d651e1cf..17d037d2 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -1074,6 +1074,18 @@ class FSTestCase(unittest.TestCase): f.get_string(0) assert f.get_string(1) == 'baz', f.get_string(1) + x = fs.File('x.c') + t = x.target_from_source('pre-', '-suf') + assert str(t) == 'pre-x-suf', str(t) + + y = fs.File('dir/y') + t = y.target_from_source('pre-', '-suf') + assert str(t) == 'dir/pre-y-suf', str(t) + + z = fs.File('zz') + t = z.target_from_source('pre-', '-suf', lambda x: x[:-1]) + assert str(t) == 'pre-z-suf', str(t) + class EntryTestCase(unittest.TestCase): def runTest(self): """Test methods specific to the Entry sub-class. diff --git a/test/SConscript-build_dir.py b/test/SConscript-build_dir.py index 165619a1..d67fdaca 100644 --- a/test/SConscript-build_dir.py +++ b/test/SConscript-build_dir.py @@ -197,4 +197,41 @@ test.fail_test(os.path.exists(test.workpath('build', 'var8', 'aaa.in'))) test.fail_test(os.path.exists(test.workpath('build', 'var8', 'bbb.in'))) test.fail_test(os.path.exists(test.workpath('build', 'var8', 'ccc.in'))) +################### +test.subdir('test2') + +test.write(['test2', 'SConstruct'], """\ +SConscript('SConscript', build_dir='Build', src_dir='.', duplicate=0) +""") + +test.write(['test2', 'SConscript'], """\ +env = Environment() +foo_obj = env.Object('foo.c') +env.Program('foo', [foo_obj, 'bar.c']) +""") + +test.write(['test2', 'bar.c'], r""" +void +bar(void) { + printf("bar.c\n"); +} +""") + +test.write(['test2', 'foo.c'], """\ +int +main(int argc, char *argv[]) { + bar(); + printf("foo.c\n"); +} +""") + +test.run(chdir="test2") + +_obj = TestSCons._obj + +test.fail_test(os.path.exists(test.workpath('test2', 'foo' + _obj))) +test.fail_test(os.path.exists(test.workpath('test2', 'bar' + _obj))) +test.fail_test(not os.path.exists(test.workpath('test2', 'Build', 'foo' + _obj))) +test.fail_test(not os.path.exists(test.workpath('test2', 'Build', 'bar' + _obj))) + test.pass_test()