~mwinter4/maus/ckov_0_9_3

« back to all changes in this revision

Viewing changes to third_party/scons-2.0.1/lib/scons-2.0.1/SCons/Defaults.py

  • Committer: tunnell
  • Date: 2010-09-30 13:56:05 UTC
  • Revision ID: tunnell@itchy-20100930135605-wxbkfgy75p0sndk3
add third party

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 SCons 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 not 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 generate 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__, 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
# Local Variables:
 
477
# tab-width:4
 
478
# indent-tabs-mode:nil
 
479
# End:
 
480
# vim: set expandtab tabstop=4 shiftwidth=4: