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
35 __revision__ = "src/engine/SCons/Defaults.py 3842 2008/12/20 22:59:52 scons"
36
37
38
39 import os
40 import os.path
41 import shutil
42 import stat
43 import string
44 import time
45 import types
46 import sys
47
48 import SCons.Action
49 import SCons.Builder
50 import SCons.CacheDir
51 import SCons.Environment
52 import SCons.PathList
53 import SCons.Subst
54 import SCons.Tool
55
56
57
58
59
60 _default_env = None
61
62
63
65 """
66 Returns the already-created default construction environment.
67 """
68 global _default_env
69 return _default_env
70
72 """
73 Initial public entry point for creating the default construction
74 Environment.
75
76 After creating the environment, we overwrite our name
77 (DefaultEnvironment) with the _fetch_DefaultEnvironment() function,
78 which more efficiently returns the initialized default construction
79 environment without checking for its existence.
80
81 (This function still exists with its _default_check because someone
82 else (*cough* Script/__init__.py *cough*) may keep a reference
83 to this function. So we can't use the fully functional idiom of
84 having the name originally be a something that *only* creates the
85 construction environment and then overwrites the name.)
86 """
87 global _default_env
88 if not _default_env:
89 import SCons.Util
90 _default_env = apply(SCons.Environment.Environment, args, kw)
91 if SCons.Util.md5:
92 _default_env.Decider('MD5')
93 else:
94 _default_env.Decider('timestamp-match')
95 global DefaultEnvironment
96 DefaultEnvironment = _fetch_DefaultEnvironment
97 _default_env._CacheDir_path = None
98 return _default_env
99
100
101
102
104 for tgt in target:
105 tgt.attributes.shared = None
106 return (target, source)
107
109 for tgt in target:
110 tgt.attributes.shared = 1
111 return (target, source)
112
114 same = env.subst('$STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME')
115 if same == '0' or same == '' or same == 'False':
116 for src in source:
117 try:
118 shared = src.attributes.shared
119 except AttributeError:
120 shared = None
121 if not shared:
122 raise SCons.Errors.UserError, "Source file: %s is static and is not compatible with shared target: %s" % (src, target[0])
123
124 SharedCheck = SCons.Action.Action(SharedFlagChecker, None)
125
126
127
128
129
130 CScan = SCons.Tool.CScanner
131 DScan = SCons.Tool.DScanner
132 LaTeXScan = SCons.Tool.LaTeXScanner
133 ObjSourceScan = SCons.Tool.SourceFileScanner
134 ProgScan = SCons.Tool.ProgramScanner
135
136
137
138
139 import SCons.Scanner.Dir
140 DirScanner = SCons.Scanner.Dir.DirScanner()
141 DirEntryScanner = SCons.Scanner.Dir.DirEntryScanner()
142
143
144 CAction = SCons.Action.Action("$CCCOM", "$CCCOMSTR")
145 ShCAction = SCons.Action.Action("$SHCCCOM", "$SHCCCOMSTR")
146 CXXAction = SCons.Action.Action("$CXXCOM", "$CXXCOMSTR")
147 ShCXXAction = SCons.Action.Action("$SHCXXCOM", "$SHCXXCOMSTR")
148
149 ASAction = SCons.Action.Action("$ASCOM", "$ASCOMSTR")
150 ASPPAction = SCons.Action.Action("$ASPPCOM", "$ASPPCOMSTR")
151
152 LinkAction = SCons.Action.Action("$LINKCOM", "$LINKCOMSTR")
153 ShLinkAction = SCons.Action.Action("$SHLINKCOM", "$SHLINKCOMSTR")
154
155 LdModuleLinkAction = SCons.Action.Action("$LDMODULECOM", "$LDMODULECOMSTR")
156
157
158
159 ActionFactory = SCons.Action.ActionFactory
160
162
163 if SCons.Util.is_List(dest):
164 elem_strs = []
165 for element in dest:
166 elem_strs.append('"' + str(element) + '"')
167 return '[' + string.join(elem_strs, ', ') + ']'
168 else:
169 return '"' + str(dest) + '"'
170
177
179 return 'Chmod(%s, 0%o)' % (get_paths_str(dest), mode)
180
181 Chmod = ActionFactory(chmod_func, chmod_strfunc)
182
193
194 Copy = ActionFactory(copy_func,
195 lambda dest, src: 'Copy("%s", "%s")' % (dest, src),
196 convert=str)
197
212
214 return 'Delete(%s)' % get_paths_str(dest)
215
216 Delete = ActionFactory(delete_func, delete_strfunc)
217
224
225 Mkdir = ActionFactory(mkdir_func,
226 lambda dir: 'Mkdir(%s)' % get_paths_str(dir))
227
232
233 Move = ActionFactory(move_func,
234 lambda dest, src: 'Move("%s", "%s")' % (dest, src),
235 convert=str)
236
250
251 Touch = ActionFactory(touch_func,
252 lambda file: 'Touch(%s)' % get_paths_str(file))
253
254
255
256 -def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None):
257 """
258 Creates a new list from 'list' by first interpolating each element
259 in the list using the 'env' dictionary and then calling f on the
260 list, and finally calling _concat_ixes to concatenate 'prefix' and
261 'suffix' onto each element of the list.
262 """
263 if not list:
264 return list
265
266 l = f(SCons.PathList.PathList(list).subst_path(env, target, source))
267 if not l is None:
268 list = l
269
270 return _concat_ixes(prefix, list, suffix, env)
271
273 """
274 Creates a new list from 'list' by concatenating the 'prefix' and
275 'suffix' arguments onto each element of the list. A trailing space
276 on 'prefix' or leading space on 'suffix' will cause them to be put
277 into separate list elements rather than being concatenated.
278 """
279
280 result = []
281
282
283 prefix = str(env.subst(prefix, SCons.Subst.SUBST_RAW))
284 suffix = str(env.subst(suffix, SCons.Subst.SUBST_RAW))
285
286 for x in list:
287 if isinstance(x, SCons.Node.FS.File):
288 result.append(x)
289 continue
290 x = str(x)
291 if x:
292
293 if prefix:
294 if prefix[-1] == ' ':
295 result.append(prefix[:-1])
296 elif x[:len(prefix)] != prefix:
297 x = prefix + x
298
299 result.append(x)
300
301 if suffix:
302 if suffix[0] == ' ':
303 result.append(suffix[1:])
304 elif x[-len(suffix):] != suffix:
305 result[-1] = result[-1]+suffix
306
307 return result
308
309 -def _stripixes(prefix, list, suffix, stripprefixes, stripsuffixes, env, c=None):
310 """
311 This is a wrapper around _concat()/_concat_ixes() that checks for the
312 existence of prefixes or suffixes on list elements and strips them
313 where it finds them. This is used by tools (like the GNU linker)
314 that need to turn something like 'libfoo.a' into '-lfoo'.
315 """
316
317 if not list:
318 return list
319
320 if not callable(c):
321 env_c = env['_concat']
322 if env_c != _concat and callable(env_c):
323
324
325
326
327 c = env_c
328 else:
329 c = _concat_ixes
330
331 stripprefixes = map(env.subst, SCons.Util.flatten(stripprefixes))
332 stripsuffixes = map(env.subst, SCons.Util.flatten(stripsuffixes))
333
334 stripped = []
335 for l in SCons.PathList.PathList(list).subst_path(env, None, None):
336 if isinstance(l, SCons.Node.FS.File):
337 stripped.append(l)
338 continue
339
340 if not SCons.Util.is_String(l):
341 l = str(l)
342
343 for stripprefix in stripprefixes:
344 lsp = len(stripprefix)
345 if l[:lsp] == stripprefix:
346 l = l[lsp:]
347
348 break
349
350 for stripsuffix in stripsuffixes:
351 lss = len(stripsuffix)
352 if l[-lss:] == stripsuffix:
353 l = l[:-lss]
354
355 break
356
357 stripped.append(l)
358
359 return c(prefix, stripped, suffix, env)
360
361 -def _defines(prefix, defs, suffix, env, c=_concat_ixes):
362 """A wrapper around _concat_ixes that turns a list or string
363 into a list of C preprocessor command-line definitions.
364 """
365 if SCons.Util.is_List(defs):
366 l = []
367 for d in defs:
368 if SCons.Util.is_List(d) or type(d) is types.TupleType:
369 l.append(str(d[0]) + '=' + str(d[1]))
370 else:
371 l.append(str(d))
372 elif SCons.Util.is_Dict(defs):
373
374
375
376
377
378
379 l = []
380 keys = defs.keys()
381 keys.sort()
382 for k in keys:
383 v = defs[k]
384 if v is None:
385 l.append(str(k))
386 else:
387 l.append(str(k) + '=' + str(v))
388 else:
389 l = [str(defs)]
390 return c(prefix, env.subst_path(l), suffix, env)
391
393 """This is a callable class that can be used in place of other
394 command generators if you don't want them to do anything.
395
396 The __call__ method for this class simply returns the thing
397 you instantiated it with.
398
399 Example usage:
400 env["DO_NOTHING"] = NullCmdGenerator
401 env["LINKCOM"] = "${DO_NOTHING('$LINK $SOURCES $TARGET')}"
402 """
403
406
407 - def __call__(self, target, source, env, for_signature=None):
409
411 """A class for finding a construction variable on the stack and
412 calling one of its methods.
413
414 We use this to support "construction variables" in our string
415 eval()s that actually stand in for methods--specifically, use
416 of "RDirs" in call to _concat that should actually execute the
417 "TARGET.RDirs" method. (We used to support this by creating a little
418 "build dictionary" that mapped RDirs to the method, but this got in
419 the way of Memoizing construction environments, because we had to
420 create new environment objects to hold the variables.)
421 """
423 self.variable = variable
424 self.method = method
426 try: 1/0
427 except ZeroDivisionError:
428
429
430 frame = sys.exc_info()[2].tb_frame.f_back
431 variable = self.variable
432 while frame:
433 if frame.f_locals.has_key(variable):
434 v = frame.f_locals[variable]
435 if v:
436 method = getattr(v, self.method)
437 return apply(method, args, kw)
438 frame = frame.f_back
439 return None
440
441 ConstructionEnvironment = {
442 'BUILDERS' : {},
443 'SCANNERS' : [],
444 'CONFIGUREDIR' : '#/.sconf_temp',
445 'CONFIGURELOG' : '#/config.log',
446 'CPPSUFFIXES' : SCons.Tool.CSuffixes,
447 'DSUFFIXES' : SCons.Tool.DSuffixes,
448 'ENV' : {},
449 'IDLSUFFIXES' : SCons.Tool.IDLSuffixes,
450 'LATEXSUFFIXES' : SCons.Tool.LaTeXSuffixes,
451 '_concat' : _concat,
452 '_defines' : _defines,
453 '_stripixes' : _stripixes,
454 '_LIBFLAGS' : '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
455 '_LIBDIRFLAGS' : '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
456 '_CPPINCFLAGS' : '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
457 '_CPPDEFFLAGS' : '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
458 'TEMPFILE' : NullCmdGenerator,
459 'Dir' : Variable_Method_Caller('TARGET', 'Dir'),
460 'Dirs' : Variable_Method_Caller('TARGET', 'Dirs'),
461 'File' : Variable_Method_Caller('TARGET', 'File'),
462 'RDirs' : Variable_Method_Caller('TARGET', 'RDirs'),
463 }
464