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 rel_2.4.0:3365:9259ea1c13d7 2015/09/21 14:03:43 bdbaddog"
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 DAction = SCons.Action.Action("$DCOM", "$DCOMSTR")
148 ShDAction = SCons.Action.Action("$SHDCOM", "$SHDCOMSTR")
149
150 ASAction = SCons.Action.Action("$ASCOM", "$ASCOMSTR")
151 ASPPAction = SCons.Action.Action("$ASPPCOM", "$ASPPCOMSTR")
152
153 LinkAction = SCons.Action.Action("$LINKCOM", "$LINKCOMSTR")
154 ShLinkAction = SCons.Action.Action("$SHLINKCOM", "$SHLINKCOMSTR")
155
156 LdModuleLinkAction = SCons.Action.Action("$LDMODULECOM", "$LDMODULECOMSTR")
157
158
159
160 ActionFactory = SCons.Action.ActionFactory
161
163
164 if SCons.Util.is_List(dest):
165 elem_strs = []
166 for element in dest:
167 elem_strs.append('"' + str(element) + '"')
168 return '[' + ', '.join(elem_strs) + ']'
169 else:
170 return '"' + str(dest) + '"'
171
178
180 return 'Chmod(%s, 0%o)' % (get_paths_str(dest), mode)
181
182 Chmod = ActionFactory(chmod_func, chmod_strfunc)
183
185 """
186 If symlinks (is true), then a symbolic link will be
187 shallow copied and recreated as a symbolic link; otherwise, copying
188 a symbolic link will be equivalent to copying the symbolic link's
189 final target regardless of symbolic link depth.
190 """
191
192 dest = str(dest)
193 src = str(src)
194
195 SCons.Node.FS.invalidate_node_memos(dest)
196 if SCons.Util.is_List(src) and os.path.isdir(dest):
197 for file in src:
198 shutil.copy2(file, dest)
199 return 0
200 elif os.path.islink(src):
201 if symlinks:
202 return os.symlink(os.readlink(src), dest)
203 else:
204 return copy_func(dest, os.path.realpath(src))
205 elif os.path.isfile(src):
206 return shutil.copy2(src, dest)
207 else:
208 return shutil.copytree(src, dest, symlinks)
209
210 Copy = ActionFactory(
211 copy_func,
212 lambda dest, src, symlinks=True: 'Copy("%s", "%s")' % (dest, src)
213 )
214
230
232 return 'Delete(%s)' % get_paths_str(dest)
233
234 Delete = ActionFactory(delete_func, delete_strfunc)
235
237 SCons.Node.FS.invalidate_node_memos(dest)
238 if not SCons.Util.is_List(dest):
239 dest = [dest]
240 for entry in dest:
241 try:
242 os.makedirs(str(entry))
243 except os.error, e:
244 p = str(entry)
245 if (e.args[0] == errno.EEXIST or
246 (sys.platform=='win32' and e.args[0]==183)) \
247 and os.path.isdir(str(entry)):
248 pass
249 else:
250 raise
251
252 Mkdir = ActionFactory(mkdir_func,
253 lambda dir: 'Mkdir(%s)' % get_paths_str(dir))
254
259
260 Move = ActionFactory(move_func,
261 lambda dest, src: 'Move("%s", "%s")' % (dest, src),
262 convert=str)
263
265 SCons.Node.FS.invalidate_node_memos(dest)
266 if not SCons.Util.is_List(dest):
267 dest = [dest]
268 for file in dest:
269 file = str(file)
270 mtime = int(time.time())
271 if os.path.exists(file):
272 atime = os.path.getatime(file)
273 else:
274 open(file, 'w')
275 atime = mtime
276 os.utime(file, (atime, mtime))
277
278 Touch = ActionFactory(touch_func,
279 lambda file: 'Touch(%s)' % get_paths_str(file))
280
281
282
283 -def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None):
284 """
285 Creates a new list from 'list' by first interpolating each element
286 in the list using the 'env' dictionary and then calling f on the
287 list, and finally calling _concat_ixes to concatenate 'prefix' and
288 'suffix' onto each element of the list.
289 """
290 if not list:
291 return list
292
293 l = f(SCons.PathList.PathList(list).subst_path(env, target, source))
294 if l is not None:
295 list = l
296
297 return _concat_ixes(prefix, list, suffix, env)
298
300 """
301 Creates a new list from 'list' by concatenating the 'prefix' and
302 'suffix' arguments onto each element of the list. A trailing space
303 on 'prefix' or leading space on 'suffix' will cause them to be put
304 into separate list elements rather than being concatenated.
305 """
306
307 result = []
308
309
310 prefix = str(env.subst(prefix, SCons.Subst.SUBST_RAW))
311 suffix = str(env.subst(suffix, SCons.Subst.SUBST_RAW))
312
313 for x in list:
314 if isinstance(x, SCons.Node.FS.File):
315 result.append(x)
316 continue
317 x = str(x)
318 if x:
319
320 if prefix:
321 if prefix[-1] == ' ':
322 result.append(prefix[:-1])
323 elif x[:len(prefix)] != prefix:
324 x = prefix + x
325
326 result.append(x)
327
328 if suffix:
329 if suffix[0] == ' ':
330 result.append(suffix[1:])
331 elif x[-len(suffix):] != suffix:
332 result[-1] = result[-1]+suffix
333
334 return result
335
336 -def _stripixes(prefix, itms, suffix, stripprefixes, stripsuffixes, env, c=None):
337 """
338 This is a wrapper around _concat()/_concat_ixes() that checks for
339 the existence of prefixes or suffixes on list items and strips them
340 where it finds them. This is used by tools (like the GNU linker)
341 that need to turn something like 'libfoo.a' into '-lfoo'.
342 """
343
344 if not itms:
345 return itms
346
347 if not callable(c):
348 env_c = env['_concat']
349 if env_c != _concat and callable(env_c):
350
351
352
353
354 c = env_c
355 else:
356 c = _concat_ixes
357
358 stripprefixes = list(map(env.subst, SCons.Util.flatten(stripprefixes)))
359 stripsuffixes = list(map(env.subst, SCons.Util.flatten(stripsuffixes)))
360
361 stripped = []
362 for l in SCons.PathList.PathList(itms).subst_path(env, None, None):
363 if isinstance(l, SCons.Node.FS.File):
364 stripped.append(l)
365 continue
366
367 if not SCons.Util.is_String(l):
368 l = str(l)
369
370 for stripprefix in stripprefixes:
371 lsp = len(stripprefix)
372 if l[:lsp] == stripprefix:
373 l = l[lsp:]
374
375 break
376
377 for stripsuffix in stripsuffixes:
378 lss = len(stripsuffix)
379 if l[-lss:] == stripsuffix:
380 l = l[:-lss]
381
382 break
383
384 stripped.append(l)
385
386 return c(prefix, stripped, suffix, env)
387
389 """process defines, resolving strings, lists, dictionaries, into a list of
390 strings
391 """
392 if SCons.Util.is_List(defs):
393 l = []
394 for d in defs:
395 if d is None:
396 continue
397 elif SCons.Util.is_List(d) or isinstance(d, tuple):
398 if len(d) >= 2:
399 l.append(str(d[0]) + '=' + str(d[1]))
400 else:
401 l.append(str(d[0]))
402 elif SCons.Util.is_Dict(d):
403 for macro,value in d.iteritems():
404 if value is not None:
405 l.append(str(macro) + '=' + str(value))
406 else:
407 l.append(str(macro))
408 elif SCons.Util.is_String(d):
409 l.append(str(d))
410 else:
411 raise SCons.Errors.UserError("DEFINE %s is not a list, dict, string or None."%repr(d))
412 elif SCons.Util.is_Dict(defs):
413
414
415
416
417
418
419 l = []
420 for k,v in sorted(defs.items()):
421 if v is None:
422 l.append(str(k))
423 else:
424 l.append(str(k) + '=' + str(v))
425 else:
426 l = [str(defs)]
427 return l
428
429 -def _defines(prefix, defs, suffix, env, c=_concat_ixes):
430 """A wrapper around _concat_ixes that turns a list or string
431 into a list of C preprocessor command-line definitions.
432 """
433
434 return c(prefix, env.subst_path(processDefines(defs)), suffix, env)
435
437 """This is a callable class that can be used in place of other
438 command generators if you don't want them to do anything.
439
440 The __call__ method for this class simply returns the thing
441 you instantiated it with.
442
443 Example usage:
444 env["DO_NOTHING"] = NullCmdGenerator
445 env["LINKCOM"] = "${DO_NOTHING('$LINK $SOURCES $TARGET')}"
446 """
447
450
451 - def __call__(self, target, source, env, for_signature=None):
453
455 """A class for finding a construction variable on the stack and
456 calling one of its methods.
457
458 We use this to support "construction variables" in our string
459 eval()s that actually stand in for methods--specifically, use
460 of "RDirs" in call to _concat that should actually execute the
461 "TARGET.RDirs" method. (We used to support this by creating a little
462 "build dictionary" that mapped RDirs to the method, but this got in
463 the way of Memoizing construction environments, because we had to
464 create new environment objects to hold the variables.)
465 """
467 self.variable = variable
468 self.method = method
470 try: 1//0
471 except ZeroDivisionError:
472
473
474 frame = sys.exc_info()[2].tb_frame.f_back
475 variable = self.variable
476 while frame:
477 if variable in frame.f_locals:
478 v = frame.f_locals[variable]
479 if v:
480 method = getattr(v, self.method)
481 return method(*args, **kw)
482 frame = frame.f_back
483 return None
484
485 ConstructionEnvironment = {
486 'BUILDERS' : {},
487 'SCANNERS' : [],
488 'CONFIGUREDIR' : '#/.sconf_temp',
489 'CONFIGURELOG' : '#/config.log',
490 'CPPSUFFIXES' : SCons.Tool.CSuffixes,
491 'DSUFFIXES' : SCons.Tool.DSuffixes,
492 'ENV' : {},
493 'IDLSUFFIXES' : SCons.Tool.IDLSuffixes,
494
495 '_concat' : _concat,
496 '_defines' : _defines,
497 '_stripixes' : _stripixes,
498 '_LIBFLAGS' : '${_concat(LIBLINKPREFIX, LIBS, LIBLINKSUFFIX, __env__)}',
499 '_LIBDIRFLAGS' : '$( ${_concat(LIBDIRPREFIX, LIBPATH, LIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
500 '_CPPINCFLAGS' : '$( ${_concat(INCPREFIX, CPPPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)',
501 '_CPPDEFFLAGS' : '${_defines(CPPDEFPREFIX, CPPDEFINES, CPPDEFSUFFIX, __env__)}',
502 'TEMPFILE' : NullCmdGenerator,
503 'Dir' : Variable_Method_Caller('TARGET', 'Dir'),
504 'Dirs' : Variable_Method_Caller('TARGET', 'Dirs'),
505 'File' : Variable_Method_Caller('TARGET', 'File'),
506 'RDirs' : Variable_Method_Caller('TARGET', 'RDirs'),
507 }
508
509
510
511
512
513
514