~ubuntu-branches/ubuntu/utopic/scons/utopic-proposed

« back to all changes in this revision

Viewing changes to engine/SCons/Executor.py

  • Committer: Bazaar Package Importer
  • Author(s): Mark Brown
  • Date: 2004-08-24 08:57:22 UTC
  • mfrom: (0.2.1 upstream) (1.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20040824085722-hfk4f0pjbyu0ebxv
Tags: 0.96.1-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""SCons.Executor
 
2
 
 
3
A module for executing actions with specific lists of target and source
 
4
Nodes.
 
5
 
 
6
"""
 
7
 
 
8
#
 
9
# Copyright (c) 2001, 2002, 2003, 2004 The SCons Foundation
 
10
#
 
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:
 
18
#
 
19
# The above copyright notice and this permission notice shall be included
 
20
# in all copies or substantial portions of the Software.
 
21
#
 
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.
 
29
#
 
30
 
 
31
__revision__ = "/home/scons/scons/branch.0/baseline/src/engine/SCons/Executor.py 0.96.1.D001 2004/08/23 09:55:29 knight"
 
32
 
 
33
 
 
34
from SCons.Debug import logInstanceCreation
 
35
import SCons.Util
 
36
 
 
37
 
 
38
class Executor:
 
39
    """A class for controlling instances of executing an action.
 
40
 
 
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.
 
44
    """
 
45
 
 
46
    def __init__(self, action, env=None, overridelist=[], targets=[], sources=[]):
 
47
        if __debug__: logInstanceCreation(self)
 
48
        self.action = action
 
49
        self.env = env
 
50
        self.overridelist = overridelist
 
51
        self.targets = targets
 
52
        self.sources = sources[:]
 
53
 
 
54
    def get_build_env(self):
 
55
        """Fetch or create the appropriate build Environment
 
56
        for this Executor.
 
57
        """
 
58
        try:
 
59
            return self.build_env
 
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
 
65
            # the expansion.
 
66
            overrides = {}
 
67
            for odict in self.overridelist:
 
68
                overrides.update(odict)
 
69
            try:
 
70
                generate_build_dict = self.targets[0].generate_build_dict
 
71
            except (AttributeError, IndexError):
 
72
                pass
 
73
            else:
 
74
                overrides.update(generate_build_dict())
 
75
 
 
76
            import SCons.Defaults
 
77
            env = self.env or SCons.Defaults.DefaultEnvironment()
 
78
            self.build_env = env.Override(overrides)
 
79
 
 
80
            # Now update the build environment with the things that we
 
81
            # don't want expanded against the current construction
 
82
            # variables.
 
83
            self.build_env._update(SCons.Util.subst_dict(self.targets,
 
84
                                                         self.sources))
 
85
            return self.build_env
 
86
 
 
87
    def get_action_list(self, target):
 
88
        """Fetch or create the appropriate action list (for this target).
 
89
 
 
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...
 
96
        """
 
97
        try:
 
98
            al = self.action_list
 
99
        except AttributeError:
 
100
            al = self.action.get_actions()
 
101
            self.action_list = al
 
102
        try:
 
103
            # XXX shouldn't reach into node attributes like this
 
104
            return target.pre_actions + al + target.post_actions
 
105
        except AttributeError:
 
106
            return al
 
107
 
 
108
    def __call__(self, target, errfunc, **kw):
 
109
        """Actually execute the action list."""
 
110
        action_list = self.get_action_list(target)
 
111
        if not action_list:
 
112
            return
 
113
        env = self.get_build_env()
 
114
        for action in action_list:
 
115
            apply(action, (self.targets, self.sources, env, errfunc), kw)
 
116
 
 
117
    def cleanup(self):
 
118
        try:
 
119
            del self.build_env
 
120
        except AttributeError:
 
121
            pass
 
122
 
 
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)
 
129
 
 
130
    def __str__(self):
 
131
        try:
 
132
            return self.string
 
133
        except AttributeError:
 
134
            action = self.action
 
135
            self.string = action.genstring(self.targets,
 
136
                                           self.sources,
 
137
                                           self.get_build_env())
 
138
            return self.string
 
139
 
 
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.
 
145
        """
 
146
        try:
 
147
            return self.raw_contents
 
148
        except AttributeError:
 
149
            action = self.action
 
150
            self.raw_contents = action.get_raw_contents(self.targets,
 
151
                                                        self.sources,
 
152
                                                        self.get_build_env())
 
153
            return self.raw_contents
 
154
 
 
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.
 
160
        """
 
161
        try:
 
162
            return self.contents
 
163
        except AttributeError:
 
164
            action = self.action
 
165
            self.contents = action.get_contents(self.targets,
 
166
                                                self.sources,
 
167
                                                self.get_build_env())
 
168
            return self.contents
 
169
 
 
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
 
173
        timestamp module.
 
174
        """
 
175
        return 0