diff options
author | Steven Knight <knight@baldmt.com> | 2003-08-10 14:59:15 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2003-08-10 14:59:15 (GMT) |
commit | 94b5aa145df7b763a262dd163203e20879f242f3 (patch) | |
tree | 9112f179649bfc9a8ad24a3a7d5195c20fd60ee0 | |
parent | ac34715d7fe736ae03e623a2d15e2e0e7f079503 (diff) | |
download | SCons-94b5aa145df7b763a262dd163203e20879f242f3.zip SCons-94b5aa145df7b763a262dd163203e20879f242f3.tar.gz SCons-94b5aa145df7b763a262dd163203e20879f242f3.tar.bz2 |
Allow prefixes and suffixes to be selected from dictionaries keyd by source file suffix.
-rw-r--r-- | doc/man/scons.1 | 8 | ||||
-rw-r--r-- | src/CHANGES.txt | 3 | ||||
-rw-r--r-- | src/engine/SCons/Builder.py | 61 | ||||
-rw-r--r-- | src/engine/SCons/BuilderTests.py | 28 |
4 files changed, 69 insertions, 31 deletions
diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 8df46cf..b9849c6 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -4946,14 +4946,14 @@ builder with the target. .IP prefix The prefix that will be prepended to the target file name. This may be a simple string, or a callable object that takes -a construction environment as its argument +two arguments, a construction environment and a list of sources, and returns a prefix. .ES b = Builder("build_it < $SOURCE > $TARGET" prefix = "file-") -def gen_prefix(env): +def gen_prefix(env, sources): return "file-" + env['PLATFORM'] + '-' b = Builder("build_it < $SOURCE > $TARGET" prefix = gen_prefix) @@ -4962,7 +4962,7 @@ b = Builder("build_it < $SOURCE > $TARGET" .IP suffix The suffix that will be appended to the target file name. This may be a simple string, or a callable object that takes -a construction environment as its argument +two arguments, a construction environment and a list of sources, and returns a suffix. If the suffix is a string, then .B scons @@ -4976,7 +4976,7 @@ to the beginning if one is desired. b = Builder("build_it < $SOURCE > $TARGET" suffix = "file-" -def gen_suffix(env): +def gen_suffix(env, sources): return "." + env['PLATFORM'] + "-file" b = Builder("build_it < $SOURCE > $TARGET" suffix = gen_suffix) diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 3df58e6..de2d75c 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -79,7 +79,8 @@ RELEASE 0.XX - XXX of the suffixes we use as C++ files. - Allow the "prefix" and "suffix" attributes of a Builder to be - callable objects that return generated strings. + callable objects that return generated strings, or dictionaries + that map a source file suffix to the right prefix/suffix. - Support a MAXLINELINELENGTH construction variable on Win32 systems to control when a temporary file is used for long command lines. diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index be1608d..34f28bc 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -110,7 +110,29 @@ class DictCmdGenerator: def __cmp__(self, other): return cmp(self.action_dict, other.action_dict) -class DictEmitter(UserDict.UserDict): +class Selector(UserDict.UserDict): + """A callable dictionary that maps file suffixes to dictionary + values.""" + def __call__(self, env, source): + ext = SCons.Util.splitext(str(source[0]))[1] + try: + return self[ext] + except KeyError: + # Try to perform Environment substitution on the keys of + # emitter_dict before giving up. + s_dict = {} + for (k,v) in self.items(): + s_k = env.subst(k) + s_dict[s_k] = v + try: + return s_dict[ext] + except KeyError: + try: + return self[None] + except KeyError: + return None + +class DictEmitter(Selector): """A callable dictionary that maps file suffixes to emitters. When called, it finds the right emitter in its dictionary for the suffix of the first source file, and calls that emitter to get the @@ -119,23 +141,9 @@ class DictEmitter(UserDict.UserDict): returned. """ def __call__(self, target, source, env): - ext = SCons.Util.splitext(str(source[0]))[1] - if ext: - try: - emitter = self[ext] - except KeyError: - # Before raising the user error, try to perform Environment - # substitution on the keys of emitter_dict. - s_dict = {} - for (k,v) in self.items(): - s_k = env.subst(k) - s_dict[s_k] = v - try: - emitter = s_dict[ext] - except KeyError: - emitter = None - if emitter: - target, source = emitter(target, source, env) + emitter = Selector.__call__(self, env, source) + if emitter: + target, source = emitter(target, source, env) return (target, source) def Builder(**kw): @@ -284,7 +292,11 @@ class BuilderBase: overrides = {}): self.action = SCons.Action.Action(action) self.multi = multi + if SCons.Util.is_Dict(prefix): + prefix = Selector(prefix) self.prefix = prefix + if SCons.Util.is_Dict(suffix): + suffix = Selector(suffix) self.suffix = suffix self.env = env self.overrides = overrides @@ -344,13 +356,14 @@ class BuilderBase: env = env.Override(overrides) - pre = self.get_prefix(env) - suf = self.get_suffix(env) src_suf = self.get_src_suffix(env) source = adjustixes(source, None, src_suf) slist = SCons.Node.arg2nodes(source, self.source_factory) + pre = self.get_prefix(env, slist) + suf = self.get_suffix(env, slist) + if target is None: try: t_from_s = slist[0].target_from_source @@ -410,16 +423,16 @@ class BuilderBase: return '.' + suff return suff - def get_prefix(self, env): + def get_prefix(self, env, sources=[]): prefix = self.prefix if callable(prefix): - prefix = prefix(env) + prefix = prefix(env, sources) return env.subst(prefix) - def get_suffix(self, env): + def get_suffix(self, env, sources=[]): suffix = self.suffix if callable(suffix): - suffix = suffix(env) + suffix = suffix(env, sources) else: suffix = self.adjust_suffix(suffix) return env.subst(suffix) diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index f8d22ed..8aafefa 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -362,7 +362,7 @@ class BuilderTestCase(unittest.TestCase): assert tgt.path == os.path.join('lib', 'libtgt5'), \ "Target has unexpected name: %s" % tgt.path - def gen_prefix(env): + def gen_prefix(env, sources): return "gen_prefix() says " + env['FOO'] my_env = Environment(FOO = 'xyzzy') builder = SCons.Builder.Builder(prefix = gen_prefix) @@ -370,6 +370,18 @@ class BuilderTestCase(unittest.TestCase): my_env['FOO'] = 'abracadabra' assert builder.get_prefix(my_env) == "gen_prefix() says abracadabra" + builder = SCons.Builder.Builder(prefix = {None : 'default-', + '.in' : 'out-', + '.x' : 'y-'}) + tgt = builder(env, source = 'f1') + assert tgt.path == 'default-f1', tgt.path + tgt = builder(env, source = 'f2.c') + assert tgt.path == 'default-f2', tgt.path + tgt = builder(env, source = 'f3.in') + assert tgt.path == 'out-f3', tgt.path + tgt = builder(env, source = 'f4.x') + assert tgt.path == 'y-f4', tgt.path + def test_src_suffix(self): """Test Builder creation with a specified source file suffix @@ -424,7 +436,7 @@ class BuilderTestCase(unittest.TestCase): assert tgt.path == 'src5.o', \ "Target has unexpected name: %s" % tgt.path - def gen_suffix(env): + def gen_suffix(env, sources): return "gen_suffix() says " + env['BAR'] my_env = Environment(BAR = 'hocus pocus') builder = SCons.Builder.Builder(suffix = gen_suffix) @@ -432,6 +444,18 @@ class BuilderTestCase(unittest.TestCase): my_env['BAR'] = 'presto chango' assert builder.get_suffix(my_env) == "gen_suffix() says presto chango" + builder = SCons.Builder.Builder(suffix = {None : '.default', + '.in' : '.out', + '.x' : '.y'}) + tgt = builder(env, source = 'f1') + assert tgt.path == 'f1.default', tgt.path + tgt = builder(env, source = 'f2.c') + assert tgt.path == 'f2.default', tgt.path + tgt = builder(env, source = 'f3.in') + assert tgt.path == 'f3.out', tgt.path + tgt = builder(env, source = 'f4.x') + assert tgt.path == 'f4.y', tgt.path + def test_ListBuilder(self): """Testing ListBuilder class.""" def function2(target, source, env, tlist = [outfile, outfile2], **kw): |