diff options
author | Steven Knight <knight@baldmt.com> | 2004-06-15 12:54:45 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2004-06-15 12:54:45 (GMT) |
commit | f0bf250b85abbe23faa7eeff0e53beb0613a2c6f (patch) | |
tree | 96cf9c87582bafacbe731704f4f10fbd8e34d331 /src | |
parent | a0d7c6333aeb9b6f2848ea3c90662f91f7f8ac0e (diff) | |
download | SCons-f0bf250b85abbe23faa7eeff0e53beb0613a2c6f.zip SCons-f0bf250b85abbe23faa7eeff0e53beb0613a2c6f.tar.gz SCons-f0bf250b85abbe23faa7eeff0e53beb0613a2c6f.tar.bz2 |
Add an option to not save the --debug=explain information.
Diffstat (limited to 'src')
-rw-r--r-- | src/CHANGES.txt | 5 | ||||
-rw-r--r-- | src/engine/SCons/Node/FS.py | 29 | ||||
-rw-r--r-- | src/engine/SCons/Node/FSTests.py | 50 | ||||
-rw-r--r-- | src/engine/SCons/Node/NodeTests.py | 14 | ||||
-rw-r--r-- | src/engine/SCons/Node/__init__.py | 32 | ||||
-rw-r--r-- | src/engine/SCons/SConsign.py | 11 | ||||
-rw-r--r-- | src/engine/SCons/SConsignTests.py | 9 | ||||
-rw-r--r-- | src/engine/SCons/Script/__init__.py | 13 |
8 files changed, 133 insertions, 30 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt index 704d7b7..ee75857 100644 --- a/src/CHANGES.txt +++ b/src/CHANGES.txt @@ -94,6 +94,11 @@ RELEASE 0.96 - XXX - Add a --debug=explain option that reports the reason(s) why SCons thinks it must rebuild something. + - Add --save-explain-info and SetOption('save_explain_info') options + to control whether the --debug=explain information is saved in + the .sconsign file(s). Not saving this information can improve + performance and save memory usage. + - Add support for functions that return platform-independent Actions to Chmod(), Copy(), Delete(), Mkdir(), Move() and Touch() files and/or directories. Like any other Actions, the returned Action diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py index 23cf8a7..2f115c9 100644 --- a/src/engine/SCons/Node/FS.py +++ b/src/engine/SCons/Node/FS.py @@ -1385,7 +1385,34 @@ class File(Base): return 0 def store_info(self, obj): - self.dir.sconsign().set_entry(self.name, obj) + # Merge our build information into the already-stored entry. + # This accomodates "chained builds" where a file that's a target + # in one build (SConstruct file) is a source in a different build. + # See test/chained-build.py for the use case. + entry = self.get_stored_info() + if not SCons.Node.Save_Explain_Info: + # If we're not saving explanation info, wipe out any that + # might be in the already-stored entry. + # + # XXX This is kind of bad that we're naming attributes that + # are really controlled in Node/__init__.py. It would be + # good to find a way to move this logic there in some way + # that still accounts for the fact that not all Node classes + # need or use this information. + attributes = [ + 'bsources', 'bsourcesigs', + 'bdepends', 'bdependsigs', + 'bimplicit', 'bimplicitsigs', + 'bact', 'bactsig', + ] + for attr in attributes: + try: + delattr(entry, attr) + except AttributeError: + pass + for key, val in obj.__dict__.items(): + entry.__dict__[key] = val + sconsign = self.dir.sconsign().set_entry(self.name, entry) def get_stored_info(self): try: diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py index d9ffd83..d4137c1 100644 --- a/src/engine/SCons/Node/FSTests.py +++ b/src/engine/SCons/Node/FSTests.py @@ -1969,6 +1969,55 @@ class SaveStringsTestCase(unittest.TestCase): expect = map(os.path.normpath, ['src/f', 'd1/f', 'd0/b', 'd1/b']) assert s == expect, s +class SaveExplainInfoTestCase(unittest.TestCase): + def runTest(self): + """Test how we store --debug=explain info.""" + test=TestCmd(workdir='') + fs = SCons.Node.FS.FS(test.workpath('fs')) + f = fs.File('file') + + class BInfo: + pass + + bi = BInfo() + bi.bact = 'file bact' + bi.arg1 = 'file arg1' + f.store_info(bi) + + i = f.get_stored_info() + assert i.bact == 'file bact', i.arg1 + assert i.arg1 == 'file arg1', i.arg1 + assert not hasattr(i, 'arg2'), i.bact + assert not hasattr(i, 'arg3'), i.bact + + save_value = SCons.Node.Save_Explain_Info + try: + SCons.Node.Save_Explain_Info = 1 + + bi = BInfo() + bi.arg2 = 'file arg2' + f.store_info(bi) + + i = f.get_stored_info() + assert i.bact == 'file bact', i.arg1 + assert i.arg1 == 'file arg1', i.arg1 + assert i.arg2 == 'file arg2', i.arg2 + assert not hasattr(i, 'arg3'), i.bact + + SCons.Node.Save_Explain_Info = 0 + + bi = BInfo() + bi.arg3 = 'file arg3' + f.store_info(bi) + + i = f.get_stored_info() + assert not hasattr(i, 'bact'), i.bact + assert i.arg1 == 'file arg1', i.arg1 + assert i.arg2 == 'file arg2', i.arg2 + assert i.arg3 == 'file arg3', i.arg2 + finally: + SCons.Node.Save_Explain_Info = save_value + if __name__ == "__main__": @@ -1989,5 +2038,6 @@ if __name__ == "__main__": suite.addTest(postprocessTestCase()) suite.addTest(SpecialAttrTestCase()) suite.addTest(SaveStringsTestCase()) + suite.addTest(SaveExplainInfoTestCase()) if not unittest.TextTestRunner().run(suite).wasSuccessful(): sys.exit(1) diff --git a/src/engine/SCons/Node/NodeTests.py b/src/engine/SCons/Node/NodeTests.py index 4c7d9c2..cd7aa18 100644 --- a/src/engine/SCons/Node/NodeTests.py +++ b/src/engine/SCons/Node/NodeTests.py @@ -396,6 +396,7 @@ class NodeTestCase(unittest.TestCase): def collect(self, args): return reduce(lambda x, y: x+y, args, self.val) self.module = M(val) + node = SCons.Node.Node() binfo = node.gen_binfo(Calculator(666)) assert isinstance(binfo, SCons.Node.BuildInfo), binfo @@ -407,6 +408,19 @@ class NodeTestCase(unittest.TestCase): assert hasattr(binfo, 'bimplicitsigs') assert binfo.bsig == 666, binfo.bsig + SCons.Node.Save_Explain_Info = 0 + + node = SCons.Node.Node() + binfo = node.gen_binfo(Calculator(777)) + assert isinstance(binfo, SCons.Node.BuildInfo), binfo + assert not hasattr(binfo, 'bsources') + assert not hasattr(binfo, 'bsourcesigs') + assert not hasattr(binfo, 'bdepends') + assert not hasattr(binfo, 'bdependsigs') + assert not hasattr(binfo, 'bimplicit') + assert not hasattr(binfo, 'bimplicitsigs') + assert binfo.bsig == 777, binfo.bsig + def test_explain(self): """Test explaining why a Node must be rebuilt """ diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index ba4cbca..64226a6 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -76,6 +76,9 @@ implicit_deps_unchanged = 0 # controls whether the cached implicit deps are ignored: implicit_deps_changed = 0 +# controls whether --debug=explain info is saved in Nodes: +Save_Explain_Info = 1 + # A variable that can be set to an interface-specific function be called # to annotate a Node with information about its creation. def do_nothing(node): pass @@ -542,21 +545,26 @@ class Node: dependsigs = map(calc_signature, depends) implicitsigs = map(calc_signature, implicit) - binfo.bsources = map(str, sources) - binfo.bdepends = map(str, depends) - binfo.bimplicit = map(str, implicit) - - binfo.bsourcesigs = sourcesigs - binfo.bdependsigs = dependsigs - binfo.bimplicitsigs = implicitsigs - sigs = sourcesigs + dependsigs + implicitsigs - if self.has_builder(): + has_builder = self.has_builder() + if has_builder: executor = self.get_executor() - binfo.bact = str(executor) - binfo.bactsig = calc.module.signature(executor) - sigs.append(binfo.bactsig) + bactsig = calc.module.signature(executor) + sigs.append(bactsig) + + if Save_Explain_Info: + binfo.bsources = map(str, sources) + binfo.bdepends = map(str, depends) + binfo.bimplicit = map(str, implicit) + + binfo.bsourcesigs = sourcesigs + binfo.bdependsigs = dependsigs + binfo.bimplicitsigs = implicitsigs + + if has_builder: + binfo.bact = str(executor) + binfo.bactsig = calc.module.signature(executor) binfo.bsig = calc.module.collect(filter(None, sigs)) diff --git a/src/engine/SCons/SConsign.py b/src/engine/SCons/SConsign.py index c97f1b6..b7b06fe 100644 --- a/src/engine/SCons/SConsign.py +++ b/src/engine/SCons/SConsign.py @@ -68,8 +68,7 @@ class Base: def get_entry(self, filename): """ - Create an entry for the filename and return it, or if one already exists, - then return it. + Fetch the specified entry attribute. """ return self.entries[filename] @@ -77,13 +76,7 @@ class Base: """ Set the entry. """ - try: - entry = self.entries[filename] - except KeyError: - self.entries[filename] = obj - else: - for key, val in obj.__dict__.items(): - entry.__dict__[key] = val + self.entries[filename] = obj self.dirty = 1 class DB(Base): diff --git a/src/engine/SCons/SConsignTests.py b/src/engine/SCons/SConsignTests.py index 79f4387..16ef816 100644 --- a/src/engine/SCons/SConsignTests.py +++ b/src/engine/SCons/SConsignTests.py @@ -47,8 +47,9 @@ class BaseTestCase(unittest.TestCase): aaa = BuildInfo('aaa') bbb = BuildInfo('bbb') + bbb.arg1 = 'bbb arg1' ccc = BuildInfo('ccc') - ccc.arg = 'ccc arg' + ccc.arg2 = 'ccc arg2' f = SCons.SConsign.Base() f.set_entry('aaa', aaa) @@ -61,12 +62,14 @@ class BaseTestCase(unittest.TestCase): e = f.get_entry('bbb') assert e == bbb, e assert e.name == 'bbb', e.name - assert not hasattr(e, 'arg'), e + assert e.arg1 == 'bbb arg1', e.arg1 + assert not hasattr(e, 'arg2'), e f.set_entry('bbb', ccc) e = f.get_entry('bbb') assert e.name == 'ccc', e.name - assert e.arg == 'ccc arg', e.arg + assert not hasattr(e, 'arg1'), e + assert e.arg2 == 'ccc arg2', e.arg1 ddd = BuildInfo('ddd') eee = BuildInfo('eee') diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index d4650d2..835409e 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -528,7 +528,6 @@ class OptParser(OptionParser): def opt_debug(option, opt, value, parser, debug_options=debug_options): if value in debug_options: - #setattr(parser.values, 'debug', value) parser.values.debug = value else: raise OptionValueError("Warning: %s is not a valid debug type" % value) @@ -541,7 +540,6 @@ class OptParser(OptionParser): def opt_duplicate(option, opt, value, parser): if not value in SCons.Node.FS.Valid_Duplicates: raise OptionValueError("`%s' is not a valid duplication style." % value) - #setattr(parser.values, 'duplicate', value) parser.values.duplicate = value # Set the duplicate style right away so it can affect linking # of SConscript files. @@ -584,7 +582,6 @@ class OptParser(OptionParser): def opt_j(option, opt, value, parser): value = int(value) - #setattr(parser.values, 'num_jobs', value) parser.values.num_jobs = value self.add_option('-j', '--jobs', action="callback", type="int", callback=opt_j, metavar="N", @@ -627,6 +624,10 @@ class OptParser(OptionParser): self.add_option('-s', '--silent', '--quiet', action="store_true", default=0, help="Don't print commands.") + self.add_option('--save-explain-info', type="int", action="store", + dest='save_explain_info', metavar='0|1', + help="(Don't) save --debug=explain information") + self.add_option('-u', '--up', '--search-up', action="store_const", dest="climb_up", default=0, const=1, help="Search up directory tree for SConstruct, " @@ -734,7 +735,8 @@ class SConscriptSettableOptions: 'max_drift':SCons.Sig.default_max_drift, 'implicit_cache':0, 'clean':0, - 'duplicate':'hard-soft-copy'} + 'duplicate':'hard-soft-copy', + 'save_explain_info':1} def get(self, name): if not self.settable.has_key(name): @@ -770,7 +772,7 @@ class SConscriptSettableOptions: # Set the duplicate stye right away so it can affect linking # of SConscript files. SCons.Node.FS.set_duplicate(value) - + self.settable[name] = value @@ -947,6 +949,7 @@ def _main(args, parser): # that are SConscript settable: SCons.Node.implicit_cache = ssoptions.get('implicit_cache') SCons.Node.FS.set_duplicate(ssoptions.get('duplicate')) + SCons.Node.Save_Explain_Info = ssoptions.get('save_explain_info') or print_explanations lookup_top = None if targets: |