OLD | NEW |
1 """SCons.Environment | 1 """SCons.Environment |
2 | 2 |
3 Base class for construction Environments. These are | 3 Base class for construction Environments. These are |
4 the primary objects used to communicate dependency and | 4 the primary objects used to communicate dependency and |
5 construction information to the build engine. | 5 construction information to the build engine. |
6 | 6 |
7 Keyword arguments supplied when the construction Environment | 7 Keyword arguments supplied when the construction Environment |
8 is created are construction variables used to initialize the | 8 is created are construction variables used to initialize the |
9 Environment | 9 Environment |
10 """ | 10 """ |
11 | 11 |
12 # | 12 # |
13 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundat
ion | 13 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 The SCons F
oundation |
14 # | 14 # |
15 # Permission is hereby granted, free of charge, to any person obtaining | 15 # Permission is hereby granted, free of charge, to any person obtaining |
16 # a copy of this software and associated documentation files (the | 16 # a copy of this software and associated documentation files (the |
17 # "Software"), to deal in the Software without restriction, including | 17 # "Software"), to deal in the Software without restriction, including |
18 # without limitation the rights to use, copy, modify, merge, publish, | 18 # without limitation the rights to use, copy, modify, merge, publish, |
19 # distribute, sublicense, and/or sell copies of the Software, and to | 19 # distribute, sublicense, and/or sell copies of the Software, and to |
20 # permit persons to whom the Software is furnished to do so, subject to | 20 # permit persons to whom the Software is furnished to do so, subject to |
21 # the following conditions: | 21 # the following conditions: |
22 # | 22 # |
23 # The above copyright notice and this permission notice shall be included | 23 # The above copyright notice and this permission notice shall be included |
24 # in all copies or substantial portions of the Software. | 24 # in all copies or substantial portions of the Software. |
25 # | 25 # |
26 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY | 26 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY |
27 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE | 27 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE |
28 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 28 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
29 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | 29 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
30 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | 30 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
31 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | 31 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
32 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | 32 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
33 # | 33 # |
34 | 34 |
35 __revision__ = "src/engine/SCons/Environment.py 3842 2008/12/20 22:59:52 scons" | 35 __revision__ = "src/engine/SCons/Environment.py 3897 2009/01/13 06:45:54 scons" |
36 | 36 |
37 | 37 |
38 import copy | 38 import copy |
39 import os | 39 import os |
40 import sys | 40 import sys |
41 import re | 41 import re |
42 import shlex | 42 import shlex |
43 import string | 43 import string |
44 from UserDict import UserDict | 44 from UserDict import UserDict |
45 | 45 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 toolname = tool[0] | 102 toolname = tool[0] |
103 toolargs = tool[1] # should be a dict of kw args | 103 toolargs = tool[1] # should be a dict of kw args |
104 tool = apply(env.Tool, [toolname], toolargs) | 104 tool = apply(env.Tool, [toolname], toolargs) |
105 else: | 105 else: |
106 env.Tool(tool) | 106 env.Tool(tool) |
107 | 107 |
108 # These names are (or will be) controlled by SCons; users should never | 108 # These names are (or will be) controlled by SCons; users should never |
109 # set or override them. This warning can optionally be turned off, | 109 # set or override them. This warning can optionally be turned off, |
110 # but scons will still ignore the illegal variable names even if it's off. | 110 # but scons will still ignore the illegal variable names even if it's off. |
111 reserved_construction_var_names = [ | 111 reserved_construction_var_names = [ |
| 112 'CHANGED_SOURCES', |
| 113 'CHANGED_TARGETS', |
112 'SOURCE', | 114 'SOURCE', |
113 'SOURCES', | 115 'SOURCES', |
114 'TARGET', | 116 'TARGET', |
115 'TARGETS', | 117 'TARGETS', |
116 ] | |
117 | |
118 future_reserved_construction_var_names = [ | |
119 'CHANGED_SOURCES', | |
120 'CHANGED_TARGETS', | |
121 'UNCHANGED_SOURCES', | 118 'UNCHANGED_SOURCES', |
122 'UNCHANGED_TARGETS', | 119 'UNCHANGED_TARGETS', |
123 ] | 120 ] |
124 | 121 |
| 122 future_reserved_construction_var_names = [] |
| 123 |
125 def copy_non_reserved_keywords(dict): | 124 def copy_non_reserved_keywords(dict): |
126 result = semi_deepcopy(dict) | 125 result = semi_deepcopy(dict) |
127 for k in result.keys(): | 126 for k in result.keys(): |
128 if k in reserved_construction_var_names: | 127 if k in reserved_construction_var_names: |
129 msg = "Ignoring attempt to set reserved variable `$%s'" | 128 msg = "Ignoring attempt to set reserved variable `$%s'" |
130 SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % k) | 129 SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % k) |
131 del result[k] | 130 del result[k] |
132 return result | 131 return result |
133 | 132 |
134 def _set_reserved(env, key, value): | 133 def _set_reserved(env, key, value): |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 # If we already have the entry, then it's obviously a valid | 421 # If we already have the entry, then it's obviously a valid |
423 # key and we don't need to check. If we do check, using a | 422 # key and we don't need to check. If we do check, using a |
424 # global, pre-compiled regular expression directly is more | 423 # global, pre-compiled regular expression directly is more |
425 # efficient than calling another function or a method. | 424 # efficient than calling another function or a method. |
426 if not self._dict.has_key(key) \ | 425 if not self._dict.has_key(key) \ |
427 and not _is_valid_var.match(key): | 426 and not _is_valid_var.match(key): |
428 raise SCons.Errors.UserError, "Illegal construction variable
`%s'" % key | 427 raise SCons.Errors.UserError, "Illegal construction variable
`%s'" % key |
429 self._dict[key] = value | 428 self._dict[key] = value |
430 | 429 |
431 def get(self, key, default=None): | 430 def get(self, key, default=None): |
432 "Emulates the get() method of dictionaries.""" | 431 """Emulates the get() method of dictionaries.""" |
433 return self._dict.get(key, default) | 432 return self._dict.get(key, default) |
434 | 433 |
435 def has_key(self, key): | 434 def has_key(self, key): |
436 return self._dict.has_key(key) | 435 return self._dict.has_key(key) |
437 | 436 |
438 def __contains__(self, key): | 437 def __contains__(self, key): |
439 return self._dict.__contains__(key) | 438 return self._dict.__contains__(key) |
440 | 439 |
441 def items(self): | 440 def items(self): |
442 return self._dict.items() | 441 return self._dict.items() |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 nodes.append(v) | 482 nodes.append(v) |
484 | 483 |
485 return nodes | 484 return nodes |
486 | 485 |
487 def gvars(self): | 486 def gvars(self): |
488 return self._dict | 487 return self._dict |
489 | 488 |
490 def lvars(self): | 489 def lvars(self): |
491 return {} | 490 return {} |
492 | 491 |
493 def subst(self, string, raw=0, target=None, source=None, conv=None): | 492 def subst(self, string, raw=0, target=None, source=None, conv=None, executor
=None): |
494 """Recursively interpolates construction variables from the | 493 """Recursively interpolates construction variables from the |
495 Environment into the specified string, returning the expanded | 494 Environment into the specified string, returning the expanded |
496 result. Construction variables are specified by a $ prefix | 495 result. Construction variables are specified by a $ prefix |
497 in the string and begin with an initial underscore or | 496 in the string and begin with an initial underscore or |
498 alphabetic character followed by any number of underscores | 497 alphabetic character followed by any number of underscores |
499 or alphanumeric characters. The construction variable names | 498 or alphanumeric characters. The construction variable names |
500 may be surrounded by curly braces to separate the name from | 499 may be surrounded by curly braces to separate the name from |
501 trailing characters. | 500 trailing characters. |
502 """ | 501 """ |
503 gvars = self.gvars() | 502 gvars = self.gvars() |
504 lvars = self.lvars() | 503 lvars = self.lvars() |
505 lvars['__env__'] = self | 504 lvars['__env__'] = self |
| 505 if executor: |
| 506 lvars.update(executor.get_lvars()) |
506 return SCons.Subst.scons_subst(string, self, raw, target, source, gvars,
lvars, conv) | 507 return SCons.Subst.scons_subst(string, self, raw, target, source, gvars,
lvars, conv) |
507 | 508 |
508 def subst_kw(self, kw, raw=0, target=None, source=None): | 509 def subst_kw(self, kw, raw=0, target=None, source=None): |
509 nkw = {} | 510 nkw = {} |
510 for k, v in kw.items(): | 511 for k, v in kw.items(): |
511 k = self.subst(k, raw, target, source) | 512 k = self.subst(k, raw, target, source) |
512 if SCons.Util.is_String(v): | 513 if SCons.Util.is_String(v): |
513 v = self.subst(v, raw, target, source) | 514 v = self.subst(v, raw, target, source) |
514 nkw[k] = v | 515 nkw[k] = v |
515 return nkw | 516 return nkw |
516 | 517 |
517 def subst_list(self, string, raw=0, target=None, source=None, conv=None): | 518 def subst_list(self, string, raw=0, target=None, source=None, conv=None, exe
cutor=None): |
518 """Calls through to SCons.Subst.scons_subst_list(). See | 519 """Calls through to SCons.Subst.scons_subst_list(). See |
519 the documentation for that function.""" | 520 the documentation for that function.""" |
520 gvars = self.gvars() | 521 gvars = self.gvars() |
521 lvars = self.lvars() | 522 lvars = self.lvars() |
522 lvars['__env__'] = self | 523 lvars['__env__'] = self |
| 524 if executor: |
| 525 lvars.update(executor.get_lvars()) |
523 return SCons.Subst.scons_subst_list(string, self, raw, target, source, g
vars, lvars, conv) | 526 return SCons.Subst.scons_subst_list(string, self, raw, target, source, g
vars, lvars, conv) |
524 | 527 |
525 def subst_path(self, path, target=None, source=None): | 528 def subst_path(self, path, target=None, source=None): |
526 """Substitute a path list, turning EntryProxies into Nodes | 529 """Substitute a path list, turning EntryProxies into Nodes |
527 and leaving Nodes (and other objects) as-is.""" | 530 and leaving Nodes (and other objects) as-is.""" |
528 | 531 |
529 if not SCons.Util.is_List(path): | 532 if not SCons.Util.is_List(path): |
530 path = [path] | 533 path = [path] |
531 | 534 |
532 def s(obj): | 535 def s(obj): |
(...skipping 658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 try: | 1194 try: |
1192 update_dict(val) | 1195 update_dict(val) |
1193 except (AttributeError, TypeError, ValueError): | 1196 except (AttributeError, TypeError, ValueError): |
1194 if SCons.Util.is_Dict(val): | 1197 if SCons.Util.is_Dict(val): |
1195 for k, v in val.items(): | 1198 for k, v in val.items(): |
1196 orig[k] = v | 1199 orig[k] = v |
1197 else: | 1200 else: |
1198 orig[val] = None | 1201 orig[val] = None |
1199 self.scanner_map_delete(kw) | 1202 self.scanner_map_delete(kw) |
1200 | 1203 |
| 1204 # allow Dirs and strings beginning with # for top-relative |
| 1205 # Note this uses the current env's fs (in self). |
| 1206 def _canonicalize(self, path): |
| 1207 if not SCons.Util.is_String(path): # typically a Dir |
| 1208 path = str(path) |
| 1209 if path and path[0] == '#': |
| 1210 path = str(self.fs.Dir(path)) |
| 1211 return path |
| 1212 |
1201 def AppendENVPath(self, name, newpath, envname = 'ENV', | 1213 def AppendENVPath(self, name, newpath, envname = 'ENV', |
1202 sep = os.pathsep, delete_existing=1): | 1214 sep = os.pathsep, delete_existing=1): |
1203 """Append path elements to the path 'name' in the 'ENV' | 1215 """Append path elements to the path 'name' in the 'ENV' |
1204 dictionary for this environment. Will only add any particular | 1216 dictionary for this environment. Will only add any particular |
1205 path once, and will normpath and normcase all paths to help | 1217 path once, and will normpath and normcase all paths to help |
1206 assure this. This can also handle the case where the env | 1218 assure this. This can also handle the case where the env |
1207 variable is a list instead of a string. | 1219 variable is a list instead of a string. |
1208 | 1220 |
1209 If delete_existing is 0, a newpath which is already in the path | 1221 If delete_existing is 0, a newpath which is already in the path |
1210 will not be moved to the end (it will be left where it is). | 1222 will not be moved to the end (it will be left where it is). |
1211 """ | 1223 """ |
1212 | 1224 |
1213 orig = '' | 1225 orig = '' |
1214 if self._dict.has_key(envname) and self._dict[envname].has_key(name): | 1226 if self._dict.has_key(envname) and self._dict[envname].has_key(name): |
1215 orig = self._dict[envname][name] | 1227 orig = self._dict[envname][name] |
1216 | 1228 |
1217 nv = SCons.Util.AppendPath(orig, newpath, sep, delete_existing) | 1229 nv = SCons.Util.AppendPath(orig, newpath, sep, delete_existing, |
| 1230 canonicalize=self._canonicalize) |
1218 | 1231 |
1219 if not self._dict.has_key(envname): | 1232 if not self._dict.has_key(envname): |
1220 self._dict[envname] = {} | 1233 self._dict[envname] = {} |
1221 | 1234 |
1222 self._dict[envname][name] = nv | 1235 self._dict[envname][name] = nv |
1223 | 1236 |
1224 def AppendUnique(self, delete_existing=0, **kw): | 1237 def AppendUnique(self, delete_existing=0, **kw): |
1225 """Append values to existing construction variables | 1238 """Append values to existing construction variables |
1226 in an Environment, if they're not already there. | 1239 in an Environment, if they're not already there. |
1227 If delete_existing is 1, removes existing values first, so | 1240 If delete_existing is 1, removes existing values first, so |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1562 variable is a list instead of a string. | 1575 variable is a list instead of a string. |
1563 | 1576 |
1564 If delete_existing is 0, a newpath which is already in the path | 1577 If delete_existing is 0, a newpath which is already in the path |
1565 will not be moved to the front (it will be left where it is). | 1578 will not be moved to the front (it will be left where it is). |
1566 """ | 1579 """ |
1567 | 1580 |
1568 orig = '' | 1581 orig = '' |
1569 if self._dict.has_key(envname) and self._dict[envname].has_key(name): | 1582 if self._dict.has_key(envname) and self._dict[envname].has_key(name): |
1570 orig = self._dict[envname][name] | 1583 orig = self._dict[envname][name] |
1571 | 1584 |
1572 nv = SCons.Util.PrependPath(orig, newpath, sep, delete_existing) | 1585 nv = SCons.Util.PrependPath(orig, newpath, sep, delete_existing, |
| 1586 canonicalize=self._canonicalize) |
1573 | 1587 |
1574 if not self._dict.has_key(envname): | 1588 if not self._dict.has_key(envname): |
1575 self._dict[envname] = {} | 1589 self._dict[envname] = {} |
1576 | 1590 |
1577 self._dict[envname][name] = nv | 1591 self._dict[envname][name] = nv |
1578 | 1592 |
1579 def PrependUnique(self, delete_existing=0, **kw): | 1593 def PrependUnique(self, delete_existing=0, **kw): |
1580 """Prepend values to existing construction variables | 1594 """Prepend values to existing construction variables |
1581 in an Environment, if they're not already there. | 1595 in an Environment, if they're not already there. |
1582 If delete_existing is 1, removes existing values first, so | 1596 If delete_existing is 1, removes existing values first, so |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2291 nkw['gvars'] = {} | 2305 nkw['gvars'] = {} |
2292 self.raw_to_mode(nkw) | 2306 self.raw_to_mode(nkw) |
2293 return apply(SCons.Subst.scons_subst_list, nargs, nkw) | 2307 return apply(SCons.Subst.scons_subst_list, nargs, nkw) |
2294 def subst_target_source(self, string, *args, **kwargs): | 2308 def subst_target_source(self, string, *args, **kwargs): |
2295 nargs = (string, self,) + args | 2309 nargs = (string, self,) + args |
2296 nkw = kwargs.copy() | 2310 nkw = kwargs.copy() |
2297 nkw['gvars'] = {} | 2311 nkw['gvars'] = {} |
2298 self.raw_to_mode(nkw) | 2312 self.raw_to_mode(nkw) |
2299 return apply(SCons.Subst.scons_subst, nargs, nkw) | 2313 return apply(SCons.Subst.scons_subst, nargs, nkw) |
2300 return _NoSubstitutionProxy(subject) | 2314 return _NoSubstitutionProxy(subject) |
OLD | NEW |