diff options
37 files changed, 1810 insertions, 671 deletions
diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 79ca4b7..a81bae5 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -686,6 +686,69 @@ def my_platform(env): env = Environment(platform = my_platform) .EE +Additionally, a specific set of tools +with which to initialize the environment +may specified as an optional keyword argument: + +.ES +env = Environment(tools = ['msvc', 'lex']) +.EE + +The elements of the tools list may also +be functions or callable objects, +in which case the Environment() method +will call the specified elements +to update the new construction environment: + +.ES +def my_tool(env): + env['XYZZY'] = 'xyzzy' + +env = Environment(tools = [my_tool]) +.EE + +SCons supports the following tool specifications +out of the box on +.B cygwin +and +.B posix +platforms: + +.ES +ar +dvipdf +dvips +g++ +g77 +gcc +gnulink +latex +lex +pdflatex +pdftex +tex +yacc +.EE + +and supports the following tool specifications out of the box on +.B win32 +platforms: + +.ES +dvipdf +dvips +g77 +latex +lex +lib +mslink +msvc +pdflatex +pdftex +tex +yacc +.EE + .SS Builder Methods Build rules are specified by calling a construction @@ -1767,7 +1830,7 @@ foo = SConscript('subdir/SConscript', "env") .TP .RI SConscriptChdir( value ) -When a non-negative +When a non-zero .I value is specified, this instructs @@ -1842,6 +1905,17 @@ or by using a similar function such as the string.split() function in the Python library. .TP +.RI Tool( string ) +Returns a callable object +that can be used to initialize +a construction environment using the +tools keyword of the Environment() method. + +.ES +env = Environment(tools = [ Tool('msvc') ]) +.EE + +.TP .RI WhereIs( program ", [" path ", [" pathext ]]) Searches for the specified executable diff --git a/rpm/scons.spec b/rpm/scons.spec index 0bfa0e0..a2cb76d 100644 --- a/rpm/scons.spec +++ b/rpm/scons.spec @@ -96,6 +96,40 @@ rm -rf $RPM_BUILD_ROOT /usr/lib/scons/SCons/Sig/__init__.pyc /usr/lib/scons/SCons/Taskmaster.py /usr/lib/scons/SCons/Taskmaster.pyc +/usr/lib/scons/SCons/Tool/__init__.py +/usr/lib/scons/SCons/Tool/__init__.pyc +/usr/lib/scons/SCons/Tool/ar.py +/usr/lib/scons/SCons/Tool/ar.pyc +/usr/lib/scons/SCons/Tool/dvipdf.py +/usr/lib/scons/SCons/Tool/dvipdf.pyc +/usr/lib/scons/SCons/Tool/dvips.py +/usr/lib/scons/SCons/Tool/dvips.pyc +/usr/lib/scons/SCons/Tool/g++.py +/usr/lib/scons/SCons/Tool/g++.pyc +/usr/lib/scons/SCons/Tool/g77.py +/usr/lib/scons/SCons/Tool/g77.pyc +/usr/lib/scons/SCons/Tool/gcc.py +/usr/lib/scons/SCons/Tool/gcc.pyc +/usr/lib/scons/SCons/Tool/gnulink.py +/usr/lib/scons/SCons/Tool/gnulink.pyc +/usr/lib/scons/SCons/Tool/latex.py +/usr/lib/scons/SCons/Tool/latex.pyc +/usr/lib/scons/SCons/Tool/lex.py +/usr/lib/scons/SCons/Tool/lex.pyc +/usr/lib/scons/SCons/Tool/lib.py +/usr/lib/scons/SCons/Tool/lib.pyc +/usr/lib/scons/SCons/Tool/mslink.py +/usr/lib/scons/SCons/Tool/mslink.pyc +/usr/lib/scons/SCons/Tool/msvc.py +/usr/lib/scons/SCons/Tool/msvc.pyc +/usr/lib/scons/SCons/Tool/pdflatex.py +/usr/lib/scons/SCons/Tool/pdflatex.pyc +/usr/lib/scons/SCons/Tool/pdftex.py +/usr/lib/scons/SCons/Tool/pdftex.pyc +/usr/lib/scons/SCons/Tool/tex.py +/usr/lib/scons/SCons/Tool/tex.pyc +/usr/lib/scons/SCons/Tool/yacc.py +/usr/lib/scons/SCons/Tool/yacc.pyc /usr/lib/scons/SCons/Util.py /usr/lib/scons/SCons/Util.pyc /usr/lib/scons/SCons/Warnings.py diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 63feea2..ad9f56c 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -38,6 +38,12 @@ RELEASE 0.08 - - Removed support for the prefix, suffix and src_suffix arguments to Builder() to be callable functions. + From Charles Crain and Steven Knight: + + - Add a "tools=" keyword argument to Environment instantiation, + and a separate Tools() method, for more flexible specification + of tool-specific environment changes. + From Steven Knight: - Add a "platform=" keyword argument to Environment instantiation, diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index dce5291..b67d63a 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -23,5 +23,22 @@ SCons/Sig/__init__.py SCons/Sig/MD5.py SCons/Sig/TimeStamp.py SCons/Taskmaster.py +SCons/Tool/__init__.py +SCons/Tool/ar.py +SCons/Tool/dvipdf.py +SCons/Tool/dvips.py +SCons/Tool/g++.py +SCons/Tool/g77.py +SCons/Tool/gcc.py +SCons/Tool/gnulink.py +SCons/Tool/latex.py +SCons/Tool/lex.py +SCons/Tool/lib.py +SCons/Tool/mslink.py +SCons/Tool/msvc.py +SCons/Tool/pdflatex.py +SCons/Tool/pdftex.py +SCons/Tool/tex.py +SCons/Tool/yacc.py SCons/Util.py SCons/Warnings.py diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 94a8946..4dd6163 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -1,6 +1,20 @@ """SCons.Builder -XXX +Builder object subsystem. + +A Builder object is a callable that encapsulates information about how +to execute actions to create a Node (file) from other Nodes (files), and +how to create those dependencies for tracking. + +The main entry point here is the Builder() factory method. This +provides a procedural interface that creates the right underlying +Builder object based on the keyword arguments supplied and the types of +the arguments. + +The goal is for this external interface to be simple enough that the +vast majority of users can create new Builders as necessary to support +building new types of files in their configurations, without having to +dive any deeper into this subsystem. """ @@ -55,6 +69,11 @@ class DictCmdGenerator: def src_suffixes(self): return self.action_dict.keys() + def add_action(self, suffix, action): + """Add a suffix-action pair to the mapping. + """ + self.action_dict[suffix] = action + def __call__(self, source, target, env, **kw): ext = None for src in map(str, source): @@ -71,9 +90,12 @@ class DictCmdGenerator: return self.action_dict[ext] except KeyError: raise UserError("Don't know how to build a file with suffix %s." % ext) + def __cmp__(self, other): + return cmp(self.action_dict, other.action_dict) def Builder(**kw): """A factory for builder objects.""" + composite = None if kw.has_key('name'): SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, "The use of the 'name' parameter to Builder() is deprecated.") @@ -83,9 +105,9 @@ def Builder(**kw): kw['action'] = SCons.Action.CommandGenerator(kw['generator']) del kw['generator'] elif kw.has_key('action') and SCons.Util.is_Dict(kw['action']): - action_dict = kw['action'] - kw['action'] = SCons.Action.CommandGenerator(DictCmdGenerator(action_dict)) - kw['src_suffix'] = action_dict.keys() + composite = DictCmdGenerator(kw['action']) + kw['action'] = SCons.Action.CommandGenerator(composite) + kw['src_suffix'] = composite.src_suffixes() if kw.has_key('emitter') and \ SCons.Util.is_String(kw['emitter']): @@ -99,9 +121,14 @@ def Builder(**kw): kw['emitter'] = EmitterProxy(var) if kw.has_key('src_builder'): - return apply(MultiStepBuilder, (), kw) + ret = apply(MultiStepBuilder, (), kw) else: - return apply(BuilderBase, (), kw) + ret = apply(BuilderBase, (), kw) + + if composite: + ret = CompositeBuilder(ret, composite) + + return ret def _init_nodes(builder, env, args, tlist, slist): """Initialize lists of target and source nodes with all of @@ -139,25 +166,7 @@ def _init_nodes(builder, env, args, tlist, slist): t.add_source(slist) if builder.scanner: t.target_scanner = builder.scanner - -class _callable_adaptor: - """When crteating a Builder, you can pass a string OR - a callable in for prefix, suffix, or src_suffix. - src_suffix even takes a list! - - If a string or list is passed, we use this class to - adapt it to a callable.""" - def __init__(self, static): - self.static = static - - def __call__(self, **kw): - return self.static - - def __cmp__(self, other): - if isinstance(other, _callable_adaptor): - return cmp(self.static, other.static) - return -1 - + def _adjust_suffix(suff): if suff and not suff[0] in [ '.', '$' ]: return '.' + suff @@ -176,7 +185,7 @@ class EmitterProxy: def __call__(self, target, source, env, **kw): emitter = self.var - # Recursively substitue the variable. + # Recursively substitute the variable. # We can't use env.subst() because it deals only # in strings. Maybe we should change that? while SCons.Util.is_String(emitter) and \ @@ -190,6 +199,9 @@ class EmitterProxy: args.update(kw) return apply(emitter, (), args) + def __cmp__(self, other): + return cmp(self.var, other.var) + class BuilderBase: """Base class for Builders, objects that create output nodes (files) from input nodes (files). @@ -212,10 +224,7 @@ class BuilderBase: self.prefix = prefix self.suffix = suffix - if SCons.Util.is_String(src_suffix): - self.src_suffix = [ src_suffix ] - else: - self.src_suffix = src_suffix + self.set_src_suffix(src_suffix) self.target_factory = target_factory or node_factory self.source_factory = source_factory or node_factory @@ -264,9 +273,9 @@ class BuilderBase: ret.append(f) return ret - pre = self.get_prefix(env, args) - suf = self.get_suffix(env, args) - src_suf = self.get_src_suffix(env, args) + pre = self.get_prefix(env) + suf = self.get_suffix(env) + src_suf = self.get_src_suffix(env) if self.emitter: # pass the targets and sources to the emitter as strings # rather than nodes since str(node) doesn't work @@ -299,7 +308,6 @@ class BuilderBase: return tlist - def execute(self, **kw): """Execute a builder's action to create an output object. """ @@ -316,21 +324,28 @@ class BuilderBase: """ return apply(self.action.get_contents, (), kw) - def src_suffixes(self, env, args): + def src_suffixes(self, env): return map(lambda x, e=env: e.subst(_adjust_suffix(x)), self.src_suffix) - def get_src_suffix(self, env, args): + def set_src_suffix(self, src_suffix): + if not src_suffix: + src_suffix = [] + elif not SCons.Util.is_List(src_suffix): + src_suffix = [ src_suffix ] + self.src_suffix = src_suffix + + def get_src_suffix(self, env): """Get the first src_suffix in the list of src_suffixes.""" - if not self.src_suffix: + ret = self.src_suffixes(env) + if not ret: return '' - else: - return self.src_suffix[0] + return ret[0] - def get_suffix(self, env, args): + def get_suffix(self, env): return env.subst(_adjust_suffix(self.suffix)) - def get_prefix(self, env, args): + def get_prefix(self, env): return env.subst(self.prefix) def targets(self, node): @@ -340,20 +355,19 @@ class BuilderBase: """ return [ node ] -class ListBuilder: - """This is technically not a Builder object, but a wrapper - around another Builder object. This is designed to look - like a Builder object, though, for purposes of building an - array of targets from a single Action execution. +class ListBuilder(SCons.Util.Proxy): + """A Proxy to support building an array of targets (for example, + foo.o and foo.h from foo.y) from a single Action execution. """ def __init__(self, builder, env, tlist): + SCons.Util.Proxy.__init__(self, builder) self.builder = builder + self.scanner = builder.scanner + self.env = env self.tlist = tlist - self.name = "ListBuilder(%s)"%builder.get_name(env) - - def get_name(self, env): - return self.name + self.multi = builder.multi + self.name = "ListBuilder(%s)"%builder.name def execute(self, **kw): if hasattr(self, 'status'): @@ -375,10 +389,17 @@ class ListBuilder: return self.tlist def __cmp__(self, other): - return cmp(self.__dict__, other.__dict__) + return cmp(self.__dict__, other.__dict__) - def __getattr__(self, name): - return getattr(self.builder, name) + def get_name(self, env): + """Attempts to get the name of the Builder. + + If the Builder's name attribute is None, then we will look at + the BUILDERS variable of env, expecting it to be a dictionary + containing this Builder, and we will return the key of the + dictionary.""" + + return "ListBuilder(%s)" % self.builder.get_name(env) class MultiStepBuilder(BuilderBase): """This is a builder subclass that can build targets in @@ -421,7 +442,12 @@ class MultiStepBuilder(BuilderBase): sdict = {} self.sdict[r] = sdict for bld in self.src_builder: - for suf in bld.src_suffixes(env, kw): + if SCons.Util.is_String(bld): + try: + bld = env['BUILDERS'][bld] + except KeyError: + continue + for suf in bld.src_suffixes(env): sdict[suf] = bld for snode in slist: @@ -440,7 +466,7 @@ class MultiStepBuilder(BuilderBase): # Only supply the builder with sources it is capable # of building. tgt = filter(lambda x, - suf=self.src_suffixes(env, kw): + suf=self.src_suffixes(env): os.path.splitext(SCons.Util.to_String(x))[1] in \ suf, tgt) final_sources.extend(tgt) @@ -452,9 +478,48 @@ class MultiStepBuilder(BuilderBase): return apply(BuilderBase.__call__, (self, env), dictKwArgs) - def src_suffixes(self, env, args): - return BuilderBase.src_suffixes(self, env, args) + \ - reduce(lambda x, y: x + y, - map(lambda b, e=env, args=args: b.src_suffixes(e, args), - self.src_builder), - []) + def get_src_builders(self, env): + """Return all the src_builders for this Builder. + + This is essentially a recursive descent of the src_builder "tree." + """ + ret = [] + for bld in self.src_builder: + if SCons.Util.is_String(bld): + # All Environments should have a BUILDERS + # variable, so no need to check for it. + try: + bld = env['BUILDERS'][bld] + except KeyError: + continue + ret.append(bld) + return ret + + def src_suffixes(self, env): + """Return a list of the src_suffix attributes for all + src_builders of this Builder. + """ + suffixes = BuilderBase.src_suffixes(self, env) + for builder in self.get_src_builders(env): + suffixes.extend(builder.src_suffixes(env)) + return suffixes + +class CompositeBuilder(SCons.Util.Proxy): + """A Builder Proxy whose main purpose is to always have + a DictCmdGenerator as its action, and to provide access + to the DictCmdGenerator's add_action() method. + """ + + def __init__(self, builder, cmdgen): + SCons.Util.Proxy.__init__(self, builder) + + # cmdgen should always be an instance of DictCmdGenerator. + self.cmdgen = cmdgen + self.builder = builder + + def add_action(self, suffix, action): + self.cmdgen.add_action(suffix, action) + self.set_src_suffix(self.cmdgen.src_suffixes()) + + def __cmp__(self, other): + return cmp(self.__dict__, other.__dict__) diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index e1fc8fc..7ff06c2 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -76,6 +76,8 @@ class Environment: for k, v in kw.items(): self.d[k] = v def subst(self, s): + if not SCons.Util.is_String(s): + return s try: if s[0] == '$': return self.d.get(s[1:], '') @@ -446,9 +448,9 @@ class BuilderTestCase(unittest.TestCase): Make sure that there is no '.' separator appended. """ builder = SCons.Builder.Builder(name = "builder", prefix = 'lib.') - assert builder.get_prefix(env,{}) == 'lib.' + assert builder.get_prefix(env) == 'lib.' builder = SCons.Builder.Builder(name = "builder", prefix = 'lib') - assert builder.get_prefix(env,{}) == 'lib' + assert builder.get_prefix(env) == 'lib' tgt = builder(env, target = 'tgt1', source = 'src1') assert tgt.path == 'libtgt1', \ "Target has unexpected name: %s" % tgt.path @@ -465,7 +467,7 @@ class BuilderTestCase(unittest.TestCase): 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,{}) + assert b1.src_suffixes(env) == ['.c'], b1.src_suffixes(env) tgt = b1(env, target = 'tgt2', source = 'src2') assert tgt.sources[0].path == 'src2.c', \ @@ -479,19 +481,19 @@ class BuilderTestCase(unittest.TestCase): b2 = SCons.Builder.Builder(name = "b2", src_suffix = '.2', src_builder = b1) - assert b2.src_suffixes(env,{}) == ['.2', '.c'], b2.src_suffixes(env,{}) + assert b2.src_suffixes(env) == ['.2', '.c'], b2.src_suffixes(env) b3 = SCons.Builder.Builder(name = "b3", action = {'.3a' : '', '.3b' : ''}) - s = b3.src_suffixes(env,{}) + 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,{}) + 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,{}) + b5 = SCons.Builder.Builder(name = "b5", action = { '.y' : ''}) + assert b5.src_suffixes(env) == ['.y'], b5.src_suffixes(env) def test_suffix(self): """Test Builder creation with a specified target suffix @@ -500,9 +502,9 @@ class BuilderTestCase(unittest.TestCase): beginning if it isn't already present. """ builder = SCons.Builder.Builder(name = "builder", suffix = '.o') - assert builder.get_suffix(env,{}) == '.o', builder.get_suffix(env,{}) + assert builder.get_suffix(env) == '.o', builder.get_suffix(env) builder = SCons.Builder.Builder(name = "builder", suffix = 'o') - assert builder.get_suffix(env,{}) == '.o', builder.get_suffix(env,{}) + assert builder.get_suffix(env) == '.o', builder.get_suffix(env) tgt = builder(env, target = 'tgt3', source = 'src3') assert tgt.path == 'tgt3.o', \ "Target has unexpected name: %s" % tgt.path @@ -582,6 +584,12 @@ class BuilderTestCase(unittest.TestCase): str(tgt.sources[0].sources[0]) assert str(tgt.sources[1]) == 'test2.foo', str(tgt.sources[1]) assert str(tgt.sources[2]) == 'test3.txt', str(tgt.sources[2]) + + builder3 = SCons.Builder.MultiStepBuilder(name = "builder3", + action = 'foo', + src_builder = 'xyzzy', + src_suffix = '.xyzzy') + assert builder3.get_src_builders(Environment()) == [] def test_CompositeBuilder(self): """Testing CompositeBuilder class.""" @@ -592,13 +600,16 @@ class BuilderTestCase(unittest.TestCase): action={ '.foo' : func_action, '.bar' : func_action }) - assert isinstance(builder, SCons.Builder.BuilderBase) + assert isinstance(builder, SCons.Builder.CompositeBuilder) assert isinstance(builder.action, SCons.Action.CommandGeneratorAction) tgt = builder(env, target='test1', source='test1.foo') assert isinstance(tgt.builder, SCons.Builder.BuilderBase) - assert isinstance(tgt.builder.action.generator, SCons.Builder.DictCmdGenerator) + assert tgt.builder.action is builder.action + tgt = builder(env, target='test2', source='test1.bar') + assert isinstance(tgt.builder, SCons.Builder.BuilderBase) + assert tgt.builder.action is builder.action flag = 0 - tgt = builder(env, target='test2', source=['test2.bar', 'test1.foo']) + tgt = builder(env, target='test3', source=['test2.bar', 'test1.foo']) try: tgt.build() except SCons.Errors.UserError: @@ -614,7 +625,7 @@ class BuilderTestCase(unittest.TestCase): action = { '.foo' : 'foo', '.bar' : 'bar' }, src_builder = foo_bld) - assert isinstance(builder, SCons.Builder.MultiStepBuilder) + assert isinstance(builder, SCons.Builder.CompositeBuilder) assert isinstance(builder.action, SCons.Action.CommandGeneratorAction) tgt = builder(env, target='t1', source='t1a.ina t1b.ina') @@ -629,12 +640,13 @@ class BuilderTestCase(unittest.TestCase): suffix = '.bar') assert isinstance(bar_bld, SCons.Builder.BuilderBase) builder = SCons.Builder.Builder(name = "builder", - action = { '.foo' : 'foo', - '.bar' : 'bar' }, + action = { '.foo' : 'foo'}, src_builder = [foo_bld, bar_bld]) - assert isinstance(builder, SCons.Builder.MultiStepBuilder) + assert isinstance(builder, SCons.Builder.CompositeBuilder) assert isinstance(builder.action, SCons.Action.CommandGeneratorAction) + builder.add_action('.bar', 'bar') + tgt = builder(env, target='t3-foo', source='t3a.foo t3b.ina') assert isinstance(tgt.builder, SCons.Builder.MultiStepBuilder) @@ -759,6 +771,10 @@ class BuilderTestCase(unittest.TestCase): assert 'baz' in map(str, tgt.sources), map(str, tgt.sources) assert 'bar' in map(str, tgt.sources), map(str, tgt.sources) + builder2a=SCons.Builder.Builder(name="builder2", action='foo', + emitter="$FOO") + assert builder2 == builder2a, repr(builder2.__dict__) + "\n" + repr(builder2a.__dict__) + if __name__ == "__main__": suite = unittest.makeSuite(BuilderTestCase, 'test_') if not unittest.TextTestRunner().run(suite).wasSuccessful(): diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index e7a49b8..778517d 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -44,14 +44,23 @@ import os.path import SCons.Action import SCons.Builder -import SCons.Errors import SCons.Node.Alias import SCons.Node.FS -import SCons.Platform import SCons.Scanner.C import SCons.Scanner.Fortran import SCons.Scanner.Prog -import SCons.Util + +def alias_builder(env, target, source): + pass + +Alias = SCons.Builder.Builder(action = alias_builder, + target_factory = SCons.Node.Alias.default_ans.Alias, + source_factory = SCons.Node.FS.default_fs.Entry, + multi = 1) + +CScan = SCons.Scanner.C.CScan() + +FortranScan = SCons.Scanner.Fortran.FortranScan() def yaccEmitter(target, source, env, **kw): # Yacc can be configured to emit a .h file as well @@ -64,17 +73,17 @@ def yaccEmitter(target, source, env, **kw): '.h') return (target, source) -CFile = SCons.Builder.Builder(action = { '.l' : '$LEXCOM', - '.y' : '$YACCCOM', - }, - emitter = yaccEmitter, - suffix = '$CFILESUFFIX') +def CFile(): + """Common function to generate a C file Builder.""" + return SCons.Builder.Builder(action = {}, + emitter = yaccEmitter, + suffix = '$CFILESUFFIX') -CXXFile = SCons.Builder.Builder(action = { '.ll' : '$LEXCOM', - '.yy' : '$YACCCOM', - }, - emitter = yaccEmitter, - suffix = '$CXXFILESUFFIX') +def CXXFile(): + """Common function to generate a C++ file Builder.""" + return SCons.Builder.Builder(action = {}, + emitter = yaccEmitter, + suffix = '$CXXFILESUFFIX') class SharedFlagChecker: """This is a callable class that is used as @@ -112,536 +121,69 @@ ShF77Action = SCons.Action.Action([ SharedCheck, "$SHF77COM" ]) F77PPAction = SCons.Action.Action([ StaticCheck, "$F77PPCOM" ]) ShF77PPAction = SCons.Action.Action([ SharedCheck, "$SHF77PPCOM" ]) -if os.path.normcase('.c') == os.path.normcase('.C'): - # We're on a case-insensitive system, so .[CF] (upper case) - # files should be treated like .[cf] (lower case) files. - C_static = CAction - C_shared = ShCAction - F_static = F77Action - F_shared = ShF77Action -else: - # We're on a case-sensitive system, so .C (upper case) files - # are C++, and .F (upper case) files get run through the C - # preprocessor. - C_static = CXXAction - C_shared = ShCXXAction - F_static = F77PPAction - F_shared = ShF77PPAction - -StaticObject = SCons.Builder.Builder(action = { ".C" : C_static, - ".cc" : CXXAction, - ".cpp" : CXXAction, - ".cxx" : CXXAction, - ".c++" : CXXAction, - ".C++" : CXXAction, - ".c" : CAction, - ".f" : F77Action, - ".for" : F77Action, - ".F" : F_static, - ".FOR" : F77Action, - ".fpp" : F77PPAction, - ".FPP" : F77PPAction }, - prefix = '$OBJPREFIX', - suffix = '$OBJSUFFIX', - src_builder = [CFile, CXXFile]) - -SharedObject = SCons.Builder.Builder(action = { ".C" : C_shared, - ".cc" : ShCXXAction, - ".cpp" : ShCXXAction, - ".cxx" : ShCXXAction, - ".c++" : ShCXXAction, - ".C++" : ShCXXAction, - ".c" : ShCAction, - ".f" : ShF77Action, - ".for" : ShF77Action, - ".FOR" : ShF77Action, - ".F" : F_shared, - ".fpp" : ShF77PPAction, - ".FPP" : ShF77PPAction }, - prefix = '$OBJPREFIX', - suffix = '$OBJSUFFIX', - src_builder = [CFile, CXXFile]) - -def win32TempFileMunge(env, cmd_list, for_signature): - """Given a list of command line arguments, see if it is too - long to pass to the win32 command line interpreter. If so, - create a temp file, then pass "@tempfile" as the sole argument - to the supplied command (which is the first element of cmd_list). - Otherwise, just return [cmd_list].""" - cmd = env.subst_list(cmd_list)[0] - if for_signature or \ - (reduce(lambda x, y: x + len(y), cmd, 0) + len(cmd)) <= 2048: - return [cmd_list] - else: - import tempfile - # We do a normpath because mktemp() has what appears to be - # a bug in Win32 that will use a forward slash as a path - # delimiter. Win32's link mistakes that for a command line - # switch and barfs. - tmp = os.path.normpath(tempfile.mktemp()) - args = map(SCons.Util.quote_spaces, cmd[1:]) - open(tmp, 'w').write(string.join(args, " ") + "\n") - return [ [cmd[0], '@' + tmp], - ['del', tmp] ] - -def win32LinkGenerator(env, target, source, for_signature, **kw): - args = [ '$LINK', '$LINKFLAGS', '/OUT:%s' % target[0], - '$(', '$_LIBDIRFLAGS', '$)', '$_LIBFLAGS' ] - args.extend(map(SCons.Util.to_String, source)) - return win32TempFileMunge(env, args, for_signature) -ProgScan = SCons.Scanner.Prog.ProgScan() +def StaticObject(): + """A function for generating the static object Builder.""" + return SCons.Builder.Builder(action = {}, + prefix = '$OBJPREFIX', + suffix = '$OBJSUFFIX', + src_builder = ['CFile', 'CXXFile']) -Program = SCons.Builder.Builder(action=[ StaticCheck, '$LINKCOM' ], - prefix='$PROGPREFIX', - suffix='$PROGSUFFIX', - src_suffix='$OBJSUFFIX', - src_builder=StaticObject, - scanner = ProgScan) +def SharedObject(): + """A function for generating the shared object Builder.""" + return SCons.Builder.Builder(action = {}, + prefix = '$OBJPREFIX', + suffix = '$OBJSUFFIX', + src_builder = ['CFile', 'CXXFile']) -def win32LibGenerator(target, source, env, for_signature, no_import_lib=0): - listCmd = [ "$SHLINK", "$SHLINKFLAGS" ] - - for tgt in target: - ext = os.path.splitext(str(tgt))[1] - if ext == env.subst("$LIBSUFFIX"): - # Put it on the command line as an import library. - if no_import_lib: - raise SCons.Errors.UserError, "%s: You cannot specify a .lib file as a target of a shared library build if no_import_library is nonzero." % tgt - listCmd.append("${WIN32IMPLIBPREFIX}%s" % tgt) - else: - listCmd.append("${WIN32DLLPREFIX}%s" % tgt) - - listCmd.extend([ '$_LIBDIRFLAGS', '$_LIBFLAGS' ]) - for src in source: - ext = os.path.splitext(str(src))[1] - if ext == env.subst("$WIN32DEFSUFFIX"): - # Treat this source as a .def file. - listCmd.append("${WIN32DEFPREFIX}%s" % src) - else: - # Just treat it as a generic source file. - listCmd.append(str(src)) - return win32TempFileMunge(env, listCmd, for_signature) - -def win32LibEmitter(target, source, env, no_import_lib=0): - dll = None - for tgt in target: - ext = os.path.splitext(str(tgt))[1] - if ext == env.subst("$SHLIBSUFFIX"): - dll = tgt - break - if not dll: - raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX") - - if env.has_key("WIN32_INSERT_DEF") and \ - env["WIN32_INSERT_DEF"] and \ - not '.def' in map(lambda x: os.path.split(str(x))[1], - source): - - # append a def file to the list of sources - source.append("%s%s" % (os.path.splitext(str(dll))[0], - env.subst("$WIN32DEFSUFFIX"))) - if not no_import_lib and \ - not env.subst("$LIBSUFFIX") in \ - map(lambda x: os.path.split(str(x))[1], target): - # Append an import library to the list of targets. - target.append("%s%s%s" % (env.subst("$LIBPREFIX"), - os.path.splitext(str(dll))[0], - env.subst("$LIBSUFFIX"))) - return (target, source) +ProgScan = SCons.Scanner.Prog.ProgScan() StaticLibrary = SCons.Builder.Builder(action=[ StaticCheck, "$ARCOM" ], prefix = '$LIBPREFIX', suffix = '$LIBSUFFIX', src_suffix = '$OBJSUFFIX', - src_builder = StaticObject) + src_builder = 'Object') SharedLibrary = SCons.Builder.Builder(action=[ SharedCheck, "$SHLINKCOM" ], - emitter="$LIBEMITTER", + emitter="$SHLIBEMITTER", prefix = '$SHLIBPREFIX', suffix = '$SHLIBSUFFIX', scanner = ProgScan, src_suffix = '$OBJSUFFIX', - src_builder = SharedObject) - -LaTeXAction = SCons.Action.Action('$LATEXCOM') - -DVI = SCons.Builder.Builder(action = { '.tex' : '$TEXCOM', - '.ltx' : LaTeXAction, - '.latex' : LaTeXAction, - }, - # The suffix is not configurable via a - # construction variable like $DVISUFFIX - # because the output file name is - # hard-coded within TeX. - suffix = '.dvi') - -PDFLaTeXAction = SCons.Action.Action('$PDFLATEXCOM') - -PDF = SCons.Builder.Builder(action = { '.dvi' : '$PDFCOM', - '.tex' : '$PDFTEXCOM', - '.ltx' : PDFLaTeXAction, - '.latex' : PDFLaTeXAction, - }, - prefix = '$PDFPREFIX', - suffix = '$PDFSUFFIX') - -PostScript = SCons.Builder.Builder(action = '$PSCOM', - prefix = '$PSPREFIX', - suffix = '$PSSUFFIX', - src_suffix = '.dvi', - src_builder = DVI) - -CScan = SCons.Scanner.C.CScan() - -FortranScan = SCons.Scanner.Fortran.FortranScan() + src_builder = 'SharedObject') + +def DVI(): + """Common function to generate a DVI file Builder.""" + return SCons.Builder.Builder(action = {}, + # The suffix is not configurable via a + # construction variable like $DVISUFFIX + # because the output file name is + # hard-coded within TeX. + suffix = '.dvi') + +def PDF(): + """A function for generating the PDF Builder.""" + return SCons.Builder.Builder(action = { }, + prefix = '$PDFPREFIX', + suffix = '$PDFSUFFIX') -def alias_builder(env, target, source): - pass - -Alias = SCons.Builder.Builder(action = alias_builder, - target_factory = SCons.Node.Alias.default_ans.Alias, - source_factory = SCons.Node.FS.default_fs.Entry, - multi = 1) +Program = SCons.Builder.Builder(action=[ StaticCheck, '$LINKCOM' ], + prefix='$PROGPREFIX', + suffix='$PROGSUFFIX', + src_suffix='$OBJSUFFIX', + src_builder='Object', + scanner = ProgScan) -def get_devstudio_versions (): - """ - Get list of devstudio versions from the Windows registry. Return a - list of strings containing version numbers; an exception will be raised - if we were unable to access the registry (eg. couldn't import - a registry-access module) or the appropriate registry keys weren't - found. - """ - - if not SCons.Util.can_read_reg: - raise SCons.Errors.InternalError, "No Windows registry module was found" - - K = 'Software\\Microsoft\\Devstudio' - L = [] - for base in (SCons.Util.HKEY_CLASSES_ROOT, - SCons.Util.HKEY_LOCAL_MACHINE, - SCons.Util.HKEY_CURRENT_USER, - SCons.Util.HKEY_USERS): - try: - k = SCons.Util.RegOpenKeyEx(base,K) - i = 0 - while 1: - try: - p = SCons.Util.RegEnumKey(k,i) - if p[0] in '123456789' and p not in L: - L.append(p) - except SCons.Util.RegError: - break - i = i + 1 - except SCons.Util.RegError: - pass - - if not L: - raise SCons.Errors.InternalError, "DevStudio was not found." - - L.sort() - L.reverse() - return L - -def get_msvc_path (path, version, platform='x86'): - """ - Get a list of devstudio directories (include, lib or path). Return - a string delimited by ';'. An exception will be raised if unable to - access the registry or appropriate registry keys not found. - """ - - if not SCons.Util.can_read_reg: - raise SCons.Errors.InternalError, "No Windows registry module was found" - - if path=='lib': - path= 'Library' - path = string.upper(path + ' Dirs') - K = ('Software\\Microsoft\\Devstudio\\%s\\' + - 'Build System\\Components\\Platforms\\Win32 (%s)\\Directories') % \ - (version,platform) - for base in (SCons.Util.HKEY_CLASSES_ROOT, - SCons.Util.HKEY_LOCAL_MACHINE, - SCons.Util.HKEY_CURRENT_USER, - SCons.Util.HKEY_USERS): - try: - k = SCons.Util.RegOpenKeyEx(base,K) - i = 0 - while 1: - try: - (p,v,t) = SCons.Util.RegEnumValue(k,i) - if string.upper(p) == path: - return v - i = i + 1 - except SCons.Util.RegError: - break - except SCons.Util.RegError: - pass - - # if we got here, then we didn't find the registry entries: - raise SCons.Errors.InternalError, "%s was not found in the registry."%path - -def get_msdev_dir(version): - """Returns the root directory of the MSDev installation from the - registry if it can be found, otherwise we guess.""" - if SCons.Util.can_read_reg: - K = ('Software\\Microsoft\\Devstudio\\%s\\' + - 'Products\\Microsoft Visual C++') % \ - version - for base in (SCons.Util.HKEY_LOCAL_MACHINE, - SCons.Util.HKEY_CURRENT_USER): - try: - k = SCons.Util.RegOpenKeyEx(base,K) - val, tok = SCons.Util.RegQueryValueEx(k, 'ProductDir') - return os.path.split(val)[0] - except SCons.Util.RegError: - pass - -def make_win32_env_from_paths(include, lib, path): - """ - Build a dictionary of construction variables for a win32 platform. - include - include path - lib - library path - path - executable path - """ - return { - 'CC' : 'cl', - 'CCFLAGS' : '/nologo', - 'CCCOM' : '$CC $CCFLAGS $CPPFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET', - 'SHCC' : '$CC', - 'SHCCFLAGS' : '$CCFLAGS', - 'SHCCCOM' : '$SHCC $SHCCFLAGS $CPPFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET', - 'CFILESUFFIX' : '.c', - 'CXX' : '$CC', - 'CXXFLAGS' : '$CCFLAGS', - 'CXXCOM' : '$CXX $CXXFLAGS $CPPFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET', - 'SHCXX' : '$CXX', - 'SHCXXFLAGS' : '$CXXFLAGS', - 'SHCXXCOM' : '$SHCXX $SHCXXFLAGS $CPPFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET', - 'CXXFILESUFFIX' : '.cc', - 'F77' : 'g77', - 'F77FLAGS' : '', - 'F77COM' : '$F77 $F77FLAGS $_F77INCFLAGS /c $SOURCES /Fo$TARGET', - 'F77PPCOM' : '$F77 $F77FLAGS $CPPFLAGS $_F77INCFLAGS /c $SOURCES /Fo$TARGET', - 'SHF77' : '$F77', - 'SHF77FLAGS' : '$F77FLAGS', - 'SHF77COM' : '$SHF77 $SHF77FLAGS $_F77INCFLAGS /c $SOURCES /Fo$TARGET', - 'SHF77PPCOM' : '$SHF77 $SHF77FLAGS $CPPFLAGS $_F77INCFLAGS /c $SOURCES /Fo$TARGET', - 'LINK' : 'link', - 'LINKFLAGS' : '/nologo', - 'LINKCOM' : SCons.Action.CommandGenerator(win32LinkGenerator), - 'SHLINK' : '$LINK', - 'SHLINKFLAGS': '$LINKFLAGS /dll', - 'SHLINKCOM' : SCons.Action.CommandGenerator(win32LibGenerator), - 'AR' : 'lib', - 'ARFLAGS' : '/nologo', - 'ARCOM' : '$AR $ARFLAGS /OUT:$TARGET $SOURCES', - 'LEX' : 'lex', - 'LEXFLAGS' : '', - 'LEXCOM' : '$LEX $LEXFLAGS -t $SOURCES > $TARGET', - 'YACC' : 'yacc', - 'YACCFLAGS' : '', - 'YACCCOM' : '$YACC $YACCFLAGS -o $TARGET $SOURCES', - 'TEX' : 'tex', - 'TEXFLAGS' : '', - 'TEXCOM' : '$TEX $TEXFLAGS $SOURCES', - 'LATEX' : 'latex', - 'LATEXFLAGS' : '', - 'LATEXCOM' : '$LATEX $LATEXFLAGS $SOURCES', - 'DVIPDF' : 'dvipdf', - 'DVIPDFFLAGS' : '', - 'PDFCOM' : '$DVIPDF $DVIPDFFLAGS $SOURCES $TARGET', - 'PDFPREFIX' : '', - 'PDFSUFFIX' : '.pdf', - 'PDFTEX' : 'pdftex', - 'PDFTEXFLAGS' : '', - 'PDFTEXCOM' : '$PDFTEX $PDFTEXFLAGS $SOURCES $TARGET', - 'PDFLATEX' : 'pdflatex', - 'PDFLATEXFLAGS' : '', - 'PDFLATEXCOM' : '$PDFLATEX $PDFLATEXFLAGS $SOURCES $TARGET', - 'DVIPS' : 'dvips', - 'DVIPSFLAGS' : '', - 'PSCOM' : '$DVIPS $DVIPSFLAGS -o $TARGET $SOURCES', - 'PSPREFIX' : '', - 'PSSUFFIX' : '.ps', - 'BUILDERS' : { 'Alias' : Alias, - 'CFile' : CFile, - 'CXXFile' : CXXFile, - 'DVI' : DVI, - 'Library' : StaticLibrary, - 'StaticLibrary' : StaticLibrary, - 'SharedLibrary' : SharedLibrary, - 'Object' : StaticObject, - 'StaticObject' : StaticObject, - 'SharedObject' : SharedObject, - 'PDF' : PDF, - 'PostScript' : PostScript, - 'Program' : Program }, - 'SCANNERS' : [CScan, FortranScan], - 'LIBDIRPREFIX' : '/LIBPATH:', - 'LIBDIRSUFFIX' : '', - 'LIBLINKPREFIX' : '', - 'LIBLINKSUFFIX' : '$LIBSUFFIX', - 'LIBEMITTER' : win32LibEmitter, - 'INCPREFIX' : '/I', - 'INCSUFFIX' : '', - 'WIN32DEFPREFIX' : '/def:', - 'WIN32DEFSUFFIX' : '.def', - 'WIN32DLLPREFIX' : '/out:', - 'WIN32IMPLIBPREFIX' : '/implib:', - 'WIN32_INSERT_DEF' : 0, - 'ENV' : { - 'INCLUDE' : include, - 'LIB' : lib, - 'PATH' : path, - }, - } - -def make_win32_env(version): - """ - Build a dictionary of construction variables for a win32 platform. - ver - the version string of DevStudio to use (e.g. "6.0") - """ - return make_win32_env_from_paths(get_msvc_path("include", version), - get_msvc_path("lib", version), - get_msvc_path("path", version) - + ";" + os.environ['PATH']) - - -if os.name == 'posix': - arcom = '$AR $ARFLAGS $TARGET $SOURCES' - ranlib = 'ranlib' - if SCons.Util.WhereIs(ranlib): - arcom = arcom + '\n$RANLIB $RANLIBFLAGS $TARGET' - - ConstructionEnvironment = { - 'CC' : 'cc', - 'CCFLAGS' : '', - 'CCCOM' : '$CC $CCFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES', - 'SHCC' : '$CC', - 'SHCCFLAGS' : '$CCFLAGS -fPIC', - 'SHCCCOM' : '$SHCC $SHCCFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES', - 'CFILESUFFIX' : '.c', - 'CXX' : 'c++', - 'CXXFLAGS' : '$CCFLAGS', - 'CXXCOM' : '$CXX $CXXFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES', - 'CXXFILESUFFIX' : '.cc', - 'SHCXX' : '$CXX', - 'SHCXXFLAGS' : '$CXXFLAGS -fPIC', - 'SHCXXCOM' : '$SHCXX $SHCXXFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES', - 'F77' : 'g77', - 'F77FLAGS' : '', - 'F77COM' : '$F77 $F77FLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES', - 'F77PPCOM' : '$F77 $F77FLAGS $CPPFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES', - 'SHF77FLAGS' : '$F77FLAGS -fPIC', - 'SHF77COM' : '$F77 $SHF77FLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES', - 'SHF77PPCOM' : '$F77 $SHF77FLAGS $CPPFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES', - 'SHF77' : '$F77', - 'SHF77FLAGS' : '$F77FLAGS -fPIC', - 'SHF77COM' : '$SHF77 $SHF77FLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES', - 'SHF77PPCOM' : '$SHF77 $SHF77FLAGS $CPPFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES', - 'LINK' : '$CXX', - 'LINKFLAGS' : '', - 'LINKCOM' : '$LINK $LINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS', - 'SHLINK' : '$LINK', - 'SHLINKFLAGS': '$LINKFLAGS -shared', - 'SHLINKCOM' : '$SHLINK $SHLINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS', - 'AR' : 'ar', - 'ARFLAGS' : 'r', - 'RANLIB' : ranlib, - 'RANLIBFLAGS' : '', - 'ARCOM' : arcom, - 'LEX' : 'lex', - 'LEXFLAGS' : '', - 'LEXCOM' : '$LEX $LEXFLAGS -t $SOURCES > $TARGET', - 'YACC' : 'yacc', - 'YACCFLAGS' : '', - 'YACCCOM' : '$YACC $YACCFLAGS -o $TARGET $SOURCES', - 'TEX' : 'tex', - 'TEXFLAGS' : '', - 'TEXCOM' : '$TEX $TEXFLAGS $SOURCES', - 'LATEX' : 'latex', - 'LATEXFLAGS' : '', - 'LATEXCOM' : '$LATEX $LATEXFLAGS $SOURCES', - 'DVIPDF' : 'dvipdf', - 'PDFCOM' : '$DVIPDF $DVIPDFFLAGS $SOURCES $TARGET', - 'PDFPREFIX' : '', - 'PDFSUFFIX' : '.pdf', - 'PDFTEX' : 'pdftex', - 'PDFTEXFLAGS' : '', - 'PDFTEXCOM' : '$PDFTEX $PDFTEXFLAGS $SOURCES $TARGET', - 'PDFLATEX' : 'pdflatex', - 'PDFLATEXFLAGS' : '', - 'PDFLATEXCOM' : '$PDFLATEX $PDFLATEXFLAGS $SOURCES $TARGET', - 'DVIPS' : 'dvips', - 'PSCOM' : '$DVIPS $DVIPSFLAGS -o $TARGET $SOURCES', - 'PSPREFIX' : '', - 'PSSUFFIX' : '.ps', - 'BUILDERS' : { 'Alias' : Alias, - 'CFile' : CFile, - 'CXXFile' : CXXFile, - 'DVI' : DVI, - 'Library' : StaticLibrary, - 'StaticLibrary' : StaticLibrary, - 'SharedLibrary' : SharedLibrary, - 'Object' : StaticObject, - 'StaticObject' : StaticObject, - 'SharedObject' : SharedObject, - 'PDF' : PDF, - 'PostScript' : PostScript, - 'Program' : Program }, - 'SCANNERS' : [CScan, FortranScan], - 'LIBDIRPREFIX' : '-L', - 'LIBDIRSUFFIX' : '', - 'LIBLINKPREFIX' : '-l', - 'LIBLINKSUFFIX' : '', - 'INCPREFIX' : '-I', - 'INCSUFFIX' : '', +ConstructionEnvironment = { + 'BUILDERS' : { 'SharedLibrary' : SharedLibrary, + 'Library' : StaticLibrary, + 'StaticLibrary' : StaticLibrary, + 'Alias' : Alias, + 'Program' : Program }, + 'SCANNERS' : [CScan, FortranScan], + 'PDFPREFIX' : '', + 'PDFSUFFIX' : '.pdf', + 'PSPREFIX' : '', + 'PSSUFFIX' : '.ps', + 'ENV' : {}, } - -elif os.name == 'nt': - versions = None - try: - versions = get_devstudio_versions() - ConstructionEnvironment = make_win32_env(versions[0]) #use highest version - except (SCons.Util.RegError, SCons.Errors.InternalError): - # Could not get the configured directories from the registry. - # However, the configured directories only appear if the user - # changes them from the default. Therefore, we'll see if - # we can get the path to the MSDev base installation from - # the registry and deduce the default directories. - MVSdir = None - if versions: - MVSdir = get_msdev_dir(versions[0]) - if MVSdir: - MVSVCdir = r'%s\VC98' % MVSdir - MVSCommondir = r'%s\Common' % MVSdir - try: - extra_path = os.pathsep + os.environ['PATH'] - except KeyError: - extra_path = '' - ConstructionEnvironment = make_win32_env_from_paths( - r'%s\atl\include;%s\mfc\include;%s\include' % (MVSVCdir, MVSVCdir, MVSVCdir), - r'%s\mfc\lib;%s\lib' % (MVSVCdir, MVSVCdir), - (r'%s\MSDev98\Bin;%s\Bin' % (MVSCommondir, MVSVCdir)) + extra_path) - else: - # The DevStudio environment variables don't exist, - # so just use the variables from the source environment. - MVSdir = r'C:\Program Files\Microsoft Visual Studio' - MVSVCdir = r'%s\VC98' % MVSdir - MVSCommondir = r'%s\Common' % MVSdir - try: - include_path = os.environ['INCLUDE'] - except KeyError: - include_path = '' - try: - lib_path = os.environ['LIB'] - except KeyError: - lib_path = '' - try: - exe_path = os.environ['PATH'] - except KeyError: - exe_path = '' - ConstructionEnvironment = make_win32_env_from_paths( - include_path, - lib_path, - exe_path) diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index a95adf9..30e0a53 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -47,6 +47,8 @@ import SCons.Node.FS import SCons.Util import SCons.Warnings from UserDict import UserDict +import SCons.Platform +import SCons.Tool def installFunc(env, target, source): try: @@ -117,12 +119,19 @@ class Environment: Environment. """ - def __init__(self, platform=SCons.Platform.Platform(), **kw): + def __init__(self, + platform=SCons.Platform.Platform(), + tools=SCons.Platform.DefaultToolList(), + **kw): self.fs = SCons.Node.FS.default_fs self._dict = our_deepcopy(SCons.Defaults.ConstructionEnvironment) if SCons.Util.is_String(platform): platform = SCons.Platform.Platform(platform) platform(self) + for tool in tools: + if SCons.Util.is_String(tool): + tool = SCons.Tool.Tool(tool) + tool(self, platform) apply(self.Replace, (), kw) # @@ -231,14 +240,7 @@ class Environment: for name, builder in bd.items(): setattr(self, name, BuilderWrapper(self, builder)) else: - SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, - "The use of the BUILDERS Environment variable as a list or Builder instance is deprecated. BUILDERS should be a dictionary of name->Builder instead.") - - if not SCons.Util.is_List(self._dict['BUILDERS']): - self._dict['BUILDERS'] = [self._dict['BUILDERS']] - for b in self._dict['BUILDERS']: - setattr(self, b.name, BuilderWrapper(self, b)) - + raise UserError, "The use of the BUILDERS Environment variable as a list or Builder instance is deprecated. BUILDERS should be a dictionary of name->Builder instead." for s in self._dict['SCANNERS']: setattr(self, s.name, s) @@ -392,6 +394,14 @@ class Environment: interp.instance(dir, fs).generate(dict, self._dict) return dict + def get_builder(self, name): + """Fetch the builder with the specified name from the environment. + """ + try: + return self._dict['BUILDERS'][name] + except KeyError: + return None + class VarInterpolator: def __init__(self, dest, src, prefix, suffix): self.dest = dest diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 167c662..2e7003a 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -30,6 +30,27 @@ import unittest from SCons.Environment import * import SCons.Warnings +def diff_env(env1, env2): + s1 = "env1 = {\n" + s2 = "env2 = {\n" + d = {} + for k in env1._dict.keys() + env2._dict.keys(): + d[k] = None + keys = d.keys() + keys.sort() + for k in keys: + if env1.has_key(k): + if env2.has_key(k): + if env1[k] != env2[k]: + s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n" + s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n" + else: + s1 = s1 + " " + repr(k) + " : " + repr(env1[k]) + "\n" + elif env2.has_key(k): + s2 = s2 + " " + repr(k) + " : " + repr(env2[k]) + "\n" + s1 = s1 + "}\n" + s2 = s2 + "}\n" + return s1 + s2 built_it = {} @@ -74,23 +95,13 @@ class EnvironmentTestCase(unittest.TestCase): """ global built_it - b1 = Builder(name = 'builder1') - b2 = Builder(name = 'builder2') - - # BUILDERS as a list or instance, now deprecated... - built_it = {} - env1 = Environment(BUILDERS = b1) - env1.builder1.execute(target = 'out1') - assert built_it['out1'] - - built_it = {} - env2 = Environment(BUILDERS = [b1]) - env1.builder1.execute(target = 'out1') - assert built_it['out1'] + b1 = Builder() + b2 = Builder() built_it = {} env3 = Environment() - env3.Replace(BUILDERS = [b1, b2]) + env3.Replace(BUILDERS = { 'builder1' : b1, + 'builder2' : b2 }) env3.builder1.execute(target = 'out1') env3.builder2.execute(target = 'out2') env3.builder1.execute(target = 'out3') @@ -120,29 +131,6 @@ class EnvironmentTestCase(unittest.TestCase): assert built_it['out1'] assert built_it['out2'] - # Now test deprecated warning for BUILDERS as a list - # or instance. - - SCons.Warnings.enableWarningClass(SCons.Warnings.DeprecatedWarning) - SCons.Warnings.warningAsException(1) - try: - try: - env=Environment(BUILDERS=b1) - except SCons.Warnings.DeprecatedWarning: - pass - else: - assert 0 - - try: - env=Environment(BUILDERS=[b1, b2]) - except SCons.Warnings.DeprecatedWarning: - pass - else: - assert 0 - finally: - SCons.Warnings.suppressWarningClass(SCons.Warnings.DeprecatedWarning) - SCons.Warnings.warningAsException(0) - def test_Scanners(self): """Test Scanner execution through different environments @@ -261,7 +249,7 @@ class EnvironmentTestCase(unittest.TestCase): """ env1 = Environment(XXX = 'x', YYY = 'y') env2 = Environment(XXX = 'x', YYY = 'y') - assert env1 == env2 + assert env1 == env2, diff_env(env1, env2) def test_Install(self): """Test Install and InstallAs methods""" @@ -292,7 +280,7 @@ class EnvironmentTestCase(unittest.TestCase): env1 = Environment(AAA = 'a', BBB = 'b') env1.Replace(BBB = 'bbb', CCC = 'ccc') env2 = Environment(AAA = 'a', BBB = 'bbb', CCC = 'ccc') - assert env1 == env2 + assert env1 == env2, diff_env(env1, env2) def test_Append(self): """Test appending to construction variables in an Environment @@ -312,7 +300,7 @@ class EnvironmentTestCase(unittest.TestCase): GGG = ['g', 'G'], HHH = UL(['h', 'H']), III = UL(['i']), JJJ = UL(['j', 'J']), KKK = UL(['k', 'K']), LLL = UL(['l', 'L'])) - assert env1 == env2, env1._dict + assert env1 == env2, diff_env(env1, env2) env3 = Environment(X = {'x' : 7}) try: @@ -479,7 +467,15 @@ class EnvironmentTestCase(unittest.TestCase): env = Environment(platform = p) assert env['XYZZY'] == 777, env - + def test_tools(self): + """Test specifying a tool callable when instantiating.""" + def t1(env, platform): + env['TOOL1'] = 111 + def t2(env, platform): + env['TOOL2'] = 222 + env = Environment(tools = [t1, t2]) + assert env['TOOL1'] == 111, env['TOOL1'] + assert env['TOOL2'] == 222, env if __name__ == "__main__": suite = unittest.makeSuite(EnvironmentTestCase, 'test_') diff --git a/src/engine/SCons/Platform/__init__.py b/src/engine/SCons/Platform/__init__.py index a519142..42b2607 100644 --- a/src/engine/SCons/Platform/__init__.py +++ b/src/engine/SCons/Platform/__init__.py @@ -61,15 +61,8 @@ def platform_default(): return 'posix' return None -class PlatformSpec: - def __init__(self, name): - self.name = name - - def __str__(self): - return self.name - -def Platform(name = platform_default()): - """Select a canned Platform specification. +def platform_module(name = platform_default()): + """Return the imported module for the platform. This looks for a module name that matches the specified argument. If the name is unspecified, we fetch the appropriate default for @@ -85,6 +78,25 @@ def Platform(name = platform_default()): raise SCons.Errors.UserError, "No platform named '%s'" % name if file: file.close() + return sys.modules[full_name] + +def DefaultToolList(name = platform_default()): + """Select a default tool list for the specified platform. + """ + module = platform_module(name) + return module.tool_list() + +class PlatformSpec: + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + +def Platform(name = platform_default()): + """Select a canned Platform specification. + """ + module = platform_module(name) spec = PlatformSpec(name) - spec.__call__ = sys.modules[full_name].generate + spec.__call__ = module.generate return spec diff --git a/src/engine/SCons/Platform/cygwin.py b/src/engine/SCons/Platform/cygwin.py index 7faafd8..6a21ae9 100644 --- a/src/engine/SCons/Platform/cygwin.py +++ b/src/engine/SCons/Platform/cygwin.py @@ -32,6 +32,10 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +def tool_list(): + return ['ar', 'dvipdf', 'dvips', 'g++', 'g77', 'gcc', 'latex', 'lex', + 'pdflatex', 'pdftex', 'tex', 'yacc', 'gnulink' ] + def generate(env): if not env.has_key('ENV'): env['ENV'] = {} diff --git a/src/engine/SCons/Platform/posix.py b/src/engine/SCons/Platform/posix.py index 4de68f6..3d20263 100644 --- a/src/engine/SCons/Platform/posix.py +++ b/src/engine/SCons/Platform/posix.py @@ -32,6 +32,10 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +def tool_list(): + return ['ar', 'dvipdf', 'dvips', 'g++', 'g77', 'gcc', 'latex', 'lex', + 'pdflatex', 'pdftex', 'tex', 'yacc', 'gnulink' ] + def generate(env): if not env.has_key('ENV'): env['ENV'] = {} diff --git a/src/engine/SCons/Platform/win32.py b/src/engine/SCons/Platform/win32.py index aa9a75f..9bcea18 100644 --- a/src/engine/SCons/Platform/win32.py +++ b/src/engine/SCons/Platform/win32.py @@ -32,6 +32,10 @@ selection method. __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +def tool_list(): + return ['dvipdf', 'latex', 'dvips', 'g77', 'lex', 'lib', 'msvc', + 'pdflatex', 'pdftex', 'tex', 'yacc', 'mslink' ] + def generate(env): if not env.has_key('ENV'): env['ENV'] = {} diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index 7fcdf77..7ae7f21 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -37,6 +37,7 @@ import SCons.Errors import SCons.Node import SCons.Node.FS import SCons.Platform +import SCons.Tool import SCons.Util import os @@ -273,5 +274,6 @@ def BuildDefaultGlobals(): globals['SConscriptChdir'] = SConscriptChdir globals['SetCommandHandler'] = SCons.Action.SetCommandHandler globals['Split'] = SCons.Util.Split + globals['Tool'] = SCons.Tool.Tool globals['WhereIs'] = SCons.Util.WhereIs return globals diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 3471190..c43f1ab 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -99,6 +99,7 @@ class BuildTask(SCons.Taskmaster.Task): # We aren't being called out of a user frame, so # don't try to walk the stack, just print the error. sys.stderr.write("\nSCons error: %s\n" % e) + raise except: sys.stderr.write("scons: *** %s\n" % sys.exc_value) raise @@ -982,6 +983,8 @@ def _main(): SCons.Sig.write() def main(): + global exit_status + try: _main() except SystemExit: diff --git a/src/engine/SCons/Tool/ToolTests.py b/src/engine/SCons/Tool/ToolTests.py new file mode 100644 index 0000000..a7e03e8 --- /dev/null +++ b/src/engine/SCons/Tool/ToolTests.py @@ -0,0 +1,60 @@ +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import sys +import unittest + +import SCons.Errors +import SCons.Tool + +class ToolTestCase(unittest.TestCase): + def test_Tool(self): + """Test the Tool() function""" + t = SCons.Tool.Tool('g++') + env= { 'BUILDERS' : {}, 'ENV' : {} } + t(env, 'foo') + assert env['CXX'] == 'c++', env['CXX'] + assert env['CXXFLAGS'] == '$CCFLAGS', env['CXXFLAGS'] + assert env['INCPREFIX'] == '-I', env['INCPREFIX'] + + try: + SCons.Tool.Tool() + except TypeError: + pass + else: + raise + + try: + p = SCons.Tool.Tool('_does_not_exist_') + except SCons.Errors.UserError: + pass + else: + raise + + +if __name__ == "__main__": + suite = unittest.makeSuite(ToolTestCase, 'test_') + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + sys.exit(1) diff --git a/src/engine/SCons/Tool/__init__.py b/src/engine/SCons/Tool/__init__.py new file mode 100644 index 0000000..08ab5c2 --- /dev/null +++ b/src/engine/SCons/Tool/__init__.py @@ -0,0 +1,125 @@ +"""SCons.Tool + +SCons tool selection. + +This looks for modules that define a callable object that can modify +a construction environment as appropriate for a given tool (or tool +chain). + +Note that because this subsysem just *selects* a callable that can +modify a construction environment, it's possible for people to define +their own "tool specification" in an arbitrary callable function. No +one needs to use or tie in to this subsystem in order to roll their own +tool definition. +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import imp +import os +import sys + +import SCons.Errors +import SCons.Defaults + +class ToolSpec: + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + +def Tool(name, platform = None): + """Select a canned Tool specification. + """ + full_name = 'SCons.Tool.' + name + if not sys.modules.has_key(full_name): + try: + file, path, desc = imp.find_module(name, + sys.modules['SCons.Tool'].__path__) + imp.load_module(full_name, file, path, desc) + except ImportError: + raise SCons.Errors.UserError, "No tool named '%s'" % name + if file: + file.close() + spec = ToolSpec(name) + spec.__call__ = sys.modules[full_name].generate + return spec + +def createObjBuilders(env): + """This is a utility function that creates the Object + and SharedObject Builders in an Environment if they + are not there already. + + If they are there already, we return the existing ones. + + This is a separate function because soooo many Tools + use this functionality. + + The return is a 2-tuple of (StaticObject, SharedObject) + """ + + try: + static_obj = env['BUILDERS']['Object'] + except KeyError: + static_obj = SCons.Defaults.StaticObject() + env['BUILDERS']['Object'] = static_obj + env['BUILDERS']['StaticObject'] = static_obj + + try: + shared_obj = env['BUILDERS']['SharedObject'] + except KeyError: + shared_obj = SCons.Defaults.SharedObject() + env['BUILDERS']['SharedObject'] = shared_obj + + return (static_obj, shared_obj) + +def createCFileBuilders(env): + """This is a utility function that creates the CFile/CXXFile + Builders in an Environment if they + are not there already. + + If they are there already, we return the existing ones. + + This is a separate function because soooo many Tools + use this functionality. + + The return is a 2-tuple of (CFile, CXXFile) + """ + + try: + c_file = env['BUILDERS']['CFile'] + except KeyError: + c_file = SCons.Defaults.CFile() + env['BUILDERS']['CFile'] = c_file + + try: + cxx_file = env['BUILDERS']['CXXFile'] + except KeyError: + cxx_file = SCons.Defaults.CXXFile() + env['BUILDERS']['CXXFile'] = cxx_file + + return (c_file, cxx_file) diff --git a/src/engine/SCons/Tool/ar.py b/src/engine/SCons/Tool/ar.py new file mode 100644 index 0000000..ab870b6 --- /dev/null +++ b/src/engine/SCons/Tool/ar.py @@ -0,0 +1,59 @@ +"""SCons.Tool.ar + +Tool-specific initialization for ar (library archive). + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Defaults +import SCons.Util + +def generate(env, platform): + """Add Builders and construction variables for ar to an Environment.""" + bld = SCons.Defaults.StaticLibrary + env['BUILDERS']['Library'] = bld + env['BUILDERS']['StaticLibrary'] = bld + + arcom = '$AR $ARFLAGS $TARGET $SOURCES' + ranlib = 'ranlib' + if SCons.Util.WhereIs(ranlib): + arcom = arcom + '\n$RANLIB $RANLIBFLAGS $TARGET' + + env['AR'] = 'ar' + env['ARFLAGS'] = 'r' + env['RANLIB'] = ranlib + env['RANLIBFLAGS'] = '' + env['ARCOM'] = arcom + env['SHLINK'] = '$LINK' + env['SHLINKFLAGS'] = '$LINKFLAGS -shared' + env['SHLINKCOM'] = '$SHLINK $SHLINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + + diff --git a/src/engine/SCons/Tool/dvipdf.py b/src/engine/SCons/Tool/dvipdf.py new file mode 100644 index 0000000..230ce92 --- /dev/null +++ b/src/engine/SCons/Tool/dvipdf.py @@ -0,0 +1,49 @@ +"""SCons.Tool.dvipdf + +Tool-specific initialization for dvipdf. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Defaults + +def generate(env, platform): + """Add Builders and construction variables for dvipdf to an Environment.""" + try: + bld = env['BUILDERS']['PDF'] + except KeyError: + bld = SCons.Defaults.PDF() + env['BUILDERS']['PDF'] = bld + bld.add_action('.dvi', '$PDFCOM') + + env['DVIPDF'] = 'dvipdf' + env['DVIPDFFLAGS'] = '' + env['PDFCOM'] = '$DVIPDF $DVIPDFFLAGS $SOURCES $TARGET' diff --git a/src/engine/SCons/Tool/dvips.py b/src/engine/SCons/Tool/dvips.py new file mode 100644 index 0000000..098cba7 --- /dev/null +++ b/src/engine/SCons/Tool/dvips.py @@ -0,0 +1,51 @@ +"""SCons.Tool.dvips + +Tool-specific initialization for dvips. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Action +import SCons.Defaults + +PostScript = SCons.Builder.Builder(action = '$PSCOM', + prefix = '$PSPREFIX', + suffix = '$PSSUFFIX', + src_suffix = '.dvi', + src_builder = 'DVI') + +def generate(env, platform): + """Add Builders and construction variables for dvips to an Environment.""" + env['BUILDERS']['PostScript'] = PostScript + + env['DVIPS'] = 'dvips' + env['DVIPSFLAGS'] = '' + env['PSCOM'] = '$DVIPS $DVIPSFLAGS -o $TARGET $SOURCES' diff --git a/src/engine/SCons/Tool/g++.py b/src/engine/SCons/Tool/g++.py new file mode 100644 index 0000000..a903b0a --- /dev/null +++ b/src/engine/SCons/Tool/g++.py @@ -0,0 +1,62 @@ +"""SCons.Tool.g++ + +Tool-specific initialization for g++. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os.path + +import SCons.Defaults +import SCons.Tool + +CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] +if os.path.normcase('.c') != os.path.normcase('.C'): + CXXSuffixes.append('.C') + +def generate(env, platform): + """Add Builders and construction variables for g++ to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in CXXSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CXXAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) + + env['CXX'] = 'c++' + env['CXXFLAGS'] = '$CCFLAGS' + env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' + env['SHCXX'] = '$CXX' + env['SHCXXFLAGS'] = '$CXXFLAGS -fPIC' + env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' + env['INCPREFIX'] = '-I' + env['INCSUFFIX'] = '' + + env['CXXFILESUFFIX'] = '.cc' diff --git a/src/engine/SCons/Tool/g77.py b/src/engine/SCons/Tool/g77.py new file mode 100644 index 0000000..dbafcf2 --- /dev/null +++ b/src/engine/SCons/Tool/g77.py @@ -0,0 +1,67 @@ +"""engine.SCons.Tool.g77 + +Tool-specific initialization for g77. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os.path + +import SCons.Defaults +import SCons.Tool + +F77Suffixes = ['.f', '.for', '.FOR'] +F77PPSuffixes = ['.fpp', '.FPP'] +if os.path.normcase('.f') == os.path.normcase('.F'): + F77Suffixes.append('.F') +else: + F77PPSuffixes.append('.F') + +def generate(env, platform): + """Add Builders and construction variables for g77 to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in F77Suffixes: + static_obj.add_action(suffix, SCons.Defaults.F77Action) + shared_obj.add_action(suffix, SCons.Defaults.ShF77Action) + + for suffix in F77PPSuffixes: + static_obj.add_action(suffix, SCons.Defaults.F77PPAction) + shared_obj.add_action(suffix, SCons.Defaults.ShF77PPAction) + + env['F77'] = 'g77' + env['F77FLAGS'] = '' + env['F77COM'] = '$F77 $F77FLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES' + env['F77PPCOM'] = '$F77 $F77FLAGS $CPPFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES' + env['SHF77'] = '$F77' + env['SHF77FLAGS'] = '$F77FLAGS -fPIC' + env['SHF77COM'] = '$SHF77 $SHF77FLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES' + env['SHF77PPCOM'] = '$SHF77 $SHF77FLAGS $CPPFLAGS $_F77INCFLAGS -c -o $TARGET $SOURCES' diff --git a/src/engine/SCons/Tool/gcc.py b/src/engine/SCons/Tool/gcc.py new file mode 100644 index 0000000..c5a1e91 --- /dev/null +++ b/src/engine/SCons/Tool/gcc.py @@ -0,0 +1,63 @@ +"""SCons.Tool.gcc + +Tool-specific initialization for gcc. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os.path + +import SCons.Tool +import SCons.Defaults + +CSuffixes = ['.c'] +if os.path.normcase('.c') == os.path.normcase('.C'): + CSuffixes.append('.C') + +def generate(env, platform): + """Add Builders and construction variables for gcc to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in CSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCAction) + + env['CC'] = 'gcc' + env['CCFLAGS'] = '' + env['CCCOM'] = '$CC $CCFLAGS $CPPFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' + env['SHCC'] = '$CC' + env['SHCCFLAGS'] = '$CCFLAGS -fPIC' + env['SHCCCOM'] = '$SHCC $SHCCFLAGS $_CPPINCFLAGS -c -o $TARGET $SOURCES' + + env['INCPREFIX'] = '-I' + env['INCSUFFIX'] = '' + + env['CFILESUFFIX'] = '.c' diff --git a/src/engine/SCons/Tool/gnulink.py b/src/engine/SCons/Tool/gnulink.py new file mode 100644 index 0000000..630d95a --- /dev/null +++ b/src/engine/SCons/Tool/gnulink.py @@ -0,0 +1,54 @@ +"""SCons.Tool.gnulink + +Tool-specific initialization for the gnu linker. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Defaults +import SCons.Util + +def generate(env, platform): + """Add Builders and construction variables for ar to an Environment.""" + env['BUILDERS']['SharedLibrary'] = SCons.Defaults.SharedLibrary + env['BUILDERS']['Program'] = SCons.Defaults.Program + + env['SHLINK'] = '$LINK' + env['SHLINKFLAGS'] = '$LINKFLAGS -shared' + env['SHLINKCOM'] = '$SHLINK $SHLINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + env['SHLIBEMITTER']= None + env['LINK'] = 'c++' + env['LINKFLAGS'] = '' + env['LINKCOM'] = '$LINK $LINKFLAGS -o $TARGET $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' + env['LIBDIRPREFIX']='-L' + env['LIBDIRSUFFIX']='' + env['LIBLINKPREFIX']='-l' + env['LIBLINKSUFFIX']='' diff --git a/src/engine/SCons/Tool/latex.py b/src/engine/SCons/Tool/latex.py new file mode 100644 index 0000000..cb53ccf --- /dev/null +++ b/src/engine/SCons/Tool/latex.py @@ -0,0 +1,55 @@ +"""SCons.Tool.latex + +Tool-specific initialization for LaTeX. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Action +import SCons.Defaults + +LaTeXAction = SCons.Action.Action('$LATEXCOM') + +def generate(env, platform): + """Add Builders and construction variables for LaTeX to an Environment.""" + + try: + bld = env['BUILDERS']['DVI'] + except KeyError: + bld = SCons.Defaults.DVI() + env['BUILDERS']['DVI'] = bld + + bld.add_action('.ltx', LaTeXAction) + bld.add_action('.latex', LaTeXAction) + + env['LATEX'] = 'latex' + env['LATEXFLAGS'] = '' + env['LATEXCOM'] = '$LATEX $LATEXFLAGS $SOURCES' diff --git a/src/engine/SCons/Tool/lex.py b/src/engine/SCons/Tool/lex.py new file mode 100644 index 0000000..c8851e2 --- /dev/null +++ b/src/engine/SCons/Tool/lex.py @@ -0,0 +1,48 @@ +"""SCons.Tool.lex + +Tool-specific initialization for lex. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Defaults +import SCons.Tool + +def generate(env, platform): + """Add Builders and construction variables for lex to an Environment.""" + c_file, cxx_file = SCons.Tool.createCFileBuilders(env) + + c_file.add_action('.l', '$LEXCOM') + cxx_file.add_action('.ll', '$LEXCOM') + + env['LEX'] = 'lex' + env['LEXFLAGS'] = '' + env['LEXCOM'] = '$LEX $LEXFLAGS -t $SOURCES > $TARGET' diff --git a/src/engine/SCons/Tool/lib.py b/src/engine/SCons/Tool/lib.py new file mode 100644 index 0000000..9683abf --- /dev/null +++ b/src/engine/SCons/Tool/lib.py @@ -0,0 +1,46 @@ +"""SCons.Tool.lib + +Tool-specific initialization for lib (MicroSoft library archiver). + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Defaults + +def generate(env, platform): + """Add Builders and construction variables for lib to an Environment.""" + env['BUILDERS']['Library'] = SCons.Defaults.StaticLibrary + env['BUILDERS']['StaticLibrary'] = SCons.Defaults.StaticLibrary + + env['AR'] = 'lib' + env['ARFLAGS'] = '/nologo' + env['ARCOM'] = '$AR $ARFLAGS /OUT:$TARGET $SOURCES' + diff --git a/src/engine/SCons/Tool/mslink.py b/src/engine/SCons/Tool/mslink.py new file mode 100644 index 0000000..2f05b46 --- /dev/null +++ b/src/engine/SCons/Tool/mslink.py @@ -0,0 +1,151 @@ +"""SCons.Tool.mslink + +Tool-specific initialization for the Microsoft linker. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os.path + +import SCons.Defaults +import SCons.Errors +import SCons.Action + +from SCons.Tool.msvc import get_msdev_paths + +def win32TempFileMunge(env, cmd_list, for_signature): + """Given a list of command line arguments, see if it is too + long to pass to the win32 command line interpreter. If so, + create a temp file, then pass "@tempfile" as the sole argument + to the supplied command (which is the first element of cmd_list). + Otherwise, just return [cmd_list].""" + cmd = env.subst_list(cmd_list)[0] + if for_signature or \ + (reduce(lambda x, y: x + len(y), cmd, 0) + len(cmd)) <= 2048: + return [cmd_list] + else: + import tempfile + # We do a normpath because mktemp() has what appears to be + # a bug in Win32 that will use a forward slash as a path + # delimiter. Win32's link mistakes that for a command line + # switch and barfs. + tmp = os.path.normpath(tempfile.mktemp()) + args = map(SCons.Util.quote_spaces, cmd[1:]) + open(tmp, 'w').write(string.join(args, " ") + "\n") + return [ [cmd[0], '@' + tmp], + ['del', tmp] ] + +def win32LinkGenerator(env, target, source, for_signature, **kw): + args = [ '$LINK', '$LINKFLAGS', '/OUT:%s' % target[0], + '$(', '$_LIBDIRFLAGS', '$)', '$_LIBFLAGS' ] + args.extend(map(SCons.Util.to_String, source)) + return win32TempFileMunge(env, args, for_signature) + +def win32LibGenerator(target, source, env, for_signature, no_import_lib=0): + listCmd = [ "$SHLINK", "$SHLINKFLAGS" ] + + for tgt in target: + ext = os.path.splitext(str(tgt))[1] + if ext == env.subst("$LIBSUFFIX"): + # Put it on the command line as an import library. + if no_import_lib: + raise SCons.Errors.UserError, "%s: You cannot specify a .lib file as a target of a shared library build if no_import_library is nonzero." % tgt + listCmd.append("${WIN32IMPLIBPREFIX}%s" % tgt) + else: + listCmd.append("${WIN32DLLPREFIX}%s" % tgt) + + listCmd.extend([ '$_LIBDIRFLAGS', '$_LIBFLAGS' ]) + for src in source: + ext = os.path.splitext(str(src))[1] + if ext == env.subst("$WIN32DEFSUFFIX"): + # Treat this source as a .def file. + listCmd.append("${WIN32DEFPREFIX}%s" % src) + else: + # Just treat it as a generic source file. + listCmd.append(str(src)) + return win32TempFileMunge(env, listCmd, for_signature) + +def win32LibEmitter(target, source, env, no_import_lib=0): + dll = None + for tgt in target: + ext = os.path.splitext(str(tgt))[1] + if ext == env.subst("$SHLIBSUFFIX"): + dll = tgt + break + if not dll: + raise SCons.Errors.UserError, "A shared library should have exactly one target with the suffix: %s" % env.subst("$SHLIBSUFFIX") + + if env.has_key("WIN32_INSERT_DEF") and \ + env["WIN32_INSERT_DEF"] and \ + not '.def' in map(lambda x: os.path.split(str(x))[1], + source): + + # append a def file to the list of sources + source.append("%s%s" % (os.path.splitext(str(dll))[0], + env.subst("$WIN32DEFSUFFIX"))) + if not no_import_lib and \ + not env.subst("$LIBSUFFIX") in \ + map(lambda x: os.path.split(str(x))[1], target): + # Append an import library to the list of targets. + target.append("%s%s%s" % (env.subst("$LIBPREFIX"), + os.path.splitext(str(dll))[0], + env.subst("$LIBSUFFIX"))) + return (target, source) + +ShLibAction = SCons.Action.CommandGenerator(win32LibGenerator) +LinkAction = SCons.Action.CommandGenerator(win32LinkGenerator) + +def generate(env, platform): + """Add Builders and construction variables for ar to an Environment.""" + env['BUILDERS']['SharedLibrary'] = SCons.Defaults.SharedLibrary + env['BUILDERS']['Program'] = SCons.Defaults.Program + + env['SHLINK'] = '$LINK' + env['SHLINKFLAGS'] = '$LINKFLAGS /dll' + env['SHLINKCOM'] = ShLibAction + env['SHLIBEMITTER']= win32LibEmitter + env['LINK'] = 'link' + env['LINKFLAGS'] = '/nologo' + env['LINKCOM'] = LinkAction + env['LIBDIRPREFIX']='/LIBPATH:' + env['LIBDIRSUFFIX']='' + env['LIBLINKPREFIX']='' + env['LIBLINKSUFFIX']='$LIBSUFFIX' + + env['WIN32DEFPREFIX'] = '/def:' + env['WIN32DEFSUFFIX'] = '.def' + env['WIN32DLLPREFIX'] = '/out:' + env['WIN32IMPLIBPREFIX'] = '/implib:' + env['WIN32_INSERT_DEF'] = 0 + + include_path, lib_path, exe_path = get_msdev_paths() + env['ENV']['LIB'] = lib_path + env['ENV']['PATH'] = exe_path diff --git a/src/engine/SCons/Tool/msvc.py b/src/engine/SCons/Tool/msvc.py new file mode 100644 index 0000000..54796e3 --- /dev/null +++ b/src/engine/SCons/Tool/msvc.py @@ -0,0 +1,223 @@ +"""engine.SCons.Tool.msvc + +Tool-specific initialization for Microsoft Visual C/C++. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import os.path +import string + +import SCons.Action +import SCons.Tool +import SCons.Errors + +CSuffixes = ['.c', '.C'] +CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] + +def get_devstudio_versions(): + """ + Get list of devstudio versions from the Windows registry. Return a + list of strings containing version numbers; an exception will be raised + if we were unable to access the registry (eg. couldn't import + a registry-access module) or the appropriate registry keys weren't + found. + """ + + if not SCons.Util.can_read_reg: + raise SCons.Errors.InternalError, "No Windows registry module was found" + + K = 'Software\\Microsoft\\Devstudio' + L = [] + for base in (SCons.Util.HKEY_CLASSES_ROOT, + SCons.Util.HKEY_LOCAL_MACHINE, + SCons.Util.HKEY_CURRENT_USER, + SCons.Util.HKEY_USERS): + try: + k = SCons.Util.RegOpenKeyEx(base,K) + i = 0 + while 1: + try: + p = SCons.Util.RegEnumKey(k,i) + if p[0] in '123456789' and p not in L: + L.append(p) + except SCons.Util.RegError: + break + i = i + 1 + except SCons.Util.RegError: + pass + + if not L: + raise SCons.Errors.InternalError, "DevStudio was not found." + + L.sort() + L.reverse() + return L + +def get_msvc_path (path, version, platform='x86'): + """ + Get a list of devstudio directories (include, lib or path). Return + a string delimited by ';'. An exception will be raised if unable to + access the registry or appropriate registry keys not found. + """ + + if not SCons.Util.can_read_reg: + raise SCons.Errors.InternalError, "No Windows registry module was found" + + if path=='lib': + path= 'Library' + path = string.upper(path + ' Dirs') + K = ('Software\\Microsoft\\Devstudio\\%s\\' + + 'Build System\\Components\\Platforms\\Win32 (%s)\\Directories') % \ + (version,platform) + for base in (SCons.Util.HKEY_CLASSES_ROOT, + SCons.Util.HKEY_LOCAL_MACHINE, + SCons.Util.HKEY_CURRENT_USER, + SCons.Util.HKEY_USERS): + try: + k = SCons.Util.RegOpenKeyEx(base,K) + i = 0 + while 1: + try: + (p,v,t) = SCons.Util.RegEnumValue(k,i) + if string.upper(p) == path: + return v + i = i + 1 + except SCons.Util.RegError: + break + except SCons.Util.RegError: + pass + + # if we got here, then we didn't find the registry entries: + raise SCons.Errors.InternalError, "%s was not found in the registry."%path + +def get_msdev_dir(version): + """Returns the root directory of the MSDev installation from the + registry if it can be found, otherwise we guess.""" + if SCons.Util.can_read_reg: + K = ('Software\\Microsoft\\Devstudio\\%s\\' + + 'Products\\Microsoft Visual C++') % \ + version + for base in (SCons.Util.HKEY_LOCAL_MACHINE, + SCons.Util.HKEY_CURRENT_USER): + try: + k = SCons.Util.RegOpenKeyEx(base,K) + val, tok = SCons.Util.RegQueryValueEx(k, 'ProductDir') + return os.path.split(val)[0] + except SCons.Util.RegError: + pass + +def get_msdev_paths(version=None): + """Return a 3-tuple of (INCLUDE, LIB, PATH) as the values + of those three environment variables that should be set + in order to execute the MSVC tools properly.""" + exe_path = '' + lib_path = '' + include_path = '' + try: + if not version: + version = get_devstudio_versions()[0] #use highest version + include_path = get_msvc_path("include", version) + lib_path = get_msvc_path("lib", version) + exe_path = get_msvc_path("path", version) + ";" + os.environ['PATH'] + except (SCons.Util.RegError, SCons.Errors.InternalError): + # Could not get the configured directories from the registry. + # However, the configured directories only appear if the user + # changes them from the default. Therefore, we'll see if + # we can get the path to the MSDev base installation from + # the registry and deduce the default directories. + MVSdir = None + if version: + MVSdir = get_msdev_dir(version) + if MVSdir: + MVSVCdir = r'%s\VC98' % MVSdir + MVSCommondir = r'%s\Common' % MVSdir + include_path = r'%s\atl\include;%s\mfc\include;%s\include' % (MVSVCdir, MVSVCdir, MVSVCdir) + lib_path = r'%s\mfc\lib;%s\lib' % (MVSVCdir, MVSVCdir) + try: + extra_path = os.pathsep + os.environ['PATH'] + except KeyError: + extra_path = '' + exe_path = (r'%s\MSDev98\Bin;%s\Bin' % (MVSCommondir, MVSVCdir)) + extra_path + else: + # The DevStudio environment variables don't exist, + # so just use the variables from the source environment. + MVSdir = r'C:\Program Files\Microsoft Visual Studio' + MVSVCdir = r'%s\VC98' % MVSdir + MVSCommondir = r'%s\Common' % MVSdir + try: + include_path = os.environ['INCLUDE'] + except KeyError: + include_path = '' + try: + lib_path = os.environ['LIB'] + except KeyError: + lib_path = '' + try: + exe_path = os.environ['PATH'] + except KeyError: + exe_path = '' + return (include_path, lib_path, exe_path) + +def generate(env, platform): + """Add Builders and construction variables for MSVC++ to an Environment.""" + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + + for suffix in CSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCAction) + + for suffix in CXXSuffixes: + static_obj.add_action(suffix, SCons.Defaults.CXXAction) + shared_obj.add_action(suffix, SCons.Defaults.ShCXXAction) + + env['CC'] = 'cl' + env['CCFLAGS'] = '/nologo' + env['CCCOM'] = '$CC $CCFLAGS $CPPFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET' + env['SHCC'] = '$CC' + env['SHCCFLAGS'] = '$CCFLAGS' + env['SHCCCOM'] = '$SHCC $SHCCFLAGS $CPPFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET' + env['CXX'] = '$CC' + env['CXXFLAGS'] = '$CCFLAGS' + env['CXXCOM'] = '$CXX $CXXFLAGS $CPPFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET' + env['SHCXX'] = '$CXX' + env['SHCXXFLAGS'] = '$CXXFLAGS' + env['SHCXXCOM'] = '$SHCXX $SHCXXFLAGS $CPPFLAGS $_CPPINCFLAGS /c $SOURCES /Fo$TARGET' + env['INCPREFIX'] = '/I' + env['INCSUFFIX'] = '' + + include_path, lib_path, exe_path = get_msdev_paths() + env['ENV']['INCLUDE'] = include_path + env['ENV']['PATH'] = exe_path + + env['CFILESUFFIX'] = '.c' + env['CXXFILESUFFIX'] = '.cc' + diff --git a/src/engine/SCons/Tool/pdflatex.py b/src/engine/SCons/Tool/pdflatex.py new file mode 100644 index 0000000..340622c --- /dev/null +++ b/src/engine/SCons/Tool/pdflatex.py @@ -0,0 +1,54 @@ +"""SCons.Tool.pdflatex + +Tool-specific initialization for pdflatex. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Action +import SCons.Defaults + +PDFLaTeXAction = SCons.Action.Action('$PDFLATEXCOM') + +def generate(env, platform): + """Add Builders and construction variables for pdflatex to an Environment.""" + try: + bld = env['BUILDERS']['PDF'] + except KeyError: + bld = SCons.Defaults.PDF() + env['BUILDERS']['PDF'] = bld + + bld.add_action('.ltx', PDFLaTeXAction) + bld.add_action('.latex', PDFLaTeXAction) + + env['PDFLATEX'] = 'pdflatex' + env['PDFLATEXFLAGS'] = '' + env['PDFLATEXCOM'] = '$PDFLATEX $PDFLATEXFLAGS $SOURCES $TARGET' diff --git a/src/engine/SCons/Tool/pdftex.py b/src/engine/SCons/Tool/pdftex.py new file mode 100644 index 0000000..1acc9ce --- /dev/null +++ b/src/engine/SCons/Tool/pdftex.py @@ -0,0 +1,50 @@ +"""SCons.Tool.pdftex + +Tool-specific initialization for pdftex. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Defaults + +def generate(env, platform): + """Add Builders and construction variables for pdftex to an Environment.""" + try: + bld = env['BUILDERS']['PDF'] + except KeyError: + bld = SCons.Defaults.PDF() + env['BUILDERS']['PDF'] = bld + + bld.add_action('.tex', '$PDFTEXCOM') + + env['PDFTEX'] = 'pdftex' + env['PDFTEXFLAGS'] = '' + env['PDFTEXCOM'] = '$PDFTEX $PDFTEXFLAGS $SOURCES $TARGET' diff --git a/src/engine/SCons/Tool/tex.py b/src/engine/SCons/Tool/tex.py new file mode 100644 index 0000000..10413aa --- /dev/null +++ b/src/engine/SCons/Tool/tex.py @@ -0,0 +1,50 @@ +"""SCons.Tool.tex + +Tool-specific initialization for TeX. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Defaults + +def generate(env, platform): + """Add Builders and construction variables for TeX to an Environment.""" + try: + bld = env['BUILDERS']['DVI'] + except KeyError: + bld = SCons.Defaults.DVI() + env['BUILDERS']['DVI'] = bld + + bld.add_action('.tex', '$TEXCOM') + + env['TEX'] = 'tex' + env['TEXFLAGS'] = '' + env['TEXCOM'] = '$TEX $TEXFLAGS $SOURCES' diff --git a/src/engine/SCons/Tool/yacc.py b/src/engine/SCons/Tool/yacc.py new file mode 100644 index 0000000..34abe77 --- /dev/null +++ b/src/engine/SCons/Tool/yacc.py @@ -0,0 +1,47 @@ +"""SCons.Tool.yacc + +Tool-specific initialization for yacc. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. + +""" + +# +# Copyright (c) 2001, 2002 Steven Knight +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import SCons.Tool + +def generate(env, platform): + """Add Builders and construction variables for yacc to an Environment.""" + c_file, cxx_file = SCons.Tool.createCFileBuilders(env) + + c_file.add_action('.y', '$YACCCOM') + cxx_file.add_action('.yy', '$YACCCOM') + + env['YACC'] = 'yacc' + env['YACCFLAGS'] = '' + env['YACCCOM'] = '$YACC $YACCFLAGS -o $TARGET $SOURCES' diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py index d366d9a..38489ef 100644 --- a/src/engine/SCons/Util.py +++ b/src/engine/SCons/Util.py @@ -336,6 +336,15 @@ else: def is_String(e): return type(e) is types.StringType or isinstance(e, UserString) +class Proxy: + """A simple generic Proxy class, forwarding all calls to + subject. Inherit from this class to create a Proxy.""" + def __init__(self, subject): + self.__subject = subject + + def __getattr__(self, name): + return getattr(self.__subject, name) + # attempt to load the windows registry module: can_read_reg = 0 try: diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py index 4f3195f..31dceb1 100644 --- a/src/engine/SCons/UtilTests.py +++ b/src/engine/SCons/UtilTests.py @@ -361,6 +361,32 @@ class UtilTestCase(unittest.TestCase): assert get_environment_var("$BAR ") == None, get_environment_var("$BAR ") assert get_environment_var("FOO$BAR") == None, get_environment_var("FOO$BAR") + def test_Proxy(self): + """Test generic Proxy class.""" + class Subject: + def foo(self): + return 1 + def bar(self): + return 2 + + s=Subject() + s.baz = 3 + + class ProxyTest(Proxy): + def bar(self): + return 4 + + p=ProxyTest(s) + + assert p.foo() == 1, p.foo() + assert p.bar() == 4, p.bar() + assert p.baz == 3, p.baz + + p.baz = 5 + s.baz = 6 + + assert p.baz == 5, p.baz + if __name__ == "__main__": suite = unittest.makeSuite(UtilTestCase, 'test_') if not unittest.TextTestRunner().run(suite).wasSuccessful(): diff --git a/src/setup.py b/src/setup.py index 8104e6d..ceb4440 100644 --- a/src/setup.py +++ b/src/setup.py @@ -78,8 +78,9 @@ arguments = { "SCons.Node", "SCons.Platform", "SCons.Scanner", + "SCons.Script", "SCons.Sig", - "SCons.Script"], + "SCons.Tool"], 'package_dir' : {'' : 'engine'}, 'scripts' : ["script/scons"], 'cmdclass' : {'install_lib' : my_install_lib} diff --git a/test/SharedLibrary.py b/test/SharedLibrary.py index 56738c7..6dcb779 100644 --- a/test/SharedLibrary.py +++ b/test/SharedLibrary.py @@ -48,7 +48,7 @@ Default(env.SharedLibrary(target = 'foo', source = obj)) test.write('SConstructFoo2', """ env=Environment() -obj = env.SharedObject('foo', 'foo.c') +obj = env.SharedObject('bar', 'foo.c') Default(env.Library(target = 'foo', source = obj)) """) @@ -193,7 +193,7 @@ SCons error: Source file: foo\..* is static and is not compatible with shared ta ) test.run(arguments = '-f SConstructFoo2', status=2, stderr=''' -SCons error: Source file: foo\..* is shared and is not compatible with static target: .* +SCons error: Source file: bar\..* is shared and is not compatible with static target: .* ''' ) |