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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 __revision__ = "src/engine/SCons/Node/__init__.py 3765 2008/11/04 08:12:16 scons"
46
47 import copy
48 from itertools import chain, izip
49 import string
50 import UserList
51
52 from SCons.Debug import logInstanceCreation
53 import SCons.Executor
54 import SCons.Memoize
55 import SCons.Util
56
57 from SCons.Debug import Trace
58
61
62
63
64
65
66
67
68
69 no_state = 0
70 pending = 1
71 executing = 2
72 up_to_date = 3
73 executed = 4
74 failed = 5
75
76 StateString = {
77 0 : "no_state",
78 1 : "pending",
79 2 : "executing",
80 3 : "up_to_date",
81 4 : "executed",
82 5 : "failed",
83 }
84
85
86 implicit_cache = 0
87
88
89 implicit_deps_unchanged = 0
90
91
92 implicit_deps_changed = 0
93
94
95
97
98 Annotate = do_nothing
99
100
101
103 """
104 The generic base class for signature information for a Node.
105
106 Node subclasses should subclass NodeInfoBase to provide their own
107 logic for dealing with their own Node-specific signature information.
108 """
109 current_version_id = 1
115 try:
116 field_list = self.field_list
117 except AttributeError:
118 return
119 for f in field_list:
120 try:
121 delattr(self, f)
122 except AttributeError:
123 pass
124 try:
125 func = getattr(node, 'get_' + f)
126 except AttributeError:
127 pass
128 else:
129 setattr(self, f, func())
133 self.__dict__.update(other.__dict__)
152
154 """
155 The generic base class for build information for a Node.
156
157 This is what gets stored in a .sconsign file for each target file.
158 It contains a NodeInfo instance for this node (signature information
159 that's specific to the type of Node) and direct attributes for the
160 generic build stuff we have to track: sources, explicit dependencies,
161 implicit dependencies, and action information.
162 """
163 current_version_id = 1
165
166
167 self._version_id = self.current_version_id
168 self.bsourcesigs = []
169 self.bdependsigs = []
170 self.bimplicitsigs = []
171 self.bactsig = None
173 self.__dict__.update(other.__dict__)
174
176 """The base Node class, for entities that we know how to
177 build, or use to build other Nodes.
178 """
179
180 if SCons.Memoize.use_memoizer:
181 __metaclass__ = SCons.Memoize.Memoized_Metaclass
182
183 memoizer_counters = []
184
187
189 if __debug__: logInstanceCreation(self, 'Node.Node')
190
191
192
193
194
195
196
197
198
199
200
201
202
203 self.sources = []
204 self.sources_set = set()
205 self._specific_sources = False
206 self.depends = []
207 self.depends_set = set()
208 self.ignore = []
209 self.ignore_set = set()
210 self.prerequisites = SCons.Util.UniqueList()
211 self.implicit = None
212 self.waiting_parents = set()
213 self.waiting_s_e = set()
214 self.ref_count = 0
215 self.wkids = None
216
217 self.env = None
218 self.state = no_state
219 self.precious = None
220 self.noclean = 0
221 self.nocache = 0
222 self.always_build = None
223 self.includes = None
224 self.attributes = self.Attrs()
225 self.side_effect = 0
226 self.side_effects = []
227 self.linked = 0
228
229 self.clear_memoized_values()
230
231
232
233
234 Annotate(self)
235
238
241
242 memoizer_counters.append(SCons.Memoize.CountValue('get_build_env'))
243
245 """Fetch the appropriate Environment to build this node.
246 """
247 try:
248 return self._memo['get_build_env']
249 except KeyError:
250 pass
251 result = self.get_executor().get_build_env()
252 self._memo['get_build_env'] = result
253 return result
254
258
260 """Set the action executor for this node."""
261 self.executor = executor
262
264 """Fetch the action executor for this node. Create one if
265 there isn't already one, and requested to do so."""
266 try:
267 executor = self.executor
268 except AttributeError:
269 if not create:
270 raise
271 try:
272 act = self.builder.action
273 except AttributeError:
274 executor = SCons.Executor.Null(targets=[self])
275 else:
276 executor = SCons.Executor.Executor(act,
277 self.env or self.builder.env,
278 [self.builder.overrides],
279 [self],
280 self.sources)
281 self.executor = executor
282 return executor
283
285 """Let the executor clean up any cached information."""
286 try:
287 executor = self.get_executor(create=None)
288 except AttributeError:
289 pass
290 else:
291 executor.cleanup()
292
294 "Remove cached executor; forces recompute when needed."
295 try:
296 delattr(self, 'executor')
297 except AttributeError:
298 pass
299
301 """Try to retrieve the node's content from a cache
302
303 This method is called from multiple threads in a parallel build,
304 so only do thread safe stuff here. Do thread unsafe stuff in
305 built().
306
307 Returns true iff the node was successfully retrieved.
308 """
309 return 0
310
311
312
313
314
316 """Get a Node ready for evaluation.
317
318 This is called before the Taskmaster decides if the Node is
319 up-to-date or not. Overriding this method allows for a Node
320 subclass to be disambiguated if necessary, or for an implicit
321 source builder to be attached.
322 """
323 pass
324
326 """Prepare for this Node to be built.
327
328 This is called after the Taskmaster has decided that the Node
329 is out-of-date and must be rebuilt, but before actually calling
330 the method to build the Node.
331
332 This default implementation checks that explicit or implicit
333 dependencies either exist or are derived, and initializes the
334 BuildInfo structure that will hold the information about how
335 this node is, uh, built.
336
337 (The existence of source files is checked separately by the
338 Executor, which aggregates checks for all of the targets built
339 by a specific action.)
340
341 Overriding this method allows for for a Node subclass to remove
342 the underlying file from the file system. Note that subclass
343 methods should call this base class method to get the child
344 check and the BuildInfo structure.
345 """
346 for d in self.depends:
347 if d.missing():
348 msg = "Explicit dependency `%s' not found, needed by target `%s'."
349 raise SCons.Errors.StopError, msg % (d, self)
350 if not self.implicit is None:
351 for i in self.implicit:
352 if i.missing():
353 msg = "Implicit dependency `%s' not found, needed by target `%s'."
354 raise SCons.Errors.StopError, msg % (i, self)
355 self.binfo = self.get_binfo()
356
358 """Actually build the node.
359
360 This is called by the Taskmaster after it's decided that the
361 Node is out-of-date and must be rebuilt, and after the prepare()
362 method has gotten everything, uh, prepared.
363
364 This method is called from multiple threads in a parallel build,
365 so only do thread safe stuff here. Do thread unsafe stuff
366 in built().
367
368 """
369 try:
370 apply(self.get_executor(), (self,), kw)
371 except SCons.Errors.BuildError, e:
372 e.node = self
373 raise
374
376 """Called just after this node is successfully built."""
377
378
379
380 for parent in self.waiting_parents:
381 parent.implicit = None
382
383 self.clear()
384
385 self.ninfo.update(self)
386
388 """Called just after this node has been visited (with or
389 without a build)."""
390 try:
391 binfo = self.binfo
392 except AttributeError:
393
394
395 pass
396 else:
397 self.ninfo.update(self)
398 self.store_info()
399
400
401
402
403
405 self.waiting_s_e.add(node)
406
408 """
409 Returns the number of nodes added to our waiting parents list:
410 1 if we add a unique waiting parent, 0 if not. (Note that the
411 returned values are intended to be used to increment a reference
412 count, so don't think you can "clean up" this function by using
413 True and False instead...)
414 """