summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2002-03-07 07:31:13 (GMT)
committerSteven Knight <knight@baldmt.com>2002-03-07 07:31:13 (GMT)
commitc233ea9e5d7f7a9f8ee369877ef1301b2702fbee (patch)
tree234fce47d3e54abc4db5cf19b645155655c6ba50 /src
parent9c97d73c12634007ce84cf162efe76f542e67085 (diff)
downloadSCons-c233ea9e5d7f7a9f8ee369877ef1301b2702fbee.zip
SCons-c233ea9e5d7f7a9f8ee369877ef1301b2702fbee.tar.gz
SCons-c233ea9e5d7f7a9f8ee369877ef1301b2702fbee.tar.bz2
Make the CFile Builder's SUFFIX configurable.
Diffstat (limited to 'src')
-rw-r--r--src/CHANGES.txt3
-rw-r--r--src/engine/SCons/Builder.py112
-rw-r--r--src/engine/SCons/BuilderTests.py56
-rw-r--r--src/engine/SCons/Defaults.py4
4 files changed, 104 insertions, 71 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 5835996..8b4269c 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -23,6 +23,9 @@ RELEASE 0.06 -
- Added RANLIB and RANLIBFLAGS construction variables. Only use them
in ARCOM if there's a "ranlib" program on the system.
+ - Add a configurable CFILESUFFIX for the Builder of .l and .y files
+ into C files.
+
RELEASE 0.05 - Thu, 21 Feb 2002 16:50:03 -0600
diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py
index 0b8fc49..2c87b6a 100644
--- a/src/engine/SCons/Builder.py
+++ b/src/engine/SCons/Builder.py
@@ -168,9 +168,9 @@ class BuilderBase:
"""
return apply(self.action.get_contents, (), kw)
- def src_suffixes(self):
+ def src_suffixes(self, env):
if self.src_suffix != '':
- return [self.src_suffix]
+ return [env.subst(self.src_suffix)]
return []
def targets(self, node):
@@ -213,8 +213,8 @@ class ListBuilder:
def get_contents(self, **kw):
return apply(self.builder.get_contents, (), kw)
- def src_suffixes(self):
- return self.builder.src_suffixes()
+ def src_suffixes(self, env):
+ return self.builder.src_suffixes(env)
def targets(self, node):
"""Return the list of targets for this builder instance.
@@ -243,19 +243,18 @@ class MultiStepBuilder(BuilderBase):
BuilderBase.__init__(self, name, action, prefix, suffix, src_suffix,
node_factory, scanner)
self.src_builder = src_builder
- self.dictSrcSuffix = {}
- for suff in self.src_builder.src_suffixes():
- self.dictSrcSuffix[suff] = None
def __call__(self, env, target = None, source = None):
slist = SCons.Util.scons_str2nodes(source, self.node_factory)
final_sources = []
src_suffix = env.subst(self.src_suffix)
+ sdict = {}
+ for suff in self.src_builder.src_suffixes(env):
+ sdict[suff] = None
for snode in slist:
path, ext = os.path.splitext(snode.abspath)
- if self.dictSrcSuffix.has_key(ext):
- tgt = self.src_builder(env, target = [ path ],
- source=snode)
+ if sdict.has_key(ext):
+ tgt = self.src_builder(env, target = [ path ], source = snode)
if not SCons.Util.is_List(tgt):
final_sources.append(tgt)
else:
@@ -265,8 +264,9 @@ class MultiStepBuilder(BuilderBase):
return BuilderBase.__call__(self, env, target=target,
source=final_sources)
- def src_suffixes(self):
- return BuilderBase.src_suffixes(self) + self.src_builder.src_suffixes()
+ def src_suffixes(self, env):
+ return BuilderBase.src_suffixes(self, env) + \
+ self.src_builder.src_suffixes(env)
class CompositeBuilder(BuilderBase):
"""This is a convenient Builder subclass that can build different
@@ -285,53 +285,61 @@ class CompositeBuilder(BuilderBase):
if src_builder and not SCons.Util.is_List(src_builder):
src_builder = [src_builder]
self.src_builder = src_builder
- self.builder_dict = {}
- for suff, act in action.items():
- # Create subsidiary builders for every suffix in the
- # action dictionary. If there's a src_builder that
- # matches the suffix, add that to the initializing
- # keywords so that a MultiStepBuilder will get created.
- kw = {'name' : name, 'action' : act, 'src_suffix' : suff}
- src_bld = filter(lambda x, s=suff: x.suffix == s, self.src_builder)
- if src_bld:
- kw['src_builder'] = src_bld[0]
- self.builder_dict[suff] = apply(Builder, (), kw)
+ self.action_dict = action
+ self.sdict = {}
+ self.sbuild = {}
def __call__(self, env, target = None, source = None):
tlist, slist = BuilderBase._create_nodes(self, env,
target=target, source=source)
- # XXX These [bs]dict tables are invariant for each unique
- # CompositeBuilder + Environment pair, so we should cache them.
- bdict = {}
- sdict = {}
- for suffix, bld in self.builder_dict.items():
- bdict[env.subst(bld.src_suffix)] = bld
- sdict[suffix] = suffix
- for s in bld.src_suffixes():
- bdict[s] = bld
- sdict[s] = suffix
-
- for tnode in tlist:
- suflist = map(lambda x, s=sdict: s[os.path.splitext(x.path)[1]],
- slist)
- last_suffix=''
- for suffix in suflist:
- if last_suffix and last_suffix != suffix:
- raise UserError, "The builder for %s can only build source files of identical suffixes: %s." % (tnode.path, str(map(lambda t: str(t.path), tnode.sources)))
- last_suffix = suffix
- if last_suffix:
- try:
- bdict[last_suffix].__call__(env, target = tnode,
- source = slist)
- except KeyError:
- raise UserError, "The builder for %s can not build files with suffix: %s" % (tnode.path, suffix)
+ r = repr(env)
+ if not self.sdict.has_key(r):
+ self.sdict[r] = {}
+ self.sbuild[r] = []
+ for suff in self.src_suffixes(env):
+ suff = env.subst(suff)
+ self.sdict[r][suff] = suff
+ self.sbuild[r].extend(filter(lambda x, e=env, s=suff:
+ e.subst(x.suffix) == s,
+ self.src_builder))
+ for sb in self.sbuild[r]:
+ suff = env.subst(sb.suffix)
+ for s in sb.src_suffixes(env):
+ self.sdict[r][env.subst(s)] = suff
+
+ sufflist = map(lambda x, s=self.sdict[r]:
+ s[os.path.splitext(x.path)[1]],
+ slist)
+ last_suffix = ''
+ for suff in sufflist:
+ if last_suffix and last_suffix != suff:
+ raise UserError, "The builder for %s can only build source files of identical suffixes: %s." % \
+ (tlist[0].path,
+ str(map(lambda t: str(t.path), tlist[0].sources)))
+ last_suffix = suff
+
+ if last_suffix:
+ kw = {
+ 'name' : self.name,
+ 'action' : self.action_dict[last_suffix],
+ 'src_suffix' : last_suffix,
+ }
+ if self.sbuild[r]:
+ kw['src_builder'] = self.sbuild[r][0]
+ # XXX We should be able to cache this
+ bld = apply(Builder, (), kw)
+ for tnode in tlist:
+ bld.__call__(env, target = tnode, source = slist)
if len(tlist) == 1:
tlist = tlist[0]
return tlist
- def src_suffixes(self):
- return reduce(lambda x, y: x + y,
- map(lambda b: b.src_suffixes(),
- self.builder_dict.values()))
+ def src_suffixes(self, env):
+ suffixes = map(lambda k, e=env: e.subst(k), self.action_dict.keys()) + \
+ reduce(lambda x, y: x + y,
+ map(lambda b, e=env: b.src_suffixes(e),
+ self.src_builder),
+ [])
+ return suffixes
diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py
index 68810b4..fc530ab 100644
--- a/src/engine/SCons/BuilderTests.py
+++ b/src/engine/SCons/BuilderTests.py
@@ -70,8 +70,17 @@ env_scanner = None
count = 0
class Environment:
+ def __init__(self, **kw):
+ self.d = {}
+ for k, v in kw.items():
+ self.d[k] = v
def subst(self, s):
- return s
+ try:
+ if s[0] == '$':
+ return self.d.get(s[1:], '')
+ except IndexError:
+ pass
+ return self.d.get(s, s)
def get_scanner(self, ext):
return env_scanner
env = Environment()
@@ -440,32 +449,43 @@ class BuilderTestCase(unittest.TestCase):
"Target has unexpected name: %s" % tgts[1].path
def test_src_suffix(self):
- """Test Builder creation with a specified source file suffix
-
- Make sure that the '.' separator is appended to the
- beginning if it isn't already present.
- """
- builder = SCons.Builder.Builder(name = "builder", src_suffix = '.c')
- assert builder.src_suffixes() == ['.c'], builder.src_suffixes()
+ """Test Builder creation with a specified source file suffix
+
+ Make sure that the '.' separator is appended to the
+ beginning if it isn't already present.
+ """
+ env = Environment(XSUFFIX = '.x', YSUFFIX = '.y')
+
+ b1 = SCons.Builder.Builder(name = "builder", src_suffix = '.c')
+ assert b1.src_suffixes(env) == ['.c'], b1.src_suffixes(env)
- tgt = builder(env, target = 'tgt2', source = 'src2')
- assert tgt.sources[0].path == 'src2.c', \
- "Source has unexpected name: %s" % tgt.sources[0].path
+ tgt = b1(env, target = 'tgt2', source = 'src2')
+ assert tgt.sources[0].path == 'src2.c', \
+ "Source has unexpected name: %s" % tgt.sources[0].path
- tgt = builder(env, target = 'tgt3', source = 'src3a src3b')
+ tgt = b1(env, target = 'tgt3', source = 'src3a src3b')
assert tgt.sources[0].path == 'src3a.c', \
- "Sources[0] has unexpected name: %s" % tgt.sources[0].path
+ "Unexpected tgt.sources[0] name: %s" % tgt.sources[0].path
assert tgt.sources[1].path == 'src3b.c', \
- "Sources[1] has unexpected name: %s" % tgt.sources[1].path
+ "Unexpected tgt.sources[1] name: %s" % tgt.sources[1].path
- b2 = SCons.Builder.Builder(name = "b2", src_suffix = '.2', src_builder = builder)
- assert b2.src_suffixes() == ['.2', '.c'], b2.src_suffixes()
+ b2 = SCons.Builder.Builder(name = "b2",
+ src_suffix = '.2',
+ src_builder = b1)
+ assert b2.src_suffixes(env) == ['.2', '.c'], b2.src_suffixes(env)
- b3 = SCons.Builder.Builder(name = "b2", action = {'.3a' : '', '.3b' : ''})
- s = b3.src_suffixes()
+ b3 = SCons.Builder.Builder(name = "b3",
+ action = {'.3a' : '', '.3b' : ''})
+ s = b3.src_suffixes(env)
s.sort()
assert s == ['.3a', '.3b'], s
+ b4 = SCons.Builder.Builder(name = "b4", src_suffix = '$XSUFFIX')
+ assert b4.src_suffixes(env) == ['.x'], b4.src_suffixes(env)
+
+ b5 = SCons.Builder.Builder(name = "b5", action = {'$YSUFFIX' : ''})
+ assert b5.src_suffixes(env) == ['.y'], b5.src_suffixes(env)
+
def test_suffix(self):
"""Test Builder creation with a specified target suffix
diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py
index 0a8e4cd..baad55a 100644
--- a/src/engine/SCons/Defaults.py
+++ b/src/engine/SCons/Defaults.py
@@ -68,7 +68,7 @@ CFile = SCons.Builder.Builder(name = 'CFile',
action = { '.l' : '$LEXCOM',
'.y' : '$YACCCOM',
},
- suffix = '.c')
+ suffix = '$CFILESUFFIX')
CPlusPlusAction = SCons.Action.Action('$CXXCOM')
@@ -205,6 +205,7 @@ def make_win32_env_from_paths(include, lib, path):
'CC' : 'cl',
'CCFLAGS' : '/nologo',
'CCCOM' : '$CC $CCFLAGS $_INCFLAGS /c $SOURCES /Fo$TARGET',
+ 'CFILESUFFIX' : '.c',
'CXX' : '$CC',
'CXXFLAGS' : '$CCFLAGS',
'CXXCOM' : '$CXX $CXXFLAGS $_INCFLAGS /c $SOURCES /Fo$TARGET',
@@ -264,6 +265,7 @@ if os.name == 'posix':
'CC' : 'cc',
'CCFLAGS' : '',
'CCCOM' : '$CC $CCFLAGS $_INCFLAGS -c -o $TARGET $SOURCES',
+ 'CFILESUFFIX' : '.c',
'CXX' : 'c++',
'CXXFLAGS' : '$CCFLAGS',
'CXXCOM' : '$CXX $CXXFLAGS $_INCFLAGS -c -o $TARGET $SOURCES',