3
A module for executing actions with specific lists of target and source
9
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
11
# Permission is hereby granted, free of charge, to any person obtaining
12
# a copy of this software and associated documentation files (the
13
# "Software"), to deal in the Software without restriction, including
14
# without limitation the rights to use, copy, modify, merge, publish,
15
# distribute, sublicense, and/or sell copies of the Software, and to
16
# permit persons to whom the Software is furnished to do so, subject to
17
# the following conditions:
19
# The above copyright notice and this permission notice shall be included
20
# in all copies or substantial portions of the Software.
22
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
23
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
24
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Executor.py 0.96.1.D001 2004/08/23 09:55:29 knight"
34
from SCons.Debug import logInstanceCreation
39
"""A class for controlling instances of executing an action.
41
This largely exists to hold a single association of an action,
42
environment, list of environment override dictionaries, targets
43
and sources for later processing as needed.
46
def __init__(self, action, env=None, overridelist=[], targets=[], sources=[]):
47
if __debug__: logInstanceCreation(self)
50
self.overridelist = overridelist
51
self.targets = targets
52
self.sources = sources[:]
54
def get_build_env(self):
55
"""Fetch or create the appropriate build Environment
60
except AttributeError:
61
# Create the build environment instance with appropriate
62
# overrides. These get evaluated against the current
63
# environment's construction variables so that users can
64
# add to existing values by referencing the variable in
67
for odict in self.overridelist:
68
overrides.update(odict)
70
generate_build_dict = self.targets[0].generate_build_dict
71
except (AttributeError, IndexError):
74
overrides.update(generate_build_dict())
77
env = self.env or SCons.Defaults.DefaultEnvironment()
78
self.build_env = env.Override(overrides)
80
# Now update the build environment with the things that we
81
# don't want expanded against the current construction
83
self.build_env._update(SCons.Util.subst_dict(self.targets,
87
def get_action_list(self, target):
88
"""Fetch or create the appropriate action list (for this target).
90
There is an architectural mistake here: we cache the action list
91
for the Executor and re-use it regardless of which target is
92
being asked for. In practice, this doesn't seem to be a problem
93
because executing the action list will update all of the targets
94
involved, so only one target's pre- and post-actions will win,
95
anyway. This is probably a bug we should fix...
99
except AttributeError:
100
al = self.action.get_actions()
101
self.action_list = al
103
# XXX shouldn't reach into node attributes like this
104
return target.pre_actions + al + target.post_actions
105
except AttributeError:
108
def __call__(self, target, errfunc, **kw):
109
"""Actually execute the action list."""
110
action_list = self.get_action_list(target)
113
env = self.get_build_env()
114
for action in action_list:
115
apply(action, (self.targets, self.sources, env, errfunc), kw)
120
except AttributeError:
123
def add_sources(self, sources):
124
"""Add source files to this Executor's list. This is necessary
125
for "multi" Builders that can be called repeatedly to build up
126
a source file list for a given target."""
127
slist = filter(lambda x, s=self.sources: x not in s, sources)
128
self.sources.extend(slist)
133
except AttributeError:
135
self.string = action.genstring(self.targets,
137
self.get_build_env())
140
def get_raw_contents(self):
141
"""Fetch the raw signature contents. This, along with
142
get_contents(), is the real reason this class exists, so we can
143
compute this once and cache it regardless of how many target or
144
source Nodes there are.
147
return self.raw_contents
148
except AttributeError:
150
self.raw_contents = action.get_raw_contents(self.targets,
152
self.get_build_env())
153
return self.raw_contents
155
def get_contents(self):
156
"""Fetch the signature contents. This, along with
157
get_raw_contents(), is the real reason this class exists, so we
158
can compute this once and cache it regardless of how many target
159
or source Nodes there are.
163
except AttributeError:
165
self.contents = action.get_contents(self.targets,
167
self.get_build_env())
170
def get_timestamp(self):
171
"""Fetch a time stamp for this Executor. We don't have one, of
172
course (only files do), but this is the interface used by the