3 The Node package for the SCons software construction utility.
5 This is, in many ways, the heart of SCons.
7 A Node is where we encapsulate all of the dependency information about
8 any thing that SCons can build, or about any thing which SCons can use
9 to build some other thing. The canonical "thing," of course, is a file,
10 but a Node can also represent something remote (like a web page) or
11 something completely abstract (like an Alias).
13 Each specific type of "thing" is specifically represented by a subclass
14 of the Node base class: Node.FS.File for files, Node.Alias for aliases,
15 etc. Dependency information is kept here in the base class, and
16 information specific to files/aliases/etc. is in the subclass. The
17 goal, if we've done this correctly, is that any type of "thing" should
18 be able to depend on any other type of "thing."
25 # Permission is hereby granted, free of charge, to any person obtaining
26 # a copy of this software and associated documentation files (the
27 # "Software"), to deal in the Software without restriction, including
28 # without limitation the rights to use, copy, modify, merge, publish,
29 # distribute, sublicense, and/or sell copies of the Software, and to
30 # permit persons to whom the Software is furnished to do so, subject to
31 # the following conditions:
33 # The above copyright notice and this permission notice shall be included
34 # in all copies or substantial portions of the Software.
36 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
37 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
38 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
39 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
40 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
41 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
42 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
45 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
56 # These are in "priority" order, so that the maximum value for any
57 # child/dependency of a node represents the state of that node if
58 # it has no builder of its own. The canonical example is a file
59 # system directory, which is only up to date if all of its children
66 stack = 6 # nodes that are in the current Taskmaster execution stack
68 # controls whether implicit depedencies are cached:
71 # controls whether implicit dep changes are ignored:
72 implicit_deps_unchanged = 0
74 # controls whether the cached implicit deps are ignored:
75 implicit_deps_changed = 0
77 # A variable that can be set to an interface-specific function be called
78 # to annotate a Node with information about its creation.
79 def do_nothing(node): pass
84 """The base Node class, for entities that we know how to
85 build, or use to build other Nodes.
92 # Note that we no longer explicitly initialize a self.builder
93 # attribute to None here. That's because the self.builder
94 # attribute may be created on-the-fly later by a subclass (the
95 # canonical example being a builder to fetch a file from a
96 # source code system like CVS or Subversion).
98 # Each list of children that we maintain is accompanied by a
99 # dictionary used to look up quickly whether a node is already
100 # present in the list. Empirical tests showed that it was
101 # fastest to maintain them as side-by-side Node attributes in
102 # this way, instead of wrapping up each list+dictionary pair in
103 # a class. (Of course, we could always still do that in the
104 # future if we had a good reason to...).
105 self.sources = [] # source files used to build node
106 self.sources_dict = {}
107 self.depends = [] # explicit dependencies (from Depends)
108 self.depends_dict = {}
109 self.ignore = [] # dependencies to ignore
110 self.ignore_dict = {}
111 self.implicit = None # implicit (scanned) dependencies (None means not scanned yet)
113 self.wkids = None # Kids yet to walk, when it's an array
114 self.source_scanner = None # implicit scanner from scanner map
115 self.target_scanner = None # explicit scanner from this node's Builder
120 self.always_build = None
121 self.found_includes = {}
123 self.overrides = {} # construction variable overrides for building this node
124 self.attributes = self.Attrs() # Generic place to stick information about the Node.
125 self.side_effect = 0 # true iff this node is a side effect
126 self.side_effects = [] # the side effects of building this target
127 self.pre_actions = []
128 self.post_actions = []
129 self.linked = 0 # is this node linked to the build directory?
131 # Let the interface in which the build engine is embedded
132 # annotate this Node with its own info (like a description of
133 # what line in what file created the node, for example).
136 def generate_build_env(self, env):
137 """Generate the appropriate Environment to build this node."""
140 def get_build_env(self):
141 """Fetch the appropriate Environment to build this node."""
142 executor = self.get_executor()
143 return executor.get_build_env()
145 def set_executor(self, executor):
146 """Set the action executor for this node."""
147 self.executor = executor
149 def get_executor(self, create=1):
150 """Fetch the action executor for this node. Create one if
151 there isn't already one, and requested to do so."""
153 executor = self.executor
154 except AttributeError:
158 env = self.generate_build_env(self.builder.env)
159 executor = SCons.Executor.Executor(self.builder,
161 self.builder.overrides,
164 self.executor = executor
167 def _for_each_action(self, func):
168 """Call a function for each action required to build a node.
170 The purpose here is to have one place for the logic that
171 collects and executes all of the actions for a node's builder,
172 even though multiple sections of code elsewhere need this logic
173 to do different things."""
174 if not self.has_builder():
176 executor = self.get_executor()
180 """Actually build the node.
182 This method is called from multiple threads in a parallel build,
183 so only do thread safe stuff here. Do thread unsafe stuff in
186 def do_action(action, targets, sources, env, self=self):
187 stat = action(targets, sources, env)
189 raise SCons.Errors.BuildError(node = self,
190 errstr = "Error %d" % stat)
191 self._for_each_action(do_action)
194 """Called just after this node is sucessfully built."""
197 # Clear out the implicit dependency caches:
198 # XXX this really should somehow be made more general and put
199 # under the control of the scanners.
200 if self.source_scanner:
201 self.found_includes = {}
204 def get_parents(node, parent): return node.get_parents()
205 def clear_cache(node, parent):
208 w = Walker(self, get_parents, ignore_cycle, clear_cache)
211 # clear out the content signature, since the contents of this
212 # node were presumably just changed:
216 """Completely clear a Node of all its cached state (so that it
217 can be re-evaluated by interfaces that do continuous integration
224 delattr(self, '_calculated_sig')
225 except AttributeError:
228 delattr(self, '_tempbsig')
229 except AttributeError:
232 self.found_includes = {}
236 """Called just after this node has been visited
237 without requiring a build.."""
240 def depends_on(self, nodes):
241 """Does this node depend on any of 'nodes'?"""
243 if node in self.children():
248 def builder_set(self, builder):
249 self.builder = builder
251 def has_builder(self):
252 """Return whether this Node has a builder or not.
254 In Boolean tests, this turns out to be a *lot* more efficient
255 than simply examining the builder attribute directly ("if
256 node.builder: ..."). When the builder attribute is examined
257 directly, it ends up calling __getattr__ for both the __len__
258 and __nonzero__ attributes on instances of our Builder Proxy
259 class(es), generating a bazillion extra calls and slowing
260 things down immensely.
264 except AttributeError:
265 # There was no explicit builder for this Node, so initialize
266 # the self.builder attribute to None now.
271 def is_derived(self):
273 Returns true iff this node is derived (i.e. built).
275 This should return true only for nodes whose path should be in
276 the build directory when duplicate=0 and should contribute their build
277 signatures when they are used as source files to other derived files. For
278 example: source with source builders are not derived in this sense,
279 and hence should not return true.
281 return self.has_builder() or self.side_effect
283 def is_pseudo_derived(self):
285 Returns true iff this node is built, but should use a source path
286 when duplicate=0 and should contribute a content signature (i.e.
287 source signature) when used as a source for other derived files.
291 def alter_targets(self):
292 """Return a list of alternate targets for this Node.
296 def get_found_includes(self, env, scanner, target):
297 """Return the scanned include lines (implicit dependencies)
300 The default is no implicit dependencies. We expect this method
301 to be overridden by any subclass that can be scanned for
302 implicit dependencies.
306 def get_implicit_deps(self, env, scanner, target):
307 """Return a list of implicit dependencies for this node.
309 This method exists to handle recursive invocation of the scanner
310 on the implicit dependencies returned by the scanner, if the
311 scanner's recursive flag says that we should.
317 recurse = scanner.recursive
318 except AttributeError:
327 d = filter(lambda x, seen=seen: not seen.has_key(x),
328 n.get_found_includes(env, scanner, target))
338 # cache used to make implicit_factory fast.
339 implicit_factory_cache = {}
341 def implicit_factory(self, path):
343 Turn a cache implicit dependency path into a node.
344 This is called so many times that doing caching
345 here is a significant perforamnce boost.
348 return self.implicit_factory_cache[path]
350 n = self.builder.source_factory(path)
351 self.implicit_factory_cache[path] = n
355 """Scan this node's dependents for implicit dependencies."""
356 # Don't bother scanning non-derived files, because we don't
357 # care what their dependencies are.
358 # Don't scan again, if we already have scanned.
359 if not self.implicit is None:
362 self.implicit_dict = {}
363 self._children_reset()
364 if not self.has_builder():
367 if implicit_cache and not implicit_deps_changed:
368 implicit = self.get_stored_implicit()
369 if implicit is not None:
370 implicit = map(self.implicit_factory, implicit)
371 self._add_child(self.implicit, self.implicit_dict, implicit)
372 calc = SCons.Sig.default_calc
373 if implicit_deps_unchanged or calc.current(self, calc.bsig(self)):
376 # one of this node's sources has changed, so
377 # we need to recalculate the implicit deps,
380 self.implicit_dict = {}
381 self._children_reset()
384 build_env = self.get_build_env()
386 for child in self.children(scan=0):
387 self._add_child(self.implicit,
389 child.get_implicit_deps(build_env,
390 child.source_scanner,
393 # scan this node itself for implicit dependencies
394 self._add_child(self.implicit,
396 self.get_implicit_deps(build_env,
401 self.store_implicit()
403 def scanner_key(self):
406 def env_set(self, env, safe=0):
407 if safe and self.env:
411 def calc_signature(self, calc):
413 Select and calculate the appropriate build signature for a node.
416 calc - the signature calculation module
417 returns - the signature
420 return self._calculated_sig
421 except AttributeError:
422 if self.is_derived():
423 if SCons.Sig.build_signature:
424 sig = self.rfile().calc_bsig(calc, self)
426 sig = self.rfile().calc_csig(calc, self)
427 elif not self.rexists():
430 sig = self.rfile().calc_csig(calc, self)
431 self._calculated_sig = sig
434 def calc_bsig(self, calc, cache=None):
435 """Return the node's build signature, calculating it first
438 Note that we don't save it in the "real" build signature
439 attribute if we have to calculate it here; the "real" build
440 signature only gets updated after a file is actually built.
442 if cache is None: cache = self
445 except AttributeError:
447 return cache._tempbsig
448 except AttributeError:
449 cache._tempbsig = calc.bsig(self, cache)
450 return cache._tempbsig
453 """Get the node's build signature (based on the signatures
454 of its dependency files and build information)."""
457 except AttributeError:
460 def set_bsig(self, bsig):
461 """Set the node's build signature (based on the signatures
462 of its dependency files and build information)."""
465 delattr(self, '_tempbsig')
466 except AttributeError:
469 def store_bsig(self):
470 """Make the build signature permanent (that is, store it in the
471 .sconsign file or equivalent)."""
475 """Delete the bsig from this node."""
477 delattr(self, 'bsig')
478 except AttributeError:
482 """Get the signature of the node's content."""
485 except AttributeError:
488 def calc_csig(self, calc, cache=None):
489 """Return the node's content signature, calculating it first
492 if cache is None: cache = self
495 except AttributeError:
496 cache.csig = calc.csig(self, cache)
499 def set_csig(self, csig):
500 """Set the signature of the node's content."""
503 def store_csig(self):
504 """Make the content signature permanent (that is, store it in the
505 .sconsign file or equivalent)."""
509 """Delete the csig from this node."""
511 delattr(self, 'csig')
512 except AttributeError:
515 def get_prevsiginfo(self):
516 """Fetch the previous signature information from the
518 return SCons.Sig._SConsign.null_siginfo
520 def get_timestamp(self):
523 def store_timestamp(self):
524 """Make the timestamp permanent (that is, store it in the
525 .sconsign file or equivalent)."""
528 def store_implicit(self):
529 """Make the implicit deps permanent (that is, store them in the
530 .sconsign file or equivalent)."""
533 def get_stored_implicit(self):
534 """Fetch the stored implicit dependencies"""
537 def set_precious(self, precious = 1):
538 """Set the Node's precious value."""
539 self.precious = precious
541 def set_always_build(self, always_build = 1):
542 """Set the Node's always_build value."""
543 self.always_build = always_build
546 """Does this node exists?"""
547 # All node exist by default:
551 """Does this node exist locally or in a repositiory?"""
552 # There are no repositories by default:
556 """Prepare for this Node to be created.
557 The default implemenation checks that all children either exist
561 return not node.is_derived() and \
562 not node.is_pseudo_derived() and \
563 not node.linked and \
565 missing_sources = filter(missing, self.children())
567 desc = "No Builder for target `%s', needed by `%s'." % (missing_sources[0], self)
568 raise SCons.Errors.StopError, desc
571 """Remove this Node: no-op by default."""
574 def add_dependency(self, depend):
575 """Adds dependencies. The depend argument must be a list."""
576 self._add_child(self.depends, self.depends_dict, depend)
578 def add_ignore(self, depend):
579 """Adds dependencies to ignore. The depend argument must be a list."""
580 self._add_child(self.ignore, self.ignore_dict, depend)
582 def add_source(self, source):
583 """Adds sources. The source argument must be a list."""
584 self._add_child(self.sources, self.sources_dict, source)
586 def _add_child(self, collection, dict, child):
587 """Adds 'child' to 'collection', first checking 'dict' to see if
588 it's already present. The 'child' argument must be a list"""
589 if type(child) is not type([]):
590 raise TypeError("child must be a list")
593 if not dict.has_key(c):
599 self._children_reset()
601 def add_wkid(self, wkid):
602 """Add a node to the list of kids waiting to be evaluated"""
603 if self.wkids != None:
604 self.wkids.append(wkid)
606 def _children_reset(self):
608 delattr(self, '_children')
609 except AttributeError:
612 def children(self, scan=1):
613 """Return a list of the node's direct children, minus those
614 that are ignored by this node."""
618 return self._children
619 except AttributeError:
620 c = filter(lambda x, i=self.ignore: x not in i,
621 self.all_children(scan=0))
625 def all_children(self, scan=1):
626 """Return a list of all the node's direct children."""
627 # The return list may contain duplicate Nodes, especially in
628 # source trees where there are a lot of repeated #includes
629 # of a tangle of .h files. Profiling shows, however, that
630 # eliminating the duplicates with a brute-force approach that
631 # preserves the order (that is, something like:
638 # takes more cycles than just letting the underlying methods
639 # hand back cached values if a Node's information is requested
640 # multiple times. (Other methods of removing duplicates, like
641 # using dictionary keys, lose the order, and the only ordered
642 # dictionary patterns I found all ended up using "not in"
643 # internally anyway...)
646 if self.implicit is None:
647 return self.sources + self.depends
649 return self.sources + self.depends + self.implicit
651 def get_parents(self):
652 return self.parents.keys()
654 def set_state(self, state):
660 def current(self, calc=None):
669 def is_literal(self):
670 """Always pass the string representation of a Node to
671 the command interpreter literally."""
674 def add_pre_action(self, act):
675 """Adds an Action performed on this Node only before
677 self.pre_actions.append(act)
679 def add_post_action(self, act):
680 """Adds and Action performed on this Node only after
682 self.post_actions.append(act)
684 def render_include_tree(self):
686 Return a text representation, suitable for displaying to the
687 user, of the include tree for the sources of this node.
689 if self.is_derived() and self.env:
690 env = self.get_build_env()
691 for s in self.sources:
692 def f(node, env=env, scanner=s.source_scanner, target=self):
693 return node.get_found_includes(env, scanner, target)
694 return SCons.Util.render_tree(s, f, 1)
698 def get_abspath(self):
700 Return an absolute path to the Node. This will return simply
701 str(Node) by default, but for Node types that have a concept of
702 relative path, this might return something different.
706 def for_signature(self):
708 Return a string representation of the Node that will always
709 be the same for this particular Node, no matter what. This
710 is by contrast to the __str__() method, which might, for
711 instance, return a relative path for a file Node. The purpose
712 of this method is to generate a value to be used in signature
713 calculation for the command line used to build a target, and
714 we use this method instead of str() to avoid unnecessary
715 rebuilds. This method does not need to return something that
716 would actually work in a command line; it can return any kind of
717 nonsense, so long as it does not change.
721 def get_string(self, for_signature):
722 """This is a convenience function designed primarily to be
723 used in command generators (i.e., CommandGeneratorActions or
724 Environment variables that are callable), which are called
725 with a for_signature argument that is nonzero if the command
726 generator is being called to generate a signature for the
727 command line, which determines if we should rebuild or not.
729 Such command generators shoud use this method in preference
730 to str(Node) when converting a Node to a string, passing
731 in the for_signature parameter, such that we will call
732 Node.for_signature() or str(Node) properly, depending on whether
733 we are calculating a signature or actually constructing a
736 return self.for_signature()
739 def get_subst_proxy(self):
741 This method is expected to return an object that will function
742 exactly like this Node, except that it implements any additional
743 special features that we would like to be in effect for
744 Environment variable substitution. The principle use is that
745 some Nodes would like to implement a __getattr__() method,
746 but putting that in the Node type itself has a tendency to kill
747 performance. We instead put it in a proxy and return it from
748 this method. It is legal for this method to return self
749 if no new functionality is needed for Environment substitution.
754 def get_children(node, parent): return node.children()
755 def ignore_cycle(node, stack): pass
756 def do_nothing(node, parent): pass
759 """An iterator for walking a Node tree.
761 This is depth-first, children are visited before the parent.
762 The Walker object can be initialized with any node, and
763 returns the next node on the descent with each next() call.
764 'kids_func' is an optional function that will be called to
765 get the children of a node instead of calling 'children'.
766 'cycle_func' is an optional function that will be called
767 when a cycle is detected.
769 This class does not get caught in node cycles caused, for example,
770 by C header file include loops.
772 def __init__(self, node, kids_func=get_children,
773 cycle_func=ignore_cycle,
774 eval_func=do_nothing):
775 self.kids_func = kids_func
776 self.cycle_func = cycle_func
777 self.eval_func = eval_func
778 node.wkids = copy.copy(kids_func(node, None))
780 self.history = {} # used to efficiently detect and avoid cycles
781 self.history[node] = None
784 """Return the next node for this walk of the tree.
786 This function is intentionally iterative, not recursive,
787 to sidestep any issues of stack size limitations.
791 if self.stack[-1].wkids:
792 node = self.stack[-1].wkids.pop(0)
793 if not self.stack[-1].wkids:
794 self.stack[-1].wkids = None
795 if self.history.has_key(node):
796 self.cycle_func(node, self.stack)
798 node.wkids = copy.copy(self.kids_func(node, self.stack[-1]))
799 self.stack.append(node)
800 self.history[node] = None
802 node = self.stack.pop()
803 del self.history[node]
806 parent = self.stack[-1]
809 self.eval_func(node, parent)
813 return not self.stack
816 arg2nodes_lookups = []
818 def arg2nodes(args, node_factory=None, lookup_list=arg2nodes_lookups):
819 """This function converts a string or list into a list of Node
820 instances. It accepts the following inputs:
822 - A single Node instance,
823 - A list containing either strings or Node instances.
824 In all cases, strings are converted to Node instances, and the
825 function returns a list of Node instances."""
829 if not SCons.Util.is_List(args):
834 if SCons.Util.is_String(v):
836 for l in lookup_list:
841 if SCons.Util.is_String(n) and node_factory:
845 nodes.append(node_factory(v))
846 # Do we enforce the following restriction? Maybe, but it
847 # would also restrict what we can do to allow people to
848 # use the engine with alternate Node implementations...
849 #elif not issubclass(v.__class__, Node):