diff options
Diffstat (limited to 'engine/SCons/Node/__init__.py')
| -rw-r--r-- | engine/SCons/Node/__init__.py | 81 | 
1 files changed, 60 insertions, 21 deletions
diff --git a/engine/SCons/Node/__init__.py b/engine/SCons/Node/__init__.py index 299673f..889e7a4 100644 --- a/engine/SCons/Node/__init__.py +++ b/engine/SCons/Node/__init__.py @@ -22,7 +22,7 @@ be able to depend on any other type of "thing."  from __future__ import print_function  # -# Copyright (c) 2001 - 2017 The SCons Foundation +# Copyright (c) 2001 - 2019 The SCons Foundation  #  # Permission is hereby granted, free of charge, to any person obtaining  # a copy of this software and associated documentation files (the @@ -43,8 +43,9 @@ from __future__ import print_function  # 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__ = "src/engine/SCons/Node/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog" +__revision__ = "src/engine/SCons/Node/__init__.py a56bbd8c09fb219ab8a9673330ffcd55279219d0 2019-03-26 23:16:31 bdeegan" +import os  import collections  import copy  from itertools import chain @@ -139,6 +140,7 @@ def exists_entry(node):      node.disambiguate()      return _exists_map[node._func_exists](node) +  def exists_file(node):      # Duplicate from source path if we are set up to do this.      if node.duplicate and not node.is_derived() and not node.linked: @@ -155,7 +157,7 @@ def exists_file(node):                      # The source file does not exist.  Make sure no old                      # copy remains in the variant directory.                      if print_duplicate: -                        print("dup: no src for %s, unlinking old variant copy"%self) +                        print("dup: no src for %s, unlinking old variant copy" % node)                      if exists_base(node) or node.islink():                          node.fs.unlink(node.get_internal_path())                      # Return None explicitly because the Base.exists() call @@ -246,6 +248,21 @@ _target_from_source_map = {0 : target_from_source_none,  # used by it.  # + +class DeciderNeedsNode(Exception): +    """ +    Indicate that the decider needs the node as well as the target and the dependency. +    Normally the node and the target are the same, but in the case of repository +    They may be different. Also the NodeInfo is retrieved from the node +    """ +    def __init__(self, call_this_decider): +        """ +        :param call_this_decider: to return the decider to call directly since deciders +               are called through several levels of indirection +        """ +        self.decider = call_this_decider + +  #  # First, the single decider functions  # @@ -269,6 +286,7 @@ def changed_since_last_build_node(node, target, prev_ni):      """      raise NotImplementedError +  def changed_since_last_build_alias(node, target, prev_ni):      cur_csig = node.get_csig()      try: @@ -276,19 +294,24 @@ def changed_since_last_build_alias(node, target, prev_ni):      except AttributeError:          return 1 +  def changed_since_last_build_entry(node, target, prev_ni):      node.disambiguate()      return _decider_map[node.changed_since_last_build](node, target, prev_ni) +  def changed_since_last_build_state_changed(node, target, prev_ni): -    return (node.state != SCons.Node.up_to_date) +    return node.state != SCons.Node.up_to_date +  def decide_source(node, target, prev_ni):      return target.get_build_env().decide_source(node, target, prev_ni) +  def decide_target(node, target, prev_ni):      return target.get_build_env().decide_target(node, target, prev_ni) +  def changed_since_last_build_python(node, target, prev_ni):      cur_csig = node.get_csig()      try: @@ -380,6 +403,7 @@ class NodeInfoBase(object):          """          state = other.__getstate__()          self.__setstate__(state) +      def format(self, field_list=None, names=0):          if field_list is None:              try: @@ -665,7 +689,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)):                  executor.cleanup()      def reset_executor(self): -        "Remove cached executor; forces recompute when needed." +        """Remove cached executor; forces recompute when needed."""          try:              delattr(self, 'executor')          except AttributeError: @@ -1136,7 +1160,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)):              binfo.bactsig = SCons.Util.MD5signature(executor.get_contents())          if self._specific_sources: -            sources = [ s for s in self.sources if not s in ignore_set] +            sources = [s for s in self.sources if not s in ignore_set]          else:              sources = executor.get_unignored_sources(self, self.ignore) @@ -1145,13 +1169,17 @@ class Node(object, with_metaclass(NoSlotsPyPy)):          binfo.bsources = [s for s in sources if s not in seen and not seen.add(s)]          binfo.bsourcesigs = [s.get_ninfo() for s in binfo.bsources] +        binfo.bdepends = [d for d in self.depends if d not in ignore_set] +        binfo.bdependsigs = [d.get_ninfo() for d in self.depends] -        binfo.bdepends = self.depends -        binfo.bdependsigs = [d.get_ninfo() for d in self.depends if d not in ignore_set] - -        binfo.bimplicit = self.implicit or [] -        binfo.bimplicitsigs = [i.get_ninfo() for i in binfo.bimplicit if i not in ignore_set] - +        # Because self.implicit is initialized to None (and not empty list []) +        # we have to handle this case +        if not self.implicit: +            binfo.bimplicit = [] +            binfo.bimplicitsigs = [] +        else: +            binfo.bimplicit = [i for i in self.implicit if i not in ignore_set] +            binfo.bimplicitsigs = [i.get_ninfo() for i in binfo.bimplicit]          return binfo @@ -1213,7 +1241,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)):          return _exists_map[self._func_exists](self)      def rexists(self): -        """Does this node exist locally or in a repositiory?""" +        """Does this node exist locally or in a repository?"""          # There are no repositories by default:          return _rexists_map[self._func_rexists](self) @@ -1452,13 +1480,18 @@ class Node(object, with_metaclass(NoSlotsPyPy)):              result = True          for child, prev_ni in zip(children, then): -            if _decider_map[child.changed_since_last_build](child, self, prev_ni): -                if t: Trace(': %s changed' % child) -                result = True +            try: +                if _decider_map[child.changed_since_last_build](child, self, prev_ni): +                    if t: Trace(': %s changed' % child) +                    result = True +            except DeciderNeedsNode as e: +                if e.decider(self, prev_ni, node=node): +                    if t: Trace(': %s changed' % child) +                    result = True -        contents = self.get_executor().get_contents()          if self.has_builder():              import SCons.Util +            contents = self.get_executor().get_contents()              newsig = SCons.Util.MD5signature(contents)              if bi.bactsig != newsig:                  if t: Trace(': bactsig %s != newsig %s' % (bi.bactsig, newsig)) @@ -1607,7 +1640,7 @@ class Node(object, with_metaclass(NoSlotsPyPy)):          # so we only print them after running them through this lambda          # to turn them into the right relative Node and then return          # its string. -        def stringify( s, E=self.dir.Entry ) : +        def stringify( s, E=self.dir.Entry):              if hasattr( s, 'dir' ) :                  return str(E(s))              return str(s) @@ -1616,15 +1649,21 @@ class Node(object, with_metaclass(NoSlotsPyPy)):          removed = [x for x in old_bkids if not x in new_bkids]          if removed: -            removed = list(map(stringify, removed)) +            removed = [stringify(r) for r in removed]              fmt = "`%s' is no longer a dependency\n"              lines.extend([fmt % s for s in removed])          for k in new_bkids:              if not k in old_bkids:                  lines.append("`%s' is a new dependency\n" % stringify(k)) -            elif _decider_map[k.changed_since_last_build](k, self, osig[k]): -                lines.append("`%s' changed\n" % stringify(k)) +            else: +                try: +                    changed = _decider_map[k.changed_since_last_build](k, self, osig[k]) +                except DeciderNeedsNode as e: +                    changed = e.decider(self, osig[k], node=self) + +                if changed: +                    lines.append("`%s' changed\n" % stringify(k))          if len(lines) == 0 and old_bkids != new_bkids:              lines.append("the dependency order changed:\n" +  | 
