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 self.sources = [] # source files used to build node
99 self.depends = [] # explicit dependencies (from Depends)
100 self.implicit = None # implicit (scanned) dependencies (None means not scanned yet)
101 self.ignore = [] # dependencies to ignore
103 self.wkids = None # Kids yet to walk, when it's an array
104 self.source_scanner = None # implicit scanner from scanner map
105 self.target_scanner = None # explicit scanner from this node's Builder
110 self.found_includes = {}
112 self.overrides = {} # construction variable overrides for building this node
113 self.attributes = self.Attrs() # Generic place to stick information about the Node.
114 self.side_effect = 0 # true iff this node is a side effect
115 self.side_effects = [] # the side effects of building this target
116 self.pre_actions = []
117 self.post_actions = []
118 self.linked = 0 # is this node linked to the build directory?
120 # Let the interface in which the build engine is embedded
121 # annotate this Node with its own info (like a description of
122 # what line in what file created the node, for example).
125 def generate_build_env(self):
126 """Generate the appropriate Environment to build this node."""
128 # The node itself doesn't have an associated Environment
129 # (which kind of implies it's a source code file, but who
130 # knows...). Regardless of why, use the environment (if
131 # any) associated with the Builder itself.
132 env = self.builder.env
133 overrides = self.builder.overrides
135 # The normal case: use the Environment used to specify how
136 # this Node is to be built.
138 overrides = self.overrides
139 return env.Override(overrides)
141 def _for_each_action(self, func):
142 """Call a function for each action required to build a node.
144 The purpose here is to have one place for the logic that
145 collects and executes all of the actions for a node's builder,
146 even though multiple sections of code elsewhere need this logic
147 to do different things."""
148 if not self.has_builder():
150 action_list = self.pre_actions + \
151 self.builder.get_actions() + \
155 targets = self.builder.targets(self)
156 env = self.generate_build_env()
157 for action in action_list:
158 func(action, targets, self.sources, env)
161 """Actually build the node.
163 This method is called from multiple threads in a parallel build,
164 so only do thread safe stuff here. Do thread unsafe stuff in
167 def do_action(action, targets, sources, env, self=self):
168 stat = action(targets, sources, env)
170 raise SCons.Errors.BuildError(node = self,
171 errstr = "Error %d" % stat)
172 self._for_each_action(do_action)
175 """Called just after this node is sucessfully built."""
178 # Clear out the implicit dependency caches:
179 # XXX this really should somehow be made more general and put
180 # under the control of the scanners.
181 if self.source_scanner:
182 self.found_includes = {}
185 def get_parents(node, parent): return node.get_parents()
186 def clear_cache(node, parent):
189 w = Walker(self, get_parents, ignore_cycle, clear_cache)
192 # clear out the content signature, since the contents of this
193 # node were presumably just changed:
197 """Completely clear a Node of all its cached state (so that it
198 can be re-evaluated by interfaces that do continuous integration
205 self.found_includes = {}
209 """Called just after this node has been visited
210 without requiring a build.."""
213 def depends_on(self, nodes):
214 """Does this node depend on any of 'nodes'?"""
216 if node in self.children():
221 def builder_set(self, builder):
222 self.builder = builder
224 def has_builder(self):
225 """Return whether this Node has a builder or not.
227 In Boolean tests, this turns out to be a *lot* more efficient
228 than simply examining the builder attribute directly ("if
229 node.builder: ..."). When the builder attribute is examined
230 directly, it ends up calling __getattr__ for both the __len__
231 and __nonzero__ attributes on instances of our Builder Proxy
232 class(es), generating a bazillion extra calls and slowing
233 things down immensely.
237 except AttributeError:
238 # There was no explicit builder for this Node, so initialize
239 # the self.builder attribute to None now.
244 def is_derived(self):
245 return self.has_builder() or self.side_effect
247 def alter_targets(self):
248 """Return a list of alternate targets for this Node.
252 def builder_sig_adapter(self):
253 """Create an adapter for calculating a builder's signature.
255 The underlying signature class will call get_contents()
256 to fetch the signature of a builder, but the actual
257 content of that signature depends on the node and the
258 environment (for construction variable substitution),
259 so this adapter provides the right glue between the two.
262 def __init__(self, node):
264 def get_contents(self):
265 return self.node.builder.get_contents(self.node.builder.targets(self.node), self.node.sources, self.node.generate_build_env())
266 def get_timestamp(self):
270 def get_found_includes(self, env, scanner, target):
271 """Return the scanned include lines (implicit dependencies)
274 The default is no implicit dependencies. We expect this method
275 to be overridden by any subclass that can be scanned for
276 implicit dependencies.
280 def get_implicit_deps(self, env, scanner, target):
281 """Return a list of implicit dependencies for this node.
283 This method exists to handle recursive invocation of the scanner
284 on the implicit dependencies returned by the scanner, if the
285 scanner's recursive flag says that we should.
291 recurse = scanner.recursive
292 except AttributeError:
301 d = filter(lambda x, seen=seen: not seen.has_key(x),
302 n.get_found_includes(env, scanner, target))
312 # cache used to make implicit_factory fast.
313 implicit_factory_cache = {}
315 def implicit_factory(self, path):
317 Turn a cache implicit dependency path into a node.
318 This is called so many times that doing caching
319 here is a significant perforamnce boost.
322 return self.implicit_factory_cache[path]
324 n = self.builder.source_factory(path)
325 self.implicit_factory_cache[path] = n
329 """Scan this node's dependents for implicit dependencies."""
330 # Don't bother scanning non-derived files, because we don't
331 # care what their dependencies are.
332 # Don't scan again, if we already have scanned.
333 if not self.implicit is None:
336 if not self.has_builder():
339 if implicit_cache and not implicit_deps_changed:
340 implicit = self.get_stored_implicit()
341 if implicit is not None:
342 implicit = map(self.implicit_factory, implicit)
343 self._add_child(self.implicit, implicit)
344 calc = SCons.Sig.default_calc
345 if implicit_deps_unchanged or calc.current(self, calc.bsig(self)):
348 # one of this node's sources has changed, so
349 # we need to recalculate the implicit deps,
354 build_env = self.generate_build_env()
356 for child in self.children(scan=0):
357 self._add_child(self.implicit,
358 child.get_implicit_deps(build_env,
359 child.source_scanner,
362 # scan this node itself for implicit dependencies
363 self._add_child(self.implicit,
364 self.get_implicit_deps(build_env,
369 self.store_implicit()
371 def scanner_key(self):
374 def env_set(self, env, safe=0):
375 if safe and self.env:
379 def calc_signature(self, calc, cache=None):
381 Select and calculate the appropriate build signature for a node.
384 calc - the signature calculation module
385 cache - alternate node to use for the signature cache
386 returns - the signature
389 if self.has_builder():
390 if SCons.Sig.build_signature:
391 return calc.bsig(self, cache)
393 return calc.csig(self, cache)
394 elif not self.exists():
397 return calc.csig(self, cache)
400 """Get the node's build signature (based on the signatures
401 of its dependency files and build information)."""
402 if not hasattr(self, 'bsig'):
406 def set_bsig(self, bsig):
407 """Set the node's build signature (based on the signatures
408 of its dependency files and build information)."""
411 def store_bsig(self):
412 """Make the build signature permanent (that is, store it in the
413 .sconsign file or equivalent)."""
417 """Delete the bsig from this node."""
418 if hasattr(self, 'bsig'):
419 delattr(self, 'bsig')
422 """Get the signature of the node's content."""
423 if not hasattr(self, 'csig'):
427 def set_csig(self, csig):
428 """Set the signature of the node's content."""
431 def store_csig(self):
432 """Make the content signature permanent (that is, store it in the
433 .sconsign file or equivalent)."""
437 """Delete the csig from this node."""
438 if hasattr(self, 'csig'):
439 delattr(self, 'csig')
441 def get_prevsiginfo(self):
442 """Fetch the previous signature information from the
446 def get_timestamp(self):
449 def store_timestamp(self):
450 """Make the timestamp permanent (that is, store it in the
451 .sconsign file or equivalent)."""
454 def store_implicit(self):
455 """Make the implicit deps permanent (that is, store them in the
456 .sconsign file or equivalent)."""
459 def get_stored_implicit(self):
460 """Fetch the stored implicit dependencies"""
463 def set_precious(self, precious = 1):
464 """Set the Node's precious value."""
465 self.precious = precious
468 """Does this node exists?"""
469 # All node exist by default:
473 """Does this node exist locally or in a repositiory?"""
474 # There are no repositories by default:
478 """Prepare for this Node to be created.
479 The default implemenation checks that all children either exist
483 return not node.is_derived() and not node.linked and not node.rexists()
484 missing_sources = filter(missing, self.children())
486 desc = "No Builder for target `%s', needed by `%s'." % (missing_sources[0], self)
487 raise SCons.Errors.StopError, desc
490 """Remove this Node: no-op by default."""
493 def add_dependency(self, depend):
494 """Adds dependencies. The depend argument must be a list."""
495 self._add_child(self.depends, depend)
497 def add_ignore(self, depend):
498 """Adds dependencies to ignore. The depend argument must be a list."""
499 self._add_child(self.ignore, depend)
501 def add_source(self, source):
502 """Adds sources. The source argument must be a list."""
503 self._add_child(self.sources, source)
505 def _add_child(self, collection, child):
506 """Adds 'child' to 'collection'. The 'child' argument must be a list"""
507 if type(child) is not type([]):
508 raise TypeError("child must be a list")
509 child = filter(lambda x, s=collection: x not in s, child)
511 collection.extend(child)
516 def add_wkid(self, wkid):
517 """Add a node to the list of kids waiting to be evaluated"""
518 if self.wkids != None:
519 self.wkids.append(wkid)
521 def children(self, scan=1):
522 """Return a list of the node's direct children, minus those
523 that are ignored by this node."""
524 return filter(lambda x, i=self.ignore: x not in i,
525 self.all_children(scan))
527 def all_children(self, scan=1):
528 """Return a list of all the node's direct children."""
529 # The return list may contain duplicate Nodes, especially in
530 # source trees where there are a lot of repeated #includes
531 # of a tangle of .h files. Profiling shows, however, that
532 # eliminating the duplicates with a brute-force approach that
533 # preserves the order (that is, something like:
540 # takes more cycles than just letting the underlying methods
541 # hand back cached values if a Node's information is requested
542 # multiple times. (Other methods of removing duplicates, like
543 # using dictionary keys, lose the order, and the only ordered
544 # dictionary patterns I found all ended up using "not in"
545 # internally anyway...)
548 if self.implicit is None:
549 return self.sources + self.depends
551 return self.sources + self.depends + self.implicit
553 def get_parents(self):
554 return self.parents.keys()
556 def set_state(self, state):
562 def current(self, calc=None):
571 def is_literal(self):
572 """Always pass the string representation of a Node to
573 the command interpreter literally."""
576 def add_pre_action(self, act):
577 """Adds an Action performed on this Node only before
579 self.pre_actions.append(act)
581 def add_post_action(self, act):
582 """Adds and Action performed on this Node only after
584 self.post_actions.append(act)
586 def render_include_tree(self):
588 Return a text representation, suitable for displaying to the
589 user, of the include tree for the sources of this node.
591 if self.has_builder() and self.env:
592 env = self.generate_build_env()
593 for s in self.sources:
594 def f(node, env=env, scanner=s.source_scanner, target=self):
595 return node.get_found_includes(env, scanner, target)
596 return SCons.Util.render_tree(s, f, 1)
600 def get_abspath(self):
602 Return an absolute path to the Node. This will return simply
603 str(Node) by default, but for Node types that have a concept of
604 relative path, this might return something different.
608 def for_signature(self):
610 Return a string representation of the Node that will always
611 be the same for this particular Node, no matter what. This
612 is by contrast to the __str__() method, which might, for
613 instance, return a relative path for a file Node. The purpose
614 of this method is to generate a value to be used in signature
615 calculation for the command line used to build a target, and
616 we use this method instead of str() to avoid unnecessary
617 rebuilds. This method does not need to return something that
618 would actually work in a command line; it can return any kind of
619 nonsense, so long as it does not change.
623 def get_string(self, for_signature):
624 """This is a convenience function designed primarily to be
625 used in command generators (i.e., CommandGeneratorActions or
626 Environment variables that are callable), which are called
627 with a for_signature argument that is nonzero if the command
628 generator is being called to generate a signature for the
629 command line, which determines if we should rebuild or not.
631 Such command generators shoud use this method in preference
632 to str(Node) when converting a Node to a string, passing
633 in the for_signature parameter, such that we will call
634 Node.for_signature() or str(Node) properly, depending on whether
635 we are calculating a signature or actually constructing a
638 return self.for_signature()
641 def get_subst_proxy(self):
643 This method is expected to return an object that will function
644 exactly like this Node, except that it implements any additional
645 special features that we would like to be in effect for
646 Environment variable substitution. The principle use is that
647 some Nodes would like to implement a __getattr__() method,
648 but putting that in the Node type itself has a tendency to kill
649 performance. We instead put it in a proxy and return it from
650 this method. It is legal for this method to return self
651 if no new functionality is needed for Environment substitution.
656 def get_children(node, parent): return node.children()
657 def ignore_cycle(node, stack): pass
658 def do_nothing(node, parent): pass
661 """An iterator for walking a Node tree.
663 This is depth-first, children are visited before the parent.
664 The Walker object can be initialized with any node, and
665 returns the next node on the descent with each next() call.
666 'kids_func' is an optional function that will be called to
667 get the children of a node instead of calling 'children'.
668 'cycle_func' is an optional function that will be called
669 when a cycle is detected.
671 This class does not get caught in node cycles caused, for example,
672 by C header file include loops.
674 def __init__(self, node, kids_func=get_children,
675 cycle_func=ignore_cycle,
676 eval_func=do_nothing):
677 self.kids_func = kids_func
678 self.cycle_func = cycle_func
679 self.eval_func = eval_func
680 node.wkids = copy.copy(kids_func(node, None))
682 self.history = {} # used to efficiently detect and avoid cycles
683 self.history[node] = None
686 """Return the next node for this walk of the tree.
688 This function is intentionally iterative, not recursive,
689 to sidestep any issues of stack size limitations.
693 if self.stack[-1].wkids:
694 node = self.stack[-1].wkids.pop(0)
695 if not self.stack[-1].wkids:
696 self.stack[-1].wkids = None
697 if self.history.has_key(node):
698 self.cycle_func(node, self.stack)
700 node.wkids = copy.copy(self.kids_func(node, self.stack[-1]))
701 self.stack.append(node)
702 self.history[node] = None
704 node = self.stack.pop()
705 del self.history[node]
708 parent = self.stack[-1]
711 self.eval_func(node, parent)
715 return not self.stack
718 arg2nodes_lookups = []
720 def arg2nodes(args, node_factory=None, lookup_list=arg2nodes_lookups):
721 """This function converts a string or list into a list of Node
722 instances. It accepts the following inputs:
724 - A single Node instance,
725 - A list containing either strings or Node instances.
726 In all cases, strings are converted to Node instances, and the
727 function returns a list of Node instances."""
731 if not SCons.Util.is_List(args):
736 if SCons.Util.is_String(v):
738 for l in lookup_list:
743 if SCons.Util.is_String(n) and node_factory:
747 nodes.append(node_factory(v))
748 # Do we enforce the following restriction? Maybe, but it
749 # would also restrict what we can do to allow people to
750 # use the engine with alternate Node implementations...
751 #elif not issubclass(v.__class__, Node):