summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2003-08-10 14:59:15 (GMT)
committerSteven Knight <knight@baldmt.com>2003-08-10 14:59:15 (GMT)
commit94b5aa145df7b763a262dd163203e20879f242f3 (patch)
tree9112f179649bfc9a8ad24a3a7d5195c20fd60ee0
parentac34715d7fe736ae03e623a2d15e2e0e7f079503 (diff)
downloadSCons-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.18
-rw-r--r--src/CHANGES.txt3
-rw-r--r--src/engine/SCons/Builder.py61
-rw-r--r--src/engine/SCons/BuilderTests.py28
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):