summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
authorSteven Knight <knight@baldmt.com>2002-01-07 05:06:56 (GMT)
committerSteven Knight <knight@baldmt.com>2002-01-07 05:06:56 (GMT)
commit053bdc2a64627a8770b6cf0fe6b4c535088088d6 (patch)
treeed63a7dbe361a5596ea33eddd608129b218a3452 /src/engine
parent1fe779a3c478c50c02504679ebda31e3ab515c3f (diff)
downloadSCons-053bdc2a64627a8770b6cf0fe6b4c535088088d6.zip
SCons-053bdc2a64627a8770b6cf0fe6b4c535088088d6.tar.gz
SCons-053bdc2a64627a8770b6cf0fe6b4c535088088d6.tar.bz2
Add support for lex and yacc.
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/SCons/Builder.py66
-rw-r--r--src/engine/SCons/BuilderTests.py14
-rw-r--r--src/engine/SCons/Defaults.py29
3 files changed, 73 insertions, 36 deletions
diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py
index 6651b13..f47e3a7 100644
--- a/src/engine/SCons/Builder.py
+++ b/src/engine/SCons/Builder.py
@@ -209,15 +209,15 @@ class BuilderBase:
if scanner:
s.scanner_set(scanner.instance(env))
- def __call__(self, env, target = None, source = None):
- tlist, slist = self._create_nodes(env, target, source)
-
- self._init_nodes(env, tlist, slist)
-
if len(tlist) == 1:
tlist = tlist[0]
return tlist
+ def __call__(self, env, target = None, source = None):
+ tlist, slist = self._create_nodes(env, target, source)
+
+ return self._init_nodes(env, tlist, slist)
+
def execute(self, **kw):
"""Execute a builder's action to create an output object.
"""
@@ -229,6 +229,11 @@ class BuilderBase:
"""
return apply(self.action.get_contents, (), kw)
+ def src_suffixes(self):
+ if self.src_suffix != '':
+ return [self.src_suffix]
+ return []
+
class MultiStepBuilder(BuilderBase):
"""This is a builder subclass that can build targets in
multiple steps. The src_builder parameter to the constructor
@@ -270,6 +275,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()
+
class CompositeBuilder(BuilderBase):
"""This is a convenient Builder subclass that can build different
files based on their suffixes. For each target, this builder
@@ -300,30 +308,23 @@ class CompositeBuilder(BuilderBase):
self.builder_dict[suff] = apply(Builder, (), kw)
def __call__(self, env, target = None, source = None):
- ret = BuilderBase.__call__(self, env, target=target, source=source)
+ tlist, slist = BuilderBase._create_nodes(self, env,
+ target=target, source=source)
- builder_dict = {}
- suff_dict = {}
+ # 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():
- builder_dict[env.subst(bld.src_suffix)] = bld
- suff_dict[suffix] = suffix
- b = bld
- while hasattr(b, 'src_builder'):
- # Walk the chain of src_builders and add the
- # src_suffix strings to the maps so that we know
- # all of those suffixes are legal, too.
- b = b.src_builder
- s = env.subst(b.src_suffix)
- builder_dict[s] = bld
- suff_dict[s] = suffix
-
- if type(ret) is types.ListType:
- tlist = ret
- else:
- tlist = [ ret ]
+ 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=suff_dict: s[os.path.splitext(x.path)[1]],
- tnode.sources)
+ 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:
@@ -331,10 +332,19 @@ class CompositeBuilder(BuilderBase):
last_suffix = suffix
if last_suffix:
try:
- tnode.builder_set(builder_dict[last_suffix])
+ 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)
- return ret
+
+ 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()))
print_actions = 1;
execute_actions = 1;
diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py
index b735a09..8293076 100644
--- a/src/engine/SCons/BuilderTests.py
+++ b/src/engine/SCons/BuilderTests.py
@@ -389,18 +389,26 @@ class BuilderTestCase(unittest.TestCase):
beginning if it isn't already present.
"""
builder = SCons.Builder.Builder(src_suffix = '.c')
- assert builder.src_suffix == '.c'
- builder = SCons.Builder.Builder(src_suffix = 'c')
- assert builder.src_suffix == '.c'
+ assert builder.src_suffixes() == ['.c'], builder.src_suffixes()
+
tgt = builder(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')
assert tgt.sources[0].path == 'src3a.c', \
"Sources[0] has unexpected name: %s" % tgt.sources[0].path
assert tgt.sources[1].path == 'src3b.c', \
"Sources[1] has unexpected name: %s" % tgt.sources[1].path
+ b2 = SCons.Builder.Builder(src_suffix = '.2', src_builder = builder)
+ assert b2.src_suffixes() == ['.2', '.c'], b2.src_suffixes()
+
+ b3 = SCons.Builder.Builder(action = {'.3a' : '', '.3b' : ''})
+ s = b3.src_suffixes()
+ s.sort()
+ assert s == ['.3a', '.3b'], s
+
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 bbc9e03..2e11c37 100644
--- a/src/engine/SCons/Defaults.py
+++ b/src/engine/SCons/Defaults.py
@@ -43,6 +43,12 @@ import SCons.Scanner.Prog
import string
import SCons.Errors
+CFile = SCons.Builder.Builder(name = 'CFile',
+ action = { '.l' : '$LEXCOM',
+ '.y' : '$YACCCOM',
+ },
+ suffix = '.c')
+
Object = SCons.Builder.Builder(name = 'Object',
action = { '.c' : '$CCCOM',
'.C' : '$CXXCOM',
@@ -53,7 +59,8 @@ Object = SCons.Builder.Builder(name = 'Object',
'.C++' : '$CXXCOM',
},
prefix = '$OBJPREFIX',
- suffix = '$OBJSUFFIX')
+ suffix = '$OBJSUFFIX',
+ src_builder = CFile)
Program = SCons.Builder.Builder(name = 'Program',
action = '$LINKCOM',
@@ -202,7 +209,13 @@ def make_win32_env_from_paths(include, lib, path):
'AR' : 'lib',
'ARFLAGS' : '/nologo',
'ARCOM' : '$AR $ARFLAGS /OUT:$TARGET $SOURCES',
- 'BUILDERS' : [Object, Program, Library],
+ 'LEX' : 'lex',
+ 'LEXFLAGS' : '',
+ 'LEXCOM' : '$LEX $LEXFLAGS -o$TARGET $SOURCES',
+ 'YACC' : 'yacc',
+ 'YACCFLAGS' : '',
+ 'YACCCOM' : '$YACC $YACCFLAGS -o $TARGET $SOURCES',
+ 'BUILDERS' : [CFile, Object, Program, Library],
'SCANNERS' : [CScan],
'OBJPREFIX' : '',
'OBJSUFFIX' : '.obj',
@@ -250,7 +263,13 @@ if os.name == 'posix':
'AR' : 'ar',
'ARFLAGS' : 'r',
'ARCOM' : '$AR $ARFLAGS $TARGET $SOURCES\nranlib $TARGET',
- 'BUILDERS' : [Object, Program, Library],
+ 'LEX' : 'lex',
+ 'LEXFLAGS' : '',
+ 'LEXCOM' : '$LEX $LEXFLAGS -o$TARGET $SOURCES',
+ 'YACC' : 'yacc',
+ 'YACCFLAGS' : '',
+ 'YACCCOM' : '$YACC $YACCFLAGS -o $TARGET $SOURCES',
+ 'BUILDERS' : [CFile, Object, Program, Library],
'SCANNERS' : [CScan],
'OBJPREFIX' : '',
'OBJSUFFIX' : '.o',
@@ -275,12 +294,12 @@ elif os.name == 'nt':
except:
try:
# We failed to detect DevStudio, so fall back to the
- # DevStudio environment variables:
+ # DevStudio environment variables:
ConstructionEnvironment = make_win32_env_from_paths(
os.environ["INCLUDE"], os.environ["LIB"], os.environ["PATH"])
except KeyError:
# The DevStudio environment variables don't exists,
- # so fall back to a reasonable default:
+ # so fall back to a reasonable default:
MVSdir = r'C:\Program Files\Microsoft Visual Studio'
MVSVCdir = r'%s\VC98' % MVSdir
ConstructionEnvironment = make_win32_env_from_paths(