diff options
author | Steven Knight <knight@baldmt.com> | 2003-08-09 03:30:48 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2003-08-09 03:30:48 (GMT) |
commit | ef6d3c2883fc43048e4eb5418eeb082d58b9d6cb (patch) | |
tree | 6b82fbae7e677011698bc39debd81d1572ff5c8c | |
parent | 2e861a0422e5330249e360b5098b3ad00d26b5e9 (diff) | |
download | SCons-ef6d3c2883fc43048e4eb5418eeb082d58b9d6cb.zip SCons-ef6d3c2883fc43048e4eb5418eeb082d58b9d6cb.tar.gz SCons-ef6d3c2883fc43048e4eb5418eeb082d58b9d6cb.tar.bz2 |
Multi-level build dir with Object() and duplicate=0.
-rw-r--r-- | src/CHANGES.txt | 4 | ||||
-rw-r--r-- | src/engine/SCons/Builder.py | 18 | ||||
-rw-r--r-- | src/engine/SCons/BuilderTests.py | 21 | ||||
-rw-r--r-- | src/engine/SCons/Node/FS.py | 4 | ||||
-rw-r--r-- | src/engine/SCons/Node/FSTests.py | 12 | ||||
-rw-r--r-- | test/SConscript-build_dir.py | 37 |
6 files changed, 85 insertions, 11 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 74b537c..9e9e774 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 b7bc1a3..be1608d 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 a7c2f12..f8d22ed 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 d12a504..249c8c6 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 d651e1c..17d037d 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 165619a..d67fdac 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() |