diff options
51 files changed, 744 insertions, 222 deletions
@@ -236,7 +236,7 @@ def SCons_revision(target, source, env): outf.close() os.chmod(t, os.stat(s)[0]) -revbuilder = Builder(name = 'SCons_revision', action = SCons_revision) +revbuilder = Builder(action = SCons_revision) env = Environment( ENV = ENV, @@ -266,7 +266,7 @@ env = Environment( UNPACK_TAR_GZ_DIR = unpack_tar_gz_dir, UNPACK_ZIP_DIR = unpack_zip_dir, - BUILDERS = [ revbuilder ], + BUILDERS = { 'SCons_revision' : revbuilder }, ) # diff --git a/doc/man/scons.1 b/doc/man/scons.1 index 10ca9d1..5570ec1 100644 --- a/doc/man/scons.1 +++ b/doc/man/scons.1 @@ -587,6 +587,26 @@ Print a message containing the working directory before and after other processing. .TP +.RI --warn= type ", --warn=no-" type +Enable or disable warnings. +.I type +specifies the type of warnings to be enabled or disabled: + +.TP +.RI --warn=all ", " --warn=no-all +Enables or disables all warnings. + +.TP +.RI --warn=dependency ", " --warn=no-dependency +Enables or disables warnings about dependencies. +These warnings are disabled by default. + +.TP +.RI --warn=deprecated ", " --warn=no-deprecated +Enables or disables warnings about use of deprecated features. +These warnings are enabled by default. + +.TP --no-print-directory Turn off -w, even if it was turned on implicitly. @@ -1101,8 +1121,12 @@ General options passed to the static library archiver. The command line used to generate a static library from object files. .IP BUILDERS -A list of the available builders. -[Alias, CFile, CXXFile, DVI, Library, Object, PDF, PostScript, Program] by default. +A dictionary mapping the names of the builders +available through this environment +to underlying Builder objects. +Builders named +Alias, CFile, CXXFile, DVI, Library, Object, PDF, PostScript, and Program +are available by default. .IP CC The C compiler. @@ -1869,7 +1893,7 @@ Example: def e(target, source, env): return (target + ['foo.foo'], source + ['foo.src']) -b = Builder(name="Foo", emitter=e) +b = Builder(emitter=e) .EE .IP generator @@ -1899,7 +1923,7 @@ Example: def g(source, target, env, for_signature): return [["gcc", "-c", "-o"] + target + source] -b = Builder(name="Object", generator=g) +b = Builder(generator=g) .EE The @@ -1915,8 +1939,8 @@ will be associated with the target result of the call). .ES -b = Builder(name='MyBuild', action="build < $SOURCE > $TARGET") -env = Environment(BUILDERS = [b]) +b = Builder(action="build < $SOURCE > $TARGET") +env = Environment(BUILDERS = {'MyBuild' : b}) env.MyBuild('foo.out', 'foo.in', my_arg = 'xyzzy') .EE @@ -2421,11 +2445,10 @@ Notice also that you can leave off the target file suffix, and the builder will add it automatically. .ES -bld = Builder(name = 'PDFBuilder', - action = 'pdftex < $SOURCES > $TARGET' +bld = Builder(action = 'pdftex < $SOURCES > $TARGET' suffix = '.pdf', src_suffix = '.tex') -env = Environment(BUILDERS = [bld]) +env = Environment(BUILDERS = {'PDFBuilder' : bld}) env.PDFBuilder(target = 'foo.pdf', source = 'foo.tex') # The following creates "bar.pdf" from "bar.tex" diff --git a/rpm/scons.spec b/rpm/scons.spec index 635e157..326b157 100644 --- a/rpm/scons.spec +++ b/rpm/scons.spec @@ -96,6 +96,8 @@ rm -rf $RPM_BUILD_ROOT /usr/lib/scons/SCons/Taskmaster.pyc /usr/lib/scons/SCons/Util.py /usr/lib/scons/SCons/Util.pyc +/usr/lib/scons/SCons/Warnings.py +/usr/lib/scons/SCons/Warnings.pyc /usr/lib/scons/SCons/__init__.py /usr/lib/scons/SCons/__init__.pyc /usr/lib/scons/SCons/exitfuncs.py diff --git a/src/CHANGES.txt b/src/CHANGES.txt index fbe895b..0d37452 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -15,6 +15,17 @@ RELEASE 0.08 - - Fixed a bug with relative CPPPATH dirs when using BuildDir(). (Bug reported by Bob Summerwill.) + - Added a warnings framework and a --warn option to enable or + disable warnings. + + - Make the C scanner warn users if files referenced by #include + directives cannot be found and --warn=dependency is specified. + + - The BUILDERS construction variable should now be a dictionary + that maps builder names to actions. Existing uses of lists, + and the Builder name= keyword argument, generate warnings + about use of deprecated features. + From Steven Knight: - Add a "platform=" keyword argument to Environment instantiation, diff --git a/src/engine/MANIFEST.in b/src/engine/MANIFEST.in index 9194557..1c9ac91 100644 --- a/src/engine/MANIFEST.in +++ b/src/engine/MANIFEST.in @@ -23,3 +23,4 @@ SCons/Sig/MD5.py SCons/Sig/TimeStamp.py SCons/Taskmaster.py SCons/Util.py +SCons/Warnings.py diff --git a/src/engine/SCons/Builder.py b/src/engine/SCons/Builder.py index 42c9484..d3feb26 100644 --- a/src/engine/SCons/Builder.py +++ b/src/engine/SCons/Builder.py @@ -40,6 +40,7 @@ import SCons.Action import SCons.Node import SCons.Node.FS import SCons.Util +import SCons.Warnings class DictCmdGenerator: """This is a callable class that can be used as a @@ -73,6 +74,9 @@ class DictCmdGenerator: def Builder(**kw): """A factory for builder objects.""" + if kw.has_key('name'): + SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, + "The use of the 'name' parameter to Builder() is deprecated.") if kw.has_key('generator'): if kw.has_key('action'): raise UserError, "You must not specify both an action and a generator." @@ -124,7 +128,7 @@ def _init_nodes(builder, env, args, tlist, slist): if isinstance(t.builder, ListBuilder) and isinstance(builder, ListBuilder) and t.builder.builder == builder.builder: raise UserError, "Two different target sets have a target in common: %s"%str(t) else: - raise UserError, "Two different builders (%s and %s) were specified for the same target: %s"%(t.builder.name, builder.name, str(t)) + raise UserError, "Two different builders (%s and %s) were specified for the same target: %s"%(t.builder.get_name(env), builder.get_name(env), str(t)) elif t.sources != slist: raise UserError, "Multiple ways to build the same target were specified for: %s" % str(t) @@ -202,8 +206,6 @@ class BuilderBase: scanner = None, emitter = None, multi = 0): - if name is None: - raise UserError, "You must specify a name for the builder." self.name = name self.action = SCons.Action.Action(action) self.multi = multi @@ -231,6 +233,22 @@ class BuilderBase: self.emitter = emitter + 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.""" + + if self.name: + return self.name + try: + index = env['BUILDERS'].values().index(self) + return env['BUILDERS'].keys()[index] + except (AttributeError, KeyError, ValueError): + return str(self.__class__) + def __cmp__(self, other): return cmp(self.__dict__, other.__dict__) @@ -342,8 +360,11 @@ class ListBuilder: def __init__(self, builder, env, tlist): self.builder = builder - self.tlist = tlist - self.name = "ListBuilder(%s)"%builder.name + self.tlist = tlist + self.name = "ListBuilder(%s)"%builder.get_name(env) + + def get_name(self, env): + return self.name def execute(self, **kw): if hasattr(self, 'status'): diff --git a/src/engine/SCons/BuilderTests.py b/src/engine/SCons/BuilderTests.py index d7fd92d..c69aaa6 100644 --- a/src/engine/SCons/BuilderTests.py +++ b/src/engine/SCons/BuilderTests.py @@ -39,6 +39,7 @@ import TestCmd import SCons.Builder import SCons.Errors import SCons.Node.FS +import SCons.Warnings # Initial setup of the common environment for all tests, # a temporary working directory containing a @@ -158,17 +159,24 @@ class BuilderTestCase(unittest.TestCase): assert target.sources[1].name == uni('n19') def test_noname(self): - """Test error reporting for missing name + """Test deprecated warning for Builder name. - Verify that the Builder constructor gives an error message if the - name is missing. + Using the name argument for Builder() is deprectaed and the + user should receive a warning. """ + SCons.Warnings.enableWarningClass(SCons.Warnings.DeprecatedWarning) + SCons.Warnings.warningAsException(1) + try: - b = SCons.Builder.Builder() - except SCons.Errors.UserError: - pass - else: - assert 0 + try: + b = SCons.Builder.Builder(name='foo') + except SCons.Warnings.DeprecatedWarning: + pass + else: + assert 0 + finally: + SCons.Warnings.suppressWarningClass(SCons.Warnings.DeprecatedWarning) + SCons.Warnings.warningAsException(0) def test_action(self): """Test Builder creation diff --git a/src/engine/SCons/Defaults.py b/src/engine/SCons/Defaults.py index 2259f40..e8bf376 100644 --- a/src/engine/SCons/Defaults.py +++ b/src/engine/SCons/Defaults.py @@ -68,8 +68,9 @@ class SharedCmdGenerator: def __call__(self, target, source, env, shared=0, **kw): for src in source: try: - if src.attributes.shared != shared: - raise SCons.Errors.UserError("Source file: %s must be built with shared=%s in order to be compatible with the selected target." % (src, str(shared))) + if (src.attributes.shared and not shared) or \ + (shared and not src.attributes.shared): + raise SCons.Errors.UserError("Source file: %s must be built with shared=%s in order to be compatible with target: %s" % (src, str(shared), target[0])) except AttributeError: pass for t in target: @@ -90,15 +91,13 @@ def yaccEmitter(target, source, env, **kw): '.h') return (target, source) -CFile = SCons.Builder.Builder(name = 'CFile', - action = { '.l' : '$LEXCOM', +CFile = SCons.Builder.Builder(action = { '.l' : '$LEXCOM', '.y' : '$YACCCOM', }, emitter = yaccEmitter, suffix = '$CFILESUFFIX') -CXXFile = SCons.Builder.Builder(name = 'CXXFile', - action = { '.ll' : '$LEXCOM', +CXXFile = SCons.Builder.Builder(action = { '.ll' : '$LEXCOM', '.yy' : '$YACCCOM', }, emitter = yaccEmitter, @@ -156,9 +155,8 @@ static_obj = SCons.Builder.DictCmdGenerator({ ".C" : C_static, ".FOR" : F77Action, ".fpp" : F77PPAction, ".FPP" : F77PPAction }) - -Object = SCons.Builder.Builder(name = 'Object', - generator = \ + +Object = SCons.Builder.Builder(generator = \ SharedCmdGenerator(static=SCons.Action.CommandGeneratorAction(static_obj), shared=SCons.Action.CommandGeneratorAction(shared_obj)), prefix = '$OBJPREFIX', @@ -166,7 +164,7 @@ Object = SCons.Builder.Builder(name = 'Object', src_suffix = static_obj.src_suffixes(), src_builder = [CFile, CXXFile]) -def win32TempFileMunge(env, cmd_list, for_signature): +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 @@ -194,8 +192,7 @@ def win32LinkGenerator(env, target, source, for_signature, **kw): args.extend(map(SCons.Util.to_String, source)) return win32TempFileMunge(env, args, for_signature) -Program = SCons.Builder.Builder(name='Program', - action='$LINKCOM', +Program = SCons.Builder.Builder(action='$LINKCOM', prefix='$PROGPREFIX', suffix='$PROGSUFFIX', src_suffix='$OBJSUFFIX', @@ -266,8 +263,7 @@ def win32LibEmitter(target, source, env, shared=0, env.subst("$LIBSUFFIX"))) return (target, source) -Library = SCons.Builder.Builder(name = 'Library', - generator = \ +Library = SCons.Builder.Builder(generator = \ SharedCmdGenerator(shared="$SHLINKCOM", static="$ARCOM"), emitter="$LIBEMITTER", @@ -282,8 +278,7 @@ Library = SCons.Builder.Builder(name = 'Library', LaTeXAction = SCons.Action.Action('$LATEXCOM') -DVI = SCons.Builder.Builder(name = 'DVI', - action = { '.tex' : '$TEXCOM', +DVI = SCons.Builder.Builder(action = { '.tex' : '$TEXCOM', '.ltx' : LaTeXAction, '.latex' : LaTeXAction, }, @@ -295,8 +290,7 @@ DVI = SCons.Builder.Builder(name = 'DVI', PDFLaTeXAction = SCons.Action.Action('$PDFLATEXCOM') -PDF = SCons.Builder.Builder(name = 'PDF', - action = { '.dvi' : '$PDFCOM', +PDF = SCons.Builder.Builder(action = { '.dvi' : '$PDFCOM', '.tex' : '$PDFTEXCOM', '.ltx' : PDFLaTeXAction, '.latex' : PDFLaTeXAction, @@ -304,8 +298,7 @@ PDF = SCons.Builder.Builder(name = 'PDF', prefix = '$PDFPREFIX', suffix = '$PDFSUFFIX') -PostScript = SCons.Builder.Builder(name = 'PostScript', - action = '$PSCOM', +PostScript = SCons.Builder.Builder(action = '$PSCOM', prefix = '$PSPREFIX', suffix = '$PSSUFFIX', src_suffix = '.dvi', @@ -316,8 +309,7 @@ CScan = SCons.Scanner.C.CScan() def alias_builder(env, target, source): pass -Alias = SCons.Builder.Builder(name = 'Alias', - action = alias_builder, +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) @@ -481,8 +473,15 @@ def make_win32_env_from_paths(include, lib, path): 'PSCOM' : '$DVIPS $DVIPSFLAGS -o $TARGET $SOURCES', 'PSPREFIX' : '', 'PSSUFFIX' : '.ps', - 'BUILDERS' : [Alias, CFile, CXXFile, DVI, Library, Object, - PDF, PostScript, Program], + 'BUILDERS' : { 'Alias' : Alias, + 'CFile' : CFile, + 'CXXFile' : CXXFile, + 'DVI' : DVI, + 'Library' : Library, + 'Object' : Object, + 'PDF' : PDF, + 'PostScript' : PostScript, + 'Program' : Program }, 'SCANNERS' : [CScan], 'LIBDIRPREFIX' : '/LIBPATH:', 'LIBDIRSUFFIX' : '', @@ -583,8 +582,15 @@ if os.name == 'posix': 'PSCOM' : '$DVIPS $DVIPSFLAGS -o $TARGET $SOURCES', 'PSPREFIX' : '', 'PSSUFFIX' : '.ps', - 'BUILDERS' : [Alias, CFile, CXXFile, DVI, Library, Object, - PDF, PostScript, Program], + 'BUILDERS' : { 'Alias' : Alias, + 'CFile' : CFile, + 'CXXFile' : CXXFile, + 'DVI' : DVI, + 'Library' : Library, + 'Object' : Object, + 'PDF' : PDF, + 'PostScript' : PostScript, + 'Program' : Program }, 'SCANNERS' : [CScan], 'LIBDIRPREFIX' : '-L', 'LIBDIRSUFFIX' : '', diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 8c61ceb..787a66d 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -45,6 +45,8 @@ from SCons.Errors import UserError import SCons.Node import SCons.Node.FS import SCons.Util +import SCons.Warnings +from UserDict import UserDict def installFunc(env, target, source): try: @@ -82,6 +84,29 @@ def our_deepcopy(x): copy = x return copy +class BuilderDict(UserDict): + """This is a dictionary-like class used by Environment + to hold Builders. We need to do this, because every time + someone changes the Builders in the Environment's BUILDERS + dictionary, we need to update the Environment's attributes.""" + def setEnvironment(self, env): + self.env = env + + def __setitem__(self, item, val): + UserDict.__setitem__(self, item, val) + try: + self.env.Replace() # re-compute Builders + except AttributeError: + # Have to catch this because sometimes + # __setitem__ gets called out of __init__, when + # we don't have an env attribute yet, nor do + # we want one! + pass + + def __delitem__(self, item): + UserDict.__delitem__(self, item) + self.env.Replace() + class Environment: """Base class for construction Environments. These are the primary objects used to communicate dependency and @@ -155,14 +180,13 @@ class Environment: """ apply(self.Replace, (), kw) - def Replace(self, **kw): - """Replace existing construction variables in an Environment - with new construction variables and/or values. - """ - self._dict.update(our_deepcopy(kw)) - if self._dict.has_key('BUILDERS') and \ - not SCons.Util.is_List(self._dict['BUILDERS']): - self._dict['BUILDERS'] = [self._dict['BUILDERS']] + def __updateBuildersAndScanners(self): + """Update attributes for builders and scanners. + + Have to be careful in this function...we can't + call functions like __setitem__() or Replace(), or + we will have infinite recursion.""" + if self._dict.has_key('SCANNERS') and \ not SCons.Util.is_List(self._dict['SCANNERS']): self._dict['SCANNERS'] = [self._dict['SCANNERS']] @@ -190,11 +214,37 @@ class Environment: kw['env'] = self.env apply(self.builder.execute, (), kw) - for b in self._dict['BUILDERS']: - setattr(self, b.name, BuilderWrapper(self, b)) + if self._dict.has_key('BUILDERS'): + if SCons.Util.is_Dict(self._dict['BUILDERS']): + bd = self._dict['BUILDERS'] + if not isinstance(bd, BuilderDict): + # Convert it to a BuilderDict. This class + # Updates our builder attributes every time + # someone changes it. + bd = BuilderDict(bd) + bd.setEnvironment(self) + self._dict['BUILDERS'] = bd + 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)) for s in self._dict['SCANNERS']: setattr(self, s.name, s) + + + def Replace(self, **kw): + """Replace existing construction variables in an Environment + with new construction variables and/or values. + """ + self._dict.update(our_deepcopy(kw)) + self.__updateBuildersAndScanners() def Append(self, **kw): """Append values to existing construction variables @@ -212,6 +262,7 @@ class Environment: self._dict[key] = [ self._dict[key] ] + kw[key] else: self._dict[key] = self._dict[key] + kw[key] + self.__updateBuildersAndScanners() def Depends(self, target, dependency): """Explicity specify that 'target's depend on 'dependency'.""" @@ -257,6 +308,7 @@ class Environment: def __setitem__(self, key, value): self._dict[key] = value + self.__updateBuildersAndScanners() def __getitem__(self, key): return self._dict[key] @@ -272,7 +324,7 @@ class Environment: source files using the supplied action. Action may be any type that the Builder constructor will accept for an action.""" - bld = SCons.Builder.Builder(name="Command", action=action) + bld = SCons.Builder.Builder(action=action) return bld(self, target, source) def Install(self, dir, source): diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index 3066fc2..6859ee3 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -27,7 +27,7 @@ import sys import unittest from SCons.Environment import * - +import SCons.Warnings built_it = {} @@ -76,6 +76,7 @@ class EnvironmentTestCase(unittest.TestCase): 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') @@ -100,6 +101,47 @@ class EnvironmentTestCase(unittest.TestCase): assert env4.builder1.env is env4 assert env4.builder2.env is env4 + # Now test BUILDERS as a dictionary. + built_it = {} + env5 = Environment(BUILDERS={ 'foo' : b1 }) + env5['BUILDERS']['bar'] = b2 + env5.foo.execute(target='out1') + env5.bar.execute(target='out2') + assert built_it['out1'] + assert built_it['out2'] + + built_it = {} + env6 = Environment() + env6['BUILDERS'] = { 'foo' : b1, + 'bar' : b2 } + env6.foo.execute(target='out1') + env6.bar.execute(target='out2') + 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 diff --git a/src/engine/SCons/Scanner/C.py b/src/engine/SCons/Scanner/C.py index c81417a..77b9525 100644 --- a/src/engine/SCons/Scanner/C.py +++ b/src/engine/SCons/Scanner/C.py @@ -38,6 +38,7 @@ import SCons.Node import SCons.Node.FS import SCons.Scanner import SCons.Util +import SCons.Warnings include_re = re.compile('^[ \t]*#[ \t]*include[ \t]+(<|")([\\w./\\\\]+)(>|")', re.M) @@ -114,6 +115,9 @@ def scan(node, env, target, fs = SCons.Node.FS.default_fs): if not n is None: nodes.append(n) + else: + SCons.Warnings.warn(SCons.Warnings.DependencyWarning, + "No dependency generated for file: %s (included from: %s) -- file not found" % (include[1], node)) node.found_includes[cpppath] = nodes # Schwartzian transform from the Python FAQ Wizard diff --git a/src/engine/SCons/Scanner/CTests.py b/src/engine/SCons/Scanner/CTests.py index f99af18..cc9e116 100644 --- a/src/engine/SCons/Scanner/CTests.py +++ b/src/engine/SCons/Scanner/CTests.py @@ -30,6 +30,7 @@ import sys import os import os.path import SCons.Node.FS +import SCons.Warnings test = TestCmd.TestCmd(workdir = '') @@ -230,11 +231,23 @@ class CScannerTestCase8(unittest.TestCase): class CScannerTestCase9(unittest.TestCase): def runTest(self): + SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning) + class TestOut: + def __call__(self, x): + self.out = x + + to = TestOut() + to.out = None + SCons.Warnings._warningOut = to test.write('fa.h','\n') fs = SCons.Node.FS.FS(test.workpath('')) s = SCons.Scanner.C.CScan(fs=fs) env = DummyEnvironment([]) deps = s.scan(fs.File('fa.cpp'), env, DummyTarget()) + + # Did we catch the warning associated with not finding fb.h? + assert to.out + deps_match(self, deps, [ 'fa.h' ]) test.unlink('fa.h') diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index c42a700..d95f8f0 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -63,6 +63,7 @@ import SCons.Sig.MD5 from SCons.Taskmaster import Taskmaster import SCons.Builder import SCons.Script.SConscript +import SCons.Warnings # @@ -200,24 +201,20 @@ def _scons_syntax_error(e): def find_deepest_user_frame(tb): """ Find the deepest stack frame that is not part of SCons. + + Input is a "pre-processed" stack trace in the form + returned by traceback.extract_tb() or traceback.extract_stack() """ - stack = [tb] - while tb.tb_next is not None: - tb = tb.tb_next - stack.append(tb) - - stack.reverse() + tb.reverse() # find the deepest traceback frame that is not part # of SCons: - for frame in stack: - filename = frame.tb_frame.f_code.co_filename + for frame in tb: + filename = frame[0] if string.find(filename, os.sep+'SCons'+os.sep) == -1: - tb = frame - break - - return tb + return frame + return tb[0] def _scons_user_error(e): """Handle user errors. Print out a message and a description of the @@ -226,10 +223,7 @@ def _scons_user_error(e): not part of SCons itself. """ etype, value, tb = sys.exc_info() - tb = find_deepest_user_frame(tb) - lineno = traceback.tb_lineno(tb) - filename = tb.tb_frame.f_code.co_filename - routine = tb.tb_frame.f_code.co_name + filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_tb(tb)) sys.stderr.write("\nSCons error: %s\n" % value) sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine)) sys.exit(2) @@ -241,10 +235,15 @@ def _scons_user_warning(e): not part of SCons itself. """ etype, value, tb = sys.exc_info() - tb = find_deepest_user_frame(tb) - lineno = traceback.tb_lineno(tb) - filename = tb.tb_frame.f_code.co_filename - routine = tb.tb_frame.f_code.co_name + filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_tb(tb)) + sys.stderr.write("\nSCons warning: %s\n" % e) + sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine)) + +def _scons_internal_warning(e): + """Slightly different from _scons_user_warning in that we use the + *current call stack* rather than sys.exc_info() to get our stack trace. + This is used by the warnings framework to print warnings.""" + filename, lineno, routine, dummy = find_deepest_user_frame(traceback.extract_stack()) sys.stderr.write("\nSCons warning: %s\n" % e) sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine)) @@ -685,9 +684,62 @@ def options_init(): short = 'W', long = ['what-if', 'new-file', 'assume-new'], arg = 'FILE', help = "Consider FILE to be changed.") - Option(func = opt_not_yet, future = 1, - long = ['warn-undefined-variables'], - help = "Warn when an undefined variable is referenced.") + def opt_warn(opt, arg): + """The --warn option. An argument to this option + should be of the form <warning-class> or no-<warning-class>. + The warning class is munged in order to get an actual class + name from the SCons.Warnings module to enable or disable. + The supplied <warning-class> is split on hyphens, each element + is captialized, then smushed back together. Then the string + "SCons.Warnings." is added to the front and "Warning" is added + to the back to get the fully qualified class name. + + For example, --warn=deprecated will enable the + SCons.Warnings.DeprecatedWarning class. + + --warn=no-dependency will disable the + SCons.Warnings.DependencyWarning class. + + As a special case, --warn=all and --warn=no-all + will enable or disable (respectively) the base + class of all warnings, which is SCons.Warning.Warning.""" + + elems = string.split(string.lower(arg), '-') + enable = 1 + if elems[0] == 'no': + enable = 0 + del elems[0] + + if len(elems) == 1 and elems[0] == 'all': + class_name = "Warning" + else: + class_name = string.join(map(string.capitalize, elems), '') + \ + "Warning" + try: + clazz = getattr(SCons.Warnings, class_name) + except AttributeError: + sys.stderr.write("No warning type: '%s'\n" % arg) + else: + if enable: + SCons.Warnings.enableWarningClass(clazz) + else: + SCons.Warnings.suppressWarningClass(clazz) + + Option(func = opt_warn, + long = [ 'warn', 'warning' ], arg='WARNING-SPEC', + help = "Enable or disable warnings.") + + + # We want to preserve the --warn-undefined-variables option for + # compatibility with GNU Make. Unfortunately, this conflicts with + # the --warn=type option that we're using for our own warning + # control. The getopt module reports "--warn not a unique prefix" + # when both are defined. We may be able to support both in the + # future with a more robust getopt solution. + # + #Option(func = opt_not_yet, future = 1, + # long = ['warn-undefined-variables'], + # help = "Warn when an undefined variable is referenced.") Option(func = opt_not_yet, future = 1, short = 'Y', long = ['repository'], arg = 'REPOSITORY', @@ -749,6 +801,10 @@ def _main(): except: getopt_err = getopt.error + # Enable deprecated warnings by default. + SCons.Warnings._warningOut = _scons_internal_warning + SCons.Warnings.enableWarningClass(SCons.Warnings.DeprecatedWarning) + try: cmd_opts, t = getopt.getopt(string.split(os.environ['SCONSFLAGS']), short_opts, long_opts) diff --git a/src/engine/SCons/Warnings.py b/src/engine/SCons/Warnings.py new file mode 100644 index 0000000..5ba3aec --- /dev/null +++ b/src/engine/SCons/Warnings.py @@ -0,0 +1,81 @@ +# +# 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. +# + +"""SCons.Warnings + +This file implements the warnings framework for SCons. + +""" + +__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" + +import sys +import copy +import traceback + +import SCons.Errors + +class Warning(SCons.Errors.UserError): + pass + +class DeprecatedWarning(Warning): + pass + +class DependencyWarning(Warning): + pass + +_warningAsException = 0 + +# The below is a list of 2-tuples. The first element is a class object. +# The second element is true if that class is enabled, false if it is disabled. +_enabled = [] + +_warningOut = None + +def suppressWarningClass(clazz): + """Suppresses all warnings that are of type clazz or + derived from clazz.""" + _enabled.insert(0, (clazz, 0)) + +def enableWarningClass(clazz): + """Suppresses all warnings that are of type clazz or + derived from clazz.""" + _enabled.insert(0, (clazz, 1)) + +def warningAsException(flag=1): + global _warningAsException + _warningAsException = flag + +def warn(clazz, *args): + global _enabled, _warningAsException, _warningOut + + warning = clazz(args) + for clazz, flag in _enabled: + if isinstance(warning, clazz): + if flag: + if _warningAsException: + raise warning + + if _warningOut: + _warningOut(warning) + break diff --git a/src/engine/SCons/WarningsTests.py b/src/engine/SCons/WarningsTests.py new file mode 100644 index 0000000..efc9adc --- /dev/null +++ b/src/engine/SCons/WarningsTests.py @@ -0,0 +1,115 @@ +# +# 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.Warnings + +class TestOutput: + def __call__(self, x): + self.out = str(x) + +class WarningsTestCase(unittest.TestCase): + def test_Warning(self): + """Test warn function.""" + + # Reset global state + SCons.Warnings._enabled = [] + SCons.Warnings._warningAsException = 0 + + to = TestOutput() + SCons.Warnings._warningOut=to + SCons.Warnings.enableWarningClass(SCons.Warnings.Warning) + SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, + "Foo") + assert to.out == "Foo", to.out + SCons.Warnings.warn(SCons.Warnings.DependencyWarning, + "Foo", 1) + assert to.out == "('Foo', 1)", to.out + + def test_WarningAsExc(self): + """Test warnings as exceptions.""" + + # Reset global state + SCons.Warnings._enabled = [] + SCons.Warnings._warningAsException = 0 + + SCons.Warnings.enableWarningClass(SCons.Warnings.Warning) + SCons.Warnings.warningAsException() + try: + SCons.Warnings.warn(SCons.Warnings.Warning, "Foo") + except: + pass + else: + assert 0 + + SCons.Warnings.warningAsException(0) + SCons.Warnings.warn(SCons.Warnings.Warning, "Foo") + + def test_Disable(self): + """Test disabling/enabling warnings.""" + + # Reset global state + SCons.Warnings._enabled = [] + SCons.Warnings._warningAsException = 0 + + to = TestOutput() + SCons.Warnings._warningOut=to + to.out = None + + # No warnings by default + SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, + "Foo") + assert to.out is None, to.out + + SCons.Warnings.enableWarningClass(SCons.Warnings.Warning) + SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, + "Foo") + assert to.out == "Foo", to.out + + to.out = None + SCons.Warnings.suppressWarningClass(SCons.Warnings.DeprecatedWarning) + SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, + "Foo") + assert to.out is None, to.out + + # Dependency warnings should still be enabled though + SCons.Warnings.enableWarningClass(SCons.Warnings.Warning) + SCons.Warnings.warn(SCons.Warnings.DependencyWarning, + "Foo") + assert to.out == "Foo", to.out + + # Try reenabling all warnings... + SCons.Warnings.enableWarningClass(SCons.Warnings.Warning) + + SCons.Warnings.enableWarningClass(SCons.Warnings.Warning) + SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, + "Foo") + assert to.out == "Foo", to.out + +if __name__ == "__main__": + suite = unittest.makeSuite(WarningsTestCase, 'test_') + if not unittest.TextTestRunner().run(suite).wasSuccessful(): + sys.exit(1) diff --git a/test/Alias.py b/test/Alias.py index 6dae8a7..aff9c2a 100644 --- a/test/Alias.py +++ b/test/Alias.py @@ -41,9 +41,9 @@ sys.exit(0) """) test.write('SConstruct', """ -B = Builder(name = "B", action = r"%s build.py $TARGET $SOURCES") -builders = Environment().Dictionary('BUILDERS') -env = Environment(BUILDERS = builders + [ B ]) +B = Builder(action = r"%s build.py $TARGET $SOURCES") +env = Environment() +env['BUILDERS']['B'] = B env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') env.B(target = 'f3.out', source = 'f3.in') diff --git a/test/CommandGenerator.py b/test/CommandGenerator.py index 9a2a7c7..c708d15 100644 --- a/test/CommandGenerator.py +++ b/test/CommandGenerator.py @@ -48,8 +48,8 @@ def g(source, target, for_signature, env): return [[python, "build.py", "$TEMPFILE"] + source, [python, "build.py"] + target + ["$TEMPFILE"]] -b = Builder(name = 'b', generator=g) -env = Environment(BUILDERS = [b], +b = Builder(generator=g) +env = Environment(BUILDERS = { 'b' : b }, TEMPFILE=".temp") env.b(target = 'foo1.out', source = 'foo1.in') env.b(target = 'foo2.out', source = 'foo2.in') diff --git a/test/Default.py b/test/Default.py index 76ce560..96d786a 100644 --- a/test/Default.py +++ b/test/Default.py @@ -43,32 +43,32 @@ file.close() """) test.write(['one', 'SConstruct'], """ -B = Builder(name = 'B', action = r'%s ../build.py $TARGET $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'bar.out', source = 'bar.in') Default('foo.out') """ % python) test.write(['two', 'SConstruct'], """ -B = Builder(name = 'B', action = r'%s ../build.py $TARGET $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'bar.out', source = 'bar.in') Default('foo.out', 'bar.out') """ % python) test.write(['three', 'SConstruct'], """ -B = Builder(name = 'B', action = r'%s ../build.py $TARGET $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'bar.out', source = 'bar.in') Default('foo.out bar.out') """ % python) test.write(['four', 'SConstruct'], """ -B = Builder(name = 'B', action = r'%s ../build.py $TARGET $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = ['foo bar'], source = 'foo.in') env.B(target = 'foo', source = 'foo.in') env.B(target = 'bar', source = 'bar.in') @@ -76,8 +76,8 @@ Default(['foo bar']) """ % python) test.write(['five', 'SConstruct'], """ -B = Builder(name = 'B', action = r'%s ../build.py $TARGET $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s ../build.py $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) Default(env.B(target = 'foo.out', source = 'foo.in')) Default(env.B(target = 'bar.out', source = 'bar.in')) """ % python) @@ -115,8 +115,8 @@ test.fail_test(test.read(test.workpath('five', 'bar.out')) != "five/bar.in\n") test.subdir('sub1') test.write('SConstruct', """ -B = Builder(name = 'B', action = r'%s build.py $TARGET $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s build.py $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'xxx.out', source = 'xxx.in') SConscript('sub1/SConscript') """ % python) @@ -124,8 +124,8 @@ SConscript('sub1/SConscript') test.write('xxx.in', "xxx.in\n") test.write(['sub1', 'SConscript'], """ -B = Builder(name = 'B', action = r'%s build.py $TARGET $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s build.py $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'xxx.out', source = 'xxx.in') Default('xxx.out') """ % python) @@ -143,8 +143,8 @@ test.subdir('sub2') test.write('SConstruct', """ Default('sub2') -B = Builder(name = 'B', action = r'%s build.py $TARGET $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s build.py $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'xxx.out', source = 'xxx.in') SConscript('sub2/SConscript') """ % python) @@ -152,8 +152,8 @@ SConscript('sub2/SConscript') test.write('xxx.in', "xxx.in\n") test.write(['sub2', 'SConscript'], """ -B = Builder(name = 'B', action = r'%s build.py $TARGET $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s build.py $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'xxx.out', source = 'xxx.in') """ % python) diff --git a/test/Depends.py b/test/Depends.py index a261a4f..cb1fae1 100644 --- a/test/Depends.py +++ b/test/Depends.py @@ -42,11 +42,9 @@ file.close() """) test.write('SConstruct', """ -Foo = Builder(name = "Foo", - action = r"%s build.py $TARGET $SOURCES subdir/foo.dep") -Bar = Builder(name = "Bar", - action = r"%s build.py $TARGET $SOURCES subdir/bar.dep") -env = Environment(BUILDERS = [Foo, Bar]) +Foo = Builder(action = r"%s build.py $TARGET $SOURCES subdir/foo.dep") +Bar = Builder(action = r"%s build.py $TARGET $SOURCES subdir/bar.dep") +env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }) env.Depends(target = ['f1.out', 'f2.out'], dependency = 'subdir/foo.dep') env.Depends(target = 'f3.out', dependency = 'subdir/bar.dep') env.Foo(target = 'f1.out', source = 'f1.in') diff --git a/test/ENV.py b/test/ENV.py index 69a5b64..cfaa1b9 100644 --- a/test/ENV.py +++ b/test/ENV.py @@ -36,9 +36,9 @@ bin2_build_py = test.workpath('bin2', 'build.py') test.write('SConstruct', """ import os -Bld = Builder(name = 'Bld', action = r"%s build.py $TARGET $SOURCES") -env1 = Environment(ENV = {'X' : 'env1'}, BUILDERS = [Bld]) -env2 = Environment(ENV = {'X' : 'env2'}, BUILDERS = [Bld]) +Bld = Builder(action = r"%s build.py $TARGET $SOURCES") +env1 = Environment(ENV = {'X' : 'env1'}, BUILDERS = { 'Bld' : Bld }) +env2 = Environment(ENV = {'X' : 'env2'}, BUILDERS = { 'Bld' : Bld }) env1.Bld(target = 'env1.out', source = 'input') env2.Bld(target = 'env2.out', source = 'input') """ % python) diff --git a/test/Ignore.py b/test/Ignore.py index f507c66..0470d7e 100644 --- a/test/Ignore.py +++ b/test/Ignore.py @@ -43,11 +43,9 @@ file.close() """) test.write('SConstruct', """ -Foo = Builder(name = "Foo", - action = r"%s build.py $TARGET $SOURCES") -Bar = Builder(name = "Bar", - action = r"%s build.py $TARGET $SOURCES") -env = Environment(BUILDERS = [Foo, Bar]) +Foo = Builder(action = r"%s build.py $TARGET $SOURCES") +Bar = Builder(action = r"%s build.py $TARGET $SOURCES") +env = Environment(BUILDERS = { 'Foo' : Foo, 'Bar' : Bar }) env.Foo(target = 'f1.out', source = ['f1a.in', 'f1b.in']) env.Ignore(target = 'f1.out', dependency = 'f1b.in') SConscript('subdir/SConscript', "env") diff --git a/test/Precious.py b/test/Precious.py index 6e752b9..e0f8c8f 100644 --- a/test/Precious.py +++ b/test/Precious.py @@ -40,8 +40,8 @@ sys.exit(0) """) test.write('SConstruct', """ -B = Builder(name = "B", action = r"%s build.py $TARGET $SOURCES") -env = Environment(BUILDERS = [B]) +B = Builder(action = r"%s build.py $TARGET $SOURCES") +env = Environment(BUILDERS = { 'B' : B }) f1 = env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') env.B(target = 'f3.out', source = 'f3.in') diff --git a/test/SConscript.py b/test/SConscript.py index 22f7144..d1e6b6a 100644 --- a/test/SConscript.py +++ b/test/SConscript.py @@ -155,10 +155,10 @@ Return('foo') test.write('SConscript5', """ -B = Builder(name = 'B', action = 'B') +B = Builder(action = 'B') def scan(): pass -S = Scanner(name = 'S', function = scan) +S = Scanner(function = scan) A = Action("A") """) diff --git a/test/SharedLibrary.py b/test/SharedLibrary.py index e1b832c..6e96fd3 100644 --- a/test/SharedLibrary.py +++ b/test/SharedLibrary.py @@ -182,7 +182,7 @@ test.run(program = test.workpath('prog'), stdout = "f1.c\nf2a.c\nf2b.c\nf2c.c\nf3a.c\nf3b.c\nf3c.c\nprog.c\n") test.run(arguments = '-f SConstructFoo', status=2, stderr=''' -SCons error: Source file: foo\..* must be built with shared=1 in order to be compatible with the selected target. +SCons error: Source file: foo\..* must be built with shared=1 in order to be compatible with target: .* File ".*", line .*, in .* ''' ) diff --git a/test/actions.py b/test/actions.py index 65fa01a..84b123e 100644 --- a/test/actions.py +++ b/test/actions.py @@ -41,8 +41,8 @@ sys.exit(0) """) test.write('SConstruct', """ -B = Builder(name = 'B', action = r'%s build.py $TARGET 1 $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s build.py $TARGET 1 $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') """ % python) @@ -55,8 +55,8 @@ test.fail_test(test.read('foo.out') != "1\nfoo.in\n") test.up_to_date(arguments = '.') test.write('SConstruct', """ -B = Builder(name = 'B', action = r'%s build.py $TARGET 2 $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s build.py $TARGET 2 $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') """ % python) @@ -74,8 +74,8 @@ def func(env, target, source): string.join(map(str, source))) print cmd return os.system(cmd) -B = Builder(name = 'B', action = func) -env = Environment(BUILDERS = [B]) +B = Builder(action = func) +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') """ % python) @@ -99,8 +99,8 @@ class bld: def get_contents(self, env, target, source): return self.cmd %% (string.join(map(str, target)), string.join(map(str, source))) -B = Builder(name = 'B', action = bld()) -env = Environment(BUILDERS = [B]) +B = Builder(action = bld()) +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') """ % python) diff --git a/test/build-errors.py b/test/build-errors.py index ea129fa..956842e 100644 --- a/test/build-errors.py +++ b/test/build-errors.py @@ -41,8 +41,8 @@ test.write("f2.in", "\n") test.write("f3.in", "\n") test.write('SConstruct1', r""" -bld = Builder(name = 'bld', action = '%s $SOURCES $TARGET') -env = Environment(BUILDERS = [bld]) +bld = Builder(action = '%s $SOURCES $TARGET') +env = Environment(BUILDERS = { 'bld' : bld }) env.bld(target = 'f1', source = 'f1.in') """ % string.replace(no_such_file, '\\', '\\\\')) @@ -78,8 +78,8 @@ scons: *** [f1] Error 127 test.write('SConstruct2', r""" -bld = Builder(name = 'bld', action = '%s $SOURCES $TARGET') -env = Environment(BUILDERS = [bld]) +bld = Builder(action = '%s $SOURCES $TARGET') +env = Environment(BUILDERS = { 'bld': bld }) env.bld(target = 'f2', source = 'f2.in') """ % string.replace(not_executable, '\\', '\\\\')) @@ -102,8 +102,8 @@ scons: *** [f2] Error 126 """ % not_executable) test.write('SConstruct3', r""" -bld = Builder(name = 'bld', action = '%s $SOURCES $TARGET') -env = Environment(BUILDERS = [bld]) +bld = Builder(action = '%s $SOURCES $TARGET') +env = Environment(BUILDERS = { 'bld' : bld }) env.bld(target = 'f3', source = 'f3.in') """ % string.replace(test.workdir, '\\', '\\\\')) diff --git a/test/builderrors.py b/test/builderrors.py index 8a574db..286b115 100644 --- a/test/builderrors.py +++ b/test/builderrors.py @@ -46,9 +46,9 @@ sys.exit(exitval) """) test.write(['one', 'SConstruct'], """ -B0 = Builder(name = 'B0', action = r'%s ../build.py 0 $TARGET $SOURCES') -B1 = Builder(name = 'B1', action = r'%s ../build.py 1 $TARGET $SOURCES') -env = Environment(BUILDERS = [B0, B1]) +B0 = Builder(action = r'%s ../build.py 0 $TARGET $SOURCES') +B1 = Builder(action = r'%s ../build.py 1 $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B0' : B0, 'B1' : B1 }) env.B1(target = 'f1.out', source = 'f1.in') env.B0(target = 'f2.out', source = 'f2.in') env.B0(target = 'f3.out', source = 'f3.in') @@ -66,9 +66,9 @@ test.fail_test(os.path.exists(test.workpath('f2.out'))) test.fail_test(os.path.exists(test.workpath('f3.out'))) test.write(['two', 'SConstruct'], """ -B0 = Builder(name = 'B0', action = r'%s ../build.py 0 $TARGET $SOURCES') -B1 = Builder(name = 'B1', action = r'%s ../build.py 1 $TARGET $SOURCES') -env = Environment(BUILDERS = [B0, B1]) +B0 = Builder(action = r'%s ../build.py 0 $TARGET $SOURCES') +B1 = Builder(action = r'%s ../build.py 1 $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B0': B0, 'B1' : B1 }) env.B0(target = 'f1.out', source = 'f1.in') env.B1(target = 'f2.out', source = 'f2.in') env.B0(target = 'f3.out', source = 'f3.in') @@ -86,9 +86,9 @@ test.fail_test(os.path.exists(test.workpath('f2.out'))) test.fail_test(os.path.exists(test.workpath('f3.out'))) test.write(['three', 'SConstruct'], """ -B0 = Builder(name = 'B0', action = r'%s ../build.py 0 $TARGET $SOURCES') -B1 = Builder(name = 'B1', action = r'%s ../build.py 1 $TARGET $SOURCES') -env = Environment(BUILDERS = [B0, B1]) +B0 = Builder(action = r'%s ../build.py 0 $TARGET $SOURCES') +B1 = Builder(action = r'%s ../build.py 1 $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B0' : B0, 'B1': B1 }) env.B0(target = 'f1.out', source = 'f1.in') env.B0(target = 'f2.out', source = 'f2.in') env.B1(target = 'f3.out', source = 'f3.in') diff --git a/test/chained-build.py b/test/chained-build.py index 98eb992..1a7daf9 100644 --- a/test/chained-build.py +++ b/test/chained-build.py @@ -33,7 +33,7 @@ def build(env, target, source): open(str(target[0]), 'wt').write(open(str(source[0]), 'rt').read()) print "built %s"%target[0] -env=Environment(BUILDERS=[Builder(name='B', action=build)]) +env=Environment(BUILDERS={'B' : Builder(action=build)}) env.B('foo.mid', 'foo.in') """) @@ -42,7 +42,7 @@ def build(env, target, source): open(str(target[0]), 'wt').write(open(str(source[0]), 'rt').read()) print "built %s"%target[0] -env=Environment(BUILDERS=[Builder(name='B', action=build)]) +env=Environment(BUILDERS={'B' : Builder(action=build)}) env.B('foo.out', 'foo.mid') """) diff --git a/test/emitter.py b/test/emitter.py index 6411325..2222abe 100644 --- a/test/emitter.py +++ b/test/emitter.py @@ -51,9 +51,9 @@ def emitter(target, source, env): target.append(str(target[0])+".foo") return target,source -b = Builder(name='foo', action=build, emitter=emitter) +b = Builder(action=build, emitter=emitter) -env=Environment(BUILDERS=[b]) +env=Environment(BUILDERS={ 'foo': b }) env.foo('f.out', 'f.in') """) diff --git a/test/errors.py b/test/errors.py index fb042bb..0f83e64 100644 --- a/test/errors.py +++ b/test/errors.py @@ -42,8 +42,8 @@ def foo(env, target, source): def exit(env, target, source): raise 'exit' -env = Environment(BUILDERS = [Builder(name='foo', action=foo), - Builder(name='exit', action=exit)]) +env = Environment(BUILDERS = { 'foo' : Builder(action=foo), + 'exit' : Builder(action=exit) }) env.foo('foo.out', 'foo.in') env.exit('exit.out', 'exit.in') diff --git a/test/exceptions.py b/test/exceptions.py index b3de487..b24e581 100644 --- a/test/exceptions.py +++ b/test/exceptions.py @@ -34,8 +34,8 @@ test = TestSCons.TestSCons(match = TestCmd.match_re_dotall) test.write('SConstruct', """ def func(source = None, target = None, env = None): raise "func exception" -B = Builder(name = 'B', action = func) -env = Environment(BUILDERS = [B]) +B = Builder(action = func) +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') """) diff --git a/test/multi.py b/test/multi.py index a64f993..f5201d9 100644 --- a/test/multi.py +++ b/test/multi.py @@ -35,8 +35,8 @@ def build(env, target, source): for s in source: file.write(open(str(s), 'rb').read()) -B = Builder(name='B', action=build, multi=1) -env = Environment(BUILDERS = [B]) +B = Builder(action=build, multi=1) +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'foo.out', source = 'bar.in') """) @@ -55,8 +55,8 @@ def build(env, target, source): for s in source: file.write(open(str(s), 'rb').read()) -B = Builder(name='B', action=build, multi=0) -env = Environment(BUILDERS = [B]) +B = Builder(action=build, multi=0) +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'foo.out', source = 'bar.in') """) @@ -74,8 +74,8 @@ def build(env, target, source): for s in source: file.write(open(str(s), 'rb').read()) -B = Builder(name='B', action=build, multi=1) -env = Environment(BUILDERS = [B]) +B = Builder(action=build, multi=1) +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in', foo=1) env.B(target = 'foo.out', source = 'bar.in', foo=2) """) @@ -93,8 +93,8 @@ def build(env, target, source): for s in source: file.write(open(str(s), 'rb').read()) -B = Builder(name='B', action=build, multi=1) -env = Environment(BUILDERS = [B]) +B = Builder(action=build, multi=1) +env = Environment(BUILDERS = { 'B' : B }) env2 = env.Copy(CCFLAGS='foo') env.B(target = 'foo.out', source = 'foo.in') env2.B(target = 'foo.out', source = 'bar.in') @@ -113,8 +113,8 @@ def build(env, target, source): for s in source: file.write(open(str(s), 'rb').read()) -B = Builder(name='B', action=build, multi=0) -env = Environment(BUILDERS = [B]) +B = Builder(action=build, multi=0) +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo.out', source = 'foo.in') env.B(target = 'foo.out', source = 'foo.in') """) @@ -128,9 +128,12 @@ def build(env, target, source): for s in source: file.write(open(str(s), 'rb').read()) -B = Builder(name='B', action=build, multi=1) -C = Builder(name='C', action=build, multi=1) -env = Environment(BUILDERS = [B,C]) +def build2(env, target, source): + build(env, target, source) + +B = Builder(action=build, multi=1) +C = Builder(action=build2, multi=1) +env = Environment(BUILDERS = { 'B' : B, 'C' : C }) env.B(target = 'foo.out', source = 'foo.in') env.C(target = 'foo.out', source = 'bar.in') """) @@ -139,7 +142,7 @@ test.run(arguments='foo.out', status=2, stderr=""" SCons error: Two different builders (B and C) were specified for the same target: foo.out -File "SConstruct", line 11, in ? +File "SConstruct", line 14, in ? """) test.write('SConstruct', """ @@ -149,8 +152,8 @@ def build(env, target, source): for s in source: file.write(open(str(s), 'rb').read()) -B = Builder(name='B', action=build, multi=1) -env = Environment(BUILDERS = [B]) +B = Builder(action=build, multi=1) +env = Environment(BUILDERS = { 'B' : B }) env.B(target = ['foo.out', 'bar.out'], source = 'foo.in') env.B(target = ['foo.out', 'bar.out'], source = 'bar.in') """) @@ -168,8 +171,8 @@ def build(env, target, source): for s in source: file.write(open(str(s), 'rb').read()) -B = Builder(name='B', action=build, multi=1) -env = Environment(BUILDERS = [B]) +B = Builder(action=build, multi=1) +env = Environment(BUILDERS = { 'B' : B }) env.B(target = ['foo.out', 'bar.out'], source = 'foo.in') env.B(target = ['bar.out', 'foo.out'], source = 'bar.in') """) @@ -197,8 +200,8 @@ def build(env, target, source): for s in source: file.write(open(str(s), 'rb').read()) -B = Builder(name='B', action=build, multi=1) -env = Environment(BUILDERS = [B]) +B = Builder(action=build, multi=1) +env = Environment(BUILDERS = { 'B' : B }) env.B(target = ['foo.out', 'bar.out'], source = 'foo.in') env.B(target = ['bar.out', 'blat.out'], source = 'bar.in') """) @@ -217,8 +220,8 @@ def build(env, target, source): for s in source: file.write(open(str(s), 'rb').read()) -B = Builder(name='B', action=build, multi=1) -env = Environment(BUILDERS = [B]) +B = Builder(action=build, multi=1) +env = Environment(BUILDERS = { 'B' : B }) env.B(target = ['foo.out', 'bar.out'], source = 'foo.in') env.B(target = 'foo.out', source = 'bar.in') """) diff --git a/test/multiline.py b/test/multiline.py index 56c051b..ba13516 100644 --- a/test/multiline.py +++ b/test/multiline.py @@ -42,10 +42,10 @@ sys.exit(0) """) test.write('SConstruct', """ -B1 = Builder(name = 'B1', action = [ [ r'%s', 'build.py', '.temp', '$SOURCES' ], - [ r'%s', 'build.py', '$TARGETS', '.temp'] ]) -B2 = Builder(name = 'B2', action = r'%s' + " build.py .temp $SOURCES\\n" + r'%s' + " build.py $TARGETS .temp") -env = Environment(BUILDERS = [B1, B2]) +B1 = Builder(action = [ [ r'%s', 'build.py', '.temp', '$SOURCES' ], + [ r'%s', 'build.py', '$TARGETS', '.temp'] ]) +B2 = Builder(action = r'%s' + " build.py .temp $SOURCES\\n" + r'%s' + " build.py $TARGETS .temp") +env = Environment(BUILDERS = { 'B1' : B1, 'B2' : B2 }) env.B1(target = 'foo1.out', source = 'foo1.in') env.B2(target = 'foo2.out', source = 'foo2.in') env.B1(target = 'foo3.out', source = 'foo3.in') diff --git a/test/option--.py b/test/option--.py index de9cbb6..6a18cf5 100644 --- a/test/option--.py +++ b/test/option--.py @@ -41,9 +41,8 @@ file.close() """) test.write('SConstruct', """ -MyBuild = Builder(name = "MyBuild", - action = r'%s build.py $TARGETS') -env = Environment(BUILDERS = [MyBuild]) +MyBuild = Builder(action = r'%s build.py $TARGETS') +env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = '-f1.out', source = 'f1.in') env.MyBuild(target = '-f2.out', source = 'f2.in') """ % python) diff --git a/test/option--D.py b/test/option--D.py index b1d06b0..dbfbb3e 100644 --- a/test/option--D.py +++ b/test/option--D.py @@ -44,8 +44,9 @@ file.close() test.write('SConstruct', """ import SCons.Defaults -B = Builder(name='B', action='%s build.py $TARGET $SOURCES') -env = Environment(BUILDERS = [B, SCons.Defaults.Alias]) +B = Builder(action='%s build.py $TARGET $SOURCES') +env = Environment() +env['BUILDERS']['B'] = B env.B(target = 'sub1/foo.out', source = 'sub1/foo.in') Export('env') SConscript('sub1/SConscript') diff --git a/test/option--U.py b/test/option--U.py index b984507..a683a8d 100644 --- a/test/option--U.py +++ b/test/option--U.py @@ -45,8 +45,8 @@ file.close() test.write('SConstruct', """ import SCons.Defaults -B = Builder(name='B', action='%s build.py $TARGET $SOURCES', multi=1) -env = Environment(BUILDERS = [B, SCons.Defaults.Alias]) +env = Environment() +env['BUILDERS']['B'] = Builder(action='%s build.py $TARGET $SOURCES', multi=1) Default(env.B(target = 'sub1/foo.out', source = 'sub1/foo.in')) Export('env') SConscript('sub2/SConscript') diff --git a/test/option--max-drift.py b/test/option--max-drift.py index 0b8f0c5..facaeca 100644 --- a/test/option--max-drift.py +++ b/test/option--max-drift.py @@ -45,8 +45,8 @@ file.close() """) test.write('SConstruct', """ -B = Builder(name = "B", action = r'%s build.py $TARGETS $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s build.py $TARGETS $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') """ % python) diff --git a/test/option--warn.py b/test/option--warn.py new file mode 100644 index 0000000..fab1a93 --- /dev/null +++ b/test/option--warn.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python +# +# 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 sys + +import TestSCons +import TestCmd + +test = TestSCons.TestSCons(match = TestCmd.match_re_dotall) + +test.write("SConstruct",""" +b=Builder(name='b', action='foo') +""") + +test.run(arguments='', stderr=r""" +SCons warning: The use of the 'name' parameter to Builder\(\) is deprecated\. +File "SConstruct", line 2, in \? +""") + +test.run(arguments='--warn=no-deprecated', stderr='') + +test.run(arguments='--warn=no-all', stderr='') + +test.run(arguments='--warn=no-all --warn=deprecated', stderr=r""" +SCons warning: The use of the 'name' parameter to Builder\(\) is deprecated\. +File "SConstruct", line 2, in \? +""") + +test.write("SConstruct",""" +def build(target, source, env): + pass + +env=Environment() +env['BUILDERS']['test'] = Builder(action=build) +env.test(target='foo', source='foo.c') +""") + +test.write("foo.c",""" +#include "not_there.h" +""") + +test.run(arguments='--warn=dependency .', stderr=r""" +SCons warning: No dependency generated for file: not_there\.h \(included from: foo\.c\) \-\- file not found +File ".+", line \d+, in .+ +""") + +test.run(arguments='--warn=all .', stderr=r""" +SCons warning: No dependency generated for file: not_there\.h \(included from: foo\.c\) \-\- file not found +File ".+", line \d+, in .+ +""") + +test.run(arguments='--warn=all --warn=no-dependency .', stderr="") + +test.run(arguments='--warn=no-dependency --warn=all .', stderr=r""" +SCons warning: No dependency generated for file: not_there\.h \(included from: foo\.c\) \-\- file not found +File ".+", line \d+, in .+ +""") + +test.pass_test() diff --git a/test/option--wuv.py b/test/option--wuv.py index 3c0ee3d..db5481a 100644 --- a/test/option--wuv.py +++ b/test/option--wuv.py @@ -30,6 +30,14 @@ import sys test = TestSCons.TestSCons() +# We want to preserve the --warn-undefined-variables option for +# compatibility with GNU Make. Unfortunately, this conflicts with +# the --warn=type option that we're using for our own warning +# control. The getopt module reports "--warn not a unique prefix" +# when both are defined. We may be able to support both in the +# future with a more robust getopt solution. +test.pass_test() #XXX Short-circuit until then. + test.write('SConstruct', "") test.run(arguments = '--warn-undefined-variables', diff --git a/test/option-c.py b/test/option-c.py index 1a240de..a686f5a 100644 --- a/test/option-c.py +++ b/test/option-c.py @@ -41,8 +41,8 @@ file.close() """) test.write('SConstruct', """ -B = Builder(name = 'B', action = r'%s build.py $TARGETS $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s build.py $TARGETS $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'foo1.out', source = 'foo1.in') env.B(target = 'foo2.out', source = 'foo2.xxx') env.B(target = 'foo2.xxx', source = 'foo2.in') diff --git a/test/option-i.py b/test/option-i.py index c594563..2e905e1 100644 --- a/test/option-i.py +++ b/test/option-i.py @@ -46,9 +46,9 @@ sys.exit(1) """) test.write('SConstruct', """ -Succeed = Builder(name = "Succeed", action = r'%s succeed.py $TARGETS') -Fail = Builder(name = "Fail", action = r'%s fail.py $TARGETS') -env = Environment(BUILDERS = [Succeed, Fail]) +Succeed = Builder(action = r'%s succeed.py $TARGETS') +Fail = Builder(action = r'%s fail.py $TARGETS') +env = Environment(BUILDERS = { 'Succeed' : Succeed, 'Fail' : Fail }) env.Fail(target = 'aaa.1', source = 'aaa.in') env.Succeed(target = 'aaa.out', source = 'aaa.1') env.Fail(target = 'bbb.1', source = 'bbb.in') diff --git a/test/option-j.py b/test/option-j.py index 49bd6ec..e67d3b4 100644 --- a/test/option-j.py +++ b/test/option-j.py @@ -52,9 +52,8 @@ file.close() """) test.write('SConstruct', """ -MyBuild = Builder(name = "MyBuild", - action = r'%s build.py $TARGETS') -env = Environment(BUILDERS = [MyBuild]) +MyBuild = Builder(action = r'%s build.py $TARGETS') +env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1', source = 'f1.in') env.MyBuild(target = 'f2', source = 'f2.in') """ % python) diff --git a/test/option-k.py b/test/option-k.py index 51fa6c6..3899f8e 100644 --- a/test/option-k.py +++ b/test/option-k.py @@ -46,9 +46,9 @@ sys.exit(1) """) test.write('SConstruct', """ -Succeed = Builder(name = "Succeed", action = r'%s succeed.py $TARGETS') -Fail = Builder(name = "Fail", action = r'%s fail.py $TARGETS') -env = Environment(BUILDERS = [Succeed, Fail]) +Succeed = Builder(action = r'%s succeed.py $TARGETS') +Fail = Builder(action = r'%s fail.py $TARGETS') +env = Environment(BUILDERS = { 'Succeed' : Succeed, 'Fail' : Fail }) env.Fail(target = 'aaa.1', source = 'aaa.in') env.Succeed(target = 'aaa.out', source = 'aaa.1') env.Succeed(target = 'bbb.out', source = 'bbb.in') diff --git a/test/option-n.py b/test/option-n.py index f436dd2..7c796df 100644 --- a/test/option-n.py +++ b/test/option-n.py @@ -41,9 +41,8 @@ file.close() """) test.write('SConstruct', """ -MyBuild = Builder(name = "MyBuild", - action = r'%s build.py $TARGETS') -env = Environment(BUILDERS = [MyBuild]) +MyBuild = Builder(action = r'%s build.py $TARGETS') +env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1.out', source = 'f1.in') env.MyBuild(target = 'f2.out', source = 'f2.in') """ % python) diff --git a/test/option-q.py b/test/option-q.py index 6e72a26..efb192a 100644 --- a/test/option-q.py +++ b/test/option-q.py @@ -43,8 +43,8 @@ file.close() """) test.write('SConstruct', """ -B = Builder(name='B', action='%s build.py $TARGET $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action='%s build.py $TARGET $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'aaa.out', source = 'aaa.in') env.B(target = 'bbb.out', source = 'bbb.in') """ % python) diff --git a/test/option-s.py b/test/option-s.py index 7601c09..450e994 100644 --- a/test/option-s.py +++ b/test/option-s.py @@ -41,9 +41,8 @@ file.close() """) test.write('SConstruct', """ -MyBuild = Builder(name = "MyBuild", - action = r'%s build.py $TARGET') -env = Environment(BUILDERS = [MyBuild]) +MyBuild = Builder(action = r'%s build.py $TARGET') +env = Environment(BUILDERS = { 'MyBuild' : MyBuild }) env.MyBuild(target = 'f1.out', source = 'f1.in') env.MyBuild(target = 'f2.out', source = 'f2.in') """ % python) diff --git a/test/option-u.py b/test/option-u.py index 8f23746..54f4f46 100644 --- a/test/option-u.py +++ b/test/option-u.py @@ -45,8 +45,8 @@ file.close() test.write('SConstruct', """ import SCons.Defaults -B = Builder(name='B', action='%s build.py $TARGET $SOURCES') -env = Environment(BUILDERS = [B, SCons.Defaults.Alias]) +env = Environment() +env['BUILDERS']['B'] = Builder(action='%s build.py $TARGET $SOURCES') env.B(target = 'sub1/foo.out', source = 'sub1/foo.in') Default('.') Export('env') diff --git a/test/sconsign.py b/test/sconsign.py index 76d8220..76fa355 100644 --- a/test/sconsign.py +++ b/test/sconsign.py @@ -44,9 +44,9 @@ def build2(target, source, env): os.chmod(dir, 0555) return None -B1 = Builder(name = "B1", action = build1) -B2 = Builder(name = "B2", action = build2) -env = Environment(BUILDERS = [B1, B2]) +B1 = Builder(action = build1) +B2 = Builder(action = build2) +env = Environment(BUILDERS = { 'B1' : B1, 'B2' : B2 }) env.B1(target = 'sub1/foo.out', source = 'foo.in') env.B2(target = 'sub2/foo.out', source = 'foo.in') env.B2(target = 'sub3/foo.out', source = 'foo.in') diff --git a/test/subdir.py b/test/subdir.py index 9e3c15a..3a874fe 100644 --- a/test/subdir.py +++ b/test/subdir.py @@ -40,8 +40,8 @@ file.close() """) test.write('SConstruct', """ -B = Builder(name = "B", action = "python build.py $TARGETS $SOURCES") -env = Environment(BUILDERS = [B]) +B = Builder(action = "python build.py $TARGETS $SOURCES") +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'subdir/f1.out', source = 'subdir/f1.in') env.B(target = 'subdir/f2.out', source = 'subdir/f2.in') env.B(target = 'subdir/f3.out', source = 'subdir/f3.in') diff --git a/test/timestamp-fallback.py b/test/timestamp-fallback.py index 8f5e262..f284afe 100644 --- a/test/timestamp-fallback.py +++ b/test/timestamp-fallback.py @@ -51,8 +51,8 @@ os.environ['PYTHONPATH'] = test.workpath('.') test.write('SConstruct', """ def build(env, target, source): open(str(target[0]), 'wt').write(open(str(source[0]), 'rt').read()) -B = Builder(name = 'B', action = build) -env = Environment(BUILDERS = [B]) +B = Builder(action = build) +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') env.B(target = 'f3.out', source = 'f3.in') diff --git a/test/up-to-date.py b/test/up-to-date.py index bc18388..3db1047 100644 --- a/test/up-to-date.py +++ b/test/up-to-date.py @@ -42,8 +42,8 @@ file.close() """) test.write('SConstruct', """ -B = Builder(name = "B", action = r'%s build.py $TARGETS $SOURCES') -env = Environment(BUILDERS = [B]) +B = Builder(action = r'%s build.py $TARGETS $SOURCES') +env = Environment(BUILDERS = { 'B' : B }) env.B(target = 'f1.out', source = 'f1.in') env.B(target = 'f2.out', source = 'f2.in') env.B(target = 'f3.out', source = 'f3.in') |