1 """SCons.Environment
2
3 Base class for construction Environments. These are
4 the primary objects used to communicate dependency and
5 construction information to the build engine.
6
7 Keyword arguments supplied when the construction Environment
8 is created are construction variables used to initialize the
9 Environment
10 """
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 __revision__ = "src/engine/SCons/Environment.py 2928 2008/04/29 22:44:09 knight"
36
37
38 import copy
39 import os
40 import os.path
41 import re
42 import shlex
43 import string
44 from UserDict import UserDict
45
46 import SCons.Action
47 import SCons.Builder
48 from SCons.Debug import logInstanceCreation
49 import SCons.Defaults
50 import SCons.Errors
51 import SCons.Memoize
52 import SCons.Node
53 import SCons.Node.Alias
54 import SCons.Node.FS
55 import SCons.Node.Python
56 import SCons.Platform
57 import SCons.SConsign
58 import SCons.Subst
59 import SCons.Tool
60 import SCons.Util
61 import SCons.Warnings
62
65
66 _null = _Null
67
68 _warn_copy_deprecated = True
69 _warn_source_signatures_deprecated = True
70 _warn_target_signatures_deprecated = True
71
72 CleanTargets = {}
73 CalculatorArgs = {}
74
75 semi_deepcopy = SCons.Util.semi_deepcopy
76
77
78
79
80 UserError = SCons.Errors.UserError
81
84
85 AliasBuilder = SCons.Builder.Builder(action = alias_builder,
86 target_factory = SCons.Node.Alias.default_ans.Alias,
87 source_factory = SCons.Node.FS.Entry,
88 multi = 1,
89 is_explicit = None,
90 name='AliasBuilder')
91
107
108
109
110
111 reserved_construction_var_names = \
112 ['TARGET', 'TARGETS', 'SOURCE', 'SOURCES']
113
122
126
128 try:
129 bd = env._dict[key]
130 for k in bd.keys():
131 del bd[k]
132 except KeyError:
133 bd = BuilderDict(kwbd, env)
134 env._dict[key] = bd
135 bd.update(value)
136
140
144
145
146
147
148
149
150
151
152
153
154
155
156
157
159 """
160 A generic Wrapper class that associates a method (which can
161 actually be any callable) with an object. As part of creating this
162 MethodWrapper object an attribute with the specified (by default,
163 the name of the supplied method) is added to the underlying object.
164 When that new "method" is called, our __call__() method adds the
165 object as the first argument, simulating the Python behavior of
166 supplying "self" on method calls.
167
168 We hang on to the name by which the method was added to the underlying
169 base class so that we can provide a method to "clone" ourselves onto
170 a new underlying object being copied (without which we wouldn't need
171 to save that info).
172 """
173 - def __init__(self, object, method, name=None):
180
182 nargs = (self.object,) + args
183 return apply(self.method, nargs, kwargs)
184
185 - def clone(self, new_object):
186 """
187 Returns an object that re-binds the underlying "method" to
188 the specified new object.
189 """
190 return self.__class__(new_object, self.method, self.name)
191
193 """
194 A MethodWrapper subclass that that associates an environment with
195 a Builder.
196
197 This mainly exists to wrap the __call__() function so that all calls
198 to Builders can have their argument lists massaged in the same way
199 (treat a lone argument as the source, treat two arguments as target
200 then source, make sure both target and source are lists) without
201 having to have cut-and-paste code to do it.
202
203 As a bit of obsessive backwards compatibility, we also intercept
204 attempts to get or set the "env" or "builder" attributes, which were
205 the names we used before we put the common functionality into the
206 MethodWrapper base class. We'll keep this around for a while in case
207 people shipped Tool modules that reached into the wrapper (like the
208 Tool/qt.py module does, or did). There shouldn't be a lot attribute
209 fetching or setting on these, so a little extra work shouldn't hurt.
210 """
212 if source is _null:
213 source = target
214 target = None
215 if not target is None and not SCons.Util.is_List(target):
216 target = [target]
217 if not source is None and not SCons.Util.is_List(source):
218 source = [source]
219 return apply(MethodWrapper.__call__, (self, target, source) + args, kw)
220
222 return '<BuilderWrapper %s>' % repr(self.name)
223
226
228 if name == 'env':
229 return self.object
230 elif name == 'builder':
231 return self.method
232 else:
233 return self.__dict__[name]
234
236 if name == 'env':
237 self.object = value
238 elif name == 'builder':
239 self.method = value
240 else:
241 self.__dict__[name] = value
242
243
244
245
246
247
248
249
250
251
252
253
255 """This is a dictionary-like class used by an Environment to hold
256 the Builders. We need to do this because every time someone changes
257 the Builders in the Environment's BUILDERS dictionary, we must
258 update the Environment's attributes."""
260
261
262
263 self.env = env
264 UserDict.__init__(self, dict)
265
267 return self.__class__(self.data, self.env)
268
270 try:
271 method = getattr(self.env, item).method
272 except AttributeError:
273 pass
274 else:
275 self.env.RemoveMethod(method)
276 UserDict.__setitem__(self, item, val)
277 BuilderWrapper(self.env, val, item)
278
280 UserDict.__delitem__(self, item)
281 delattr(self.env, item)
282
286
287
288
289 _is_valid_var = re.compile(r'[_a-zA-Z]\w*$')
290
292 """Return if the specified string is a legitimate construction
293 variable.
294 """
295 return _is_valid_var.match(varstr)
296
297
298