Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(539)

Side by Side Diff: scons-2.0.1/engine/SCons/Defaults.py

Issue 6711079: Added an unmodified copy of SCons to third_party. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/third_party/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « scons-2.0.1/engine/SCons/Debug.py ('k') | scons-2.0.1/engine/SCons/Environment.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 """SCons.Defaults
2
3 Builders and other things for the local site. Here's where we'll
4 duplicate the functionality of autoconf until we move it into the
5 installation procedure or use something like qmconf.
6
7 The code that reads the registry to find MSVC components was borrowed
8 from distutils.msvccompiler.
9
10 """
11
12 #
13 # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The S Cons Foundation
14 #
15 # Permission is hereby granted, free of charge, to any person obtaining
16 # a copy of this software and associated documentation files (the
17 # "Software"), to deal in the Software without restriction, including
18 # without limitation the rights to use, copy, modify, merge, publish,
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
21 # the following conditions:
22 #
23 # The above copyright notice and this permission notice shall be included
24 # in all copies or substantial portions of the Software.
25 #
26 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
27 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
28 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
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
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.
33 #
34 from __future__ import division
35
36 __revision__ = "src/engine/SCons/Defaults.py 5134 2010/08/16 23:02:40 bdeegan"
37
38
39 import os
40 import errno
41 import shutil
42 import stat
43 import time
44 import sys
45
46 import SCons.Action
47 import SCons.Builder
48 import SCons.CacheDir
49 import SCons.Environment
50 import SCons.PathList
51 import SCons.Subst
52 import SCons.Tool
53
54 # A placeholder for a default Environment (for fetching source files
55 # from source code management systems and the like). This must be
56 # initialized later, after the top-level directory is set by the calling
57 # interface.
58 _default_env = None
59
60 # Lazily instantiate the default environment so the overhead of creating
61 # it doesn't apply when it's not needed.
62 def _fetch_DefaultEnvironment(*args, **kw):
63 """
64 Returns the already-created default construction environment.
65 """
66 global _default_env
67 return _default_env
68
69 def DefaultEnvironment(*args, **kw):
70 """
71 Initial public entry point for creating the default construction
72 Environment.
73
74 After creating the environment, we overwrite our name
75 (DefaultEnvironment) with the _fetch_DefaultEnvironment() function,
76 which more efficiently returns the initialized default construction
77 environment without checking for its existence.
78
79 (This function still exists with its _default_check because someone
80 else (*cough* Script/__init__.py *cough*) may keep a reference
81 to this function. So we can't use the fully functional idiom of
82 having the name originally be a something that *only* creates the
83 construction environment and then overwrites the name.)
84 """
85 global _default_env
86 if not _default_env:
87 import SCons.Util
88 _default_env = SCons.Environment.Environment(*args, **kw)
89 if SCons.Util.md5:
90 _default_env.Decider('MD5')
91 else:
92 _default_env.Decider('timestamp-match')
93 global DefaultEnvironment
94 DefaultEnvironment = _fetch_DefaultEnvironment
95 _default_env._CacheDir_path = None
96 return _default_env
97
98 # Emitters for setting the shared attribute on object files,
99 # and an action for checking that all of the source files
100 # going into a shared library are, in fact, shared.
101 def StaticObjectEmitter(target, source, env):
102 for tgt in target:
103 tgt.attributes.shared = None
104 return (target, source)
105
106 def SharedObjectEmitter(target, source, env):
107 for tgt in target:
108 tgt.attributes.shared = 1
109 return (target, source)
110
111 def SharedFlagChecker(source, target, env):
112 same = env.subst('$STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME')
113 if same == '0' or same == '' or same == 'False':
114 for src in source:
115 try:
116 shared = src.attributes.shared
117 except AttributeError:
118 shared = None
119 if not shared:
120 raise SCons.Errors.UserError("Source file: %s is static and is n ot compatible with shared target: %s" % (src, target[0]))
121
122 SharedCheck = SCons.Action.Action(SharedFlagChecker, None)
123
124 # Some people were using these variable name before we made
125 # SourceFileScanner part of the public interface. Don't break their
126 # SConscript files until we've given them some fair warning and a
127 # transition period.
128 CScan = SCons.Tool.CScanner
129 DScan = SCons.Tool.DScanner
130 LaTeXScan = SCons.Tool.LaTeXScanner
131 ObjSourceScan = SCons.Tool.SourceFileScanner
132 ProgScan = SCons.Tool.ProgramScanner
133
134 # These aren't really tool scanners, so they don't quite belong with
135 # the rest of those in Tool/__init__.py, but I'm not sure where else
136 # they should go. Leave them here for now.
137 import SCons.Scanner.Dir
138 DirScanner = SCons.Scanner.Dir.DirScanner()
139 DirEntryScanner = SCons.Scanner.Dir.DirEntryScanner()
140
141 # Actions for common languages.
142 CAction = SCons.Action.Action("$CCCOM", "$CCCOMSTR")
143 ShCAction = SCons.Action.Action("$SHCCCOM", "$SHCCCOMSTR")
144 CXXAction = SCons.Action.Action("$CXXCOM", "$CXXCOMSTR")
145 ShCXXAction = SCons.Action.Action("$SHCXXCOM", "$SHCXXCOMSTR")
146
147 ASAction = SCons.Action.Action("$ASCOM", "$ASCOMSTR")
148 ASPPAction = SCons.Action.Action("$ASPPCOM", "$ASPPCOMSTR")
149
150 LinkAction = SCons.Action.Action("$LINKCOM", "$LINKCOMSTR")
151 ShLinkAction = SCons.Action.Action("$SHLINKCOM", "$SHLINKCOMSTR")
152
153 LdModuleLinkAction = SCons.Action.Action("$LDMODULECOM", "$LDMODULECOMSTR")
154
155 # Common tasks that we allow users to perform in platform-independent
156 # ways by creating ActionFactory instances.
157 ActionFactory = SCons.Action.ActionFactory
158
159 def get_paths_str(dest):
160 # If dest is a list, we need to manually call str() on each element
161 if SCons.Util.is_List(dest):
162 elem_strs = []
163 for element in dest:
164 elem_strs.append('"' + str(element) + '"')
165 return '[' + ', '.join(elem_strs) + ']'
166 else:
167 return '"' + str(dest) + '"'
168
169 def chmod_func(dest, mode):
170 SCons.Node.FS.invalidate_node_memos(dest)
171 if not SCons.Util.is_List(dest):
172 dest = [dest]
173 for element in dest:
174 os.chmod(str(element), mode)
175
176 def chmod_strfunc(dest, mode):
177 return 'Chmod(%s, 0%o)' % (get_paths_str(dest), mode)
178
179 Chmod = ActionFactory(chmod_func, chmod_strfunc)
180
181 def copy_func(dest, src):
182 SCons.Node.FS.invalidate_node_memos(dest)
183 if SCons.Util.is_List(src) and os.path.isdir(dest):
184 for file in src:
185 shutil.copy2(file, dest)
186 return 0
187 elif os.path.isfile(src):
188 return shutil.copy2(src, dest)
189 else:
190 return shutil.copytree(src, dest, 1)
191
192 Copy = ActionFactory(copy_func,
193 lambda dest, src: 'Copy("%s", "%s")' % (dest, src),
194 convert=str)
195
196 def delete_func(dest, must_exist=0):
197 SCons.Node.FS.invalidate_node_memos(dest)
198 if not SCons.Util.is_List(dest):
199 dest = [dest]
200 for entry in dest:
201 entry = str(entry)
202 if not must_exist and not os.path.exists(entry):
203 continue
204 if not os.path.exists(entry) or os.path.isfile(entry):
205 os.unlink(entry)
206 continue
207 else:
208 shutil.rmtree(entry, 1)
209 continue
210
211 def delete_strfunc(dest, must_exist=0):
212 return 'Delete(%s)' % get_paths_str(dest)
213
214 Delete = ActionFactory(delete_func, delete_strfunc)
215
216 def mkdir_func(dest):
217 SCons.Node.FS.invalidate_node_memos(dest)
218 if not SCons.Util.is_List(dest):
219 dest = [dest]
220 for entry in dest:
221 try:
222 os.makedirs(str(entry))
223 except os.error, e:
224 p = str(entry)
225 if (e.args[0] == errno.EEXIST or
226 (sys.platform=='win32' and e.args[0]==183)) \
227 and os.path.isdir(str(entry)):
228 pass # not an error if already exists
229 else:
230 raise
231
232 Mkdir = ActionFactory(mkdir_func,
233 lambda dir: 'Mkdir(%s)' % get_paths_str(dir))
234
235 def move_func(dest, src):
236 SCons.Node.FS.invalidate_node_memos(dest)
237 SCons.Node.FS.invalidate_node_memos(src)
238 shutil.move(src, dest)
239
240 Move = ActionFactory(move_func,
241 lambda dest, src: 'Move("%s", "%s")' % (dest, src),
242 convert=str)
243
244 def touch_func(dest):
245 SCons.Node.FS.invalidate_node_memos(dest)
246 if not SCons.Util.is_List(dest):
247 dest = [dest]
248 for file in dest:
249 file = str(file)
250 mtime = int(time.time())
251 if os.path.exists(file):
252 atime = os.path.getatime(file)
253 else:
254 open(file, 'w')
255 atime = mtime
256 os.utime(file, (atime, mtime))
257
258 Touch = ActionFactory(touch_func,
259 lambda file: 'Touch(%s)' % get_paths_str(file))
260
261 # Internal utility functions
262
263 def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None):
264 """
265 Creates a new list from 'list' by first interpolating each element
266 in the list using the 'env' dictionary and then calling f on the
267 list, and finally calling _concat_ixes to concatenate 'prefix' and
268 'suffix' onto each element of the list.
269 """
270 if not list:
271 return list
272
273 l = f(SCons.PathList.PathList(list).subst_path(env, target, source))
274 if l is not None:
275 list = l
276
277 return _concat_ixes(prefix, list, suffix, env)
278
279 def _concat_ixes(prefix, list, suffix, env):
280 """
281 Creates a new list from 'list' by concatenating the 'prefix' and
282 'suffix' arguments onto each element of the list. A trailing space
283 on 'prefix' or leading space on 'suffix' will cause them to be put
284 into separate list elements rather than being concatenated.
285 """
286
287 result = []
288
289 # ensure that prefix and suffix are strings
290 prefix = str(env.subst(prefix, SCons.Subst.SUBST_RAW))
291 suffix = str(env.subst(suffix, SCons.Subst.SUBST_RAW))
292
293 for x in list:
294 if isinstance(x, SCons.Node.FS.File):
295 result.append(x)
296 continue
297 x = str(x)
298 if x:
299
300 if prefix:
301 if prefix[-1] == ' ':
302 result.append(prefix[:-1])
303 elif x[:len(prefix)] != prefix:
304 x = prefix + x
305
306 result.append(x)
307
308 if suffix:
309 if suffix[0] == ' ':
310 result.append(suffix[1:])
311 elif x[-len(suffix):] != suffix:
312 result[-1] = result[-1]+suffix
313
314 return result
315
316 def _stripixes(prefix, itms, suffix, stripprefixes, stripsuffixes, env, c=None):
317 """
318 This is a wrapper around _concat()/_concat_ixes() that checks for
319 the existence of prefixes or suffixes on list items and strips them
320 where it finds them. This is used by tools (like the GNU linker)
321 that need to turn something like 'libfoo.a' into '-lfoo'.
322 """
323
324 if not itms:
325 return itms
326
327 if not callable(c):
328 env_c = env['_concat']
329 if env_c != _concat and callable(env_c):
330 # There's a custom _concat() method in the construction
331 # environment, and we've allowed people to set that in
332 # the past (see test/custom-concat.py), so preserve the
333 # backwards compatibility.
334 c = env_c
335 else:
336 c = _concat_ixes
337
338 stripprefixes = list(map(env.subst, SCons.Util.flatten(stripprefixes)))
339 stripsuffixes = list(map(env.subst, SCons.Util.flatten(stripsuffixes)))
340
341 stripped = []
342 for l in SCons.PathList.PathList(itms).subst_path(env, None, None):
343 if isinstance(l, SCons.Node.FS.File):
344 stripped.append(l)
345 continue
346
347 if not SCons.Util.is_String(l):
348 l = str(l)
349
350 for stripprefix in stripprefixes:
351 lsp = len(stripprefix)
352 if l[:lsp] == stripprefix:
353 l = l[lsp:]
354 # Do not strip more than one prefix
355 break
356
357 for stripsuffix in stripsuffixes:
358 lss = len(stripsuffix)
359 if l[-lss:] == stripsuffix:
360 l = l[:-lss]
361 # Do not strip more than one suffix
362 break
363
364 stripped.append(l)
365
366 return c(prefix, stripped, suffix, env)
367
368 def processDefines(defs):
369 """process defines, resolving strings, lists, dictionaries, into a list of
370 strings
371 """
372 if SCons.Util.is_List(defs):
373 l = []
374 for d in defs:
375 if SCons.Util.is_List(d) or isinstance(d, tuple):
376 l.append(str(d[0]) + '=' + str(d[1]))
377 else:
378 l.append(str(d))
379 elif SCons.Util.is_Dict(defs):
380 # The items in a dictionary are stored in random order, but
381 # if the order of the command-line options changes from
382 # invocation to invocation, then the signature of the command
383 # line will change and we'll get random unnecessary rebuilds.
384 # Consequently, we have to sort the keys to ensure a
385 # consistent order...
386 l = []
387 for k,v in sorted(defs.items()):
388 if v is None:
389 l.append(str(k))
390 else:
391 l.append(str(k) + '=' + str(v))
392 else:
393 l = [str(defs)]
394 return l
395
396 def _defines(prefix, defs, suffix, env, c=_concat_ixes):
397 """A wrapper around _concat_ixes that turns a list or string
398 into a list of C preprocessor command-line definitions.
399 """
400
401 return c(prefix, env.subst_path(processDefines(defs)), suffix, env)
402
403 class NullCmdGenerator(object):
404 """This is a callable class that can be used in place of other
405 command generators if you don't want them to do anything.
406
407 The __call__ method for this class simply returns the thing
408 you instantiated it with.
409
410 Example usage:
411 env["DO_NOTHING"] = NullCmdGenerator
412 env["LINKCOM"] = "${DO_NOTHING('$LINK $SOURCES $TARGET')}"
413 """
414
415 def __init__(self, cmd):
416 self.cmd = cmd
417
418 def __call__(self, target, source, env, for_signature=None):
419 return self.cmd
420
421 class Variable_Method_Caller(object):
422 """A class for finding a construction variable on the stack and
423 calling one of its methods.
424
425 We use this to support "construction variables" in our string
426 eval()s that actually stand in for methods--specifically, use
427 of "RDirs" in call to _concat that should actually execute the
428 "TARGET.RDirs" method. (We used to support this by creating a little
429 "build dictionary" that mapped RDirs to the method, but this got in
430 the way of Memoizing construction environments, because we had to
431 create new environment objects to hold the variables.)
432 """
433 def __init__(self, variable, method):
434 self.variable = variable
435 self.method = method
436 def __call__(self, *args, **kw):
437 try: 1//0
438 except ZeroDivisionError:
439 # Don't start iterating with the current stack-frame to
440 # prevent creating reference cycles (f_back is safe).
441 frame = sys.exc_info()[2].tb_frame.f_back
442 variable = self.variable
443 while frame:
444 if variable in frame.f_locals:
445 v = frame.f_locals[variable]
446 if v:
447 method = getattr(v, self.method)
448 return method(*args, **kw)
449 frame = frame.f_back
450 return None
451
452 ConstructionEnvironment = {
453 'BUILDERS' : {},
454 'SCANNERS' : [],
455 'CONFIGUREDIR' : '#/.sconf_temp',
456 'CONFIGURELOG' : '#/config.log',
457 'CPPSUFFIXES' : SCons.Tool.CSuffixes,
458 'DSUFFIXES' : SCons.Tool.DSuffixes,
459 'ENV' : {},
460 'IDLSUFFIXES' : SCons.Tool.IDLSuffixes,
461 # 'LATEXSUFFIXES' : SCons.Tool.LaTeXSuffixes, # moved to the TeX tools genera te functions
462 '_concat' : _concat,
463 '_defines' : _defines,
464 '_stripixes' : _stripixes,
465 '_LIBFLAGS' : '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
466 '_LIBDIRFLAGS' : '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__ , RDirs, TARGET, SOURCE)} $)',
467 '_CPPINCFLAGS' : '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDir s, TARGET, SOURCE)} $)',
468 '_CPPDEFFLAGS' : '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env_ _)}',
469 'TEMPFILE' : NullCmdGenerator,
470 'Dir' : Variable_Method_Caller('TARGET', 'Dir'),
471 'Dirs' : Variable_Method_Caller('TARGET', 'Dirs'),
472 'File' : Variable_Method_Caller('TARGET', 'File'),
473 'RDirs' : Variable_Method_Caller('TARGET', 'RDirs'),
474 }
475
476 # Local Variables:
477 # tab-width:4
478 # indent-tabs-mode:nil
479 # End:
480 # vim: set expandtab tabstop=4 shiftwidth=4:
OLDNEW
« no previous file with comments | « scons-2.0.1/engine/SCons/Debug.py ('k') | scons-2.0.1/engine/SCons/Environment.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698