diff options
Diffstat (limited to 'src/engine/SCons/Node/__init__.py')
| -rw-r--r-- | src/engine/SCons/Node/__init__.py | 606 |
1 files changed, 242 insertions, 364 deletions
diff --git a/src/engine/SCons/Node/__init__.py b/src/engine/SCons/Node/__init__.py index e73e5f3..38cff92 100644 --- a/src/engine/SCons/Node/__init__.py +++ b/src/engine/SCons/Node/__init__.py @@ -48,10 +48,8 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import copy import string -import UserList from SCons.Debug import logInstanceCreation -import SCons.Executor import SCons.SConsign import SCons.Util @@ -62,7 +60,6 @@ import SCons.Util # it has no builder of its own. The canonical example is a file # system directory, which is only up to date if all of its children # were up to date. -no_state = 0 pending = 1 executing = 2 up_to_date = 3 @@ -70,17 +67,7 @@ executed = 4 failed = 5 stack = 6 # nodes that are in the current Taskmaster execution stack -StateString = { - 0 : "0", - 1 : "pending", - 2 : "executing", - 3 : "up_to_date", - 4 : "executed", - 5 : "failed", - 6 : "stack", -} - -# controls whether implicit dependencies are cached: +# controls whether implicit depedencies are cached: implicit_cache = 0 # controls whether implicit dep changes are ignored: @@ -95,69 +82,20 @@ def do_nothing(node): pass Annotate = do_nothing -# Classes for signature info for Nodes. - -class NodeInfo: - """ - A generic class for signature information for a Node. - - We actually expect that modules containing Node subclasses will also - subclass NodeInfo, to provide their own logic for dealing with their - own Node-specific signature information. - """ - def __init__(self): - """A null initializer so that subclasses have a superclass - initialization method to call for future use. - """ - pass - def __cmp__(self, other): - return cmp(self.__dict__, other.__dict__) - def update(self, node): - pass - def merge(self, other): - for key, val in other.__dict__.items(): - self.__dict__[key] = val - class BuildInfo: - """ - The generic build information for a Node. - - This is what gets stored in a .sconsign file for each target file. - It contains a NodeInfo instance for this node (signature information - that's specific to the type of Node) and direct attributes for the - generic build stuff we have to track: sources, explicit dependencies, - implicit dependencies, and action information. - """ - def __init__(self, node): - self.ninfo = node.new_ninfo() - self.bsourcesigs = [] - self.bdependsigs = [] - self.bimplicitsigs = [] - self.bactsig = None def __cmp__(self, other): - return cmp(self.ninfo, other.ninfo) - def merge(self, other): - for key, val in other.__dict__.items(): - try: - merge = self.__dict__[key].merge - except (AttributeError, KeyError): - self.__dict__[key] = val - else: - merge(val) + return cmp(self.__dict__, other.__dict__) class Node: """The base Node class, for entities that we know how to build, or use to build other Nodes. """ - if SCons.Memoize.use_memoizer: - __metaclass__ = SCons.Memoize.Memoized_Metaclass - class Attrs: pass def __init__(self): - if __debug__: logInstanceCreation(self, 'Node.Node') + if __debug__: logInstanceCreation(self, 'Node') # Note that we no longer explicitly initialize a self.builder # attribute to None here. That's because the self.builder # attribute may be created on-the-fly later by a subclass (the @@ -180,13 +118,17 @@ class Node: self.implicit = None # implicit (scanned) dependencies (None means not scanned yet) self.waiting_parents = [] self.wkids = None # Kids yet to walk, when it's an array + self.target_scanner = None # explicit scanner from this node's Builder + self.source_scanner = None + self.backup_source_scanner = None self.env = None - self.state = no_state + self.state = None self.precious = None self.always_build = None self.found_includes = {} self.includes = None + self.overrides = {} # construction variable overrides for building this node self.attributes = self.Attrs() # Generic place to stick information about the Node. self.side_effect = 0 # true iff this node is a side effect self.side_effects = [] # the side effects of building this target @@ -202,14 +144,15 @@ class Node: def get_suffix(self): return '' - def get_build_env(self): - """Fetch the appropriate Environment to build this node. - __cacheable__""" - return self.get_executor().get_build_env() + def generate_build_dict(self): + """Return an appropriate dictionary of values for building + this Node.""" + return {} - def get_build_scanner_path(self, scanner): - """Fetch the appropriate scanner path for this node.""" - return self.get_executor().get_build_scanner_path(scanner) + def get_build_env(self): + """Fetch the appropriate Environment to build this node.""" + executor = self.get_executor() + return executor.get_build_env() def set_executor(self, executor): """Set the action executor for this node.""" @@ -223,35 +166,15 @@ class Node: except AttributeError: if not create: raise - try: - act = self.builder.action - except AttributeError: - executor = SCons.Executor.Null(targets=[self]) - else: - executor = SCons.Executor.Executor(act, - self.env or self.builder.env, - [self.builder.overrides], - [self], - self.sources) + import SCons.Executor + executor = SCons.Executor.Executor(self.builder.action, + self.builder.env, + [self.builder.overrides], + [self], + self.sources) self.executor = executor return executor - def executor_cleanup(self): - """Let the executor clean up any cached information.""" - try: - executor = self.get_executor(create=None) - except AttributeError: - pass - else: - executor.cleanup() - - def reset_executor(self): - "Remove cached executor; forces recompute when needed." - try: - delattr(self, 'executor') - except AttributeError: - pass - def retrieve_from_cache(self): """Try to retrieve the node's content from a cache @@ -270,15 +193,15 @@ class Node: so only do thread safe stuff here. Do thread unsafe stuff in built(). """ - def exitstatfunc(stat, node=self): - if stat: - msg = "Error %d" % stat - raise SCons.Errors.BuildError(node=node, errstr=msg) + if not self.has_builder(): + return + def errfunc(stat, node=self): + raise SCons.Errors.BuildError(node=node, errstr="Error %d" % stat) executor = self.get_executor() - apply(executor, (self, exitstatfunc), kw) + apply(executor, (self, errfunc), kw) def built(self): - """Called just after this node is successfully built.""" + """Called just after this node is sucessfully built.""" # Clear the implicit dependency caches of any Nodes # waiting for this Node to be built. @@ -287,27 +210,30 @@ class Node: parent.del_binfo() try: - new = self.binfo + new_binfo = self.binfo except AttributeError: # Node arrived here without build info; apparently it # doesn't need it, so don't bother calculating or storing # it. - new = None + new_binfo = None # Reset this Node's cached state since it was just built and # various state has changed. + save_state = self.get_state() self.clear() + self.set_state(save_state) + + # Had build info, so it should be stored in the signature + # cache. However, if the build info included a content + # signature then it should be recalculated before being + # stored. - if new: - # It had build info, so it should be stored in the signature - # cache. However, if the build info included a content - # signature then it must be recalculated before being stored. - if hasattr(new.ninfo, 'csig'): - self.get_csig() + if new_binfo: + if hasattr(new_binfo, 'csig'): + new_binfo = self.gen_binfo() # sets self.binfo else: - new.ninfo.update(self) - self.binfo = new - self.store_info(self.binfo) + self.binfo = new_binfo + self.store_info(new_binfo) def add_to_waiting_parents(self, node): self.waiting_parents.append(node) @@ -320,16 +246,21 @@ class Node: def postprocess(self): """Clean up anything we don't need to hang onto after we've been built.""" - self.executor_cleanup() + try: + executor = self.get_executor(create=None) + except AttributeError: + pass + else: + executor.cleanup() def clear(self): """Completely clear a Node of all its cached state (so that it can be re-evaluated by interfaces that do continuous integration builds). - __reset_cache__ """ - self.executor_cleanup() + self.set_state(None) self.del_binfo() + self.del_cinfo() try: delattr(self, '_calculated_sig') except AttributeError: @@ -345,8 +276,15 @@ class Node: without requiring a build..""" pass + def depends_on(self, nodes): + """Does this node depend on any of 'nodes'?""" + for node in nodes: + if node in self.children(): + return 1 + + return 0 + def builder_set(self, builder): - "__cache_reset__" self.builder = builder def has_builder(self): @@ -369,9 +307,6 @@ class Node: b = self.builder return not b is None - def set_explicit(self, is_explicit): - self.is_explicit = is_explicit - def has_explicit_builder(self): """Return whether this Node has an explicit builder @@ -379,18 +314,7 @@ class Node: non-explicit, so that it can be overridden by an explicit builder that the user supplies (the canonical example being directories).""" - try: - return self.is_explicit - except AttributeError: - self.is_explicit = None - return self.is_explicit - - def get_builder(self, default_builder=None): - """Return the set builder, or a specified default value""" - try: - return self.builder - except AttributeError: - return default_builder + return self.has_builder() and self.builder.is_explicit multiple_side_effect_has_builder = has_builder @@ -403,7 +327,6 @@ class Node: signatures when they are used as source files to other derived files. For example: source with source builders are not derived in this sense, and hence should not return true. - __cacheable__ """ return self.has_builder() or self.side_effect @@ -420,7 +343,7 @@ class Node: """ return [], None - def get_found_includes(self, env, scanner, path): + def get_found_includes(self, env, scanner, target): """Return the scanned include lines (implicit dependencies) found in this node. @@ -430,7 +353,7 @@ class Node: """ return [] - def get_implicit_deps(self, env, scanner, path): + def get_implicit_deps(self, env, scanner, target): """Return a list of implicit dependencies for this node. This method exists to handle recursive invocation of the scanner @@ -444,57 +367,59 @@ class Node: # for this Node. scanner = scanner.select(self) + try: + recurse = scanner.recursive + except AttributeError: + recurse = None + nodes = [self] seen = {} seen[self] = 1 deps = [] while nodes: - n = nodes.pop(0) - d = filter(lambda x, seen=seen: not seen.has_key(x), - n.get_found_includes(env, scanner, path)) - if d: - deps.extend(d) - for n in d: - seen[n] = 1 - nodes.extend(scanner.recurse_nodes(d)) + n = nodes.pop(0) + d = filter(lambda x, seen=seen: not seen.has_key(x), + n.get_found_includes(env, scanner, target)) + if d: + deps.extend(d) + for n in d: + seen[n] = 1 + if recurse: + nodes.extend(d) return deps - def get_scanner(self, env, kw={}): - return env.get_scanner(self.scanner_key()) + # cache used to make implicit_factory fast. + implicit_factory_cache = {} + + def implicit_factory(self, path): + """ + Turn a cache implicit dependency path into a node. + This is called so many times that doing caching + here is a significant performance boost. + """ + try: + return self.implicit_factory_cache[path] + except KeyError: + n = self.builder.source_factory(path) + self.implicit_factory_cache[path] = n + return n def get_source_scanner(self, node): """Fetch the source scanner for the specified node NOTE: "self" is the target being built, "node" is the source file for which we want to fetch the scanner. - - Implies self.has_builder() is true; again, expect to only be - called from locations where this is already verified. - - This function may be called very often; it attempts to cache - the scanner found to improve performance. """ - scanner = None + if self.source_scanner: + return self.source_scanner try: scanner = self.builder.source_scanner + if scanner: + return scanner except AttributeError: pass - if not scanner: - # The builder didn't have an explicit scanner, so go look up - # a scanner from env['SCANNERS'] based on the node's scanner - # key (usually the file extension). - scanner = self.get_scanner(self.get_build_env()) - if scanner: - scanner = scanner.select(node) - return scanner - - def add_to_implicit(self, deps): - if not hasattr(self, 'implicit') or self.implicit is None: - self.implicit = [] - self.implicit_dict = {} - self._children_reset() - self._add_child(self.implicit, self.implicit_dict, deps) + return node.backup_source_scanner or None def scan(self): """Scan this node's dependents for implicit dependencies.""" @@ -514,44 +439,34 @@ class Node: # Here's where we implement --implicit-cache. if implicit_cache and not implicit_deps_changed: implicit = self.get_stored_implicit() - if implicit: - factory = build_env.get_factory(self.builder.source_factory) - nodes = [] - for i in implicit: - try: - n = factory(i) - except TypeError: - # The implicit dependency was cached as one type - # of Node last time, but the configuration has - # changed (probably) and it's a different type - # this time. Just ignore the mismatch and go - # with what our current configuration says the - # Node is. - pass - else: - nodes.append(n) - self._add_child(self.implicit, self.implicit_dict, nodes) + if implicit is not None: + implicit = map(self.implicit_factory, implicit) + self._add_child(self.implicit, self.implicit_dict, implicit) calc = build_env.get_calculator() - if implicit_deps_unchanged or self.current(calc): + if implicit_deps_unchanged or self.current(calc, scan=0): return - # one of this node's sources has changed, so - # we need to recalculate the implicit deps, - # and the bsig: - self.implicit = [] - self.implicit_dict = {} - self._children_reset() - self.del_binfo() - - executor = self.get_executor() - - # Have the executor scan the sources. - executor.scan_sources(self.builder.source_scanner) + else: + # one of this node's sources has changed, so + # we need to recalculate the implicit deps, + # and the bsig: + self.implicit = [] + self.implicit_dict = {} + self._children_reset() + self.del_binfo() + + for child in self.children(scan=0): + scanner = self.get_source_scanner(child) + if scanner: + deps = child.get_implicit_deps(build_env, scanner, self) + self._add_child(self.implicit, self.implicit_dict, deps) + + # scan this node itself for implicit dependencies + deps = self.get_implicit_deps(build_env, self.target_scanner, self) + self._add_child(self.implicit, self.implicit_dict, deps) - # If there's a target scanner, have the executor scan the target - # node itself and associated targets that might be built. - scanner = self.builder.target_scanner - if scanner: - executor.scan_targets(scanner) + # XXX See note above re: --implicit-cache. + #if implicit_cache: + # self.store_implicit() def scanner_key(self): return None @@ -561,10 +476,6 @@ class Node: return self.env = env - # - # SIGNATURE SUBSYSTEM - # - def calculator(self): import SCons.Defaults @@ -574,42 +485,46 @@ class Node: def calc_signature(self, calc=None): """ Select and calculate the appropriate build signature for a node. - __cacheable__ self - the node calc - the signature calculation module returns - the signature """ - if self.is_derived(): - import SCons.Defaults - - env = self.env or SCons.Defaults.DefaultEnvironment() - if env.use_build_signature(): - return self.get_bsig(calc) - elif not self.rexists(): - return None - return self.get_csig(calc) - - def new_ninfo(self): - return NodeInfo() - - def new_binfo(self): - return BuildInfo(self) - - def get_binfo(self): try: - return self.binfo + return self._calculated_sig except AttributeError: - self.binfo = self.new_binfo() - return self.binfo + if self.is_derived(): + import SCons.Defaults + + env = self.env or SCons.Defaults.DefaultEnvironment() + if env.use_build_signature(): + sig = self.calc_bsig(calc) + else: + sig = self.calc_csig(calc) + elif not self.rexists(): + sig = None + else: + sig = self.calc_csig(calc) + self._calculated_sig = sig + return sig + + def new_binfo(self): + return BuildInfo() def del_binfo(self): - """Delete the build info from this node.""" + """Delete the bsig from this node.""" try: delattr(self, 'binfo') except AttributeError: pass + def calc_bsig(self, calc=None): + try: + return self.binfo.bsig + except AttributeError: + self.binfo = self.gen_binfo(calc) + return self.binfo.bsig + def gen_binfo(self, calc=None, scan=1): """ Generate a node's build signature, the digested signatures @@ -623,70 +538,68 @@ class Node: node's children's signatures. We expect that they're already built and updated by someone else, if that's what's wanted. - __cacheable__ """ if calc is None: calc = self.calculator() - binfo = self.get_binfo() + binfo = self.new_binfo() if scan: self.scan() - executor = self.get_executor() + sources = self.filter_ignore(self.sources) + depends = self.filter_ignore(self.depends) + if self.implicit is None: + implicit = [] + else: + implicit = self.filter_ignore(self.implicit) + def calc_signature(node, calc=calc): return node.calc_signature(calc) - - sources = executor.process_sources(None, self.ignore) - sourcesigs = executor.process_sources(calc_signature, self.ignore) - - depends = self.depends - implicit = self.implicit or [] - - if self.ignore: - depends = filter(self.do_not_ignore, depends) - implicit = filter(self.do_not_ignore, implicit) - + sourcesigs = map(calc_signature, sources) dependsigs = map(calc_signature, depends) implicitsigs = map(calc_signature, implicit) sigs = sourcesigs + dependsigs + implicitsigs if self.has_builder(): - binfo.bact = str(executor) + executor = self.get_executor() + binfo.bact = executor.strfunction() binfo.bactsig = calc.module.signature(executor) sigs.append(binfo.bactsig) - binfo.bsources = sources - binfo.bdepends = depends - binfo.bimplicit = 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 - binfo.ninfo.bsig = calc.module.collect(filter(None, sigs)) + binfo.bsig = calc.module.collect(filter(None, sigs)) return binfo - def get_bsig(self, calc=None): - binfo = self.get_binfo() + def del_cinfo(self): try: - return binfo.ninfo.bsig + del self.binfo.csig except AttributeError: - self.binfo = self.gen_binfo(calc) - return self.binfo.ninfo.bsig + pass - def get_csig(self, calc=None): - binfo = self.get_binfo() + def calc_csig(self, calc=None): try: - return binfo.ninfo.csig + binfo = self.binfo + except AttributeError: + binfo = self.binfo = self.new_binfo() + try: + return binfo.csig except AttributeError: if calc is None: calc = self.calculator() - csig = binfo.ninfo.csig = calc.module.signature(self) - return csig + binfo.csig = calc.module.signature(self) + self.store_info(binfo) + return binfo.csig def store_info(self, obj): """Make the build signature permanent (that is, store it in the @@ -700,10 +613,6 @@ class Node: """Fetch the stored implicit dependencies""" return None - # - # - # - def set_precious(self, precious = 1): """Set the Node's precious value.""" self.precious = precious @@ -721,24 +630,18 @@ class Node: """Does this node exist locally or in a repositiory?""" # There are no repositories by default: return self.exists() - - def missing(self): - """__cacheable__""" - return not self.is_derived() and \ - not self.is_pseudo_derived() and \ - not self.linked and \ - not self.rexists() def prepare(self): """Prepare for this Node to be created. The default implemenation checks that all children either exist or are derived. """ - l = self.depends - if not self.implicit is None: - l = l + self.implicit - missing_sources = self.get_executor().get_missing_sources() \ - + filter(lambda c: c.missing(), l) + def missing(node): + return not node.is_derived() and \ + not node.is_pseudo_derived() and \ + not node.linked and \ + not node.rexists() + missing_sources = filter(missing, self.children()) if missing_sources: desc = "Source `%s' not found, needed by target `%s'." % (missing_sources[0], self) raise SCons.Errors.StopError, desc @@ -806,15 +709,33 @@ class Node: self.wkids.append(wkid) def _children_reset(self): - "__cache_reset__" - # We need to let the Executor clear out any calculated - # bsig info that it's cached so we can re-calculate it. - self.executor_cleanup() + try: + delattr(self, '_children') + except AttributeError: + pass - def do_not_ignore(self, node): - return node not in self.ignore + def filter_ignore(self, nodelist): + ignore = self.ignore + result = [] + for node in nodelist: + if node not in ignore: + result.append(node) + return result - def _all_children_get(self): + def children(self, scan=1): + """Return a list of the node's direct children, minus those + that are ignored by this node.""" + if scan: + self.scan() + try: + return self._children + except AttributeError: + c = self.all_children(scan=0) + self._children = self.filter_ignore(c) + return self._children + + def all_children(self, scan=1): + """Return a list of all the node's direct children.""" # The return list may contain duplicate Nodes, especially in # source trees where there are a lot of repeated #includes # of a tangle of .h files. Profiling shows, however, that @@ -832,31 +753,13 @@ class Node: # using dictionary keys, lose the order, and the only ordered # dictionary patterns I found all ended up using "not in" # internally anyway...) + if scan: + self.scan() if self.implicit is None: return self.sources + self.depends else: return self.sources + self.depends + self.implicit - def _children_get(self): - "__cacheable__" - children = self._all_children_get() - if self.ignore: - children = filter(self.do_not_ignore, children) - return children - - def all_children(self, scan=1): - """Return a list of all the node's direct children.""" - if scan: - self.scan() - return self._all_children_get() - - def children(self, scan=1): - """Return a list of the node's direct children, minus those - that are ignored by this node.""" - if scan: - self.scan() - return self._children_get() - def set_state(self, state): self.state = state @@ -876,8 +779,6 @@ class Node: rebind their current() method to this method.""" # Allow the children to calculate their signatures. self.binfo = self.gen_binfo(calc) - if self.always_build: - return None state = 0 for kid in self.children(None): s = kid.get_state() @@ -890,6 +791,16 @@ class Node: the command interpreter literally.""" return 1 + def add_pre_action(self, act): + """Adds an Action performed on this Node only before + building it.""" + self.pre_actions.append(act) + + def add_post_action(self, act): + """Adds and Action performed on this Node only after + building it.""" + self.post_actions.append(act) + def render_include_tree(self): """ Return a text representation, suitable for displaying to the @@ -899,9 +810,8 @@ class Node: env = self.get_build_env() for s in self.sources: scanner = self.get_source_scanner(s) - path = self.get_build_scanner_path(scanner) - def f(node, env=env, scanner=scanner, path=path): - return node.get_found_includes(env, scanner, path) + def f(node, env=env, scanner=scanner, target=self): + return node.get_found_includes(env, scanner, target) return SCons.Util.render_tree(s, f, 1) else: return None @@ -974,63 +884,53 @@ class Node: result[k] = s try: - osig = {} - dictify(osig, old.bsources, old.bsourcesigs) - dictify(osig, old.bdepends, old.bdependsigs) - dictify(osig, old.bimplicit, old.bimplicitsigs) + old_bkids = old.bsources + old.bdepends + old.bimplicit except AttributeError: return "Cannot explain why `%s' is being rebuilt: No previous build information found\n" % self - new = self.get_binfo() - - nsig = {} - dictify(nsig, new.bsources, new.bsourcesigs) - dictify(nsig, new.bdepends, new.bdependsigs) - dictify(nsig, new.bimplicit, new.bimplicitsigs) - - old_bkids = old.bsources + old.bdepends + old.bimplicit - new_bkids = new.bsources + new.bdepends + new.bimplicit + osig = {} + dictify(osig, old.bsources, old.bsourcesigs) + dictify(osig, old.bdepends, old.bdependsigs) + dictify(osig, old.bimplicit, old.bimplicitsigs) - # The sources and dependencies we'll want to report are all stored - # as relative paths to this target's directory, but we want to - # report them relative to the top-level SConstruct directory, - # so we only print them after running them through this lambda - # to turn them into the right relative Node and then return - # its string. - stringify = lambda s, E=self.dir.Entry: str(E(s)) + new_bsources = map(str, self.binfo.bsources) + new_bdepends = map(str, self.binfo.bdepends) + new_bimplicit = map(str, self.binfo.bimplicit) - lines = [] + nsig = {} + dictify(nsig, new_bsources, self.binfo.bsourcesigs) + dictify(nsig, new_bdepends, self.binfo.bdependsigs) + dictify(nsig, new_bimplicit, self.binfo.bimplicitsigs) - removed = filter(lambda x, nk=new_bkids: not x in nk, old_bkids) - if removed: - removed = map(stringify, removed) - fmt = "`%s' is no longer a dependency\n" - lines.extend(map(lambda s, fmt=fmt: fmt % s, removed)) + new_bkids = new_bsources + new_bdepends + new_bimplicit + lines = map(lambda x: "`%s' is no longer a dependency\n" % x, + filter(lambda x, nk=new_bkids: not x in nk, old_bkids)) for k in new_bkids: if not k in old_bkids: - lines.append("`%s' is a new dependency\n" % stringify(k)) + lines.append("`%s' is a new dependency\n" % k) elif osig[k] != nsig[k]: - lines.append("`%s' changed\n" % stringify(k)) + lines.append("`%s' changed\n" % k) if len(lines) == 0 and old_bkids != new_bkids: lines.append("the dependency order changed:\n" + - "%sold: %s\n" % (' '*15, map(stringify, old_bkids)) + - "%snew: %s\n" % (' '*15, map(stringify, new_bkids))) + "%sold: %s\n" % (' '*15, old_bkids) + + "%snew: %s\n" % (' '*15, new_bkids)) if len(lines) == 0: + newact, newactsig = self.binfo.bact, self.binfo.bactsig def fmt_with_title(title, strlines): lines = string.split(strlines, '\n') sep = '\n' + ' '*(15 + len(title)) return ' '*15 + title + string.join(lines, sep) + '\n' - if old.bactsig != new.bactsig: - if old.bact == new.bact: + if old.bactsig != newactsig: + if old.bact == newact: lines.append("the contents of the build action changed\n" + - fmt_with_title('action: ', new.bact)) + fmt_with_title('action: ', newact)) else: lines.append("the build action changed:\n" + fmt_with_title('old: ', old.bact) + - fmt_with_title('new: ', new.bact)) + fmt_with_title('new: ', newact)) if len(lines) == 0: return "rebuilding `%s' for unknown reasons\n" % self @@ -1042,28 +942,6 @@ class Node: lines = ["%s:\n" % preamble] + lines return string.join(lines, ' '*11) -l = [1] -ul = UserList.UserList([2]) -try: - l.extend(ul) -except TypeError: - def NodeList(l): - return l -else: - class NodeList(UserList.UserList): - def __str__(self): - return str(map(str, self.data)) -del l -del ul - -if SCons.Memoize.use_old_memoization(): - _Base = Node - class Node(SCons.Memoize.Memoizer, _Base): - def __init__(self, *args, **kw): - apply(_Base.__init__, (self,)+args, kw) - SCons.Memoize.Memoizer.__init__(self) - - def get_children(node, parent): return node.children() def ignore_cycle(node, stack): pass def do_nothing(node, parent): pass |
