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
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 from __future__ import division
35
36 __revision__ = "src/engine/SCons/Defaults.py 5023 2010/06/14 22:05:46 scons"
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
55
56
57
58 _default_env = None
59
60
61
63 """
64 Returns the already-created default construction environment.
65 """
66 global _default_env
67 return _default_env
68
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
99
100
102 for tgt in target:
103 tgt.attributes.shared = None
104 return (target, source)
105
107 for tgt in target:
108 tgt.attributes.shared = 1
109 return (target, source)
110
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 not compatible with shared target: %s" % (src, target[0]))
121
122 SharedCheck = SCons.Action.Action(SharedFlagChecker, None)
123
124
125
126
127
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
135
136
137 import SCons.Scanner.Dir
138 DirScanner = SCons.Scanner.Dir.DirScanner()
139 DirEntryScanner = SCons.Scanner.Dir.DirEntryScanner()
140
141
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
156
157 ActionFactory = SCons.Action.ActionFactory
158
160
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
175
177 return 'Chmod(%s, 0%o)' % (get_paths_str(dest), mode)
178
179 Chmod = ActionFactory(chmod_func, chmod_strfunc)
180
191
192 Copy = ActionFactory(copy_func,
193 lambda dest, src: 'Copy("%s", "%s")' % (dest, src),
194 convert=str)
195
210
212 return 'Delete(%s)' % get_paths_str(dest)
213
214 Delete = ActionFactory(delete_func, delete_strfunc)
215
231
232 Mkdir = ActionFactory(mkdir_func,
233 lambda dir: 'Mkdir(%s)' % get_paths_str(dir))
234
239
240 Move = ActionFactory(move_func,
241 lambda dest, src: 'Move("%s", "%s")' % (dest, src),
242 convert=str)
243
257
258 Touch = ActionFactory(touch_func,
259 lambda file: 'Touch(%s)' % get_paths_str(file))
260
261
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
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
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
331
332
333
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
355 break
356
357 for stripsuffix in stripsuffixes:
358 lss = len(stripsuffix)
359 if l[-lss:] == stripsuffix:
360 l = l[:-lss]
361
362 break
363
364 stripped.append(l)
365
366 return c(prefix, stripped, suffix, env)
367
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
381
382
383
384
385
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
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
417
418 - def __call__(self, target, source, env, for_signature=None):
420
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 """
434 self.variable = variable
435 self.method = method
437 try: 1//0
438 except ZeroDivisionError:
439
440
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
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__, RDirs, 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
477
478
479
480
481