Improve new post-PathList refactoring performance. (Charles Crain)
[scons.git] / src / engine / SCons / Node / __init__.py
1 """SCons.Node
2
3 The Node package for the SCons software construction utility.
4
5 This is, in many ways, the heart of SCons.
6
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).
12
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."
19
20 """
21
22 #
23 # __COPYRIGHT__
24 #
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:
32 #
33 # The above copyright notice and this permission notice shall be included
34 # in all copies or substantial portions of the Software.
35 #
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.
43 #
44
45 __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
46
47
48
49 import copy
50
51 import SCons.Sig
52 import SCons.Util
53
54 # Node states
55 #
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
60 # were up to date.
61 pending = 1
62 executing = 2
63 up_to_date = 3
64 executed = 4
65 failed = 5
66 stack = 6 # nodes that are in the current Taskmaster execution stack
67
68 # controls whether implicit depedencies are cached:
69 implicit_cache = 0
70
71 # controls whether implicit dep changes are ignored:
72 implicit_deps_unchanged = 0
73
74 # controls whether the cached implicit deps are ignored:
75 implicit_deps_changed = 0
76
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
80
81 Annotate = do_nothing
82
83 class Node:
84     """The base Node class, for entities that we know how to
85     build, or use to build other Nodes.
86     """
87
88     class Attrs:
89         pass
90
91     def __init__(self):
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).
97
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
102         self.parents = {}
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
106
107         self.env = None
108         self.state = None
109         self.precious = None
110         self.found_includes = {}
111         self.includes = None
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? 
119
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).
123         Annotate(self)
124
125     def generate_build_env(self):
126         """Generate the appropriate Environment to build this node."""
127         if self.env is None:
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
134         else:
135             # The normal case: use the Environment used to specify how
136             # this Node is to be built.
137             env = self.env
138             overrides = self.overrides
139         return env.Override(overrides)
140
141     def _for_each_action(self, func):
142         """Call a function for each action required to build a node.
143
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():
149             return
150         action_list = self.pre_actions + \
151                       self.builder.get_actions() + \
152                       self.post_actions
153         if not action_list:
154             return
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)
159
160     def build(self):
161         """Actually build the node.
162
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
165         built().
166         """
167         def do_action(action, targets, sources, env, self=self):
168             stat = action(targets, sources, env)
169             if stat:
170                 raise SCons.Errors.BuildError(node = self,
171                                               errstr = "Error %d" % stat)
172         self._for_each_action(do_action)
173
174     def built(self):
175         """Called just after this node is sucessfully built."""
176         self.store_bsig()
177
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 = {}
183             self.includes = None
184
185             def get_parents(node, parent): return node.get_parents()
186             def clear_cache(node, parent):
187                 node.implicit = None
188                 node.del_bsig()
189             w = Walker(self, get_parents, ignore_cycle, clear_cache)
190             while w.next(): pass
191
192         # clear out the content signature, since the contents of this
193         # node were presumably just changed:
194         self.del_csig()
195
196     def clear(self):
197         """Completely clear a Node of all its cached state (so that it
198         can be re-evaluated by interfaces that do continuous integration
199         builds).
200         """
201         self.set_state(None)
202         self.del_bsig()
203         self.del_csig()
204         self.includes = None
205         self.found_includes = {}
206         self.implicit = None
207
208     def visited(self):
209         """Called just after this node has been visited
210         without requiring a build.."""
211         pass
212
213     def depends_on(self, nodes):
214         """Does this node depend on any of 'nodes'?"""
215         for node in nodes:
216             if node in self.children():
217                 return 1
218
219         return 0
220
221     def builder_set(self, builder):
222         self.builder = builder
223
224     def has_builder(self):
225         """Return whether this Node has a builder or not.
226
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.
234         """
235         try:
236             b = self.builder
237         except AttributeError:
238             # There was no explicit builder for this Node, so initialize
239             # the self.builder attribute to None now.
240             self.builder = None
241             b = self.builder
242         return not b is None
243
244     def is_derived(self):
245         return self.has_builder() or self.side_effect
246
247     def alter_targets(self):
248         """Return a list of alternate targets for this Node.
249         """
250         return [], None
251
252     def builder_sig_adapter(self):
253         """Create an adapter for calculating a builder's signature.
254
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.
260         """
261         class Adapter:
262             def __init__(self, node):
263                 self.node = 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):
267                 return None
268         return Adapter(self)
269
270     def get_found_includes(self, env, scanner, target):
271         """Return the scanned include lines (implicit dependencies)
272         found in this node.
273
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.
277         """
278         return []
279
280     def get_implicit_deps(self, env, scanner, target):
281         """Return a list of implicit dependencies for this node.
282
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.
286         """
287         if not scanner:
288             return []
289
290         try:
291             recurse = scanner.recursive
292         except AttributeError:
293             recurse = None
294
295         nodes = [self]
296         seen = {}
297         seen[self] = 1
298         deps = []
299         while nodes:
300            n = nodes.pop(0)
301            d = filter(lambda x, seen=seen: not seen.has_key(x),
302                       n.get_found_includes(env, scanner, target))
303            if d:
304                deps.extend(d)
305                for n in d:
306                    seen[n] = 1
307                if recurse:
308                    nodes.extend(d)
309
310         return deps
311
312     # cache used to make implicit_factory fast.
313     implicit_factory_cache = {}
314     
315     def implicit_factory(self, path):
316         """
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.
320         """
321         try:
322             return self.implicit_factory_cache[path]
323         except KeyError:
324             n = self.builder.source_factory(path)
325             self.implicit_factory_cache[path] = n
326             return n
327
328     def scan(self):
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:
334             return
335         self.implicit = []
336         if not self.has_builder():
337             return
338
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)):
346                     return
347                 else:
348                     # one of this node's sources has changed, so
349                     # we need to recalculate the implicit deps,
350                     # and the bsig:
351                     self.implicit = []
352                     self.del_bsig()
353
354         build_env = self.generate_build_env()
355
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,
360                                                     self))
361
362         # scan this node itself for implicit dependencies
363         self._add_child(self.implicit,
364                         self.get_implicit_deps(build_env,
365                                                self.target_scanner,
366                                                self))
367
368         if implicit_cache:
369             self.store_implicit()
370
371     def scanner_key(self):
372         return None
373
374     def env_set(self, env, safe=0):
375         if safe and self.env:
376             return
377         self.env = env
378
379     def calc_signature(self, calc, cache=None):
380         """
381         Select and calculate the appropriate build signature for a node.
382
383         self - the node
384         calc - the signature calculation module
385         cache - alternate node to use for the signature cache
386         returns - the signature
387         """
388
389         if self.has_builder():
390             if SCons.Sig.build_signature:
391                 return calc.bsig(self, cache)
392             else:
393                 return calc.csig(self, cache)
394         elif not self.exists():
395             return None
396         else:
397             return calc.csig(self, cache)
398
399     def get_bsig(self):
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'):
403             return None
404         return self.bsig
405
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)."""
409         self.bsig = bsig
410
411     def store_bsig(self):
412         """Make the build signature permanent (that is, store it in the
413         .sconsign file or equivalent)."""
414         pass
415
416     def del_bsig(self):
417         """Delete the bsig from this node."""
418         if hasattr(self, 'bsig'):
419             delattr(self, 'bsig')
420
421     def get_csig(self):
422         """Get the signature of the node's content."""
423         if not hasattr(self, 'csig'):
424             return None
425         return self.csig
426
427     def set_csig(self, csig):
428         """Set the signature of the node's content."""
429         self.csig = csig
430
431     def store_csig(self):
432         """Make the content signature permanent (that is, store it in the
433         .sconsign file or equivalent)."""
434         pass
435
436     def del_csig(self):
437         """Delete the csig from this node."""
438         if hasattr(self, 'csig'):
439             delattr(self, 'csig')
440
441     def get_prevsiginfo(self):
442         """Fetch the previous signature information from the
443         .sconsign entry."""
444         return None
445
446     def get_timestamp(self):
447         return 0
448
449     def store_timestamp(self):
450         """Make the timestamp permanent (that is, store it in the
451         .sconsign file or equivalent)."""
452         pass
453
454     def store_implicit(self):
455         """Make the implicit deps permanent (that is, store them in the
456         .sconsign file or equivalent)."""
457         pass
458
459     def get_stored_implicit(self):
460         """Fetch the stored implicit dependencies"""
461         return None
462
463     def set_precious(self, precious = 1):
464         """Set the Node's precious value."""
465         self.precious = precious
466
467     def exists(self):
468         """Does this node exists?"""
469         # All node exist by default:
470         return 1
471     
472     def rexists(self):
473         """Does this node exist locally or in a repositiory?"""
474         # There are no repositories by default:
475         return self.exists()
476     
477     def prepare(self):
478         """Prepare for this Node to be created.
479         The default implemenation checks that all children either exist
480         or are derived.
481         """
482         def missing(node):
483             return not node.is_derived() and not node.linked and not node.rexists()
484         missing_sources = filter(missing, self.children())
485         if missing_sources:
486             desc = "No Builder for target `%s', needed by `%s'." % (missing_sources[0], self)
487             raise SCons.Errors.StopError, desc
488
489     def remove(self):
490         """Remove this Node:  no-op by default."""
491         return None
492
493     def add_dependency(self, depend):
494         """Adds dependencies. The depend argument must be a list."""
495         self._add_child(self.depends, depend)
496
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)
500
501     def add_source(self, source):
502         """Adds sources. The source argument must be a list."""
503         self._add_child(self.sources, source)
504
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)
510         if child:
511             collection.extend(child)
512
513         for c in child:
514             c.parents[self] = 1
515
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)
520
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))
526
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:
534         #
535         #       u = []
536         #       for n in list:
537         #           if n not in u:
538         #               u.append(n)"
539         #
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...)
546         if scan:
547             self.scan()
548         if self.implicit is None:
549             return self.sources + self.depends
550         else:
551             return self.sources + self.depends + self.implicit
552
553     def get_parents(self):
554         return self.parents.keys()
555
556     def set_state(self, state):
557         self.state = state
558
559     def get_state(self):
560         return self.state
561
562     def current(self, calc=None):
563         return None
564
565     def rfile(self):
566         return self
567
568     def rstr(self):
569         return str(self)
570
571     def is_literal(self):
572         """Always pass the string representation of a Node to
573         the command interpreter literally."""
574         return 1
575
576     def add_pre_action(self, act):
577         """Adds an Action performed on this Node only before
578         building it."""
579         self.pre_actions.append(act)
580
581     def add_post_action(self, act):
582         """Adds and Action performed on this Node only after
583         building it."""
584         self.post_actions.append(act)
585
586     def render_include_tree(self):
587         """
588         Return a text representation, suitable for displaying to the
589         user, of the include tree for the sources of this node.
590         """
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)
597         else:
598             return None
599
600     def get_abspath(self):
601         """
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.
605         """
606         return str(self)
607
608     def for_signature(self):
609         """
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.
620         """
621         return str(self)
622
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.
630
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
636         command line."""
637         if for_signature:
638             return self.for_signature()
639         return str(self)
640
641     def get_subst_proxy(self):
642         """
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.
652         """
653         return self
654         
655
656 def get_children(node, parent): return node.children()
657 def ignore_cycle(node, stack): pass
658 def do_nothing(node, parent): pass
659
660 class Walker:
661     """An iterator for walking a Node tree.
662
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.
670
671     This class does not get caught in node cycles caused, for example,
672     by C header file include loops.
673     """
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))
681         self.stack = [node]
682         self.history = {} # used to efficiently detect and avoid cycles
683         self.history[node] = None
684
685     def next(self):
686         """Return the next node for this walk of the tree.
687
688         This function is intentionally iterative, not recursive,
689         to sidestep any issues of stack size limitations.
690         """
691
692         while self.stack:
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)
699                 else:
700                     node.wkids = copy.copy(self.kids_func(node, self.stack[-1]))
701                     self.stack.append(node)
702                     self.history[node] = None
703             else:
704                 node = self.stack.pop()
705                 del self.history[node]
706                 if node:
707                     if self.stack:
708                         parent = self.stack[-1]
709                     else:
710                         parent = None
711                     self.eval_func(node, parent)
712                 return node
713
714     def is_done(self):
715         return not self.stack
716
717
718 arg2nodes_lookups = []
719
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:
723         - A single string,
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."""
728
729     if not args:
730         return []
731     if not SCons.Util.is_List(args):
732         args = [args]
733
734     nodes = []
735     for v in args:
736         if SCons.Util.is_String(v):
737             n = None
738             for l in lookup_list:
739                 n = l(v)
740                 if not n is None:
741                     break
742             if not n is None:
743                 if SCons.Util.is_String(n) and node_factory:
744                     n = node_factory(n)
745                 nodes.append(n)
746             elif 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):
752         #    raise TypeError
753         else:
754             nodes.append(v)
755
756     return nodes