+ Scons updated to latest stable version 1.2
This commit is contained in:
parent
8977683c0d
commit
8687dd795d
191 changed files with 7866 additions and 3194 deletions
48
SConstruct
48
SConstruct
|
@ -33,38 +33,38 @@ else:
|
|||
|
||||
# All of the following options may be modified at the command-line, for example:
|
||||
# `python scons/scons PREFIX=/opt`
|
||||
opts = Options('config.py')
|
||||
opts = Variables('config.py')
|
||||
opts.Add('CXX', 'The C++ compiler to use (defaults to g++).', 'g++')
|
||||
opts.Add('PREFIX', 'The install path "prefix"', '/usr/local')
|
||||
opts.Add(PathOption('BOOST_INCLUDES', 'Search path for boost include files', '/usr/include'))
|
||||
opts.Add(PathOption('BOOST_LIBS', 'Search path for boost library files', '/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathVariable('BOOST_INCLUDES', 'Search path for boost include files', '/usr/include'))
|
||||
opts.Add(PathVariable('BOOST_LIBS', 'Search path for boost library files', '/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add('BOOST_TOOLKIT','Specify boost toolkit, e.g., gcc41.','',False)
|
||||
opts.Add('BOOST_ABI', 'Specify boost ABI, e.g., d.','',False)
|
||||
opts.Add('BOOST_VERSION','Specify boost version, e.g., 1_35.','',False)
|
||||
opts.Add(('FREETYPE_CONFIG', 'The path to the freetype-config executable.', 'freetype-config'))
|
||||
opts.Add(('XML2_CONFIG', 'The path to the xml2-config executable.', 'xml2-config'))
|
||||
opts.Add(PathOption('ICU_INCLUDES', 'Search path for ICU include files', '/usr/include'))
|
||||
opts.Add(PathOption('ICU_LIBS','Search path for ICU include files','/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathOption('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include'))
|
||||
opts.Add(PathOption('PNG_LIBS','Search path for libpng include files','/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathOption('JPEG_INCLUDES', 'Search path for libjpeg include files', '/usr/include'))
|
||||
opts.Add(PathOption('JPEG_LIBS', 'Search path for libjpeg library files', '/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathOption('TIFF_INCLUDES', 'Search path for libtiff include files', '/usr/include'))
|
||||
opts.Add(PathOption('TIFF_LIBS', 'Search path for libtiff library files', '/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathOption('PGSQL_INCLUDES', 'Search path for PostgreSQL include files', '/usr/include'))
|
||||
opts.Add(PathOption('PGSQL_LIBS', 'Search path for PostgreSQL library files', '/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathOption('PROJ_INCLUDES', 'Search path for PROJ.4 include files', '/usr/local/include'))
|
||||
opts.Add(PathOption('PROJ_LIBS', 'Search path for PROJ.4 library files', '/usr/local/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathOption('GDAL_INCLUDES', 'Search path for GDAL include files', '/usr/include'))
|
||||
opts.Add(PathOption('GDAL_LIBS', 'Search path for GDAL library files', '/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathOption('PYTHON','Python executable', sys.executable))
|
||||
opts.Add(ListOption('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster','gdal']))
|
||||
opts.Add(ListOption('BINDINGS','Language bindings to build','all',['python']))
|
||||
opts.Add(BoolOption('DEBUG', 'Compile a debug version of mapnik', 'False'))
|
||||
opts.Add(PathVariable('ICU_INCLUDES', 'Search path for ICU include files', '/usr/include'))
|
||||
opts.Add(PathVariable('ICU_LIBS','Search path for ICU include files','/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathVariable('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include'))
|
||||
opts.Add(PathVariable('PNG_LIBS','Search path for libpng include files','/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathVariable('JPEG_INCLUDES', 'Search path for libjpeg include files', '/usr/include'))
|
||||
opts.Add(PathVariable('JPEG_LIBS', 'Search path for libjpeg library files', '/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathVariable('TIFF_INCLUDES', 'Search path for libtiff include files', '/usr/include'))
|
||||
opts.Add(PathVariable('TIFF_LIBS', 'Search path for libtiff library files', '/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathVariable('PGSQL_INCLUDES', 'Search path for PostgreSQL include files', '/usr/include'))
|
||||
opts.Add(PathVariable('PGSQL_LIBS', 'Search path for PostgreSQL library files', '/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathVariable('PROJ_INCLUDES', 'Search path for PROJ.4 include files', '/usr/local/include'))
|
||||
opts.Add(PathVariable('PROJ_LIBS', 'Search path for PROJ.4 library files', '/usr/local/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathVariable('GDAL_INCLUDES', 'Search path for GDAL include files', '/usr/include'))
|
||||
opts.Add(PathVariable('GDAL_LIBS', 'Search path for GDAL library files', '/usr/' + LIBDIR_SCHEMA))
|
||||
opts.Add(PathVariable('PYTHON','Python executable', sys.executable))
|
||||
opts.Add(ListVariable('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster','gdal']))
|
||||
opts.Add(ListVariable('BINDINGS','Language bindings to build','all',['python']))
|
||||
opts.Add(BoolVariable('DEBUG', 'Compile a debug version of mapnik', 'False'))
|
||||
opts.Add('DESTDIR', 'The root directory to install into. Useful mainly for binary package building', '/')
|
||||
opts.Add(EnumOption('THREADING','Set threading support','multi', ['multi','single']))
|
||||
opts.Add(EnumOption('XMLPARSER','Set xml parser ','tinyxml', ['tinyxml','spirit','libxml2']))
|
||||
opts.Add(BoolOption('INTERNAL_LIBAGG', 'Use provided libagg', 'True'))
|
||||
opts.Add(EnumVariable('THREADING','Set threading support','multi', ['multi','single']))
|
||||
opts.Add(EnumVariable('XMLPARSER','Set xml parser ','tinyxml', ['tinyxml','spirit','libxml2']))
|
||||
opts.Add(BoolVariable('INTERNAL_LIBAGG', 'Use provided libagg', 'True'))
|
||||
|
||||
env = Environment(ENV=os.environ, options=opts)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
This copyright and license do not apply to any other software
|
||||
with which this software may have been included.
|
||||
|
||||
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
|
||||
SCons - a software construction tool
|
||||
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
"""SCons.Errors
|
||||
|
||||
This file contains the exception classes used to handle internal
|
||||
and user errors in SCons.
|
||||
|
||||
"""
|
||||
|
||||
__revision__ = "src/engine/SCons/Errors.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
|
||||
|
||||
class BuildError(Exception):
|
||||
def __init__(self, node=None, errstr="Unknown error", status=0,
|
||||
filename=None, executor=None, action=None, command=None,
|
||||
*args):
|
||||
self.node = node
|
||||
self.errstr = errstr
|
||||
self.status = status
|
||||
self.filename = filename
|
||||
self.executor = executor
|
||||
self.action = action
|
||||
self.command = command
|
||||
apply(Exception.__init__, (self,) + args)
|
||||
|
||||
class InternalError(Exception):
|
||||
pass
|
||||
|
||||
class UserError(Exception):
|
||||
pass
|
||||
|
||||
class StopError(Exception):
|
||||
pass
|
||||
|
||||
class EnvironmentError(Exception):
|
||||
pass
|
||||
|
||||
class ExplicitExit(Exception):
|
||||
def __init__(self, node=None, status=None, *args):
|
||||
self.node = node
|
||||
self.status = status
|
||||
apply(Exception.__init__, (self,) + args)
|
||||
|
||||
class TaskmasterException(Exception):
|
||||
def __init__(self, node=None, exc_info=(None, None, None), *args):
|
||||
self.node = node
|
||||
self.errstr = "Exception"
|
||||
self.exc_info = exc_info
|
||||
apply(Exception.__init__, (self,) + args)
|
|
@ -1,126 +0,0 @@
|
|||
"""SCons.Scanner.LaTeX
|
||||
|
||||
This module implements the dependency scanner for LaTeX code.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/LaTeX.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import os.path
|
||||
import string
|
||||
|
||||
import SCons.Scanner
|
||||
|
||||
def LaTeXScanner():
|
||||
"""Return a prototype Scanner instance for scanning LaTeX source files"""
|
||||
ds = LaTeX(name = "LaTeXScanner",
|
||||
suffixes = '$LATEXSUFFIXES',
|
||||
path_variable = 'TEXINPUTS',
|
||||
regex = '\\\\(include|includegraphics(?:\[[^\]]+\])?|input|bibliography|usepackage){([^}]*)}',
|
||||
recursive = 0)
|
||||
return ds
|
||||
|
||||
class LaTeX(SCons.Scanner.Classic):
|
||||
"""Class for scanning LaTeX files for included files.
|
||||
|
||||
Unlike most scanners, which use regular expressions that just
|
||||
return the included file name, this returns a tuple consisting
|
||||
of the keyword for the inclusion ("include", "includegraphics",
|
||||
"input", or "bibliography"), and then the file name itself.
|
||||
Based on a quick look at LaTeX documentation, it seems that we
|
||||
need a should append .tex suffix for the "include" keywords,
|
||||
append .tex if there is no extension for the "input" keyword,
|
||||
but leave the file name untouched for "includegraphics." For
|
||||
the "bibliography" keyword we need to add .bib if there is
|
||||
no extension. (This need to be revisited since if there
|
||||
is no extension for an :includegraphics" keyword latex will
|
||||
append .ps or .eps to find the file; while pdftex will use
|
||||
other extensions.)
|
||||
"""
|
||||
def latex_name(self, include):
|
||||
filename = include[1]
|
||||
if include[0] == 'input':
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
filename = filename + '.tex'
|
||||
if (include[0] == 'include'):
|
||||
filename = filename + '.tex'
|
||||
if include[0] == 'bibliography':
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
filename = filename + '.bib'
|
||||
if include[0] == 'usepackage':
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
filename = filename + '.sty'
|
||||
return filename
|
||||
def sort_key(self, include):
|
||||
return SCons.Node.FS._my_normcase(self.latex_name(include))
|
||||
def find_include(self, include, source_dir, path):
|
||||
i = SCons.Node.FS.find_file(self.latex_name(include),
|
||||
(source_dir,) + path)
|
||||
return i, include
|
||||
|
||||
def scan(self, node, path=()):
|
||||
#
|
||||
# Modify the default scan function to allow for the regular
|
||||
# expression to return a comma separated list of file names
|
||||
# as can be the case with the bibliography keyword.
|
||||
#
|
||||
# cache the includes list in node so we only scan it once:
|
||||
if node.includes != None:
|
||||
includes = node.includes
|
||||
else:
|
||||
includes = self.cre.findall(node.get_contents())
|
||||
node.includes = includes
|
||||
|
||||
# This is a hand-coded DSU (decorate-sort-undecorate, or
|
||||
# Schwartzian transform) pattern. The sort key is the raw name
|
||||
# of the file as specifed on the #include line (including the
|
||||
# " or <, since that may affect what file is found), which lets
|
||||
# us keep the sort order constant regardless of whether the file
|
||||
# is actually found in a Repository or locally.
|
||||
nodes = []
|
||||
source_dir = node.get_dir()
|
||||
for include in includes:
|
||||
#
|
||||
# Handle multiple filenames in include[1]
|
||||
#
|
||||
inc_list = string.split(include[1],',')
|
||||
for j in range(len(inc_list)):
|
||||
include_local = [include[0],inc_list[j]]
|
||||
n, i = self.find_include(include_local, source_dir, path)
|
||||
|
||||
if n is None:
|
||||
SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
|
||||
"No dependency generated for file: %s (included from: %s) -- file not found" % (i, node))
|
||||
else:
|
||||
sortkey = self.sort_key(include)
|
||||
nodes.append((sortkey, n))
|
||||
|
||||
nodes.sort()
|
||||
nodes = map(lambda pair: pair[1], nodes)
|
||||
return nodes
|
|
@ -1,135 +0,0 @@
|
|||
"""engine.SCons.Tool.f77
|
||||
|
||||
Tool-specific initialization for the generic Posix f77 Fortran compiler.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/f77.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import SCons.Defaults
|
||||
import SCons.Scanner.Fortran
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
import fortran
|
||||
|
||||
compilers = ['f77']
|
||||
|
||||
#
|
||||
F77Suffixes = ['.f77']
|
||||
F77PPSuffixes = []
|
||||
if SCons.Util.case_sensitive_suffixes('.f77', '.F77'):
|
||||
F77PPSuffixes.append('.F77')
|
||||
else:
|
||||
F77Suffixes.append('.F77')
|
||||
|
||||
#
|
||||
F77Scan = SCons.Scanner.Fortran.FortranScan("F77PATH")
|
||||
|
||||
for suffix in F77Suffixes + F77PPSuffixes:
|
||||
SCons.Tool.SourceFileScanner.add_scanner(suffix, F77Scan)
|
||||
del suffix
|
||||
|
||||
#
|
||||
fVLG = fortran.VariableListGenerator
|
||||
|
||||
F77Generator = fVLG('F77', 'FORTRAN', '_FORTRAND')
|
||||
F77FlagsGenerator = fVLG('F77FLAGS', 'FORTRANFLAGS')
|
||||
F77CommandGenerator = fVLG('F77COM', 'FORTRANCOM', '_F77COMD')
|
||||
F77CommandStrGenerator = fVLG('F77COMSTR', 'FORTRANCOMSTR', '_F77COMSTRD')
|
||||
F77PPCommandGenerator = fVLG('F77PPCOM', 'FORTRANPPCOM', '_F77PPCOMD')
|
||||
F77PPCommandStrGenerator = fVLG('F77PPCOMSTR', 'FORTRANPPCOMSTR', '_F77PPCOMSTRD')
|
||||
ShF77Generator = fVLG('SHF77', 'SHFORTRAN', 'F77', 'FORTRAN', '_FORTRAND')
|
||||
ShF77FlagsGenerator = fVLG('SHF77FLAGS', 'SHFORTRANFLAGS')
|
||||
ShF77CommandGenerator = fVLG('SHF77COM', 'SHFORTRANCOM', '_SHF77COMD')
|
||||
ShF77CommandStrGenerator = fVLG('SHF77COMSTR', 'SHFORTRANCOMSTR', '_SHF77COMSTRD')
|
||||
ShF77PPCommandGenerator = fVLG('SHF77PPCOM', 'SHFORTRANPPCOM', '_SHF77PPCOMD')
|
||||
ShF77PPCommandStrGenerator = fVLG('SHF77PPCOMSTR', 'SHFORTRANPPCOMSTR', '_SHF77PPCOMSTRD')
|
||||
|
||||
del fVLG
|
||||
|
||||
#
|
||||
F77Action = SCons.Action.Action('$_F77COMG ', '$_F77COMSTRG')
|
||||
F77PPAction = SCons.Action.Action('$_F77PPCOMG ', '$_F77PPCOMSTRG')
|
||||
ShF77Action = SCons.Action.Action('$_SHF77COMG ', '$_SHF77COMSTRG')
|
||||
ShF77PPAction = SCons.Action.Action('$_SHF77PPCOMG ', '$_SHF77PPCOMSTRG')
|
||||
|
||||
def add_to_env(env):
|
||||
"""Add Builders and construction variables for f77 to an Environment."""
|
||||
env.AppendUnique(FORTRANSUFFIXES = F77Suffixes + F77PPSuffixes)
|
||||
|
||||
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
|
||||
|
||||
for suffix in F77Suffixes:
|
||||
static_obj.add_action(suffix, F77Action)
|
||||
shared_obj.add_action(suffix, ShF77Action)
|
||||
static_obj.add_emitter(suffix, fortran.FortranEmitter)
|
||||
shared_obj.add_emitter(suffix, fortran.ShFortranEmitter)
|
||||
|
||||
for suffix in F77PPSuffixes:
|
||||
static_obj.add_action(suffix, F77PPAction)
|
||||
shared_obj.add_action(suffix, ShF77PPAction)
|
||||
static_obj.add_emitter(suffix, fortran.FortranEmitter)
|
||||
shared_obj.add_emitter(suffix, fortran.ShFortranEmitter)
|
||||
|
||||
env['_F77G'] = F77Generator
|
||||
env['_F77FLAGSG'] = F77FlagsGenerator
|
||||
env['_F77COMG'] = F77CommandGenerator
|
||||
env['_F77PPCOMG'] = F77PPCommandGenerator
|
||||
env['_F77COMSTRG'] = F77CommandStrGenerator
|
||||
env['_F77PPCOMSTRG'] = F77PPCommandStrGenerator
|
||||
|
||||
env['_SHF77G'] = ShF77Generator
|
||||
env['_SHF77FLAGSG'] = ShF77FlagsGenerator
|
||||
env['_SHF77COMG'] = ShF77CommandGenerator
|
||||
env['_SHF77PPCOMG'] = ShF77PPCommandGenerator
|
||||
env['_SHF77COMSTRG'] = ShF77CommandStrGenerator
|
||||
env['_SHF77PPCOMSTRG'] = ShF77PPCommandStrGenerator
|
||||
|
||||
env['_F77INCFLAGS'] = '$( ${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||
|
||||
env['_F77COMD'] = '$_F77G -o $TARGET -c $_F77FLAGSG $_F77INCFLAGS $SOURCES'
|
||||
env['_F77PPCOMD'] = '$_F77G -o $TARGET -c $_F77FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS $SOURCES'
|
||||
env['_SHF77COMD'] = '$_SHF77G -o $TARGET -c $_SHF77FLAGSG $_F77INCFLAGS $SOURCES'
|
||||
env['_SHF77PPCOMD'] = '$_SHF77G -o $TARGET -c $_SHF77FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F77INCFLAGS $SOURCES'
|
||||
|
||||
def generate(env):
|
||||
fortran.add_to_env(env)
|
||||
|
||||
import f90
|
||||
import f95
|
||||
f90.add_to_env(env)
|
||||
f95.add_to_env(env)
|
||||
|
||||
add_to_env(env)
|
||||
|
||||
env['_FORTRAND'] = env.Detect(compilers) or 'f77'
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
|
@ -1,132 +0,0 @@
|
|||
"""engine.SCons.Tool.f90
|
||||
|
||||
Tool-specific initialization for the generic Posix f90 Fortran compiler.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/f90.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import SCons.Defaults
|
||||
import SCons.Scanner.Fortran
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
import fortran
|
||||
|
||||
compilers = ['f90']
|
||||
|
||||
#
|
||||
F90Suffixes = ['.f90']
|
||||
F90PPSuffixes = []
|
||||
if SCons.Util.case_sensitive_suffixes('.f90', '.F90'):
|
||||
F90PPSuffixes.append('.F90')
|
||||
else:
|
||||
F90Suffixes.append('.F90')
|
||||
|
||||
#
|
||||
F90Scan = SCons.Scanner.Fortran.FortranScan("F90PATH")
|
||||
|
||||
for suffix in F90Suffixes + F90PPSuffixes:
|
||||
SCons.Tool.SourceFileScanner.add_scanner(suffix, F90Scan)
|
||||
del suffix
|
||||
|
||||
#
|
||||
fVLG = fortran.VariableListGenerator
|
||||
|
||||
F90Generator = fVLG('F90', 'FORTRAN', '_FORTRAND')
|
||||
F90FlagsGenerator = fVLG('F90FLAGS', 'FORTRANFLAGS')
|
||||
F90CommandGenerator = fVLG('F90COM', 'FORTRANCOM', '_F90COMD')
|
||||
F90CommandStrGenerator = fVLG('F90COMSTR', 'FORTRANCOMSTR', '_F90COMSTRD')
|
||||
F90PPCommandGenerator = fVLG('F90PPCOM', 'FORTRANPPCOM', '_F90PPCOMD')
|
||||
F90PPCommandStrGenerator = fVLG('F90PPCOMSTR', 'FORTRANPPCOMSTR', '_F90PPCOMSTRD')
|
||||
ShF90Generator = fVLG('SHF90', 'SHFORTRAN', 'F90', 'FORTRAN', '_FORTRAND')
|
||||
ShF90FlagsGenerator = fVLG('SHF90FLAGS', 'SHFORTRANFLAGS')
|
||||
ShF90CommandGenerator = fVLG('SHF90COM', 'SHFORTRANCOM', '_SHF90COMD')
|
||||
ShF90CommandStrGenerator = fVLG('SHF90COMSTR', 'SHFORTRANCOMSTR', '_SHF90COMSTRD')
|
||||
ShF90PPCommandGenerator = fVLG('SHF90PPCOM', 'SHFORTRANPPCOM', '_SHF90PPCOMD')
|
||||
ShF90PPCommandStrGenerator = fVLG('SHF90PPCOMSTR', 'SHFORTRANPPCOMSTR', '_SHF90PPCOMSTRD')
|
||||
|
||||
del fVLG
|
||||
|
||||
#
|
||||
F90Action = SCons.Action.Action('$_F90COMG ', '$_F90COMSTRG')
|
||||
F90PPAction = SCons.Action.Action('$_F90PPCOMG ', '$_F90PPCOMSTRG')
|
||||
ShF90Action = SCons.Action.Action('$_SHF90COMG ', '$_SHF90COMSTRG')
|
||||
ShF90PPAction = SCons.Action.Action('$_SHF90PPCOMG ', '$_SHF90PPCOMSTRG')
|
||||
|
||||
def add_to_env(env):
|
||||
"""Add Builders and construction variables for f90 to an Environment."""
|
||||
env.AppendUnique(FORTRANSUFFIXES = F90Suffixes + F90PPSuffixes)
|
||||
|
||||
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
|
||||
|
||||
for suffix in F90Suffixes:
|
||||
static_obj.add_action(suffix, F90Action)
|
||||
shared_obj.add_action(suffix, ShF90Action)
|
||||
static_obj.add_emitter(suffix, fortran.FortranEmitter)
|
||||
shared_obj.add_emitter(suffix, fortran.ShFortranEmitter)
|
||||
|
||||
for suffix in F90PPSuffixes:
|
||||
static_obj.add_action(suffix, F90PPAction)
|
||||
shared_obj.add_action(suffix, ShF90PPAction)
|
||||
static_obj.add_emitter(suffix, fortran.FortranEmitter)
|
||||
shared_obj.add_emitter(suffix, fortran.ShFortranEmitter)
|
||||
|
||||
env['_F90G'] = F90Generator
|
||||
env['_F90FLAGSG'] = F90FlagsGenerator
|
||||
env['_F90COMG'] = F90CommandGenerator
|
||||
env['_F90COMSTRG'] = F90CommandStrGenerator
|
||||
env['_F90PPCOMG'] = F90PPCommandGenerator
|
||||
env['_F90PPCOMSTRG'] = F90PPCommandStrGenerator
|
||||
|
||||
env['_SHF90G'] = ShF90Generator
|
||||
env['_SHF90FLAGSG'] = ShF90FlagsGenerator
|
||||
env['_SHF90COMG'] = ShF90CommandGenerator
|
||||
env['_SHF90COMSTRG'] = ShF90CommandStrGenerator
|
||||
env['_SHF90PPCOMG'] = ShF90PPCommandGenerator
|
||||
env['_SHF90PPCOMSTRG'] = ShF90PPCommandStrGenerator
|
||||
|
||||
env['_F90INCFLAGS'] = '$( ${_concat(INCPREFIX, F90PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||
env['_F90COMD'] = '$_F90G -o $TARGET -c $_F90FLAGSG $_F90INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||
env['_F90PPCOMD'] = '$_F90G -o $TARGET -c $_F90FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F90INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||
env['_SHF90COMD'] = '$_SHF90G -o $TARGET -c $_SHF90FLAGSG $_F90INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||
env['_SHF90PPCOMD'] = '$_SHF90G -o $TARGET -c $_SHF90FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F90INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||
|
||||
def generate(env):
|
||||
fortran.add_to_env(env)
|
||||
|
||||
import f77
|
||||
f77.add_to_env(env)
|
||||
|
||||
add_to_env(env)
|
||||
|
||||
env['_FORTRAND'] = env.Detect(compilers) or 'f90'
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
|
@ -1,135 +0,0 @@
|
|||
"""engine.SCons.Tool.f95
|
||||
|
||||
Tool-specific initialization for the generic Posix f95 Fortran compiler.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/f95.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import SCons.Defaults
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
import fortran
|
||||
|
||||
compilers = ['f95']
|
||||
|
||||
#
|
||||
F95Suffixes = ['.f95']
|
||||
F95PPSuffixes = []
|
||||
if SCons.Util.case_sensitive_suffixes('.f95', '.F95'):
|
||||
F95PPSuffixes.append('.F95')
|
||||
else:
|
||||
F95Suffixes.append('.F95')
|
||||
|
||||
#
|
||||
F95Scan = SCons.Scanner.Fortran.FortranScan("F95PATH")
|
||||
|
||||
for suffix in F95Suffixes + F95PPSuffixes:
|
||||
SCons.Tool.SourceFileScanner.add_scanner(suffix, F95Scan)
|
||||
del suffix
|
||||
|
||||
#
|
||||
fVLG = fortran.VariableListGenerator
|
||||
|
||||
F95Generator = fVLG('F95', 'FORTRAN', '_FORTRAND')
|
||||
F95FlagsGenerator = fVLG('F95FLAGS', 'FORTRANFLAGS')
|
||||
F95CommandGenerator = fVLG('F95COM', 'FORTRANCOM', '_F95COMD')
|
||||
F95CommandStrGenerator = fVLG('F95COMSTR', 'FORTRANCOMSTR', '_F95COMSTRD')
|
||||
F95PPCommandGenerator = fVLG('F95PPCOM', 'FORTRANPPCOM', '_F95PPCOMD')
|
||||
F95PPCommandStrGenerator = fVLG('F95PPCOMSTR', 'FORTRANPPCOMSTR', '_F95PPCOMSTRD')
|
||||
ShF95Generator = fVLG('SHF95', 'SHFORTRAN', 'F95', 'FORTRAN', '_FORTRAND')
|
||||
ShF95FlagsGenerator = fVLG('SHF95FLAGS', 'SHFORTRANFLAGS')
|
||||
ShF95CommandGenerator = fVLG('SHF95COM', 'SHFORTRANCOM', '_SHF95COMD')
|
||||
ShF95CommandStrGenerator = fVLG('SHF95COMSTR', 'SHFORTRANCOMSTR', '_SHF95COMSTRD')
|
||||
ShF95PPCommandGenerator = fVLG('SHF95PPCOM', 'SHFORTRANPPCOM', '_SHF95PPCOMD')
|
||||
ShF95PPCommandStrGenerator = fVLG('SHF95PPCOMSTR', 'SHFORTRANPPCOMSTR', '_SHF95PPCOMSTRD')
|
||||
|
||||
del fVLG
|
||||
|
||||
#
|
||||
F95Action = SCons.Action.Action('$_F95COMG ', '$_F95COMSTRG')
|
||||
F95PPAction = SCons.Action.Action('$_F95PPCOMG ', '$_F95PPCOMSTRG')
|
||||
ShF95Action = SCons.Action.Action('$_SHF95COMG ', '$_SHF95COMSTRG')
|
||||
ShF95PPAction = SCons.Action.Action('$_SHF95PPCOMG ', '$_SHF95PPCOMSTRG')
|
||||
|
||||
def add_to_env(env):
|
||||
"""Add Builders and construction variables for f95 to an Environment."""
|
||||
env.AppendUnique(FORTRANSUFFIXES = F95Suffixes + F95PPSuffixes)
|
||||
|
||||
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
|
||||
|
||||
for suffix in F95Suffixes:
|
||||
static_obj.add_action(suffix, F95Action)
|
||||
shared_obj.add_action(suffix, ShF95Action)
|
||||
static_obj.add_emitter(suffix, fortran.FortranEmitter)
|
||||
shared_obj.add_emitter(suffix, fortran.ShFortranEmitter)
|
||||
|
||||
for suffix in F95PPSuffixes:
|
||||
static_obj.add_action(suffix, F95PPAction)
|
||||
shared_obj.add_action(suffix, ShF95PPAction)
|
||||
static_obj.add_emitter(suffix, fortran.FortranEmitter)
|
||||
shared_obj.add_emitter(suffix, fortran.ShFortranEmitter)
|
||||
|
||||
env['_F95G'] = F95Generator
|
||||
env['_F95FLAGSG'] = F95FlagsGenerator
|
||||
env['_F95COMG'] = F95CommandGenerator
|
||||
env['_F95COMSTRG'] = F95CommandStrGenerator
|
||||
env['_F95PPCOMG'] = F95PPCommandGenerator
|
||||
env['_F95PPCOMSTRG'] = F95PPCommandStrGenerator
|
||||
|
||||
env['_SHF95G'] = ShF95Generator
|
||||
env['_SHF95FLAGSG'] = ShF95FlagsGenerator
|
||||
env['_SHF95COMG'] = ShF95CommandGenerator
|
||||
env['_SHF95COMSTRG'] = ShF95CommandStrGenerator
|
||||
env['_SHF95PPCOMG'] = ShF95PPCommandGenerator
|
||||
env['_SHF95PPCOMSTRG'] = ShF95PPCommandStrGenerator
|
||||
|
||||
env['_F95INCFLAGS'] = '$( ${_concat(INCPREFIX, F95PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||
|
||||
env['_F95COMD'] = '$_F95G -o $TARGET -c $_F95FLAGSG $_F95INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||
env['_F95PPCOMD'] = '$_F95G -o $TARGET -c $_F95FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F95INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||
env['_SHF95COMD'] = '$_SHF95G -o $TARGET -c $_SHF95FLAGSG $_F95INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||
env['_SHF95PPCOMD'] = '$_SHF95G -o $TARGET -c $_SHF95FLAGSG $CPPFLAGS $_CPPDEFFLAGS $_F95INCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||
|
||||
def generate(env):
|
||||
fortran.add_to_env(env)
|
||||
|
||||
import f77
|
||||
f77.add_to_env(env)
|
||||
|
||||
import f90
|
||||
f90.add_to_env(env)
|
||||
|
||||
add_to_env(env)
|
||||
|
||||
env['_FORTRAND'] = env.Detect(compilers) or 'f95'
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
|
@ -1,186 +0,0 @@
|
|||
"""SCons.Tool.fortran
|
||||
|
||||
Tool-specific initialization for a generic Posix f77/f90 Fortran compiler.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/fortran.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import re
|
||||
import string
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Defaults
|
||||
import SCons.Scanner.Fortran
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
|
||||
compilers = ['f95', 'f90', 'f77']
|
||||
|
||||
#
|
||||
# Not yet sure how to deal with fortran pre-processor functions.
|
||||
# Different compilers do this differently in modern fortran. Some still
|
||||
# rely on the c pre-processor, some (like cvf, ivf) have their own
|
||||
# pre-processor technology and use intermediary suffixes (.i90)
|
||||
#
|
||||
FortranSuffixes = [".f", ".for", ".ftn", ]
|
||||
FortranPPSuffixes = ['.fpp', '.FPP']
|
||||
upper_case = [".F", ".FOR", ".FTN"]
|
||||
if SCons.Util.case_sensitive_suffixes('.f', '.F'):
|
||||
FortranPPSuffixes.extend(upper_case)
|
||||
else:
|
||||
FortranSuffixes.extend(upper_case)
|
||||
|
||||
#
|
||||
FortranScan = SCons.Scanner.Fortran.FortranScan("FORTRANPATH")
|
||||
|
||||
for suffix in FortranSuffixes + FortranPPSuffixes:
|
||||
SCons.Tool.SourceFileScanner.add_scanner(suffix, FortranScan)
|
||||
del suffix
|
||||
|
||||
#
|
||||
def _fortranEmitter(target, source, env):
|
||||
node = source[0].rfile()
|
||||
if not node.exists() and not node.is_derived():
|
||||
print "Could not locate " + str(node.name)
|
||||
return ([], [])
|
||||
mod_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(\w+)"""
|
||||
cre = re.compile(mod_regex,re.M)
|
||||
# Retrieve all USE'd module names
|
||||
modules = cre.findall(node.get_contents())
|
||||
# Remove unique items from the list
|
||||
modules = SCons.Util.unique(modules)
|
||||
# Convert module name to a .mod filename
|
||||
suffix = env.subst('$FORTRANMODSUFFIX', target=target, source=source)
|
||||
moddir = env.subst('$FORTRANMODDIR', target=target, source=source)
|
||||
modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
|
||||
for m in modules:
|
||||
target.append(env.fs.File(m, moddir))
|
||||
return (target, source)
|
||||
|
||||
def FortranEmitter(target, source, env):
|
||||
target, source = _fortranEmitter(target, source, env)
|
||||
return SCons.Defaults.StaticObjectEmitter(target, source, env)
|
||||
|
||||
def ShFortranEmitter(target, source, env):
|
||||
target, source = _fortranEmitter(target, source, env)
|
||||
return SCons.Defaults.SharedObjectEmitter(target, source, env)
|
||||
|
||||
class VariableListGenerator:
|
||||
def __init__(self, *variablelist):
|
||||
self.variablelist = variablelist
|
||||
def __call__(self, env, target, source, for_signature=0):
|
||||
for v in self.variablelist:
|
||||
try: return env[v]
|
||||
except KeyError: pass
|
||||
return ''
|
||||
|
||||
#
|
||||
FortranGenerator = VariableListGenerator('FORTRAN', 'F77', '_FORTRAND')
|
||||
FortranFlagsGenerator = VariableListGenerator('FORTRANFLAGS', 'F77FLAGS')
|
||||
FortranCommandGenerator = VariableListGenerator('FORTRANCOM', 'F77COM', '_FORTRANCOMD')
|
||||
FortranCommandStrGenerator = VariableListGenerator('FORTRANCOMSTR', 'F77COMSTR', '_FORTRANCOMSTRD')
|
||||
FortranPPCommandGenerator = VariableListGenerator('FORTRANPPCOM', 'F77PPCOM', '_FORTRANPPCOMD')
|
||||
FortranPPCommandStrGenerator = VariableListGenerator('FORTRANPPCOMSTR', 'F77PPCOMSTR', '_FORTRANPPCOMSTRD')
|
||||
ShFortranGenerator = VariableListGenerator('SHFORTRAN', 'SHF77', 'FORTRAN', 'F77', '_FORTRAND')
|
||||
ShFortranFlagsGenerator = VariableListGenerator('SHFORTRANFLAGS', 'SHF77FLAGS')
|
||||
ShFortranCommandGenerator = VariableListGenerator('SHFORTRANCOM', 'SHF77COM', '_SHFORTRANCOMD')
|
||||
ShFortranCommandStrGenerator = VariableListGenerator('SHFORTRANCOMSTR', 'SHF77COMSTR', '_SHFORTRANCOMSTRD')
|
||||
ShFortranPPCommandGenerator = VariableListGenerator('SHFORTRANPPCOM', 'SHF77PPCOM', '_SHFORTRANPPCOMD')
|
||||
ShFortranPPCommandStrGenerator = VariableListGenerator('SHFORTRANPPCOMSTR', 'SHF77PPCOMSTR', '_SHFORTRANPPCOMSTRD')
|
||||
|
||||
#
|
||||
FortranAction = SCons.Action.Action('$_FORTRANCOMG ', '$_FORTRANCOMSTRG')
|
||||
FortranPPAction = SCons.Action.Action('$_FORTRANPPCOMG ', '$_FORTRANPPCOMSTRG')
|
||||
ShFortranAction = SCons.Action.Action('$_SHFORTRANCOMG ', '$_SHFORTRANCOMSTRG')
|
||||
ShFortranPPAction = SCons.Action.Action('$_SHFORTRANPPCOMG ', '$_SHFORTRANPPCOMSTRG')
|
||||
|
||||
def add_to_env(env):
|
||||
"""Add Builders and construction variables for Fortran to an Environment."""
|
||||
|
||||
env['_FORTRANG'] = FortranGenerator
|
||||
env['_FORTRANFLAGSG'] = FortranFlagsGenerator
|
||||
env['_FORTRANCOMG'] = FortranCommandGenerator
|
||||
env['_FORTRANCOMSTRG'] = FortranCommandStrGenerator
|
||||
env['_FORTRANPPCOMG'] = FortranPPCommandGenerator
|
||||
env['_FORTRANPPCOMSTRG'] = FortranPPCommandStrGenerator
|
||||
|
||||
env['_SHFORTRANG'] = ShFortranGenerator
|
||||
env['_SHFORTRANFLAGSG'] = ShFortranFlagsGenerator
|
||||
env['_SHFORTRANCOMG'] = ShFortranCommandGenerator
|
||||
env['_SHFORTRANCOMSTRG'] = ShFortranCommandStrGenerator
|
||||
env['_SHFORTRANPPCOMG'] = ShFortranPPCommandGenerator
|
||||
env['_SHFORTRANPPCOMSTRG'] = ShFortranPPCommandStrGenerator
|
||||
|
||||
env['_FORTRANINCFLAGS'] = '$( ${_concat(INCPREFIX, FORTRANPATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||
|
||||
env['FORTRANMODPREFIX'] = '' # like $LIBPREFIX
|
||||
env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX
|
||||
|
||||
env['FORTRANMODDIR'] = '' # where the compiler should place .mod files
|
||||
env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX
|
||||
env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX
|
||||
env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs)} $)'
|
||||
|
||||
env.AppendUnique(FORTRANSUFFIXES = FortranSuffixes + FortranPPSuffixes)
|
||||
|
||||
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
|
||||
|
||||
for suffix in FortranSuffixes:
|
||||
static_obj.add_action(suffix, FortranAction)
|
||||
shared_obj.add_action(suffix, ShFortranAction)
|
||||
static_obj.add_emitter(suffix, FortranEmitter)
|
||||
shared_obj.add_emitter(suffix, ShFortranEmitter)
|
||||
|
||||
for suffix in FortranPPSuffixes:
|
||||
static_obj.add_action(suffix, FortranPPAction)
|
||||
shared_obj.add_action(suffix, ShFortranPPAction)
|
||||
static_obj.add_emitter(suffix, FortranEmitter)
|
||||
shared_obj.add_emitter(suffix, ShFortranEmitter)
|
||||
|
||||
env['_FORTRANCOMD'] = '$_FORTRANG -o $TARGET -c $_FORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||
env['_FORTRANPPCOMD'] = '$_FORTRANG -o $TARGET -c $_FORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||
env['_SHFORTRANCOMD'] = '$_SHFORTRANG -o $TARGET -c $_SHFORTRANFLAGSG $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||
env['_SHFORTRANPPCOMD'] = '$_SHFORTRANG -o $TARGET -c $_SHFORTRANFLAGSG $CPPFLAGS $_CPPDEFFLAGS $_FORTRANINCFLAGS $_FORTRANMODFLAG $SOURCES'
|
||||
|
||||
def generate(env):
|
||||
import f77
|
||||
import f90
|
||||
import f95
|
||||
f77.add_to_env(env)
|
||||
f90.add_to_env(env)
|
||||
f95.add_to_env(env)
|
||||
|
||||
add_to_env(env)
|
||||
|
||||
env['_FORTRAND'] = env.Detect(compilers) or 'f77'
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
|
@ -1,268 +0,0 @@
|
|||
"""SCons.Tool.tex
|
||||
|
||||
Tool-specific initialization for TeX.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/tex.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import os.path
|
||||
import re
|
||||
import string
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Node
|
||||
import SCons.Node.FS
|
||||
import SCons.Util
|
||||
|
||||
warning_rerun_re = re.compile("^LaTeX Warning:.*Rerun", re.MULTILINE)
|
||||
|
||||
rerun_citations_str = "^LaTeX Warning:.*\n.*Rerun to get citations correct"
|
||||
rerun_citations_re = re.compile(rerun_citations_str, re.MULTILINE)
|
||||
|
||||
undefined_references_str = '(^LaTeX Warning:.*undefined references)|(^Package \w+ Warning:.*undefined citations)'
|
||||
undefined_references_re = re.compile(undefined_references_str, re.MULTILINE)
|
||||
|
||||
openout_aux_re = re.compile(r"\\openout.*`(.*\.aux)'")
|
||||
openout_re = re.compile(r"\\openout.*`(.*)'")
|
||||
|
||||
makeindex_re = re.compile(r"^[^%]*\\makeindex", re.MULTILINE)
|
||||
tableofcontents_re = re.compile(r"^[^%]*\\tableofcontents", re.MULTILINE)
|
||||
bibliography_re = re.compile(r"^[^%]*\\bibliography", re.MULTILINE)
|
||||
|
||||
# An Action sufficient to build any generic tex file.
|
||||
TeXAction = None
|
||||
|
||||
# An action to build a latex file. This action might be needed more
|
||||
# than once if we are dealing with labels and bibtex.
|
||||
LaTeXAction = None
|
||||
|
||||
# An action to run BibTeX on a file.
|
||||
BibTeXAction = None
|
||||
|
||||
# An action to run MakeIndex on a file.
|
||||
MakeIndexAction = None
|
||||
|
||||
def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None):
|
||||
"""A builder for LaTeX files that checks the output in the aux file
|
||||
and decides how many times to use LaTeXAction, and BibTeXAction."""
|
||||
|
||||
basename = SCons.Util.splitext(str(source[0]))[0]
|
||||
basedir = os.path.split(str(source[0]))[0]
|
||||
|
||||
# Notice that all the filenames are not prefixed with the basedir.
|
||||
# That's because the *COM variables have the cd command in the prolog.
|
||||
|
||||
bblfilename = basename + '.bbl'
|
||||
bblContents = ""
|
||||
if os.path.exists(bblfilename):
|
||||
bblContents = open(bblfilename, "rb").read()
|
||||
|
||||
idxfilename = basename + '.idx'
|
||||
idxContents = ""
|
||||
if os.path.exists(idxfilename):
|
||||
idxContents = open(idxfilename, "rb").read()
|
||||
|
||||
tocfilename = basename + '.toc'
|
||||
tocContents = ""
|
||||
if os.path.exists(tocfilename):
|
||||
tocContents = open(tocfilename, "rb").read()
|
||||
|
||||
# Run LaTeX once to generate a new aux file.
|
||||
XXXLaTeXAction(target, source, env)
|
||||
|
||||
# Decide if various things need to be run, or run again. We check
|
||||
# for the existence of files before opening them--even ones like the
|
||||
# aux file that TeX always creates--to make it possible to write tests
|
||||
# with stubs that don't necessarily generate all of the same files.
|
||||
|
||||
# Read the log file to find all .aux files
|
||||
logfilename = basename + '.log'
|
||||
auxfiles = []
|
||||
if os.path.exists(logfilename):
|
||||
content = open(logfilename, "rb").read()
|
||||
auxfiles = openout_aux_re.findall(content)
|
||||
|
||||
# Now decide if bibtex will need to be run.
|
||||
for auxfilename in auxfiles:
|
||||
if os.path.exists(os.path.join(basedir, auxfilename)):
|
||||
content = open(os.path.join(basedir, auxfilename), "rb").read()
|
||||
if string.find(content, "bibdata") != -1:
|
||||
bibfile = env.fs.File(basename)
|
||||
BibTeXAction(bibfile, bibfile, env)
|
||||
break
|
||||
|
||||
must_rerun_latex = 0
|
||||
# Now decide if latex will need to be run again due to table of contents.
|
||||
if os.path.exists(tocfilename) and tocContents != open(tocfilename, "rb").read():
|
||||
must_rerun_latex = 1
|
||||
|
||||
# Now decide if latex will need to be run again due to bibliography.
|
||||
if os.path.exists(bblfilename) and bblContents != open(bblfilename, "rb").read():
|
||||
must_rerun_latex = 1
|
||||
|
||||
# Now decide if latex will need to be run again due to index.
|
||||
if os.path.exists(idxfilename) and idxContents != open(idxfilename, "rb").read():
|
||||
# We must run makeindex
|
||||
idxfile = env.fs.File(basename)
|
||||
MakeIndexAction(idxfile, idxfile, env)
|
||||
must_rerun_latex = 1
|
||||
|
||||
if must_rerun_latex == 1:
|
||||
XXXLaTeXAction(target, source, env)
|
||||
|
||||
# Now decide if latex needs to be run yet again to resolve warnings.
|
||||
logfilename = basename + '.log'
|
||||
for _ in range(int(env.subst('$LATEXRETRIES'))):
|
||||
if not os.path.exists(logfilename):
|
||||
break
|
||||
content = open(logfilename, "rb").read()
|
||||
if not warning_rerun_re.search(content) and \
|
||||
not rerun_citations_re.search(content) and \
|
||||
not undefined_references_re.search(content):
|
||||
break
|
||||
XXXLaTeXAction(target, source, env)
|
||||
return 0
|
||||
|
||||
def LaTeXAuxAction(target = None, source= None, env=None):
|
||||
InternalLaTeXAuxAction( LaTeXAction, target, source, env )
|
||||
|
||||
LaTeX_re = re.compile("\\\\document(style|class)")
|
||||
|
||||
def is_LaTeX(flist):
|
||||
# Scan a file list to decide if it's TeX- or LaTeX-flavored.
|
||||
for f in flist:
|
||||
content = f.get_contents()
|
||||
if LaTeX_re.search(content):
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def TeXLaTeXFunction(target = None, source= None, env=None):
|
||||
"""A builder for TeX and LaTeX that scans the source file to
|
||||
decide the "flavor" of the source and then executes the appropriate
|
||||
program."""
|
||||
if is_LaTeX(source):
|
||||
LaTeXAuxAction(target,source,env)
|
||||
else:
|
||||
TeXAction(target,source,env)
|
||||
return 0
|
||||
|
||||
def tex_emitter(target, source, env):
|
||||
base = SCons.Util.splitext(str(source[0]))[0]
|
||||
target.append(base + '.aux')
|
||||
env.Precious(base + '.aux')
|
||||
target.append(base + '.log')
|
||||
for f in source:
|
||||
content = f.get_contents()
|
||||
if tableofcontents_re.search(content):
|
||||
target.append(base + '.toc')
|
||||
env.Precious(base + '.toc')
|
||||
if makeindex_re.search(content):
|
||||
target.append(base + '.ilg')
|
||||
target.append(base + '.ind')
|
||||
target.append(base + '.idx')
|
||||
env.Precious(base + '.idx')
|
||||
if bibliography_re.search(content):
|
||||
target.append(base + '.bbl')
|
||||
env.Precious(base + '.bbl')
|
||||
target.append(base + '.blg')
|
||||
|
||||
# read log file to get all output file (include .aux files)
|
||||
logfilename = base + '.log'
|
||||
dir, base_nodir = os.path.split(base)
|
||||
if os.path.exists(logfilename):
|
||||
content = open(logfilename, "rb").read()
|
||||
out_files = openout_re.findall(content)
|
||||
out_files = filter(lambda f, b=base_nodir+'.aux': f != b, out_files)
|
||||
if dir != '':
|
||||
out_files = map(lambda f, d=dir: d+os.sep+f, out_files)
|
||||
target.extend(out_files)
|
||||
for f in out_files:
|
||||
env.Precious( f )
|
||||
|
||||
return (target, source)
|
||||
|
||||
TeXLaTeXAction = None
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for TeX to an Environment."""
|
||||
|
||||
# A generic tex file Action, sufficient for all tex files.
|
||||
global TeXAction
|
||||
if TeXAction is None:
|
||||
TeXAction = SCons.Action.Action("$TEXCOM", "$TEXCOMSTR")
|
||||
|
||||
# An Action to build a latex file. This might be needed more
|
||||
# than once if we are dealing with labels and bibtex.
|
||||
global LaTeXAction
|
||||
if LaTeXAction is None:
|
||||
LaTeXAction = SCons.Action.Action("$LATEXCOM", "$LATEXCOMSTR")
|
||||
|
||||
# Define an action to run BibTeX on a file.
|
||||
global BibTeXAction
|
||||
if BibTeXAction is None:
|
||||
BibTeXAction = SCons.Action.Action("$BIBTEXCOM", "$BIBTEXCOMSTR")
|
||||
|
||||
# Define an action to run MakeIndex on a file.
|
||||
global MakeIndexAction
|
||||
if MakeIndexAction is None:
|
||||
MakeIndexAction = SCons.Action.Action("$MAKEINDEXCOM", "$MAKEINDEXCOMSTR")
|
||||
|
||||
global TeXLaTeXAction
|
||||
if TeXLaTeXAction is None:
|
||||
TeXLaTeXAction = SCons.Action.Action(TeXLaTeXFunction, strfunction=None)
|
||||
|
||||
import dvi
|
||||
dvi.generate(env)
|
||||
|
||||
bld = env['BUILDERS']['DVI']
|
||||
bld.add_action('.tex', TeXLaTeXAction)
|
||||
bld.add_emitter('.tex', tex_emitter)
|
||||
|
||||
env['TEX'] = 'tex'
|
||||
env['TEXFLAGS'] = SCons.Util.CLVar('')
|
||||
env['TEXCOM'] = 'cd ${TARGET.dir} && $TEX $TEXFLAGS ${SOURCE.file}'
|
||||
|
||||
# Duplicate from latex.py. If latex.py goes away, then this is still OK.
|
||||
env['LATEX'] = 'latex'
|
||||
env['LATEXFLAGS'] = SCons.Util.CLVar('')
|
||||
env['LATEXCOM'] = 'cd ${TARGET.dir} && $LATEX $LATEXFLAGS ${SOURCE.file}'
|
||||
env['LATEXRETRIES'] = 3
|
||||
|
||||
env['BIBTEX'] = 'bibtex'
|
||||
env['BIBTEXFLAGS'] = SCons.Util.CLVar('')
|
||||
env['BIBTEXCOM'] = 'cd ${TARGET.dir} && $BIBTEX $BIBTEXFLAGS ${SOURCE.filebase}'
|
||||
|
||||
env['MAKEINDEX'] = 'makeindex'
|
||||
env['MAKEINDEXFLAGS'] = SCons.Util.CLVar('')
|
||||
env['MAKEINDEXCOM'] = 'cd ${TARGET.dir} && $MAKEINDEX $MAKEINDEXFLAGS ${SOURCE.file}'
|
||||
|
||||
def exists(env):
|
||||
return env.Detect('tex')
|
|
@ -1,13 +0,0 @@
|
|||
Metadata-Version: 1.0
|
||||
Name: scons
|
||||
Version: 0.97.0d20071212
|
||||
Summary: Open Source next-generation build tool.
|
||||
Improved, cross-platform substitute for the classic Make
|
||||
utility. In short, SCons is an easier, more reliable
|
||||
and faster way to build software.
|
||||
Home-page: http://www.scons.org/
|
||||
Author: Steven Knight
|
||||
Author-email: knight@baldmt.com
|
||||
License: UNKNOWN
|
||||
Description: UNKNOWN
|
||||
Platform: UNKNOWN
|
|
@ -30,9 +30,9 @@ other modules:
|
|||
a pre-substitution command for debugging purposes.
|
||||
|
||||
get_contents()
|
||||
Fetches the "contents" of an Action for signature calculation.
|
||||
This is what gets MD5 checksumm'ed to decide if a target needs
|
||||
to be rebuilt because its action changed.
|
||||
Fetches the "contents" of an Action for signature calculation
|
||||
plus the varlist. This is what gets MD5 checksummed to decide
|
||||
if a target needs to be rebuilt because its action changed.
|
||||
|
||||
genstring()
|
||||
Returns a string representation of the Action *without*
|
||||
|
@ -57,6 +57,10 @@ this module:
|
|||
pre-substitution representations, and *then* execute an action
|
||||
without worrying about the specific Actions involved.
|
||||
|
||||
get_presig()
|
||||
Fetches the "contents" of a subclass for signature calculation.
|
||||
The varlist is added to this to produce the Action's contents.
|
||||
|
||||
strfunction()
|
||||
Returns a substituted string representation of the Action.
|
||||
This is used by the _ActionAction.show() command to display the
|
||||
|
@ -72,8 +76,7 @@ way for wrapping up the functions.
|
|||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -93,32 +96,33 @@ way for wrapping up the functions.
|
|||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Action.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Action.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import cPickle
|
||||
import dis
|
||||
import os
|
||||
import os.path
|
||||
import string
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
from SCons.Debug import logInstanceCreation
|
||||
import SCons.Errors
|
||||
import SCons.Executor
|
||||
import SCons.Util
|
||||
import SCons.Subst
|
||||
|
||||
class _Null:
|
||||
# we use these a lot, so try to optimize them
|
||||
is_String = SCons.Util.is_String
|
||||
is_List = SCons.Util.is_List
|
||||
|
||||
class _null:
|
||||
pass
|
||||
|
||||
_null = _Null
|
||||
|
||||
print_actions = 1
|
||||
execute_actions = 1
|
||||
print_actions_presub = 0
|
||||
|
||||
default_ENV = None
|
||||
|
||||
def rfile(n):
|
||||
try:
|
||||
return n.rfile()
|
||||
|
@ -150,6 +154,141 @@ else:
|
|||
i = i+1
|
||||
return string.join(result, '')
|
||||
|
||||
|
||||
def _callable_contents(obj):
|
||||
"""Return the signature contents of a callable Python object.
|
||||
"""
|
||||
try:
|
||||
# Test if obj is a method.
|
||||
return _function_contents(obj.im_func)
|
||||
|
||||
except AttributeError:
|
||||
try:
|
||||
# Test if obj is a callable object.
|
||||
return _function_contents(obj.__call__.im_func)
|
||||
|
||||
except AttributeError:
|
||||
try:
|
||||
# Test if obj is a code object.
|
||||
return _code_contents(obj)
|
||||
|
||||
except AttributeError:
|
||||
# Test if obj is a function object.
|
||||
return _function_contents(obj)
|
||||
|
||||
|
||||
def _object_contents(obj):
|
||||
"""Return the signature contents of any Python object.
|
||||
|
||||
We have to handle the case where object contains a code object
|
||||
since it can be pickled directly.
|
||||
"""
|
||||
try:
|
||||
# Test if obj is a method.
|
||||
return _function_contents(obj.im_func)
|
||||
|
||||
except AttributeError:
|
||||
try:
|
||||
# Test if obj is a callable object.
|
||||
return _function_contents(obj.__call__.im_func)
|
||||
|
||||
except AttributeError:
|
||||
try:
|
||||
# Test if obj is a code object.
|
||||
return _code_contents(obj)
|
||||
|
||||
except AttributeError:
|
||||
try:
|
||||
# Test if obj is a function object.
|
||||
return _function_contents(obj)
|
||||
|
||||
except AttributeError:
|
||||
# Should be a pickable Python object.
|
||||
try:
|
||||
return cPickle.dumps(obj)
|
||||
except (cPickle.PicklingError, TypeError):
|
||||
# This is weird, but it seems that nested classes
|
||||
# are unpickable. The Python docs say it should
|
||||
# always be a PicklingError, but some Python
|
||||
# versions seem to return TypeError. Just do
|
||||
# the best we can.
|
||||
return str(obj)
|
||||
|
||||
|
||||
def _code_contents(code):
|
||||
"""Return the signature contents of a code object.
|
||||
|
||||
By providing direct access to the code object of the
|
||||
function, Python makes this extremely easy. Hooray!
|
||||
|
||||
Unfortunately, older versions of Python include line
|
||||
number indications in the compiled byte code. Boo!
|
||||
So we remove the line number byte codes to prevent
|
||||
recompilations from moving a Python function.
|
||||
"""
|
||||
|
||||
contents = []
|
||||
|
||||
# The code contents depends on the number of local variables
|
||||
# but not their actual names.
|
||||
contents.append("%s,%s" % (code.co_argcount, len(code.co_varnames)))
|
||||
try:
|
||||
contents.append(",%s,%s" % (len(code.co_cellvars), len(code.co_freevars)))
|
||||
except AttributeError:
|
||||
# Older versions of Python do not support closures.
|
||||
contents.append(",0,0")
|
||||
|
||||
# The code contents depends on any constants accessed by the
|
||||
# function. Note that we have to call _object_contents on each
|
||||
# constants because the code object of nested functions can
|
||||
# show-up among the constants.
|
||||
#
|
||||
# Note that we also always ignore the first entry of co_consts
|
||||
# which contains the function doc string. We assume that the
|
||||
# function does not access its doc string.
|
||||
contents.append(',(' + string.join(map(_object_contents,code.co_consts[1:]),',') + ')')
|
||||
|
||||
# The code contents depends on the variable names used to
|
||||
# accessed global variable, as changing the variable name changes
|
||||
# the variable actually accessed and therefore changes the
|
||||
# function result.
|
||||
contents.append(',(' + string.join(map(_object_contents,code.co_names),',') + ')')
|
||||
|
||||
|
||||
# The code contents depends on its actual code!!!
|
||||
contents.append(',(' + str(remove_set_lineno_codes(code.co_code)) + ')')
|
||||
|
||||
return string.join(contents, '')
|
||||
|
||||
|
||||
def _function_contents(func):
|
||||
"""Return the signature contents of a function."""
|
||||
|
||||
contents = [_code_contents(func.func_code)]
|
||||
|
||||
# The function contents depends on the value of defaults arguments
|
||||
if func.func_defaults:
|
||||
contents.append(',(' + string.join(map(_object_contents,func.func_defaults),',') + ')')
|
||||
else:
|
||||
contents.append(',()')
|
||||
|
||||
# The function contents depends on the closure captured cell values.
|
||||
try:
|
||||
closure = func.func_closure or []
|
||||
except AttributeError:
|
||||
# Older versions of Python do not support closures.
|
||||
closure = []
|
||||
|
||||
#xxx = [_object_contents(x.cell_contents) for x in closure]
|
||||
try:
|
||||
xxx = map(lambda x: _object_contents(x.cell_contents), closure)
|
||||
except AttributeError:
|
||||
xxx = []
|
||||
contents.append(',(' + string.join(xxx, ',') + ')')
|
||||
|
||||
return string.join(contents, '')
|
||||
|
||||
|
||||
def _actionAppend(act1, act2):
|
||||
# This function knows how to slap two actions together.
|
||||
# Mainly, it handles ListActions by concatenating into
|
||||
|
@ -169,7 +308,34 @@ def _actionAppend(act1, act2):
|
|||
else:
|
||||
return ListAction([ a1, a2 ])
|
||||
|
||||
def _do_create_action(act, *args, **kw):
|
||||
def _do_create_keywords(args, kw):
|
||||
"""This converts any arguments after the action argument into
|
||||
their equivalent keywords and adds them to the kw argument.
|
||||
"""
|
||||
v = kw.get('varlist', ())
|
||||
# prevent varlist="FOO" from being interpreted as ['F', 'O', 'O']
|
||||
if is_String(v): v = (v,)
|
||||
kw['varlist'] = tuple(v)
|
||||
if args:
|
||||
# turn positional args into equivalent keywords
|
||||
cmdstrfunc = args[0]
|
||||
if cmdstrfunc is None or is_String(cmdstrfunc):
|
||||
kw['cmdstr'] = cmdstrfunc
|
||||
elif callable(cmdstrfunc):
|
||||
kw['strfunction'] = cmdstrfunc
|
||||
else:
|
||||
raise SCons.Errors.UserError(
|
||||
'Invalid command display variable type. '
|
||||
'You must either pass a string or a callback which '
|
||||
'accepts (target, source, env) as parameters.')
|
||||
if len(args) > 1:
|
||||
kw['varlist'] = args[1:] + kw['varlist']
|
||||
if kw.get('strfunction', _null) is not _null \
|
||||
and kw.get('cmdstr', _null) is not _null:
|
||||
raise SCons.Errors.UserError(
|
||||
'Cannot have both strfunction and cmdstr args to Action()')
|
||||
|
||||
def _do_create_action(act, kw):
|
||||
"""This is the actual "implementation" for the
|
||||
Action factory method, below. This handles the
|
||||
fact that passing lists to Action() itself has
|
||||
|
@ -182,8 +348,11 @@ def _do_create_action(act, *args, **kw):
|
|||
|
||||
if isinstance(act, ActionBase):
|
||||
return act
|
||||
if SCons.Util.is_List(act):
|
||||
return apply(CommandAction, (act,)+args, kw)
|
||||
|
||||
if is_List(act):
|
||||
#TODO(1.5) return CommandAction(act, **kw)
|
||||
return apply(CommandAction, (act,), kw)
|
||||
|
||||
if callable(act):
|
||||
try:
|
||||
gen = kw['generator']
|
||||
|
@ -194,8 +363,9 @@ def _do_create_action(act, *args, **kw):
|
|||
action_type = CommandGeneratorAction
|
||||
else:
|
||||
action_type = FunctionAction
|
||||
return apply(action_type, (act,)+args, kw)
|
||||
if SCons.Util.is_String(act):
|
||||
return action_type(act, kw)
|
||||
|
||||
if is_String(act):
|
||||
var=SCons.Util.get_environment_var(act)
|
||||
if var:
|
||||
# This looks like a string that is purely an Environment
|
||||
|
@ -204,30 +374,37 @@ def _do_create_action(act, *args, **kw):
|
|||
# of that Environment variable, so a user could put something
|
||||
# like a function or a CommandGenerator in that variable
|
||||
# instead of a string.
|
||||
return apply(LazyAction, (var,)+args, kw)
|
||||
return LazyAction(var, kw)
|
||||
commands = string.split(str(act), '\n')
|
||||
if len(commands) == 1:
|
||||
return apply(CommandAction, (commands[0],)+args, kw)
|
||||
else:
|
||||
listCmdActions = map(lambda x, args=args, kw=kw:
|
||||
apply(CommandAction, (x,)+args, kw),
|
||||
commands)
|
||||
return ListAction(listCmdActions)
|
||||
#TODO(1.5) return CommandAction(commands[0], **kw)
|
||||
return apply(CommandAction, (commands[0],), kw)
|
||||
# The list of string commands may include a LazyAction, so we
|
||||
# reprocess them via _do_create_list_action.
|
||||
return _do_create_list_action(commands, kw)
|
||||
return None
|
||||
|
||||
def _do_create_list_action(act, kw):
|
||||
"""A factory for list actions. Convert the input list into Actions
|
||||
and then wrap them in a ListAction."""
|
||||
acts = []
|
||||
for a in act:
|
||||
aa = _do_create_action(a, kw)
|
||||
if aa is not None: acts.append(aa)
|
||||
if not acts:
|
||||
return None
|
||||
elif len(acts) == 1:
|
||||
return acts[0]
|
||||
else:
|
||||
return ListAction(acts)
|
||||
|
||||
def Action(act, *args, **kw):
|
||||
"""A factory for action objects."""
|
||||
if SCons.Util.is_List(act):
|
||||
acts = map(lambda a, args=args, kw=kw:
|
||||
apply(_do_create_action, (a,)+args, kw),
|
||||
act)
|
||||
acts = filter(None, acts)
|
||||
if len(acts) == 1:
|
||||
return acts[0]
|
||||
else:
|
||||
return ListAction(acts)
|
||||
else:
|
||||
return apply(_do_create_action, (act,)+args, kw)
|
||||
# Really simple: the _do_create_* routines do the heavy lifting.
|
||||
_do_create_keywords(args, kw)
|
||||
if is_List(act):
|
||||
return _do_create_list_action(act, kw)
|
||||
return _do_create_action(act, kw)
|
||||
|
||||
class ActionBase:
|
||||
"""Base class for all types of action objects that can be held by
|
||||
|
@ -240,6 +417,17 @@ class ActionBase:
|
|||
def genstring(self, target, source, env):
|
||||
return str(self)
|
||||
|
||||
def get_contents(self, target, source, env):
|
||||
result = [ self.get_presig(target, source, env) ]
|
||||
# This should never happen, as the Action() factory should wrap
|
||||
# the varlist, but just in case an action is created directly,
|
||||
# we duplicate this check here.
|
||||
vl = self.varlist
|
||||
if is_String(vl): vl = (vl,)
|
||||
for v in vl:
|
||||
result.append(env.subst('${'+v+'}'))
|
||||
return string.join(result, '')
|
||||
|
||||
def __add__(self, other):
|
||||
return _actionAppend(self, other)
|
||||
|
||||
|
@ -265,9 +453,16 @@ class ActionBase:
|
|||
|
||||
class _ActionAction(ActionBase):
|
||||
"""Base class for actions that create output objects."""
|
||||
def __init__(self, strfunction=_null, presub=_null, chdir=None, exitstatfunc=None, **kw):
|
||||
if not strfunction is _null:
|
||||
self.strfunction = strfunction
|
||||
def __init__(self, cmdstr=_null, strfunction=_null, varlist=(),
|
||||
presub=_null, chdir=None, exitstatfunc=None,
|
||||
**kw):
|
||||
self.cmdstr = cmdstr
|
||||
if strfunction is not _null:
|
||||
if strfunction is None:
|
||||
self.cmdstr = None
|
||||
else:
|
||||
self.strfunction = strfunction
|
||||
self.varlist = varlist
|
||||
self.presub = presub
|
||||
self.chdir = chdir
|
||||
if not exitstatfunc:
|
||||
|
@ -283,16 +478,16 @@ class _ActionAction(ActionBase):
|
|||
show=_null,
|
||||
execute=_null,
|
||||
chdir=_null):
|
||||
if not SCons.Util.is_List(target):
|
||||
if not is_List(target):
|
||||
target = [target]
|
||||
if not SCons.Util.is_List(source):
|
||||
if not is_List(source):
|
||||
source = [source]
|
||||
|
||||
if exitstatfunc is _null: exitstatfunc = self.exitstatfunc
|
||||
if presub is _null:
|
||||
presub = self.presub
|
||||
if presub is _null:
|
||||
presub = print_actions_presub
|
||||
if presub is _null:
|
||||
presub = print_actions_presub
|
||||
if exitstatfunc is _null: exitstatfunc = self.exitstatfunc
|
||||
if show is _null: show = print_actions
|
||||
if execute is _null: execute = execute_actions
|
||||
if chdir is _null: chdir = self.chdir
|
||||
|
@ -302,19 +497,19 @@ class _ActionAction(ActionBase):
|
|||
try:
|
||||
chdir = str(chdir.abspath)
|
||||
except AttributeError:
|
||||
if not SCons.Util.is_String(chdir):
|
||||
if not is_String(chdir):
|
||||
chdir = str(target[0].dir)
|
||||
if presub:
|
||||
t = string.join(map(str, target), ' and ')
|
||||
l = string.join(self.presub_lines(env), '\n ')
|
||||
out = "Building %s with action:\n %s\n" % (t, l)
|
||||
sys.stdout.write(out)
|
||||
s = None
|
||||
cmd = None
|
||||
if show and self.strfunction:
|
||||
s = self.strfunction(target, source, env)
|
||||
if s:
|
||||
cmd = self.strfunction(target, source, env)
|
||||
if cmd:
|
||||
if chdir:
|
||||
s = ('os.chdir(%s)\n' % repr(chdir)) + s
|
||||
cmd = ('os.chdir(%s)\n' % repr(chdir)) + cmd
|
||||
try:
|
||||
get = env.get
|
||||
except AttributeError:
|
||||
|
@ -323,7 +518,7 @@ class _ActionAction(ActionBase):
|
|||
print_func = get('PRINT_CMD_LINE_FUNC')
|
||||
if not print_func:
|
||||
print_func = self.print_cmd_line
|
||||
print_func(s, target, source, env)
|
||||
print_func(cmd, target, source, env)
|
||||
stat = 0
|
||||
if execute:
|
||||
if chdir:
|
||||
|
@ -341,7 +536,7 @@ class _ActionAction(ActionBase):
|
|||
finally:
|
||||
if save_cwd:
|
||||
os.chdir(save_cwd)
|
||||
if s and save_cwd:
|
||||
if cmd and save_cwd:
|
||||
print_func('os.chdir(%s)' % repr(save_cwd), target, source, env)
|
||||
|
||||
return stat
|
||||
|
@ -357,9 +552,87 @@ def _string_from_cmd_list(cmd_list):
|
|||
cl.append(arg)
|
||||
return string.join(cl)
|
||||
|
||||
# A fiddlin' little function that has an 'import SCons.Environment' which
|
||||
# can't be moved to the top level without creating an import loop. Since
|
||||
# this import creates a local variable named 'SCons', it blocks access to
|
||||
# the global variable, so we move it here to prevent complaints about local
|
||||
# variables being used uninitialized.
|
||||
default_ENV = None
|
||||
def get_default_ENV(env):
|
||||
global default_ENV
|
||||
try:
|
||||
return env['ENV']
|
||||
except KeyError:
|
||||
if not default_ENV:
|
||||
import SCons.Environment
|
||||
# This is a hideously expensive way to get a default shell
|
||||
# environment. What it really should do is run the platform
|
||||
# setup to get the default ENV. Fortunately, it's incredibly
|
||||
# rare for an Environment not to have a shell environment, so
|
||||
# we're not going to worry about it overmuch.
|
||||
default_ENV = SCons.Environment.Environment()['ENV']
|
||||
return default_ENV
|
||||
|
||||
# This function is still in draft mode. We're going to need something like
|
||||
# it in the long run as more and more places use subprocess, but I'm sure
|
||||
# it'll have to be tweaked to get the full desired functionality.
|
||||
# one special arg (so far?), 'error', to tell what to do with exceptions.
|
||||
def _subproc(env, cmd, error = 'ignore', **kw):
|
||||
"""Do common setup for a subprocess.Popen() call"""
|
||||
# allow std{in,out,err} to be "'devnull'"
|
||||
io = kw.get('stdin')
|
||||
if is_String(io) and io == 'devnull':
|
||||
kw['stdin'] = open(os.devnull)
|
||||
io = kw.get('stdout')
|
||||
if is_String(io) and io == 'devnull':
|
||||
kw['stdout'] = open(os.devnull, 'w')
|
||||
io = kw.get('stderr')
|
||||
if is_String(io) and io == 'devnull':
|
||||
kw['stderr'] = open(os.devnull, 'w')
|
||||
|
||||
# Figure out what shell environment to use
|
||||
ENV = kw.get('env', None)
|
||||
if ENV is None: ENV = get_default_ENV(env)
|
||||
|
||||
# Ensure that the ENV values are all strings:
|
||||
new_env = {}
|
||||
for key, value in ENV.items():
|
||||
if is_List(value):
|
||||
# If the value is a list, then we assume it is a path list,
|
||||
# because that's a pretty common list-like value to stick
|
||||
# in an environment variable:
|
||||
value = SCons.Util.flatten_sequence(value)
|
||||
new_env[key] = string.join(map(str, value), os.pathsep)
|
||||
else:
|
||||
# It's either a string or something else. If it's a string,
|
||||
# we still want to call str() because it might be a *Unicode*
|
||||
# string, which makes subprocess.Popen() gag. If it isn't a
|
||||
# string or a list, then we just coerce it to a string, which
|
||||
# is the proper way to handle Dir and File instances and will
|
||||
# produce something reasonable for just about everything else:
|
||||
new_env[key] = str(value)
|
||||
kw['env'] = new_env
|
||||
|
||||
try:
|
||||
#FUTURE return subprocess.Popen(cmd, **kw)
|
||||
return apply(subprocess.Popen, (cmd,), kw)
|
||||
except EnvironmentError, e:
|
||||
if error == 'raise': raise
|
||||
# return a dummy Popen instance that only returns error
|
||||
class dummyPopen:
|
||||
def __init__(self, e): self.exception = e
|
||||
def communicate(self): return ('','')
|
||||
def wait(self): return -self.exception.errno
|
||||
stdin = None
|
||||
class f:
|
||||
def read(self): return ''
|
||||
def readline(self): return ''
|
||||
stdout = stderr = f()
|
||||
return dummyPopen(e)
|
||||
|
||||
class CommandAction(_ActionAction):
|
||||
"""Class for command-execution actions."""
|
||||
def __init__(self, cmd, cmdstr=None, *args, **kw):
|
||||
def __init__(self, cmd, **kw):
|
||||
# Cmd can actually be a list or a single item; if it's a
|
||||
# single item it should be the command string to execute; if a
|
||||
# list then it should be the words of the command string to
|
||||
|
@ -371,25 +644,16 @@ class CommandAction(_ActionAction):
|
|||
# variables.
|
||||
if __debug__: logInstanceCreation(self, 'Action.CommandAction')
|
||||
|
||||
if not cmdstr is None:
|
||||
if callable(cmdstr):
|
||||
args = (cmdstr,)+args
|
||||
elif not SCons.Util.is_String(cmdstr):
|
||||
raise SCons.Errors.UserError(\
|
||||
'Invalid command display variable type. ' \
|
||||
'You must either pass a string or a callback which ' \
|
||||
'accepts (target, source, env) as parameters.')
|
||||
|
||||
apply(_ActionAction.__init__, (self,)+args, kw)
|
||||
if SCons.Util.is_List(cmd):
|
||||
if filter(SCons.Util.is_List, cmd):
|
||||
#TODO(1.5) _ActionAction.__init__(self, **kw)
|
||||
apply(_ActionAction.__init__, (self,), kw)
|
||||
if is_List(cmd):
|
||||
if filter(is_List, cmd):
|
||||
raise TypeError, "CommandAction should be given only " \
|
||||
"a single command"
|
||||
self.cmd_list = cmd
|
||||
self.cmdstr = cmdstr
|
||||
|
||||
def __str__(self):
|
||||
if SCons.Util.is_List(self.cmd_list):
|
||||
if is_List(self.cmd_list):
|
||||
return string.join(map(str, self.cmd_list), ' ')
|
||||
return str(self.cmd_list)
|
||||
|
||||
|
@ -412,7 +676,9 @@ class CommandAction(_ActionAction):
|
|||
return result, ignore, silent
|
||||
|
||||
def strfunction(self, target, source, env):
|
||||
if not self.cmdstr is None:
|
||||
if self.cmdstr is None:
|
||||
return None
|
||||
if self.cmdstr is not _null:
|
||||
from SCons.Subst import SUBST_RAW
|
||||
c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
||||
if c:
|
||||
|
@ -431,11 +697,8 @@ class CommandAction(_ActionAction):
|
|||
handle lists of commands, even though that's not how we use it
|
||||
externally.
|
||||
"""
|
||||
from SCons.Subst import escape_list
|
||||
import SCons.Util
|
||||
flatten = SCons.Util.flatten
|
||||
is_String = SCons.Util.is_String
|
||||
is_List = SCons.Util.is_List
|
||||
escape_list = SCons.Subst.escape_list
|
||||
flatten_sequence = SCons.Util.flatten_sequence
|
||||
|
||||
try:
|
||||
shell = env['SHELL']
|
||||
|
@ -452,14 +715,7 @@ class CommandAction(_ActionAction):
|
|||
|
||||
escape = env.get('ESCAPE', lambda x: x)
|
||||
|
||||
try:
|
||||
ENV = env['ENV']
|
||||
except KeyError:
|
||||
global default_ENV
|
||||
if not default_ENV:
|
||||
import SCons.Environment
|
||||
default_ENV = SCons.Environment.Environment()['ENV']
|
||||
ENV = default_ENV
|
||||
ENV = get_default_ENV(env)
|
||||
|
||||
# Ensure that the ENV values are all strings:
|
||||
for key, value in ENV.items():
|
||||
|
@ -468,7 +724,7 @@ class CommandAction(_ActionAction):
|
|||
# If the value is a list, then we assume it is a
|
||||
# path list, because that's a pretty common list-like
|
||||
# value to stick in an environment variable:
|
||||
value = flatten(value)
|
||||
value = flatten_sequence(value)
|
||||
ENV[key] = string.join(map(str, value), os.pathsep)
|
||||
else:
|
||||
# If it isn't a string or a list, then we just coerce
|
||||
|
@ -492,7 +748,7 @@ class CommandAction(_ActionAction):
|
|||
command=cmd_line)
|
||||
return 0
|
||||
|
||||
def get_contents(self, target, source, env):
|
||||
def get_presig(self, target, source, env):
|
||||
"""Return the signature contents of this action's command line.
|
||||
|
||||
This strips $(-$) and everything in between the string,
|
||||
|
@ -500,7 +756,7 @@ class CommandAction(_ActionAction):
|
|||
"""
|
||||
from SCons.Subst import SUBST_SIG
|
||||
cmd = self.cmd_list
|
||||
if SCons.Util.is_List(cmd):
|
||||
if is_List(cmd):
|
||||
cmd = string.join(map(str, cmd))
|
||||
else:
|
||||
cmd = str(cmd)
|
||||
|
@ -508,7 +764,7 @@ class CommandAction(_ActionAction):
|
|||
|
||||
def get_implicit_deps(self, target, source, env):
|
||||
icd = env.get('IMPLICIT_COMMAND_DEPENDENCIES', True)
|
||||
if SCons.Util.is_String(icd) and icd[:1] == '$':
|
||||
if is_String(icd) and icd[:1] == '$':
|
||||
icd = env.subst(icd)
|
||||
if not icd or icd in ('0', 'None'):
|
||||
return []
|
||||
|
@ -524,20 +780,21 @@ class CommandAction(_ActionAction):
|
|||
|
||||
class CommandGeneratorAction(ActionBase):
|
||||
"""Class for command-generator actions."""
|
||||
def __init__(self, generator, *args, **kw):
|
||||
def __init__(self, generator, kw):
|
||||
if __debug__: logInstanceCreation(self, 'Action.CommandGeneratorAction')
|
||||
self.generator = generator
|
||||
self.gen_args = args
|
||||
self.gen_kw = kw
|
||||
self.varlist = kw.get('varlist', ())
|
||||
|
||||
def _generate(self, target, source, env, for_signature):
|
||||
# ensure that target is a list, to make it easier to write
|
||||
# generator functions:
|
||||
if not SCons.Util.is_List(target):
|
||||
if not is_List(target):
|
||||
target = [target]
|
||||
|
||||
ret = self.generator(target=target, source=source, env=env, for_signature=for_signature)
|
||||
gen_cmd = apply(Action, (ret,)+self.gen_args, self.gen_kw)
|
||||
#TODO(1.5) gen_cmd = Action(ret, **self.gen_kw)
|
||||
gen_cmd = apply(Action, (ret,), self.gen_kw)
|
||||
if not gen_cmd:
|
||||
raise SCons.Errors.UserError("Object returned from command generator: %s cannot be used to create an Action." % repr(ret))
|
||||
return gen_cmd
|
||||
|
@ -561,13 +818,13 @@ class CommandGeneratorAction(ActionBase):
|
|||
return act(target, source, env, exitstatfunc, presub,
|
||||
show, execute, chdir)
|
||||
|
||||
def get_contents(self, target, source, env):
|
||||
def get_presig(self, target, source, env):
|
||||
"""Return the signature contents of this action's command line.
|
||||
|
||||
This strips $(-$) and everything in between the string,
|
||||
since those parts don't affect signatures.
|
||||
"""
|
||||
return self._generate(target, source, env, 1).get_contents(target, source, env)
|
||||
return self._generate(target, source, env, 1).get_presig(target, source, env)
|
||||
|
||||
def get_implicit_deps(self, target, source, env):
|
||||
return self._generate(target, source, env, 1).get_implicit_deps(target, source, env)
|
||||
|
@ -593,22 +850,23 @@ class CommandGeneratorAction(ActionBase):
|
|||
|
||||
class LazyAction(CommandGeneratorAction, CommandAction):
|
||||
|
||||
def __init__(self, var, *args, **kw):
|
||||
def __init__(self, var, kw):
|
||||
if __debug__: logInstanceCreation(self, 'Action.LazyAction')
|
||||
apply(CommandAction.__init__, (self, '$'+var)+args, kw)
|
||||
#FUTURE CommandAction.__init__(self, '${'+var+'}', **kw)
|
||||
apply(CommandAction.__init__, (self, '${'+var+'}'), kw)
|
||||
self.var = SCons.Util.to_String(var)
|
||||
self.gen_args = args
|
||||
self.gen_kw = kw
|
||||
|
||||
def get_parent_class(self, env):
|
||||
c = env.get(self.var)
|
||||
if SCons.Util.is_String(c) and not '\n' in c:
|
||||
if is_String(c) and not '\n' in c:
|
||||
return CommandAction
|
||||
return CommandGeneratorAction
|
||||
|
||||
def _generate_cache(self, env):
|
||||
c = env.get(self.var, '')
|
||||
gen_cmd = apply(Action, (c,)+self.gen_args, self.gen_kw)
|
||||
#TODO(1.5) gen_cmd = Action(c, **self.gen_kw)
|
||||
gen_cmd = apply(Action, (c,), self.gen_kw)
|
||||
if not gen_cmd:
|
||||
raise SCons.Errors.UserError("$%s value %s cannot be used to create an Action." % (self.var, repr(c)))
|
||||
return gen_cmd
|
||||
|
@ -619,33 +877,34 @@ class LazyAction(CommandGeneratorAction, CommandAction):
|
|||
def __call__(self, target, source, env, *args, **kw):
|
||||
args = (self, target, source, env) + args
|
||||
c = self.get_parent_class(env)
|
||||
#TODO(1.5) return c.__call__(*args, **kw)
|
||||
return apply(c.__call__, args, kw)
|
||||
|
||||
def get_contents(self, target, source, env):
|
||||
def get_presig(self, target, source, env):
|
||||
c = self.get_parent_class(env)
|
||||
return c.get_contents(self, target, source, env)
|
||||
return c.get_presig(self, target, source, env)
|
||||
|
||||
|
||||
|
||||
class FunctionAction(_ActionAction):
|
||||
"""Class for Python function actions."""
|
||||
|
||||
def __init__(self, execfunction, cmdstr=_null, *args, **kw):
|
||||
def __init__(self, execfunction, kw):
|
||||
if __debug__: logInstanceCreation(self, 'Action.FunctionAction')
|
||||
|
||||
if not cmdstr is _null:
|
||||
if callable(cmdstr):
|
||||
args = (cmdstr,)+args
|
||||
elif not (cmdstr is None or SCons.Util.is_String(cmdstr)):
|
||||
raise SCons.Errors.UserError(\
|
||||
'Invalid function display variable type. ' \
|
||||
'You must either pass a string or a callback which ' \
|
||||
'accepts (target, source, env) as parameters.')
|
||||
|
||||
self.execfunction = execfunction
|
||||
apply(_ActionAction.__init__, (self,)+args, kw)
|
||||
self.varlist = kw.get('varlist', [])
|
||||
self.cmdstr = cmdstr
|
||||
try:
|
||||
self.funccontents = _callable_contents(execfunction)
|
||||
except AttributeError:
|
||||
try:
|
||||
# See if execfunction will do the heavy lifting for us.
|
||||
self.gc = execfunction.get_contents
|
||||
except AttributeError:
|
||||
# This is weird, just do the best we can.
|
||||
self.funccontents = _object_contents(execfunction)
|
||||
|
||||
#TODO(1.5) _ActionAction.__init__(self, **kw)
|
||||
apply(_ActionAction.__init__, (self,), kw)
|
||||
|
||||
def function_name(self):
|
||||
try:
|
||||
|
@ -659,14 +918,20 @@ class FunctionAction(_ActionAction):
|
|||
def strfunction(self, target, source, env):
|
||||
if self.cmdstr is None:
|
||||
return None
|
||||
if not self.cmdstr is _null:
|
||||
if self.cmdstr is not _null:
|
||||
from SCons.Subst import SUBST_RAW
|
||||
c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
||||
if c:
|
||||
return c
|
||||
def array(a):
|
||||
def quote(s):
|
||||
return '"' + str(s) + '"'
|
||||
try:
|
||||
str_for_display = s.str_for_display
|
||||
except AttributeError:
|
||||
s = repr(s)
|
||||
else:
|
||||
s = str_for_display()
|
||||
return s
|
||||
return '[' + string.join(map(quote, a), ", ") + ']'
|
||||
try:
|
||||
strfunc = self.execfunction.strfunction
|
||||
|
@ -689,73 +954,49 @@ class FunctionAction(_ActionAction):
|
|||
return "%s(target, source, env)" % name
|
||||
|
||||
def execute(self, target, source, env):
|
||||
rsources = map(rfile, source)
|
||||
exc_info = (None,None,None)
|
||||
try:
|
||||
result = self.execfunction(target=target, source=rsources, env=env)
|
||||
except EnvironmentError, e:
|
||||
# If an IOError/OSError happens, raise a BuildError.
|
||||
# Report the name of the file or directory that caused the
|
||||
# error, which might be different from the target being built
|
||||
# (for example, failure to create the directory in which the
|
||||
# target file will appear).
|
||||
try: filename = e.filename
|
||||
except AttributeError: filename = None
|
||||
result = SCons.Errors.BuildError(node=target,
|
||||
errstr=e.strerror,
|
||||
status=1,
|
||||
filename=filename,
|
||||
action=self,
|
||||
command=self.strfunction(target, source, env))
|
||||
else:
|
||||
if result:
|
||||
msg = "Error %s" % result
|
||||
result = SCons.Errors.BuildError(errstr=msg,
|
||||
status=result,
|
||||
action=self,
|
||||
command=self.strfunction(target, source, env))
|
||||
return result
|
||||
|
||||
def get_contents(self, target, source, env):
|
||||
"""Return the signature contents of this callable action.
|
||||
|
||||
By providing direct access to the code object of the
|
||||
function, Python makes this extremely easy. Hooray!
|
||||
|
||||
Unfortunately, older versions of Python include line
|
||||
number indications in the compiled byte code. Boo!
|
||||
So we remove the line number byte codes to prevent
|
||||
recompilations from moving a Python function.
|
||||
"""
|
||||
execfunction = self.execfunction
|
||||
try:
|
||||
# Test if execfunction is a function.
|
||||
code = execfunction.func_code.co_code
|
||||
except AttributeError:
|
||||
rsources = map(rfile, source)
|
||||
try:
|
||||
# Test if execfunction is a method.
|
||||
code = execfunction.im_func.func_code.co_code
|
||||
except AttributeError:
|
||||
try:
|
||||
# Test if execfunction is a callable object.
|
||||
code = execfunction.__call__.im_func.func_code.co_code
|
||||
except AttributeError:
|
||||
try:
|
||||
# See if execfunction will do the heavy lifting for us.
|
||||
gc = self.execfunction.get_contents
|
||||
except AttributeError:
|
||||
# This is weird, just do the best we can.
|
||||
contents = str(self.execfunction)
|
||||
else:
|
||||
contents = gc(target, source, env)
|
||||
else:
|
||||
contents = str(code)
|
||||
else:
|
||||
contents = str(code)
|
||||
else:
|
||||
contents = str(code)
|
||||
contents = remove_set_lineno_codes(contents)
|
||||
return contents + env.subst(string.join(map(lambda v: '${'+v+'}',
|
||||
self.varlist)))
|
||||
result = self.execfunction(target=target, source=rsources, env=env)
|
||||
except KeyboardInterrupt, e:
|
||||
raise
|
||||
except SystemExit, e:
|
||||
raise
|
||||
except Exception, e:
|
||||
result = e
|
||||
exc_info = sys.exc_info()
|
||||
|
||||
if result:
|
||||
result = SCons.Errors.convert_to_BuildError(result, exc_info)
|
||||
result.node=target
|
||||
result.action=self
|
||||
result.command=self.strfunction(target, source, env)
|
||||
|
||||
# FIXME: This maintains backward compatibility with respect to
|
||||
# which type of exceptions were returned by raising an
|
||||
# exception and which ones were returned by value. It would
|
||||
# probably be best to always return them by value here, but
|
||||
# some codes do not check the return value of Actions and I do
|
||||
# not have the time to modify them at this point.
|
||||
if (exc_info[1] and
|
||||
not isinstance(exc_info[1],EnvironmentError)):
|
||||
raise result
|
||||
|
||||
return result
|
||||
finally:
|
||||
# Break the cycle between the traceback object and this
|
||||
# function stack frame. See the sys.exc_info() doc info for
|
||||
# more information about this issue.
|
||||
del exc_info
|
||||
|
||||
|
||||
def get_presig(self, target, source, env):
|
||||
"""Return the signature contents of this callable action."""
|
||||
try:
|
||||
return self.gc(target, source, env)
|
||||
except AttributeError:
|
||||
return self.funccontents
|
||||
|
||||
def get_implicit_deps(self, target, source, env):
|
||||
return []
|
||||
|
@ -769,6 +1010,9 @@ class ListAction(ActionBase):
|
|||
return x
|
||||
return Action(x)
|
||||
self.list = map(list_of_actions, list)
|
||||
# our children will have had any varlist
|
||||
# applied; we don't need to do it again
|
||||
self.varlist = ()
|
||||
|
||||
def genstring(self, target, source, env):
|
||||
return string.join(map(lambda a, t=target, s=source, e=env:
|
||||
|
@ -780,11 +1024,10 @@ class ListAction(ActionBase):
|
|||
return string.join(map(str, self.list), '\n')
|
||||
|
||||
def presub_lines(self, env):
|
||||
return SCons.Util.flatten(map(lambda a, env=env:
|
||||
a.presub_lines(env),
|
||||
self.list))
|
||||
return SCons.Util.flatten_sequence(
|
||||
map(lambda a, env=env: a.presub_lines(env), self.list))
|
||||
|
||||
def get_contents(self, target, source, env):
|
||||
def get_presig(self, target, source, env):
|
||||
"""Return the signature contents of this action list.
|
||||
|
||||
Simple concatenation of the signatures of the elements.
|
||||
|
@ -822,6 +1065,7 @@ class ActionCaller:
|
|||
self.parent = parent
|
||||
self.args = args
|
||||
self.kw = kw
|
||||
|
||||
def get_contents(self, target, source, env):
|
||||
actfunc = self.parent.actfunc
|
||||
try:
|
||||
|
@ -837,33 +1081,50 @@ class ActionCaller:
|
|||
contents = str(actfunc)
|
||||
contents = remove_set_lineno_codes(contents)
|
||||
return contents
|
||||
|
||||
def subst(self, s, target, source, env):
|
||||
# If s is a list, recursively apply subst()
|
||||
# to every element in the list
|
||||
if is_List(s):
|
||||
result = []
|
||||
for elem in s:
|
||||
result.append(self.subst(elem, target, source, env))
|
||||
return self.parent.convert(result)
|
||||
|
||||
# Special-case hack: Let a custom function wrapped in an
|
||||
# ActionCaller get at the environment through which the action
|
||||
# was called by using this hard-coded value as a special return.
|
||||
if s == '$__env__':
|
||||
return env
|
||||
elif SCons.Util.is_String(s):
|
||||
return env.subst(s, 0, target, source)
|
||||
elif is_String(s):
|
||||
return env.subst(s, 1, target, source)
|
||||
return self.parent.convert(s)
|
||||
|
||||
def subst_args(self, target, source, env):
|
||||
return map(lambda x, self=self, t=target, s=source, e=env:
|
||||
self.subst(x, t, s, e),
|
||||
self.args)
|
||||
|
||||
def subst_kw(self, target, source, env):
|
||||
kw = {}
|
||||
for key in self.kw.keys():
|
||||
kw[key] = self.subst(self.kw[key], target, source, env)
|
||||
return kw
|
||||
|
||||
def __call__(self, target, source, env):
|
||||
args = self.subst_args(target, source, env)
|
||||
kw = self.subst_kw(target, source, env)
|
||||
#TODO(1.5) return self.parent.actfunc(*args, **kw)
|
||||
return apply(self.parent.actfunc, args, kw)
|
||||
|
||||
def strfunction(self, target, source, env):
|
||||
args = self.subst_args(target, source, env)
|
||||
kw = self.subst_kw(target, source, env)
|
||||
#TODO(1.5) return self.parent.strfunc(*args, **kw)
|
||||
return apply(self.parent.strfunc, args, kw)
|
||||
|
||||
def __str__(self):
|
||||
#TODO(1.5) return self.parent.strfunc(*self.args, **self.kw)
|
||||
return apply(self.parent.strfunc, self.args, self.kw)
|
||||
|
||||
class ActionFactory:
|
||||
|
@ -879,6 +1140,7 @@ class ActionFactory:
|
|||
self.actfunc = actfunc
|
||||
self.strfunc = strfunc
|
||||
self.convert = convert
|
||||
|
||||
def __call__(self, *args, **kw):
|
||||
ac = ActionCaller(self, args, kw)
|
||||
action = Action(ac, strfunction=ac.strfunction)
|
|
@ -76,7 +76,7 @@ There are the following methods for internal use within this module:
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -98,9 +98,7 @@ There are the following methods for internal use within this module:
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Builder.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import SCons.compat
|
||||
__revision__ = "src/engine/SCons/Builder.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import UserDict
|
||||
import UserList
|
||||
|
@ -234,7 +232,7 @@ def Builder(**kw):
|
|||
if kw.has_key('generator'):
|
||||
if kw.has_key('action'):
|
||||
raise UserError, "You must not specify both an action and a generator."
|
||||
kw['action'] = SCons.Action.CommandGeneratorAction(kw['generator'])
|
||||
kw['action'] = SCons.Action.CommandGeneratorAction(kw['generator'], {})
|
||||
del kw['generator']
|
||||
elif kw.has_key('action'):
|
||||
source_ext_match = kw.get('source_ext_match', 1)
|
||||
|
@ -242,7 +240,7 @@ def Builder(**kw):
|
|||
del kw['source_ext_match']
|
||||
if SCons.Util.is_Dict(kw['action']):
|
||||
composite = DictCmdGenerator(kw['action'], source_ext_match)
|
||||
kw['action'] = SCons.Action.CommandGeneratorAction(composite)
|
||||
kw['action'] = SCons.Action.CommandGeneratorAction(composite, {})
|
||||
kw['src_suffix'] = composite.src_suffixes()
|
||||
else:
|
||||
kw['action'] = SCons.Action.Action(kw['action'])
|
||||
|
@ -363,7 +361,7 @@ class BuilderBase:
|
|||
name = None,
|
||||
chdir = _null,
|
||||
is_explicit = 1,
|
||||
src_builder = [],
|
||||
src_builder = None,
|
||||
ensure_suffix = False,
|
||||
**overrides):
|
||||
if __debug__: logInstanceCreation(self, 'Builder.BuilderBase')
|
||||
|
@ -410,7 +408,9 @@ class BuilderBase:
|
|||
self.executor_kw['chdir'] = chdir
|
||||
self.is_explicit = is_explicit
|
||||
|
||||
if not SCons.Util.is_List(src_builder):
|
||||
if src_builder is None:
|
||||
src_builder = []
|
||||
elif not SCons.Util.is_List(src_builder):
|
||||
src_builder = [ src_builder ]
|
||||
self.src_builder = src_builder
|
||||
|
||||
|
@ -505,7 +505,7 @@ class BuilderBase:
|
|||
tlist = [ t_from_s(pre, suf, splitext) ]
|
||||
else:
|
||||
target = self._adjustixes(target, pre, suf, self.ensure_suffix)
|
||||
tlist = env.arg2nodes(target, target_factory)
|
||||
tlist = env.arg2nodes(target, target_factory, target=target, source=source)
|
||||
|
||||
if self.emitter:
|
||||
# The emitter is going to do str(node), but because we're
|
||||
|
@ -712,14 +712,9 @@ class BuilderBase:
|
|||
return None
|
||||
|
||||
result = []
|
||||
|
||||
if SCons.Util.is_List(source):
|
||||
source = SCons.Util.flatten(source)
|
||||
else:
|
||||
source = [source]
|
||||
for s in source:
|
||||
for s in SCons.Util.flatten(source):
|
||||
if SCons.Util.is_String(s):
|
||||
match_suffix = match_src_suffix(s)
|
||||
match_suffix = match_src_suffix(env.subst(s))
|
||||
if not match_suffix and not '.' in s:
|
||||
src_suf = self.get_src_suffix(env)
|
||||
s = self._adjustixes(s, None, src_suf)[0]
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/CacheDir.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/CacheDir.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
__doc__ = """
|
||||
CacheDir support
|
||||
|
@ -34,6 +34,7 @@ import sys
|
|||
|
||||
import SCons.Action
|
||||
|
||||
cache_enabled = True
|
||||
cache_debug = False
|
||||
cache_force = False
|
||||
cache_show = False
|
||||
|
@ -129,31 +130,33 @@ class CacheDir:
|
|||
except ImportError:
|
||||
msg = "No hashlib or MD5 module available, CacheDir() not supported"
|
||||
SCons.Warnings.warn(SCons.Warnings.NoMD5ModuleWarning, msg)
|
||||
self.path = None
|
||||
else:
|
||||
self.path = path
|
||||
self.current_cache_debug = None
|
||||
self.debugFP = None
|
||||
|
||||
def CacheDebugWrite(self, fmt, target, cachefile):
|
||||
self.debugFP.write(fmt % (target, os.path.split(cachefile)[1]))
|
||||
|
||||
def CacheDebugQuiet(self, fmt, target, cachefile):
|
||||
pass
|
||||
|
||||
def CacheDebugInit(self, fmt, target, cachefile):
|
||||
if cache_debug:
|
||||
def CacheDebug(self, fmt, target, cachefile):
|
||||
if cache_debug != self.current_cache_debug:
|
||||
if cache_debug == '-':
|
||||
self.debugFP = sys.stdout
|
||||
else:
|
||||
elif cache_debug:
|
||||
self.debugFP = open(cache_debug, 'w')
|
||||
self.CacheDebug = self.CacheDebugWrite
|
||||
self.CacheDebug(fmt, target, cachefile)
|
||||
else:
|
||||
self.CacheDebug = self.CacheDebugQuiet
|
||||
else:
|
||||
self.debugFP = None
|
||||
self.current_cache_debug = cache_debug
|
||||
if self.debugFP:
|
||||
self.debugFP.write(fmt % (target, os.path.split(cachefile)[1]))
|
||||
|
||||
CacheDebug = CacheDebugInit
|
||||
def is_enabled(self):
|
||||
return (cache_enabled and not self.path is None)
|
||||
|
||||
def cachepath(self, node):
|
||||
"""
|
||||
"""
|
||||
if not self.is_enabled():
|
||||
return None, None
|
||||
|
||||
sig = node.get_cachedir_bsig()
|
||||
subdir = string.upper(sig[0])
|
||||
dir = os.path.join(self.path, subdir)
|
||||
|
@ -184,6 +187,9 @@ class CacheDir:
|
|||
execute the CacheRetrieveFunc and then have the latter
|
||||
explicitly check SCons.Action.execute_actions itself.
|
||||
"""
|
||||
if not self.is_enabled():
|
||||
return False
|
||||
|
||||
retrieved = False
|
||||
|
||||
if cache_show:
|
||||
|
@ -202,16 +208,10 @@ class CacheDir:
|
|||
return retrieved
|
||||
|
||||
def push(self, node):
|
||||
if not self.is_enabled():
|
||||
return
|
||||
return CachePush(node, [], node.get_build_env())
|
||||
|
||||
def push_if_forced(self, node):
|
||||
if cache_force:
|
||||
return self.push(node)
|
||||
|
||||
class Null(SCons.Util.Null):
|
||||
def repr(self):
|
||||
return 'CacheDir.Null()'
|
||||
def cachepath(self, node):
|
||||
return None, None
|
||||
def retrieve(self, node):
|
||||
return False
|
|
@ -142,6 +142,101 @@ int main() {
|
|||
_YesNoResult(context, ret, None, text)
|
||||
return ret
|
||||
|
||||
def CheckCC(context):
|
||||
"""
|
||||
Configure check for a working C compiler.
|
||||
|
||||
This checks whether the C compiler, as defined in the $CC construction
|
||||
variable, can compile a C source file. It uses the current $CCCOM value
|
||||
too, so that it can test against non working flags.
|
||||
|
||||
"""
|
||||
context.Display("Checking whether the C compiler works")
|
||||
text = """
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
ret = _check_empty_program(context, 'CC', text, 'C')
|
||||
_YesNoResult(context, ret, None, text)
|
||||
return ret
|
||||
|
||||
def CheckSHCC(context):
|
||||
"""
|
||||
Configure check for a working shared C compiler.
|
||||
|
||||
This checks whether the C compiler, as defined in the $SHCC construction
|
||||
variable, can compile a C source file. It uses the current $SHCCCOM value
|
||||
too, so that it can test against non working flags.
|
||||
|
||||
"""
|
||||
context.Display("Checking whether the (shared) C compiler works")
|
||||
text = """
|
||||
int foo()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
ret = _check_empty_program(context, 'SHCC', text, 'C', use_shared = True)
|
||||
_YesNoResult(context, ret, None, text)
|
||||
return ret
|
||||
|
||||
def CheckCXX(context):
|
||||
"""
|
||||
Configure check for a working CXX compiler.
|
||||
|
||||
This checks whether the CXX compiler, as defined in the $CXX construction
|
||||
variable, can compile a CXX source file. It uses the current $CXXCOM value
|
||||
too, so that it can test against non working flags.
|
||||
|
||||
"""
|
||||
context.Display("Checking whether the C++ compiler works")
|
||||
text = """
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
ret = _check_empty_program(context, 'CXX', text, 'C++')
|
||||
_YesNoResult(context, ret, None, text)
|
||||
return ret
|
||||
|
||||
def CheckSHCXX(context):
|
||||
"""
|
||||
Configure check for a working shared CXX compiler.
|
||||
|
||||
This checks whether the CXX compiler, as defined in the $SHCXX construction
|
||||
variable, can compile a CXX source file. It uses the current $SHCXXCOM value
|
||||
too, so that it can test against non working flags.
|
||||
|
||||
"""
|
||||
context.Display("Checking whether the (shared) C++ compiler works")
|
||||
text = """
|
||||
int main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
"""
|
||||
ret = _check_empty_program(context, 'SHCXX', text, 'C++', use_shared = True)
|
||||
_YesNoResult(context, ret, None, text)
|
||||
return ret
|
||||
|
||||
def _check_empty_program(context, comp, text, language, use_shared = False):
|
||||
"""Return 0 on success, 1 otherwise."""
|
||||
if not context.env.has_key(comp) or not context.env[comp]:
|
||||
# The compiler construction variable is not set or empty
|
||||
return 1
|
||||
|
||||
lang, suffix, msg = _lang2suffix(language)
|
||||
if msg:
|
||||
return 1
|
||||
|
||||
if use_shared:
|
||||
return context.CompileSharedObject(text, suffix)
|
||||
else:
|
||||
return context.CompileProg(text, suffix)
|
||||
|
||||
|
||||
def CheckFunc(context, function_name, header = None, language = None):
|
||||
"""
|
||||
|
@ -206,7 +301,9 @@ int main() {
|
|||
|
||||
context.Display("Checking for %s function %s()... " % (lang, function_name))
|
||||
ret = context.BuildProg(text, suffix)
|
||||
_YesNoResult(context, ret, "HAVE_" + function_name, text)
|
||||
_YesNoResult(context, ret, "HAVE_" + function_name, text,
|
||||
"Define to 1 if the system has the function `%s'." %\
|
||||
function_name)
|
||||
return ret
|
||||
|
||||
|
||||
|
@ -253,7 +350,8 @@ def CheckHeader(context, header_name, header = None, language = None,
|
|||
|
||||
context.Display("Checking for %s header file %s... " % (lang, header_name))
|
||||
ret = context.CompileProg(text, suffix)
|
||||
_YesNoResult(context, ret, "HAVE_" + header_name, text)
|
||||
_YesNoResult(context, ret, "HAVE_" + header_name, text,
|
||||
"Define to 1 if you have the <%s> header file." % header_name)
|
||||
return ret
|
||||
|
||||
|
||||
|
@ -310,7 +408,8 @@ int main() {
|
|||
|
||||
context.Display("Checking for %s type %s... " % (lang, type_name))
|
||||
ret = context.BuildProg(text, suffix)
|
||||
_YesNoResult(context, ret, "HAVE_" + type_name, text)
|
||||
_YesNoResult(context, ret, "HAVE_" + type_name, text,
|
||||
"Define to 1 if the system has the type `%s'." % type_name)
|
||||
if ret and fallback and context.headerfilename:
|
||||
f = open(context.headerfilename, "a")
|
||||
f.write("typedef %s %s;\n" % (fallback, type_name))
|
||||
|
@ -371,11 +470,11 @@ int main()
|
|||
}
|
||||
"""
|
||||
|
||||
# XXX: Try* vs CompileProg ?
|
||||
st = context.TryCompile(src % (type_name, expect), suffix)
|
||||
if st:
|
||||
_Have(context, "SIZEOF_" + type_name, str(expect))
|
||||
st = context.CompileProg(src % (type_name, expect), suffix)
|
||||
if not st:
|
||||
context.Display("yes\n")
|
||||
_Have(context, "SIZEOF_%s" % type_name, expect,
|
||||
"The size of `%s', as computed by sizeof." % type_name)
|
||||
return expect
|
||||
else:
|
||||
context.Display("no\n")
|
||||
|
@ -400,21 +499,78 @@ int main() {
|
|||
return 0;
|
||||
}
|
||||
"""
|
||||
ret = context.TryRun(src, suffix)
|
||||
st = ret[0]
|
||||
st, out = context.RunProg(src, suffix)
|
||||
try:
|
||||
size = int(ret[1])
|
||||
_Have(context, "SIZEOF_" + type_name, str(size))
|
||||
context.Display("%d\n" % size)
|
||||
size = int(out)
|
||||
except ValueError:
|
||||
# If cannot convert output of test prog to an integer (the size),
|
||||
# something went wront, so just fail
|
||||
st = 1
|
||||
size = 0
|
||||
_LogFailed(context, src, st)
|
||||
context.Display(" Failed !\n")
|
||||
if st:
|
||||
|
||||
if not st:
|
||||
context.Display("yes\n")
|
||||
_Have(context, "SIZEOF_%s" % type_name, size,
|
||||
"The size of `%s', as computed by sizeof." % type_name)
|
||||
return size
|
||||
else:
|
||||
context.Display("no\n")
|
||||
_LogFailed(context, src, st)
|
||||
return 0
|
||||
|
||||
return 0
|
||||
|
||||
def CheckDeclaration(context, symbol, includes = None, language = None):
|
||||
"""Checks whether symbol is declared.
|
||||
|
||||
Use the same test as autoconf, that is test whether the symbol is defined
|
||||
as a macro or can be used as an r-value.
|
||||
|
||||
Arguments:
|
||||
symbol : str
|
||||
the symbol to check
|
||||
includes : str
|
||||
Optional "header" can be defined to include a header file.
|
||||
language : str
|
||||
only C and C++ supported.
|
||||
|
||||
Returns:
|
||||
status : bool
|
||||
True if the check failed, False if succeeded."""
|
||||
|
||||
# Include "confdefs.h" first, so that the header can use HAVE_HEADER_H.
|
||||
if context.headerfilename:
|
||||
includetext = '#include "%s"' % context.headerfilename
|
||||
else:
|
||||
includetext = ''
|
||||
|
||||
if not includes:
|
||||
includes = ""
|
||||
|
||||
lang, suffix, msg = _lang2suffix(language)
|
||||
if msg:
|
||||
context.Display("Cannot check for declaration %s: %s\n" % (type_name, msg))
|
||||
return msg
|
||||
|
||||
src = includetext + includes
|
||||
context.Display('Checking whether %s is declared... ' % symbol)
|
||||
|
||||
src = src + r"""
|
||||
int main()
|
||||
{
|
||||
#ifndef %s
|
||||
(void) %s;
|
||||
#endif
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
""" % (symbol, symbol)
|
||||
|
||||
st = context.CompileProg(src, suffix)
|
||||
_YesNoResult(context, st, "HAVE_DECL_" + symbol, src,
|
||||
"Set to 1 if %s is defined." % symbol)
|
||||
return st
|
||||
|
||||
def CheckLib(context, libs, func_name = None, header = None,
|
||||
extra_libs = None, call = None, language = None, autoadd = 1):
|
||||
"""
|
||||
|
@ -509,7 +665,8 @@ return 0;
|
|||
|
||||
ret = context.BuildProg(text, suffix)
|
||||
|
||||
_YesNoResult(context, ret, sym, text)
|
||||
_YesNoResult(context, ret, sym, text,
|
||||
"Define to 1 if you have the `%s' library." % lib_name)
|
||||
if oldLIBS != -1 and (ret or not autoadd):
|
||||
context.SetLIBS(oldLIBS)
|
||||
|
||||
|
@ -522,15 +679,17 @@ return 0;
|
|||
# END OF PUBLIC FUNCTIONS
|
||||
#
|
||||
|
||||
def _YesNoResult(context, ret, key, text):
|
||||
def _YesNoResult(context, ret, key, text, comment = None):
|
||||
"""
|
||||
Handle the result of a test with a "yes" or "no" result.
|
||||
"ret" is the return value: empty if OK, error message when not.
|
||||
"key" is the name of the symbol to be defined (HAVE_foo).
|
||||
"text" is the source code of the program used for testing.
|
||||
"comment" is the C comment to add above the line defining the symbol (the
|
||||
comment is automatically put inside a /* */). If None, no comment is added.
|
||||
"""
|
||||
if key:
|
||||
_Have(context, key, not ret)
|
||||
_Have(context, key, not ret, comment)
|
||||
if ret:
|
||||
context.Display("no\n")
|
||||
_LogFailed(context, text, ret)
|
||||
|
@ -538,7 +697,7 @@ def _YesNoResult(context, ret, key, text):
|
|||
context.Display("yes\n")
|
||||
|
||||
|
||||
def _Have(context, key, have):
|
||||
def _Have(context, key, have, comment = None):
|
||||
"""
|
||||
Store result of a test in context.havedict and context.headerfilename.
|
||||
"key" is a "HAVE_abc" name. It is turned into all CAPITALS and non-
|
||||
|
@ -566,12 +725,17 @@ def _Have(context, key, have):
|
|||
else:
|
||||
line = "#define %s %s\n" % (key_up, str(have))
|
||||
|
||||
if comment is not None:
|
||||
lines = "\n/* %s */\n" % comment + line
|
||||
else:
|
||||
lines = "\n" + line
|
||||
|
||||
if context.headerfilename:
|
||||
f = open(context.headerfilename, "a")
|
||||
f.write(line)
|
||||
f.write(lines)
|
||||
f.close()
|
||||
elif hasattr(context,'config_h'):
|
||||
context.config_h = context.config_h + line
|
||||
context.config_h = context.config_h + lines
|
||||
|
||||
|
||||
def _LogFailed(context, text, msg):
|
|
@ -7,7 +7,7 @@ needed by most users.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -29,7 +29,7 @@ needed by most users.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Debug.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Debug.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os
|
||||
import string
|
||||
|
@ -115,39 +115,57 @@ else:
|
|||
res = resource.getrusage(resource.RUSAGE_SELF)
|
||||
return res[4]
|
||||
|
||||
|
||||
|
||||
caller_dicts = {}
|
||||
|
||||
def caller(*backlist):
|
||||
# returns caller's stack
|
||||
def caller_stack(*backlist):
|
||||
import traceback
|
||||
if not backlist:
|
||||
backlist = [0]
|
||||
result = []
|
||||
for back in backlist:
|
||||
tb = traceback.extract_stack(limit=3+back)
|
||||
key = tb[1][:3]
|
||||
try:
|
||||
entry = caller_dicts[key]
|
||||
except KeyError:
|
||||
entry = caller_dicts[key] = {}
|
||||
key = tb[0][:3]
|
||||
entry[key] = entry.get(key, 0) + 1
|
||||
result.append('%s:%d(%s)' % func_shorten(key))
|
||||
return result
|
||||
|
||||
caller_bases = {}
|
||||
caller_dicts = {}
|
||||
|
||||
# trace a caller's stack
|
||||
def caller_trace(back=0):
|
||||
import traceback
|
||||
tb = traceback.extract_stack(limit=3+back)
|
||||
tb.reverse()
|
||||
callee = tb[1][:3]
|
||||
caller_bases[callee] = caller_bases.get(callee, 0) + 1
|
||||
for caller in tb[2:]:
|
||||
caller = callee + caller[:3]
|
||||
try:
|
||||
entry = caller_dicts[callee]
|
||||
except KeyError:
|
||||
caller_dicts[callee] = entry = {}
|
||||
entry[caller] = entry.get(caller, 0) + 1
|
||||
callee = caller
|
||||
|
||||
# print a single caller and its callers, if any
|
||||
def _dump_one_caller(key, file, level=0):
|
||||
l = []
|
||||
for c,v in caller_dicts[key].items():
|
||||
l.append((-v,c))
|
||||
l.sort()
|
||||
leader = ' '*level
|
||||
for v,c in l:
|
||||
file.write("%s %6d %s:%d(%s)\n" % ((leader,-v) + func_shorten(c[-3:])))
|
||||
if caller_dicts.has_key(c):
|
||||
_dump_one_caller(c, file, level+1)
|
||||
|
||||
# print each call tree
|
||||
def dump_caller_counts(file=sys.stdout):
|
||||
keys = caller_dicts.keys()
|
||||
keys = caller_bases.keys()
|
||||
keys.sort()
|
||||
for k in keys:
|
||||
file.write("Callers of %s:%d(%s):\n" % func_shorten(k))
|
||||
counts = caller_dicts[k]
|
||||
callers = counts.keys()
|
||||
callers.sort()
|
||||
for c in callers:
|
||||
#file.write(" counts[%s] = %s\n" % (c, counts[c]))
|
||||
t = ((counts[c],) + func_shorten(c))
|
||||
file.write(" %6d %s:%d(%s)\n" % t)
|
||||
file.write("Callers of %s:%d(%s), %d calls:\n"
|
||||
% (func_shorten(k) + (caller_bases[k],)))
|
||||
_dump_one_caller(k, file)
|
||||
|
||||
shorten_list = [
|
||||
( '/scons/SCons/', 1),
|
||||
|
@ -168,10 +186,8 @@ def func_shorten(func_tuple):
|
|||
if i >= 0:
|
||||
if t[1]:
|
||||
i = i + len(t[0])
|
||||
f = f[i:]
|
||||
break
|
||||
return (f,)+func_tuple[1:]
|
||||
|
||||
return (f[i:],)+func_tuple[1:]
|
||||
return func_tuple
|
||||
|
||||
|
||||
TraceFP = {}
|
|
@ -10,7 +10,7 @@ from distutils.msvccompiler.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -32,7 +32,7 @@ from distutils.msvccompiler.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Defaults.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Defaults.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
|
||||
|
||||
|
@ -40,6 +40,7 @@ import os
|
|||
import os.path
|
||||
import shutil
|
||||
import stat
|
||||
import string
|
||||
import time
|
||||
import types
|
||||
import sys
|
||||
|
@ -93,7 +94,7 @@ def DefaultEnvironment(*args, **kw):
|
|||
_default_env.Decider('timestamp-match')
|
||||
global DefaultEnvironment
|
||||
DefaultEnvironment = _fetch_DefaultEnvironment
|
||||
_default_env._CacheDir = SCons.CacheDir.Null()
|
||||
_default_env._CacheDir_path = None
|
||||
return _default_env
|
||||
|
||||
# Emitters for setting the shared attribute on object files,
|
||||
|
@ -157,19 +158,36 @@ LdModuleLinkAction = SCons.Action.Action("$LDMODULECOM", "$LDMODULECOMSTR")
|
|||
# ways by creating ActionFactory instances.
|
||||
ActionFactory = SCons.Action.ActionFactory
|
||||
|
||||
def chmod_func(path, mode):
|
||||
return os.chmod(str(path), mode)
|
||||
def get_paths_str(dest):
|
||||
# If dest is a list, we need to manually call str() on each element
|
||||
if SCons.Util.is_List(dest):
|
||||
elem_strs = []
|
||||
for element in dest:
|
||||
elem_strs.append('"' + str(element) + '"')
|
||||
return '[' + string.join(elem_strs, ', ') + ']'
|
||||
else:
|
||||
return '"' + str(dest) + '"'
|
||||
|
||||
Chmod = ActionFactory(chmod_func,
|
||||
lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
|
||||
def chmod_func(dest, mode):
|
||||
SCons.Node.FS.invalidate_node_memos(dest)
|
||||
if not SCons.Util.is_List(dest):
|
||||
dest = [dest]
|
||||
for element in dest:
|
||||
os.chmod(str(element), mode)
|
||||
|
||||
def chmod_strfunc(dest, mode):
|
||||
return 'Chmod(%s, 0%o)' % (get_paths_str(dest), mode)
|
||||
|
||||
Chmod = ActionFactory(chmod_func, chmod_strfunc)
|
||||
|
||||
def copy_func(dest, src):
|
||||
SCons.Node.FS.invalidate_node_memos(dest)
|
||||
if SCons.Util.is_List(src) and os.path.isdir(dest):
|
||||
for file in src:
|
||||
shutil.copy(file, dest)
|
||||
shutil.copy2(file, dest)
|
||||
return 0
|
||||
elif os.path.isfile(src):
|
||||
return shutil.copy(src, dest)
|
||||
return shutil.copy2(src, dest)
|
||||
else:
|
||||
return shutil.copytree(src, dest, 1)
|
||||
|
||||
|
@ -177,40 +195,61 @@ Copy = ActionFactory(copy_func,
|
|||
lambda dest, src: 'Copy("%s", "%s")' % (dest, src),
|
||||
convert=str)
|
||||
|
||||
def delete_func(entry, must_exist=0):
|
||||
entry = str(entry)
|
||||
if not must_exist and not os.path.exists(entry):
|
||||
return None
|
||||
if not os.path.exists(entry) or os.path.isfile(entry):
|
||||
return os.unlink(entry)
|
||||
else:
|
||||
return shutil.rmtree(entry, 1)
|
||||
def delete_func(dest, must_exist=0):
|
||||
SCons.Node.FS.invalidate_node_memos(dest)
|
||||
if not SCons.Util.is_List(dest):
|
||||
dest = [dest]
|
||||
for entry in dest:
|
||||
entry = str(entry)
|
||||
if not must_exist and not os.path.exists(entry):
|
||||
continue
|
||||
if not os.path.exists(entry) or os.path.isfile(entry):
|
||||
os.unlink(entry)
|
||||
continue
|
||||
else:
|
||||
shutil.rmtree(entry, 1)
|
||||
continue
|
||||
|
||||
def delete_strfunc(entry, must_exist=0):
|
||||
return 'Delete("%s")' % entry
|
||||
def delete_strfunc(dest, must_exist=0):
|
||||
return 'Delete(%s)' % get_paths_str(dest)
|
||||
|
||||
Delete = ActionFactory(delete_func, delete_strfunc)
|
||||
|
||||
Mkdir = ActionFactory(os.makedirs,
|
||||
lambda dir: 'Mkdir("%s")' % dir,
|
||||
convert=str)
|
||||
def mkdir_func(dest):
|
||||
SCons.Node.FS.invalidate_node_memos(dest)
|
||||
if not SCons.Util.is_List(dest):
|
||||
dest = [dest]
|
||||
for entry in dest:
|
||||
os.makedirs(str(entry))
|
||||
|
||||
Move = ActionFactory(lambda dest, src: os.rename(src, dest),
|
||||
Mkdir = ActionFactory(mkdir_func,
|
||||
lambda dir: 'Mkdir(%s)' % get_paths_str(dir))
|
||||
|
||||
def move_func(dest, src):
|
||||
SCons.Node.FS.invalidate_node_memos(dest)
|
||||
SCons.Node.FS.invalidate_node_memos(src)
|
||||
os.rename(src, dest)
|
||||
|
||||
Move = ActionFactory(move_func,
|
||||
lambda dest, src: 'Move("%s", "%s")' % (dest, src),
|
||||
convert=str)
|
||||
|
||||
def touch_func(file):
|
||||
file = str(file)
|
||||
mtime = int(time.time())
|
||||
if os.path.exists(file):
|
||||
atime = os.path.getatime(file)
|
||||
else:
|
||||
open(file, 'w')
|
||||
atime = mtime
|
||||
return os.utime(file, (atime, mtime))
|
||||
def touch_func(dest):
|
||||
SCons.Node.FS.invalidate_node_memos(dest)
|
||||
if not SCons.Util.is_List(dest):
|
||||
dest = [dest]
|
||||
for file in dest:
|
||||
file = str(file)
|
||||
mtime = int(time.time())
|
||||
if os.path.exists(file):
|
||||
atime = os.path.getatime(file)
|
||||
else:
|
||||
open(file, 'w')
|
||||
atime = mtime
|
||||
os.utime(file, (atime, mtime))
|
||||
|
||||
Touch = ActionFactory(touch_func,
|
||||
lambda file: 'Touch("%s")' % file)
|
||||
lambda file: 'Touch(%s)' % get_paths_str(file))
|
||||
|
||||
# Internal utility functions
|
||||
|
||||
|
@ -224,9 +263,6 @@ def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None):
|
|||
if not list:
|
||||
return list
|
||||
|
||||
if SCons.Util.is_List(list):
|
||||
list = SCons.Util.flatten(list)
|
||||
|
||||
l = f(SCons.PathList.PathList(list).subst_path(env, target, source))
|
||||
if not l is None:
|
||||
list = l
|
||||
|
@ -270,7 +306,7 @@ def _concat_ixes(prefix, list, suffix, env):
|
|||
|
||||
return result
|
||||
|
||||
def _stripixes(prefix, list, suffix, stripprefix, stripsuffix, env, c=None):
|
||||
def _stripixes(prefix, list, suffix, stripprefixes, stripsuffixes, env, c=None):
|
||||
"""
|
||||
This is a wrapper around _concat()/_concat_ixes() that checks for the
|
||||
existence of prefixes or suffixes on list elements and strips them
|
||||
|
@ -292,22 +328,32 @@ def _stripixes(prefix, list, suffix, stripprefix, stripsuffix, env, c=None):
|
|||
else:
|
||||
c = _concat_ixes
|
||||
|
||||
if SCons.Util.is_List(list):
|
||||
list = SCons.Util.flatten(list)
|
||||
stripprefixes = map(env.subst, SCons.Util.flatten(stripprefixes))
|
||||
stripsuffixes = map(env.subst, SCons.Util.flatten(stripsuffixes))
|
||||
|
||||
lsp = len(stripprefix)
|
||||
lss = len(stripsuffix)
|
||||
stripped = []
|
||||
for l in SCons.PathList.PathList(list).subst_path(env, None, None):
|
||||
if isinstance(l, SCons.Node.FS.File):
|
||||
stripped.append(l)
|
||||
continue
|
||||
|
||||
if not SCons.Util.is_String(l):
|
||||
l = str(l)
|
||||
if l[:lsp] == stripprefix:
|
||||
l = l[lsp:]
|
||||
if l[-lss:] == stripsuffix:
|
||||
l = l[:-lss]
|
||||
|
||||
for stripprefix in stripprefixes:
|
||||
lsp = len(stripprefix)
|
||||
if l[:lsp] == stripprefix:
|
||||
l = l[lsp:]
|
||||
# Do not strip more than one prefix
|
||||
break
|
||||
|
||||
for stripsuffix in stripsuffixes:
|
||||
lss = len(stripsuffix)
|
||||
if l[-lss:] == stripsuffix:
|
||||
l = l[:-lss]
|
||||
# Do not strip more than one suffix
|
||||
break
|
||||
|
||||
stripped.append(l)
|
||||
|
||||
return c(prefix, stripped, suffix, env)
|
||||
|
@ -378,7 +424,10 @@ class Variable_Method_Caller:
|
|||
self.method = method
|
||||
def __call__(self, *args, **kw):
|
||||
try: 1/0
|
||||
except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame
|
||||
except ZeroDivisionError:
|
||||
# Don't start iterating with the current stack-frame to
|
||||
# prevent creating reference cycles (f_back is safe).
|
||||
frame = sys.exc_info()[2].tb_frame.f_back
|
||||
variable = self.variable
|
||||
while frame:
|
||||
if frame.f_locals.has_key(variable):
|
|
@ -10,7 +10,7 @@ Environment
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -32,12 +32,13 @@ Environment
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Environment.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Environment.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
|
||||
import copy
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
import re
|
||||
import shlex
|
||||
import string
|
||||
from UserDict import UserDict
|
||||
|
@ -64,6 +65,10 @@ class _Null:
|
|||
|
||||
_null = _Null
|
||||
|
||||
_warn_copy_deprecated = True
|
||||
_warn_source_signatures_deprecated = True
|
||||
_warn_target_signatures_deprecated = True
|
||||
|
||||
CleanTargets = {}
|
||||
CalculatorArgs = {}
|
||||
|
||||
|
@ -100,24 +105,40 @@ def apply_tools(env, tools, toolpath):
|
|||
else:
|
||||
env.Tool(tool)
|
||||
|
||||
# These names are controlled by SCons; users should never set or override
|
||||
# them. This warning can optionally be turned off, but scons will still
|
||||
# ignore the illegal variable names even if it's off.
|
||||
reserved_construction_var_names = \
|
||||
['TARGET', 'TARGETS', 'SOURCE', 'SOURCES']
|
||||
# These names are (or will be) controlled by SCons; users should never
|
||||
# set or override them. This warning can optionally be turned off,
|
||||
# but scons will still ignore the illegal variable names even if it's off.
|
||||
reserved_construction_var_names = [
|
||||
'SOURCE',
|
||||
'SOURCES',
|
||||
'TARGET',
|
||||
'TARGETS',
|
||||
]
|
||||
|
||||
future_reserved_construction_var_names = [
|
||||
'CHANGED_SOURCES',
|
||||
'CHANGED_TARGETS',
|
||||
'UNCHANGED_SOURCES',
|
||||
'UNCHANGED_TARGETS',
|
||||
]
|
||||
|
||||
def copy_non_reserved_keywords(dict):
|
||||
result = semi_deepcopy(dict)
|
||||
for k in result.keys():
|
||||
if k in reserved_construction_var_names:
|
||||
SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning,
|
||||
"Ignoring attempt to set reserved variable `%s'" % k)
|
||||
msg = "Ignoring attempt to set reserved variable `$%s'"
|
||||
SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % k)
|
||||
del result[k]
|
||||
return result
|
||||
|
||||
def _set_reserved(env, key, value):
|
||||
msg = "Ignoring attempt to set reserved variable `%s'" % key
|
||||
SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg)
|
||||
msg = "Ignoring attempt to set reserved variable `$%s'"
|
||||
SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % key)
|
||||
|
||||
def _set_future_reserved(env, key, value):
|
||||
env._dict[key] = value
|
||||
msg = "`$%s' will be reserved in a future release and setting it will become ignored"
|
||||
SCons.Warnings.warn(SCons.Warnings.FutureReservedVariableWarning, msg % key)
|
||||
|
||||
def _set_BUILDERS(env, key, value):
|
||||
try:
|
||||
|
@ -137,6 +158,24 @@ def _set_SCANNERS(env, key, value):
|
|||
env._dict[key] = value
|
||||
env.scanner_map_delete()
|
||||
|
||||
def _delete_duplicates(l, keep_last):
|
||||
"""Delete duplicates from a sequence, keeping the first or last."""
|
||||
seen={}
|
||||
result=[]
|
||||
if keep_last: # reverse in & out, then keep first
|
||||
l.reverse()
|
||||
for i in l:
|
||||
try:
|
||||
if not seen.has_key(i):
|
||||
result.append(i)
|
||||
seen[i]=1
|
||||
except TypeError:
|
||||
# probably unhashable. Just keep it.
|
||||
result.append(i)
|
||||
if keep_last:
|
||||
result.reverse()
|
||||
return result
|
||||
|
||||
|
||||
|
||||
# The following is partly based on code in a comment added by Peter
|
||||
|
@ -225,7 +264,7 @@ class BuilderWrapper(MethodWrapper):
|
|||
elif name == 'builder':
|
||||
return self.method
|
||||
else:
|
||||
return self.__dict__[name]
|
||||
raise AttributeError, name
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if name == 'env':
|
||||
|
@ -279,6 +318,18 @@ class BuilderDict(UserDict):
|
|||
for i, v in dict.items():
|
||||
self.__setitem__(i, v)
|
||||
|
||||
|
||||
|
||||
_is_valid_var = re.compile(r'[_a-zA-Z]\w*$')
|
||||
|
||||
def is_valid_construction_var(varstr):
|
||||
"""Return if the specified string is a legitimate construction
|
||||
variable.
|
||||
"""
|
||||
return _is_valid_var.match(varstr)
|
||||
|
||||
|
||||
|
||||
class SubstitutionEnvironment:
|
||||
"""Base class for different flavors of construction environments.
|
||||
|
||||
|
@ -329,9 +380,16 @@ class SubstitutionEnvironment:
|
|||
self._special_set = {}
|
||||
for key in reserved_construction_var_names:
|
||||
self._special_set[key] = _set_reserved
|
||||
for key in future_reserved_construction_var_names:
|
||||
self._special_set[key] = _set_future_reserved
|
||||
self._special_set['BUILDERS'] = _set_BUILDERS
|
||||
self._special_set['SCANNERS'] = _set_SCANNERS
|
||||
|
||||
# Freeze the keys of self._special_set in a list for use by
|
||||
# methods that need to check. (Empirically, list scanning has
|
||||
# gotten better than dict.has_key() in Python 2.5.)
|
||||
self._special_set_keys = self._special_set.keys()
|
||||
|
||||
def __cmp__(self, other):
|
||||
return cmp(self._dict, other._dict)
|
||||
|
||||
|
@ -346,12 +404,28 @@ class SubstitutionEnvironment:
|
|||
return self._dict[key]
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
special = self._special_set.get(key)
|
||||
if special:
|
||||
special(self, key, value)
|
||||
# This is heavily used. This implementation is the best we have
|
||||
# according to the timings in bench/env.__setitem__.py.
|
||||
#
|
||||
# The "key in self._special_set_keys" test here seems to perform
|
||||
# pretty well for the number of keys we have. A hard-coded
|
||||
# list works a little better in Python 2.5, but that has the
|
||||
# disadvantage of maybe getting out of sync if we ever add more
|
||||
# variable names. Using self._special_set.has_key() works a
|
||||
# little better in Python 2.4, but is worse then this test.
|
||||
# So right now it seems like a good trade-off, but feel free to
|
||||
# revisit this with bench/env.__setitem__.py as needed (and
|
||||
# as newer versions of Python come out).
|
||||
if key in self._special_set_keys:
|
||||
self._special_set[key](self, key, value)
|
||||
else:
|
||||
if not SCons.Util.is_valid_construction_var(key):
|
||||
raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key
|
||||
# If we already have the entry, then it's obviously a valid
|
||||
# key and we don't need to check. If we do check, using a
|
||||
# global, pre-compiled regular expression directly is more
|
||||
# efficient than calling another function or a method.
|
||||
if not self._dict.has_key(key) \
|
||||
and not _is_valid_var.match(key):
|
||||
raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key
|
||||
self._dict[key] = value
|
||||
|
||||
def get(self, key, default=None):
|
||||
|
@ -361,6 +435,9 @@ class SubstitutionEnvironment:
|
|||
def has_key(self, key):
|
||||
return self._dict.has_key(key)
|
||||
|
||||
def __contains__(self, key):
|
||||
return self._dict.__contains__(key)
|
||||
|
||||
def items(self):
|
||||
return self._dict.items()
|
||||
|
||||
|
@ -373,10 +450,7 @@ class SubstitutionEnvironment:
|
|||
if not args:
|
||||
return []
|
||||
|
||||
if SCons.Util.is_List(args):
|
||||
args = SCons.Util.flatten(args)
|
||||
else:
|
||||
args = [args]
|
||||
args = SCons.Util.flatten(args)
|
||||
|
||||
nodes = []
|
||||
for v in args:
|
||||
|
@ -465,7 +539,7 @@ class SubstitutionEnvironment:
|
|||
try:
|
||||
get = obj.get
|
||||
except AttributeError:
|
||||
pass
|
||||
obj = SCons.Util.to_String_for_subst(obj)
|
||||
else:
|
||||
obj = get()
|
||||
return obj
|
||||
|
@ -481,7 +555,7 @@ class SubstitutionEnvironment:
|
|||
# We have an object plus a string, or multiple
|
||||
# objects that we need to smush together. No choice
|
||||
# but to make them into a string.
|
||||
p = string.join(map(SCons.Util.to_String, p), '')
|
||||
p = string.join(map(SCons.Util.to_String_for_subst, p), '')
|
||||
else:
|
||||
p = s(p)
|
||||
r.append(p)
|
||||
|
@ -491,24 +565,21 @@ class SubstitutionEnvironment:
|
|||
|
||||
def backtick(self, command):
|
||||
import subprocess
|
||||
if SCons.Util.is_List(command):
|
||||
p = subprocess.Popen(command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
else:
|
||||
p = subprocess.Popen(command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
universal_newlines=True,
|
||||
shell=True)
|
||||
out = p.stdout.read()
|
||||
p.stdout.close()
|
||||
err = p.stderr.read()
|
||||
p.stderr.close()
|
||||
# common arguments
|
||||
kw = { 'stdin' : 'devnull',
|
||||
'stdout' : subprocess.PIPE,
|
||||
'stderr' : subprocess.PIPE,
|
||||
'universal_newlines' : True,
|
||||
}
|
||||
# if the command is a list, assume it's been quoted
|
||||
# othewise force a shell
|
||||
if not SCons.Util.is_List(command): kw['shell'] = True
|
||||
# run constructed command
|
||||
#TODO(1.5) p = SCons.Action._subproc(self, command, **kw)
|
||||
p = apply(SCons.Action._subproc, (self, command), kw)
|
||||
out,err = p.communicate()
|
||||
status = p.wait()
|
||||
if err:
|
||||
import sys
|
||||
sys.stderr.write(err)
|
||||
if status:
|
||||
raise OSError("'%s' exited %d" % (command, status))
|
||||
|
@ -543,16 +614,19 @@ class SubstitutionEnvironment:
|
|||
environment, and doesn't even create a wrapper object if there
|
||||
are no overrides.
|
||||
"""
|
||||
if overrides:
|
||||
o = copy_non_reserved_keywords(overrides)
|
||||
overrides = {}
|
||||
for key, value in o.items():
|
||||
if not overrides: return self
|
||||
o = copy_non_reserved_keywords(overrides)
|
||||
if not o: return self
|
||||
overrides = {}
|
||||
merges = None
|
||||
for key, value in o.items():
|
||||
if key == 'parse_flags':
|
||||
merges = value
|
||||
else:
|
||||
overrides[key] = SCons.Subst.scons_subst_once(value, self, key)
|
||||
if overrides:
|
||||
env = OverrideEnvironment(self, overrides)
|
||||
return env
|
||||
else:
|
||||
return self
|
||||
env = OverrideEnvironment(self, overrides)
|
||||
if merges: env.MergeFlags(merges)
|
||||
return env
|
||||
|
||||
def ParseFlags(self, *flags):
|
||||
"""
|
||||
|
@ -709,13 +783,16 @@ class SubstitutionEnvironment:
|
|||
do_parse(arg, do_parse)
|
||||
return dict
|
||||
|
||||
def MergeFlags(self, args, unique=1):
|
||||
def MergeFlags(self, args, unique=1, dict=None):
|
||||
"""
|
||||
Merge the dict in args into the construction variables. If args
|
||||
is not a dict, it is converted into a dict using ParseFlags.
|
||||
If unique is not set, the flags are appended rather than merged.
|
||||
Merge the dict in args into the construction variables of this
|
||||
env, or the passed-in dict. If args is not a dict, it is
|
||||
converted into a dict using ParseFlags. If unique is not set,
|
||||
the flags are appended rather than merged.
|
||||
"""
|
||||
|
||||
if dict is None:
|
||||
dict = self
|
||||
if not SCons.Util.is_Dict(args):
|
||||
args = self.ParseFlags(args)
|
||||
if not unique:
|
||||
|
@ -763,6 +840,26 @@ class SubstitutionEnvironment:
|
|||
self[key] = t
|
||||
return self
|
||||
|
||||
# def MergeShellPaths(self, args, prepend=1):
|
||||
# """
|
||||
# Merge the dict in args into the shell environment in env['ENV'].
|
||||
# Shell path elements are appended or prepended according to prepend.
|
||||
|
||||
# Uses Pre/AppendENVPath, so it always appends or prepends uniquely.
|
||||
|
||||
# Example: env.MergeShellPaths({'LIBPATH': '/usr/local/lib'})
|
||||
# prepends /usr/local/lib to env['ENV']['LIBPATH'].
|
||||
# """
|
||||
|
||||
# for pathname, pathval in args.items():
|
||||
# if not pathval:
|
||||
# continue
|
||||
# if prepend:
|
||||
# apply(self.PrependENVPath, (pathname, pathval))
|
||||
# else:
|
||||
# apply(self.AppendENVPath, (pathname, pathval))
|
||||
|
||||
|
||||
# Used by the FindSourceFiles() method, below.
|
||||
# Stuck here for support of pre-2.2 Python versions.
|
||||
def build_source(ss, result):
|
||||
|
@ -819,7 +916,8 @@ class Base(SubstitutionEnvironment):
|
|||
platform=None,
|
||||
tools=None,
|
||||
toolpath=None,
|
||||
options=None,
|
||||
variables=None,
|
||||
parse_flags = None,
|
||||
**kw):
|
||||
"""
|
||||
Initialization of a basic SCons construction environment,
|
||||
|
@ -862,14 +960,19 @@ class Base(SubstitutionEnvironment):
|
|||
self._dict['PLATFORM'] = str(platform)
|
||||
platform(self)
|
||||
|
||||
# Apply the passed-in variables and customizable options to the
|
||||
# Apply the passed-in and customizable variables to the
|
||||
# environment before calling the tools, because they may use
|
||||
# some of them during initialization.
|
||||
if kw.has_key('options'):
|
||||
# Backwards compatibility: they may stll be using the
|
||||
# old "options" keyword.
|
||||
variables = kw['options']
|
||||
del kw['options']
|
||||
apply(self.Replace, (), kw)
|
||||
keys = kw.keys()
|
||||
if options:
|
||||
keys = keys + options.keys()
|
||||
options.Update(self)
|
||||
if variables:
|
||||
keys = keys + variables.keys()
|
||||
variables.Update(self)
|
||||
|
||||
save = {}
|
||||
for k in keys:
|
||||
|
@ -888,12 +991,15 @@ class Base(SubstitutionEnvironment):
|
|||
tools = ['default']
|
||||
apply_tools(self, tools, toolpath)
|
||||
|
||||
# Now restore the passed-in variables and customized options
|
||||
# Now restore the passed-in and customized variables
|
||||
# to the environment, since the values the user set explicitly
|
||||
# should override any values set by the tools.
|
||||
for key, val in save.items():
|
||||
self._dict[key] = val
|
||||
|
||||
# Finally, apply any flags to be merged in
|
||||
if parse_flags: self.MergeFlags(parse_flags)
|
||||
|
||||
#######################################################################
|
||||
# Utility methods that are primarily for internal use by SCons.
|
||||
# These begin with lower-case letters.
|
||||
|
@ -909,11 +1015,18 @@ class Base(SubstitutionEnvironment):
|
|||
|
||||
def get_CacheDir(self):
|
||||
try:
|
||||
return self._CacheDir
|
||||
path = self._CacheDir_path
|
||||
except AttributeError:
|
||||
cd = SCons.Defaults.DefaultEnvironment()._CacheDir
|
||||
self._CacheDir = cd
|
||||
return cd
|
||||
path = SCons.Defaults.DefaultEnvironment()._CacheDir_path
|
||||
try:
|
||||
if path == self._last_CacheDir_path:
|
||||
return self._last_CacheDir
|
||||
except AttributeError:
|
||||
pass
|
||||
cd = SCons.CacheDir.CacheDir(path)
|
||||
self._last_CacheDir_path = path
|
||||
self._last_CacheDir = cd
|
||||
return cd
|
||||
|
||||
def get_factory(self, factory, default='File'):
|
||||
"""Return a factory function for creating Nodes for this
|
||||
|
@ -1085,31 +1198,39 @@ class Base(SubstitutionEnvironment):
|
|||
orig[val] = None
|
||||
self.scanner_map_delete(kw)
|
||||
|
||||
def AppendENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep):
|
||||
def AppendENVPath(self, name, newpath, envname = 'ENV',
|
||||
sep = os.pathsep, delete_existing=1):
|
||||
"""Append path elements to the path 'name' in the 'ENV'
|
||||
dictionary for this environment. Will only add any particular
|
||||
path once, and will normpath and normcase all paths to help
|
||||
assure this. This can also handle the case where the env
|
||||
variable is a list instead of a string.
|
||||
|
||||
If delete_existing is 0, a newpath which is already in the path
|
||||
will not be moved to the end (it will be left where it is).
|
||||
"""
|
||||
|
||||
orig = ''
|
||||
if self._dict.has_key(envname) and self._dict[envname].has_key(name):
|
||||
orig = self._dict[envname][name]
|
||||
|
||||
nv = SCons.Util.AppendPath(orig, newpath, sep)
|
||||
nv = SCons.Util.AppendPath(orig, newpath, sep, delete_existing)
|
||||
|
||||
if not self._dict.has_key(envname):
|
||||
self._dict[envname] = {}
|
||||
|
||||
self._dict[envname][name] = nv
|
||||
|
||||
def AppendUnique(self, **kw):
|
||||
def AppendUnique(self, delete_existing=0, **kw):
|
||||
"""Append values to existing construction variables
|
||||
in an Environment, if they're not already there.
|
||||
If delete_existing is 1, removes existing values first, so
|
||||
values move to end.
|
||||
"""
|
||||
kw = copy_non_reserved_keywords(kw)
|
||||
for key, val in kw.items():
|
||||
if SCons.Util.is_List(val):
|
||||
val = _delete_duplicates(val, delete_existing)
|
||||
if not self._dict.has_key(key) or self._dict[key] in ('', None):
|
||||
self._dict[key] = val
|
||||
elif SCons.Util.is_Dict(self._dict[key]) and \
|
||||
|
@ -1119,20 +1240,29 @@ class Base(SubstitutionEnvironment):
|
|||
dk = self._dict[key]
|
||||
if not SCons.Util.is_List(dk):
|
||||
dk = [dk]
|
||||
val = filter(lambda x, dk=dk: x not in dk, val)
|
||||
if delete_existing:
|
||||
dk = filter(lambda x, val=val: x not in val, dk)
|
||||
else:
|
||||
val = filter(lambda x, dk=dk: x not in dk, val)
|
||||
self._dict[key] = dk + val
|
||||
else:
|
||||
dk = self._dict[key]
|
||||
if SCons.Util.is_List(dk):
|
||||
# By elimination, val is not a list. Since dk is a
|
||||
# list, wrap val in a list first.
|
||||
if not val in dk:
|
||||
if delete_existing:
|
||||
dk = filter(lambda x, val=val: x not in val, dk)
|
||||
self._dict[key] = dk + [val]
|
||||
else:
|
||||
if not val in dk:
|
||||
self._dict[key] = dk + [val]
|
||||
else:
|
||||
self._dict[key] = self._dict[key] + val
|
||||
if delete_existing:
|
||||
dk = filter(lambda x, val=val: x not in val, dk)
|
||||
self._dict[key] = dk + val
|
||||
self.scanner_map_delete(kw)
|
||||
|
||||
def Clone(self, tools=[], toolpath=None, **kw):
|
||||
def Clone(self, tools=[], toolpath=None, parse_flags = None, **kw):
|
||||
"""Return a copy of a construction Environment. The
|
||||
copy is like a Python "deep copy"--that is, independent
|
||||
copies are made recursively of each objects--except that
|
||||
|
@ -1150,9 +1280,14 @@ class Base(SubstitutionEnvironment):
|
|||
else:
|
||||
clone._dict['BUILDERS'] = BuilderDict(cbd, clone)
|
||||
|
||||
# Check the methods added via AddMethod() and re-bind them to
|
||||
# the cloned environment. Only do this if the attribute hasn't
|
||||
# been overwritten by the user explicitly and still points to
|
||||
# the added method.
|
||||
clone.added_methods = []
|
||||
for mw in self.added_methods:
|
||||
clone.added_methods.append(mw.clone(clone))
|
||||
if mw == getattr(self, mw.name):
|
||||
clone.added_methods.append(mw.clone(clone))
|
||||
|
||||
clone._memo = {}
|
||||
|
||||
|
@ -1169,10 +1304,18 @@ class Base(SubstitutionEnvironment):
|
|||
# apply them again in case the tools overwrote them
|
||||
apply(clone.Replace, (), new)
|
||||
|
||||
# Finally, apply any flags to be merged in
|
||||
if parse_flags: clone.MergeFlags(parse_flags)
|
||||
|
||||
if __debug__: logInstanceCreation(self, 'Environment.EnvironmentClone')
|
||||
return clone
|
||||
|
||||
def Copy(self, *args, **kw):
|
||||
global _warn_copy_deprecated
|
||||
if _warn_copy_deprecated:
|
||||
msg = "The env.Copy() method is deprecated; use the env.Clone() method instead."
|
||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedCopyWarning, msg)
|
||||
_warn_copy_deprecated = False
|
||||
return apply(self.Clone, args, kw)
|
||||
|
||||
def _changed_build(self, dependency, target, prev_ni):
|
||||
|
@ -1410,31 +1553,39 @@ class Base(SubstitutionEnvironment):
|
|||
orig[val] = None
|
||||
self.scanner_map_delete(kw)
|
||||
|
||||
def PrependENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep):
|
||||
def PrependENVPath(self, name, newpath, envname = 'ENV', sep = os.pathsep,
|
||||
delete_existing=1):
|
||||
"""Prepend path elements to the path 'name' in the 'ENV'
|
||||
dictionary for this environment. Will only add any particular
|
||||
path once, and will normpath and normcase all paths to help
|
||||
assure this. This can also handle the case where the env
|
||||
variable is a list instead of a string.
|
||||
|
||||
If delete_existing is 0, a newpath which is already in the path
|
||||
will not be moved to the front (it will be left where it is).
|
||||
"""
|
||||
|
||||
orig = ''
|
||||
if self._dict.has_key(envname) and self._dict[envname].has_key(name):
|
||||
orig = self._dict[envname][name]
|
||||
|
||||
nv = SCons.Util.PrependPath(orig, newpath, sep)
|
||||
nv = SCons.Util.PrependPath(orig, newpath, sep, delete_existing)
|
||||
|
||||
if not self._dict.has_key(envname):
|
||||
self._dict[envname] = {}
|
||||
|
||||
self._dict[envname][name] = nv
|
||||
|
||||
def PrependUnique(self, **kw):
|
||||
"""Append values to existing construction variables
|
||||
def PrependUnique(self, delete_existing=0, **kw):
|
||||
"""Prepend values to existing construction variables
|
||||
in an Environment, if they're not already there.
|
||||
If delete_existing is 1, removes existing values first, so
|
||||
values move to front.
|
||||
"""
|
||||
kw = copy_non_reserved_keywords(kw)
|
||||
for key, val in kw.items():
|
||||
if SCons.Util.is_List(val):
|
||||
val = _delete_duplicates(val, not delete_existing)
|
||||
if not self._dict.has_key(key) or self._dict[key] in ('', None):
|
||||
self._dict[key] = val
|
||||
elif SCons.Util.is_Dict(self._dict[key]) and \
|
||||
|
@ -1444,16 +1595,25 @@ class Base(SubstitutionEnvironment):
|
|||
dk = self._dict[key]
|
||||
if not SCons.Util.is_List(dk):
|
||||
dk = [dk]
|
||||
val = filter(lambda x, dk=dk: x not in dk, val)
|
||||
if delete_existing:
|
||||
dk = filter(lambda x, val=val: x not in val, dk)
|
||||
else:
|
||||
val = filter(lambda x, dk=dk: x not in dk, val)
|
||||
self._dict[key] = val + dk
|
||||
else:
|
||||
dk = self._dict[key]
|
||||
if SCons.Util.is_List(dk):
|
||||
# By elimination, val is not a list. Since dk is a
|
||||
# list, wrap val in a list first.
|
||||
if not val in dk:
|
||||
if delete_existing:
|
||||
dk = filter(lambda x, val=val: x not in val, dk)
|
||||
self._dict[key] = [val] + dk
|
||||
else:
|
||||
if not val in dk:
|
||||
self._dict[key] = [val] + dk
|
||||
else:
|
||||
if delete_existing:
|
||||
dk = filter(lambda x, val=val: x not in val, dk)
|
||||
self._dict[key] = val + dk
|
||||
self.scanner_map_delete(kw)
|
||||
|
||||
|
@ -1532,6 +1692,7 @@ class Base(SubstitutionEnvironment):
|
|||
pass
|
||||
elif SCons.Util.is_String(pathext):
|
||||
pathext = self.subst(pathext)
|
||||
prog = self.subst(prog)
|
||||
path = SCons.Util.WhereIs(prog, path, pathext, reject)
|
||||
if path: return path
|
||||
return None
|
||||
|
@ -1634,10 +1795,11 @@ class Base(SubstitutionEnvironment):
|
|||
t.set_always_build()
|
||||
return tlist
|
||||
|
||||
def BuildDir(self, build_dir, src_dir, duplicate=1):
|
||||
build_dir = self.arg2nodes(build_dir, self.fs.Dir)[0]
|
||||
src_dir = self.arg2nodes(src_dir, self.fs.Dir)[0]
|
||||
self.fs.BuildDir(build_dir, src_dir, duplicate)
|
||||
def BuildDir(self, *args, **kw):
|
||||
if kw.has_key('build_dir'):
|
||||
kw['variant_dir'] = kw['build_dir']
|
||||
del kw['build_dir']
|
||||
return apply(self.VariantDir, args, kw)
|
||||
|
||||
def Builder(self, **kw):
|
||||
nkw = self.subst_kw(kw)
|
||||
|
@ -1645,10 +1807,9 @@ class Base(SubstitutionEnvironment):
|
|||
|
||||
def CacheDir(self, path):
|
||||
import SCons.CacheDir
|
||||
if path is None:
|
||||
self._CacheDir = SCons.CacheDir.Null()
|
||||
else:
|
||||
self._CacheDir = SCons.CacheDir.CacheDir(self.subst(path))
|
||||
if not path is None:
|
||||
path = self.subst(path)
|
||||
self._CacheDir_path = path
|
||||
|
||||
def Clean(self, targets, files):
|
||||
global CleanTargets
|
||||
|
@ -1699,7 +1860,13 @@ class Base(SubstitutionEnvironment):
|
|||
def Dir(self, name, *args, **kw):
|
||||
"""
|
||||
"""
|
||||
return apply(self.fs.Dir, (self.subst(name),) + args, kw)
|
||||
s = self.subst(name)
|
||||
if SCons.Util.is_Sequence(s):
|
||||
result=[]
|
||||
for e in s:
|
||||
result.append(apply(self.fs.Dir, (e,) + args, kw))
|
||||
return result
|
||||
return apply(self.fs.Dir, (s,) + args, kw)
|
||||
|
||||
def NoClean(self, *targets):
|
||||
"""Tags a target so that it will not be cleaned by -c"""
|
||||
|
@ -1722,7 +1889,13 @@ class Base(SubstitutionEnvironment):
|
|||
def Entry(self, name, *args, **kw):
|
||||
"""
|
||||
"""
|
||||
return apply(self.fs.Entry, (self.subst(name),) + args, kw)
|
||||
s = self.subst(name)
|
||||
if SCons.Util.is_Sequence(s):
|
||||
result=[]
|
||||
for e in s:
|
||||
result.append(apply(self.fs.Entry, (e,) + args, kw))
|
||||
return result
|
||||
return apply(self.fs.Entry, (s,) + args, kw)
|
||||
|
||||
def Environment(self, **kw):
|
||||
return apply(SCons.Environment.Environment, [], self.subst_kw(kw))
|
||||
|
@ -1733,6 +1906,10 @@ class Base(SubstitutionEnvironment):
|
|||
action = apply(self.Action, (action,) + args, kw)
|
||||
result = action([], [], self)
|
||||
if isinstance(result, SCons.Errors.BuildError):
|
||||
errstr = result.errstr
|
||||
if result.filename:
|
||||
errstr = result.filename + ': ' + errstr
|
||||
sys.stderr.write("scons: *** %s\n" % errstr)
|
||||
return result.status
|
||||
else:
|
||||
return result
|
||||
|
@ -1740,7 +1917,13 @@ class Base(SubstitutionEnvironment):
|
|||
def File(self, name, *args, **kw):
|
||||
"""
|
||||
"""
|
||||
return apply(self.fs.File, (self.subst(name),) + args, kw)
|
||||
s = self.subst(name)
|
||||
if SCons.Util.is_Sequence(s):
|
||||
result=[]
|
||||
for e in s:
|
||||
result.append(apply(self.fs.File, (e,) + args, kw))
|
||||
return result
|
||||
return apply(self.fs.File, (s,) + args, kw)
|
||||
|
||||
def FindFile(self, file, dirs):
|
||||
file = self.subst(file)
|
||||
|
@ -1819,6 +2002,11 @@ class Base(SubstitutionEnvironment):
|
|||
name = self.subst(name)
|
||||
if not os.path.isabs(name):
|
||||
name = os.path.join(str(self.fs.SConstruct_dir), name)
|
||||
if name:
|
||||
name = os.path.normpath(name)
|
||||
sconsign_dir = os.path.dirname(name)
|
||||
if sconsign_dir and not os.path.exists(sconsign_dir):
|
||||
self.Execute(SCons.Defaults.Mkdir(sconsign_dir))
|
||||
SCons.SConsign.File(name, dbm_module)
|
||||
|
||||
def SideEffect(self, side_effect, target):
|
||||
|
@ -1845,6 +2033,12 @@ class Base(SubstitutionEnvironment):
|
|||
return entries
|
||||
|
||||
def SourceSignatures(self, type):
|
||||
global _warn_source_signatures_deprecated
|
||||
if _warn_source_signatures_deprecated:
|
||||
msg = "The env.SourceSignatures() method is deprecated;\n" + \
|
||||
"\tconvert your build to use the env.Decider() method instead."
|
||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedSourceSignaturesWarning, msg)
|
||||
_warn_source_signatures_deprecated = False
|
||||
type = self.subst(type)
|
||||
self.src_sig_type = type
|
||||
if type == 'MD5':
|
||||
|
@ -1875,6 +2069,12 @@ class Base(SubstitutionEnvironment):
|
|||
return [self.subst(arg)]
|
||||
|
||||
def TargetSignatures(self, type):
|
||||
global _warn_target_signatures_deprecated
|
||||
if _warn_target_signatures_deprecated:
|
||||
msg = "The env.TargetSignatures() method is deprecated;\n" + \
|
||||
"\tconvert your build to use the env.Decider() method instead."
|
||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedTargetSignaturesWarning, msg)
|
||||
_warn_target_signatures_deprecated = False
|
||||
type = self.subst(type)
|
||||
self.tgt_sig_type = type
|
||||
if type in ('MD5', 'content'):
|
||||
|
@ -1895,6 +2095,11 @@ class Base(SubstitutionEnvironment):
|
|||
"""
|
||||
return SCons.Node.Python.Value(value, built_value)
|
||||
|
||||
def VariantDir(self, variant_dir, src_dir, duplicate=1):
|
||||
variant_dir = self.arg2nodes(variant_dir, self.fs.Dir)[0]
|
||||
src_dir = self.arg2nodes(src_dir, self.fs.Dir)[0]
|
||||
self.fs.VariantDir(variant_dir, src_dir, duplicate)
|
||||
|
||||
def FindSourceFiles(self, node='.'):
|
||||
""" returns a list of all source files.
|
||||
"""
|
||||
|
@ -1978,7 +2183,7 @@ class OverrideEnvironment(Base):
|
|||
except KeyError:
|
||||
return self.__dict__['__subject'].__getitem__(key)
|
||||
def __setitem__(self, key, value):
|
||||
if not SCons.Util.is_valid_construction_var(key):
|
||||
if not is_valid_construction_var(key):
|
||||
raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key
|
||||
self.__dict__['overrides'][key] = value
|
||||
def __delitem__(self, key):
|
||||
|
@ -2007,6 +2212,10 @@ class OverrideEnvironment(Base):
|
|||
return 1
|
||||
except KeyError:
|
||||
return self.__dict__['__subject'].has_key(key)
|
||||
def __contains__(self, key):
|
||||
if self.__dict__['overrides'].__contains__(key):
|
||||
return 1
|
||||
return self.__dict__['__subject'].__contains__(key)
|
||||
def Dictionary(self):
|
||||
"""Emulates the items() method of dictionaries."""
|
||||
d = self.__dict__['__subject'].Dictionary().copy()
|
198
scons/scons-local-1.2.0/SCons/Errors.py
Normal file
198
scons/scons-local-1.2.0/SCons/Errors.py
Normal file
|
@ -0,0 +1,198 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
"""SCons.Errors
|
||||
|
||||
This file contains the exception classes used to handle internal
|
||||
and user errors in SCons.
|
||||
|
||||
"""
|
||||
|
||||
__revision__ = "src/engine/SCons/Errors.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Util
|
||||
|
||||
import exceptions
|
||||
|
||||
class BuildError(Exception):
|
||||
""" Errors occuring while building.
|
||||
|
||||
BuildError have the following attributes:
|
||||
|
||||
Information about the cause of the build error:
|
||||
-----------------------------------------------
|
||||
|
||||
errstr : a description of the error message
|
||||
|
||||
status : the return code of the action that caused the build
|
||||
error. Must be set to a non-zero value even if the
|
||||
build error is not due to an action returning a
|
||||
non-zero returned code.
|
||||
|
||||
exitstatus : SCons exit status due to this build error.
|
||||
Must be nonzero unless due to an explicit Exit()
|
||||
call. Not always the same as status, since
|
||||
actions return a status code that should be
|
||||
respected, but SCons typically exits with 2
|
||||
irrespective of the return value of the failed
|
||||
action.
|
||||
|
||||
filename : The name of the file or directory that caused the
|
||||
build error. Set to None if no files are associated with
|
||||
this error. This might be different from the target
|
||||
being built. For example, failure to create the
|
||||
directory in which the target file will appear. It
|
||||
can be None if the error is not due to a particular
|
||||
filename.
|
||||
|
||||
exc_info : Info about exception that caused the build
|
||||
error. Set to (None, None, None) if this build
|
||||
error is not due to an exception.
|
||||
|
||||
|
||||
Information about the cause of the location of the error:
|
||||
---------------------------------------------------------
|
||||
|
||||
node : the error occured while building this target node(s)
|
||||
|
||||
executor : the executor that caused the build to fail (might
|
||||
be None if the build failures is not due to the
|
||||
executor failing)
|
||||
|
||||
action : the action that caused the build to fail (might be
|
||||
None if the build failures is not due to the an
|
||||
action failure)
|
||||
|
||||
command : the command line for the action that caused the
|
||||
build to fail (might be None if the build failures
|
||||
is not due to the an action failure)
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
node=None, errstr="Unknown error", status=2, exitstatus=2,
|
||||
filename=None, executor=None, action=None, command=None,
|
||||
exc_info=(None, None, None)):
|
||||
|
||||
self.errstr = errstr
|
||||
self.status = status
|
||||
self.exitstatus = exitstatus
|
||||
self.filename = filename
|
||||
self.exc_info = exc_info
|
||||
|
||||
self.node = node
|
||||
self.executor = executor
|
||||
self.action = action
|
||||
self.command = command
|
||||
|
||||
Exception.__init__(self, node, errstr, status, exitstatus, filename,
|
||||
executor, action, command, exc_info)
|
||||
|
||||
def __str__(self):
|
||||
if self.filename:
|
||||
return self.filename + ': ' + self.errstr
|
||||
else:
|
||||
return self.errstr
|
||||
|
||||
class InternalError(Exception):
|
||||
pass
|
||||
|
||||
class UserError(Exception):
|
||||
pass
|
||||
|
||||
class StopError(Exception):
|
||||
pass
|
||||
|
||||
class EnvironmentError(Exception):
|
||||
pass
|
||||
|
||||
class ExplicitExit(Exception):
|
||||
def __init__(self, node=None, status=None, *args):
|
||||
self.node = node
|
||||
self.status = status
|
||||
self.exitstatus = status
|
||||
apply(Exception.__init__, (self,) + args)
|
||||
|
||||
def convert_to_BuildError(status, exc_info=None):
|
||||
"""
|
||||
Convert any return code a BuildError Exception.
|
||||
|
||||
`status' can either be a return code or an Exception.
|
||||
The buildError.status we set here will normally be
|
||||
used as the exit status of the "scons" process.
|
||||
"""
|
||||
if not exc_info and isinstance(status, Exception):
|
||||
exc_info = (status.__class__, status, None)
|
||||
|
||||
if isinstance(status, BuildError):
|
||||
buildError = status
|
||||
buildError.exitstatus = 2 # always exit with 2 on build errors
|
||||
elif isinstance(status, ExplicitExit):
|
||||
status = status.status
|
||||
errstr = 'Explicit exit, status %s' % status
|
||||
buildError = BuildError(
|
||||
errstr=errstr,
|
||||
status=status, # might be 0, OK here
|
||||
exitstatus=status, # might be 0, OK here
|
||||
exc_info=exc_info)
|
||||
# TODO(1.5):
|
||||
#elif isinstance(status, (StopError, UserError)):
|
||||
elif isinstance(status, StopError) or isinstance(status, UserError):
|
||||
buildError = BuildError(
|
||||
errstr=str(status),
|
||||
status=2,
|
||||
exitstatus=2,
|
||||
exc_info=exc_info)
|
||||
elif isinstance(status, exceptions.EnvironmentError):
|
||||
# If an IOError/OSError happens, raise a BuildError.
|
||||
# Report the name of the file or directory that caused the
|
||||
# error, which might be different from the target being built
|
||||
# (for example, failure to create the directory in which the
|
||||
# target file will appear).
|
||||
try: filename = status.filename
|
||||
except AttributeError: filename = None
|
||||
buildError = BuildError(
|
||||
errstr=status.strerror,
|
||||
status=status.errno,
|
||||
exitstatus=2,
|
||||
filename=filename,
|
||||
exc_info=exc_info)
|
||||
elif isinstance(status, Exception):
|
||||
buildError = BuildError(
|
||||
errstr='%s : %s' % (status.__class__.__name__, status),
|
||||
status=2,
|
||||
exitstatus=2,
|
||||
exc_info=exc_info)
|
||||
elif SCons.Util.is_String(status):
|
||||
buildError = BuildError(
|
||||
errstr=status,
|
||||
status=2,
|
||||
exitstatus=2)
|
||||
else:
|
||||
buildError = BuildError(
|
||||
errstr="Error %s" % status,
|
||||
status=status,
|
||||
exitstatus=2)
|
||||
|
||||
#import sys
|
||||
#sys.stderr.write("convert_to_BuildError: status %s => (errstr %s, status %s)"%(status,buildError.errstr, buildError.status))
|
||||
return buildError
|
|
@ -6,7 +6,7 @@ Nodes.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -28,7 +28,7 @@ Nodes.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Executor.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Executor.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import string
|
||||
|
||||
|
@ -134,7 +134,11 @@ class Executor:
|
|||
raise status
|
||||
elif status:
|
||||
msg = "Error %s" % status
|
||||
raise SCons.Errors.BuildError(errstr=msg, executor=self, action=act)
|
||||
raise SCons.Errors.BuildError(
|
||||
errstr=msg,
|
||||
node=self.targets,
|
||||
executor=self,
|
||||
action=act)
|
||||
return status
|
||||
|
||||
# use extra indirection because with new-style objects (Python 2.2
|
||||
|
@ -160,6 +164,16 @@ class Executor:
|
|||
self.sources_need_sorting = False
|
||||
return self.sources
|
||||
|
||||
def prepare(self):
|
||||
"""
|
||||
Preparatory checks for whether this Executor can go ahead
|
||||
and (try to) build its targets.
|
||||
"""
|
||||
for s in self.get_sources():
|
||||
if s.missing():
|
||||
msg = "Source `%s' not found, needed by target `%s'."
|
||||
raise SCons.Errors.StopError, msg % (s, self.targets[0])
|
||||
|
||||
def add_pre_action(self, action):
|
||||
self.pre_actions.append(action)
|
||||
|
||||
|
@ -221,40 +235,35 @@ class Executor:
|
|||
This essentially short-circuits an N*M scan of the sources for
|
||||
each individual target, which is a hell of a lot more efficient.
|
||||
"""
|
||||
map(lambda N: N.disambiguate(), node_list)
|
||||
|
||||
env = self.get_build_env()
|
||||
select_specific_scanner = lambda t: (t[0], t[1].select(t[0]))
|
||||
remove_null_scanners = lambda t: not t[1] is None
|
||||
add_scanner_path = lambda t, s=self: \
|
||||
(t[0], t[1], s.get_build_scanner_path(t[1]))
|
||||
if scanner:
|
||||
scanner_list = map(lambda n, s=scanner: (n, s), node_list)
|
||||
else:
|
||||
kw = self.get_kw()
|
||||
get_initial_scanners = lambda n, e=env, kw=kw: \
|
||||
(n, n.get_env_scanner(e, kw))
|
||||
scanner_list = map(get_initial_scanners, node_list)
|
||||
scanner_list = filter(remove_null_scanners, scanner_list)
|
||||
|
||||
scanner_list = map(select_specific_scanner, scanner_list)
|
||||
scanner_list = filter(remove_null_scanners, scanner_list)
|
||||
scanner_path_list = map(add_scanner_path, scanner_list)
|
||||
|
||||
deps = []
|
||||
for node, scanner, path in scanner_path_list:
|
||||
deps.extend(node.get_implicit_deps(env, scanner, path))
|
||||
if scanner:
|
||||
for node in node_list:
|
||||
node.disambiguate()
|
||||
s = scanner.select(node)
|
||||
if not s:
|
||||
continue
|
||||
path = self.get_build_scanner_path(s)
|
||||
deps.extend(node.get_implicit_deps(env, s, path))
|
||||
else:
|
||||
kw = self.get_kw()
|
||||
for node in node_list:
|
||||
node.disambiguate()
|
||||
scanner = node.get_env_scanner(env, kw)
|
||||
if not scanner:
|
||||
continue
|
||||
scanner = scanner.select(node)
|
||||
if not scanner:
|
||||
continue
|
||||
path = self.get_build_scanner_path(scanner)
|
||||
deps.extend(node.get_implicit_deps(env, scanner, path))
|
||||
|
||||
deps.extend(self.get_implicit_deps())
|
||||
|
||||
for tgt in self.targets:
|
||||
tgt.add_to_implicit(deps)
|
||||
|
||||
def get_missing_sources(self):
|
||||
"""
|
||||
"""
|
||||
return filter(lambda s: s.missing(), self.get_sources())
|
||||
|
||||
def _get_unignored_sources_key(self, ignore=()):
|
||||
return tuple(ignore)
|
||||
|
||||
|
@ -317,10 +326,25 @@ class Executor:
|
|||
result.extend(act.get_implicit_deps(self.targets, self.get_sources(), build_env))
|
||||
return result
|
||||
|
||||
nullenv = None
|
||||
|
||||
_Executor = Executor
|
||||
def get_NullEnvironment():
|
||||
"""Use singleton pattern for Null Environments."""
|
||||
global nullenv
|
||||
|
||||
class Null(_Executor):
|
||||
import SCons.Util
|
||||
class NullEnvironment(SCons.Util.Null):
|
||||
import SCons.CacheDir
|
||||
_CacheDir_path = None
|
||||
_CacheDir = SCons.CacheDir.CacheDir(None)
|
||||
def get_CacheDir(self):
|
||||
return self._CacheDir
|
||||
|
||||
if not nullenv:
|
||||
nullenv = NullEnvironment()
|
||||
return nullenv
|
||||
|
||||
class Null:
|
||||
"""A null Executor, with a null build Environment, that does
|
||||
nothing when the rest of the methods call it.
|
||||
|
||||
|
@ -330,20 +354,40 @@ class Null(_Executor):
|
|||
"""
|
||||
def __init__(self, *args, **kw):
|
||||
if __debug__: logInstanceCreation(self, 'Executor.Null')
|
||||
kw['action'] = []
|
||||
apply(_Executor.__init__, (self,), kw)
|
||||
self.targets = kw['targets']
|
||||
def get_build_env(self):
|
||||
import SCons.Util
|
||||
class NullEnvironment(SCons.Util.Null):
|
||||
#def get_scanner(self, key):
|
||||
# return None
|
||||
#def changed_since_last_build(self, dependency, target, prev_ni):
|
||||
# return dependency.changed_since_last_buld(target, prev_ni)
|
||||
def get_CacheDir(self):
|
||||
import SCons.CacheDir
|
||||
return SCons.CacheDir.Null()
|
||||
return NullEnvironment()
|
||||
return get_NullEnvironment()
|
||||
def get_build_scanner_path(self):
|
||||
return None
|
||||
def cleanup(self):
|
||||
pass
|
||||
def prepare(self):
|
||||
pass
|
||||
def get_unignored_sources(self, *args, **kw):
|
||||
return tuple(())
|
||||
def get_action_list(self):
|
||||
return []
|
||||
def __call__(self, *args, **kw):
|
||||
return 0
|
||||
def get_contents(self):
|
||||
return ''
|
||||
|
||||
def _morph(self):
|
||||
"""Morph this Null executor to a real Executor object."""
|
||||
self.__class__ = Executor
|
||||
self.__init__([], targets=self.targets)
|
||||
|
||||
# The following methods require morphing this Null Executor to a
|
||||
# real Executor object.
|
||||
|
||||
def add_pre_action(self, action):
|
||||
self._morph()
|
||||
self.add_pre_action(action)
|
||||
def add_post_action(self, action):
|
||||
self._morph()
|
||||
self.add_post_action(action)
|
||||
def set_action_list(self, action):
|
||||
self._morph()
|
||||
self.set_action_list(action)
|
||||
|
||||
|
|
@ -7,7 +7,7 @@ stop, and wait on jobs.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -29,9 +29,37 @@ stop, and wait on jobs.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Job.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Job.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os
|
||||
import signal
|
||||
|
||||
import SCons.Errors
|
||||
|
||||
# The default stack size (in kilobytes) of the threads used to execute
|
||||
# jobs in parallel.
|
||||
#
|
||||
# We use a stack size of 256 kilobytes. The default on some platforms
|
||||
# is too large and prevents us from creating enough threads to fully
|
||||
# parallelized the build. For example, the default stack size on linux
|
||||
# is 8 MBytes.
|
||||
|
||||
explicit_stack_size = None
|
||||
default_stack_size = 256
|
||||
|
||||
interrupt_msg = 'Build interrupted.'
|
||||
|
||||
|
||||
class InterruptState:
|
||||
def __init__(self):
|
||||
self.interrupted = False
|
||||
|
||||
def set(self):
|
||||
self.interrupted = True
|
||||
|
||||
def __call__(self):
|
||||
return self.interrupted
|
||||
|
||||
import SCons.compat
|
||||
|
||||
class Jobs:
|
||||
"""An instance of this class initializes N jobs, and provides
|
||||
|
@ -54,8 +82,12 @@ class Jobs:
|
|||
|
||||
self.job = None
|
||||
if num > 1:
|
||||
stack_size = explicit_stack_size
|
||||
if stack_size is None:
|
||||
stack_size = default_stack_size
|
||||
|
||||
try:
|
||||
self.job = Parallel(taskmaster, num)
|
||||
self.job = Parallel(taskmaster, num, stack_size)
|
||||
self.num_jobs = num
|
||||
except NameError:
|
||||
pass
|
||||
|
@ -63,21 +95,71 @@ class Jobs:
|
|||
self.job = Serial(taskmaster)
|
||||
self.num_jobs = 1
|
||||
|
||||
def run(self):
|
||||
"""run the job"""
|
||||
def run(self, postfunc=lambda: None):
|
||||
"""Run the jobs.
|
||||
|
||||
postfunc() will be invoked after the jobs has run. It will be
|
||||
invoked even if the jobs are interrupted by a keyboard
|
||||
interrupt (well, in fact by a signal such as either SIGINT,
|
||||
SIGTERM or SIGHUP). The execution of postfunc() is protected
|
||||
against keyboard interrupts and is guaranteed to run to
|
||||
completion."""
|
||||
self._setup_sig_handler()
|
||||
try:
|
||||
self.job.start()
|
||||
except KeyboardInterrupt:
|
||||
# mask any further keyboard interrupts so that scons
|
||||
# can shutdown cleanly:
|
||||
# (this only masks the keyboard interrupt for Python,
|
||||
# child processes can still get the keyboard interrupt)
|
||||
import signal
|
||||
signal.signal(signal.SIGINT, signal.SIG_IGN)
|
||||
raise
|
||||
finally:
|
||||
postfunc()
|
||||
self._reset_sig_handler()
|
||||
|
||||
def cleanup(self):
|
||||
self.job.cleanup()
|
||||
def were_interrupted(self):
|
||||
"""Returns whether the jobs were interrupted by a signal."""
|
||||
return self.job.interrupted()
|
||||
|
||||
def _setup_sig_handler(self):
|
||||
"""Setup an interrupt handler so that SCons can shutdown cleanly in
|
||||
various conditions:
|
||||
|
||||
a) SIGINT: Keyboard interrupt
|
||||
b) SIGTERM: kill or system shutdown
|
||||
c) SIGHUP: Controlling shell exiting
|
||||
|
||||
We handle all of these cases by stopping the taskmaster. It
|
||||
turns out that it very difficult to stop the build process
|
||||
by throwing asynchronously an exception such as
|
||||
KeyboardInterrupt. For example, the python Condition
|
||||
variables (threading.Condition) and Queue's do not seem to
|
||||
asynchronous-exception-safe. It would require adding a whole
|
||||
bunch of try/finally block and except KeyboardInterrupt all
|
||||
over the place.
|
||||
|
||||
Note also that we have to be careful to handle the case when
|
||||
SCons forks before executing another process. In that case, we
|
||||
want the child to exit immediately.
|
||||
"""
|
||||
def handler(signum, stack, self=self, parentpid=os.getpid()):
|
||||
if os.getpid() == parentpid:
|
||||
self.job.taskmaster.stop()
|
||||
self.job.interrupted.set()
|
||||
else:
|
||||
os._exit(2)
|
||||
|
||||
self.old_sigint = signal.signal(signal.SIGINT, handler)
|
||||
self.old_sigterm = signal.signal(signal.SIGTERM, handler)
|
||||
try:
|
||||
self.old_sighup = signal.signal(signal.SIGHUP, handler)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
def _reset_sig_handler(self):
|
||||
"""Restore the signal handlers to their previous state (before the
|
||||
call to _setup_sig_handler()."""
|
||||
|
||||
signal.signal(signal.SIGINT, self.old_sigint)
|
||||
signal.signal(signal.SIGTERM, self.old_sigterm)
|
||||
try:
|
||||
signal.signal(signal.SIGHUP, self.old_sighup)
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
class Serial:
|
||||
"""This class is used to execute tasks in series, and is more efficient
|
||||
|
@ -97,6 +179,7 @@ class Serial:
|
|||
execute (e.g. execute() raised an exception)."""
|
||||
|
||||
self.taskmaster = taskmaster
|
||||
self.interrupted = InterruptState()
|
||||
|
||||
def start(self):
|
||||
"""Start the job. This will begin pulling tasks from the taskmaster
|
||||
|
@ -112,11 +195,18 @@ class Serial:
|
|||
|
||||
try:
|
||||
task.prepare()
|
||||
task.execute()
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
if task.needs_execute():
|
||||
task.execute()
|
||||
except:
|
||||
task.exception_set()
|
||||
if self.interrupted():
|
||||
try:
|
||||
raise SCons.Errors.BuildError(
|
||||
task.targets[0], errstr=interrupt_msg)
|
||||
except:
|
||||
task.exception_set()
|
||||
else:
|
||||
task.exception_set()
|
||||
|
||||
# Let the failed() callback function arrange for the
|
||||
# build to stop if that's appropriate.
|
||||
task.failed()
|
||||
|
@ -124,9 +214,8 @@ class Serial:
|
|||
task.executed()
|
||||
|
||||
task.postprocess()
|
||||
self.taskmaster.cleanup()
|
||||
|
||||
def cleanup(self):
|
||||
pass
|
||||
|
||||
# Trap import failure so that everything in the Job module but the
|
||||
# Parallel class (and its dependent classes) will work if the interpreter
|
||||
|
@ -142,28 +231,29 @@ else:
|
|||
dequeues the task, executes it, and posts a tuple including the task
|
||||
and a boolean indicating whether the task executed successfully. """
|
||||
|
||||
def __init__(self, requestQueue, resultsQueue):
|
||||
def __init__(self, requestQueue, resultsQueue, interrupted):
|
||||
threading.Thread.__init__(self)
|
||||
self.setDaemon(1)
|
||||
self.requestQueue = requestQueue
|
||||
self.resultsQueue = resultsQueue
|
||||
self.interrupted = interrupted
|
||||
self.start()
|
||||
|
||||
def run(self):
|
||||
while 1:
|
||||
task = self.requestQueue.get()
|
||||
|
||||
if not task:
|
||||
if task is None:
|
||||
# The "None" value is used as a sentinel by
|
||||
# ThreadPool.cleanup(). This indicates that there
|
||||
# are no more tasks, so we should quit.
|
||||
break
|
||||
|
||||
try:
|
||||
if self.interrupted():
|
||||
raise SCons.Errors.BuildError(
|
||||
task.targets[0], errstr=interrupt_msg)
|
||||
task.execute()
|
||||
except KeyboardInterrupt:
|
||||
# be explicit here for test/interrupts.py
|
||||
ok = False
|
||||
except:
|
||||
task.exception_set()
|
||||
ok = False
|
||||
|
@ -175,27 +265,49 @@ else:
|
|||
class ThreadPool:
|
||||
"""This class is responsible for spawning and managing worker threads."""
|
||||
|
||||
def __init__(self, num):
|
||||
"""Create the request and reply queues, and 'num' worker threads."""
|
||||
def __init__(self, num, stack_size, interrupted):
|
||||
"""Create the request and reply queues, and 'num' worker threads.
|
||||
|
||||
One must specify the stack size of the worker threads. The
|
||||
stack size is specified in kilobytes.
|
||||
"""
|
||||
self.requestQueue = Queue.Queue(0)
|
||||
self.resultsQueue = Queue.Queue(0)
|
||||
|
||||
try:
|
||||
prev_size = threading.stack_size(stack_size*1024)
|
||||
except AttributeError, e:
|
||||
# Only print a warning if the stack size has been
|
||||
# explicitly set.
|
||||
if not explicit_stack_size is None:
|
||||
msg = "Setting stack size is unsupported by this version of Python:\n " + \
|
||||
e.args[0]
|
||||
SCons.Warnings.warn(SCons.Warnings.StackSizeWarning, msg)
|
||||
except ValueError, e:
|
||||
msg = "Setting stack size failed:\n " + str(e)
|
||||
SCons.Warnings.warn(SCons.Warnings.StackSizeWarning, msg)
|
||||
|
||||
# Create worker threads
|
||||
self.workers = []
|
||||
for _ in range(num):
|
||||
worker = Worker(self.requestQueue, self.resultsQueue)
|
||||
worker = Worker(self.requestQueue, self.resultsQueue, interrupted)
|
||||
self.workers.append(worker)
|
||||
|
||||
def put(self, obj):
|
||||
# Once we drop Python 1.5 we can change the following to:
|
||||
#if 'prev_size' in locals():
|
||||
if 'prev_size' in locals().keys():
|
||||
threading.stack_size(prev_size)
|
||||
|
||||
def put(self, task):
|
||||
"""Put task into request queue."""
|
||||
self.requestQueue.put(obj)
|
||||
self.requestQueue.put(task)
|
||||
|
||||
def get(self, block = True):
|
||||
def get(self):
|
||||
"""Remove and return a result tuple from the results queue."""
|
||||
return self.resultsQueue.get(block)
|
||||
return self.resultsQueue.get()
|
||||
|
||||
def preparation_failed(self, obj):
|
||||
self.resultsQueue.put((obj, False))
|
||||
def preparation_failed(self, task):
|
||||
self.resultsQueue.put((task, False))
|
||||
|
||||
def cleanup(self):
|
||||
"""
|
||||
|
@ -233,7 +345,7 @@ else:
|
|||
This class is thread safe.
|
||||
"""
|
||||
|
||||
def __init__(self, taskmaster, num):
|
||||
def __init__(self, taskmaster, num, stack_size):
|
||||
"""Create a new parallel job given a taskmaster.
|
||||
|
||||
The taskmaster's next_task() method should return the next
|
||||
|
@ -249,7 +361,8 @@ else:
|
|||
multiple tasks simultaneously. """
|
||||
|
||||
self.taskmaster = taskmaster
|
||||
self.tp = ThreadPool(num)
|
||||
self.interrupted = InterruptState()
|
||||
self.tp = ThreadPool(num, stack_size, self.interrupted)
|
||||
|
||||
self.maxjobs = num
|
||||
|
||||
|
@ -269,22 +382,21 @@ else:
|
|||
if task is None:
|
||||
break
|
||||
|
||||
# prepare task for execution
|
||||
try:
|
||||
# prepare task for execution
|
||||
task.prepare()
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
# Let the failed() callback function arrange
|
||||
# for the build to stop if that's appropriate.
|
||||
task.exception_set()
|
||||
self.tp.preparation_failed(task)
|
||||
jobs = jobs + 1
|
||||
continue
|
||||
|
||||
# dispatch task
|
||||
self.tp.put(task)
|
||||
jobs = jobs + 1
|
||||
task.failed()
|
||||
task.postprocess()
|
||||
else:
|
||||
if task.needs_execute():
|
||||
# dispatch task
|
||||
self.tp.put(task)
|
||||
jobs = jobs + 1
|
||||
else:
|
||||
task.executed()
|
||||
task.postprocess()
|
||||
|
||||
if not task and not jobs: break
|
||||
|
||||
|
@ -292,11 +404,20 @@ else:
|
|||
# back and put the next batch of tasks on the queue.
|
||||
while 1:
|
||||
task, ok = self.tp.get()
|
||||
|
||||
jobs = jobs - 1
|
||||
|
||||
if ok:
|
||||
task.executed()
|
||||
else:
|
||||
if self.interrupted():
|
||||
try:
|
||||
raise SCons.Errors.BuildError(
|
||||
task.targets[0], errstr=interrupt_msg)
|
||||
except:
|
||||
task.exception_set()
|
||||
|
||||
# Let the failed() callback function arrange
|
||||
# for the build to stop if that's appropriate.
|
||||
task.failed()
|
||||
|
||||
task.postprocess()
|
||||
|
@ -304,5 +425,5 @@ else:
|
|||
if self.tp.resultsQueue.empty():
|
||||
break
|
||||
|
||||
def cleanup(self):
|
||||
self.tp.cleanup()
|
||||
self.taskmaster.cleanup()
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Memoize.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Memoize.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
__doc__ = """Memoizer
|
||||
|
||||
|
@ -217,33 +217,47 @@ class Memoizer:
|
|||
|
||||
class M:
|
||||
def __init__(cls, name, bases, cls_dict):
|
||||
cls.has_metaclass = 1
|
||||
|
||||
class A:
|
||||
__metaclass__ = M
|
||||
cls.use_metaclass = 1
|
||||
def fake_method(self):
|
||||
pass
|
||||
new.instancemethod(fake_method, None, cls)
|
||||
|
||||
try:
|
||||
has_metaclass = A.has_metaclass
|
||||
class A:
|
||||
__metaclass__ = M
|
||||
|
||||
use_metaclass = A.use_metaclass
|
||||
except AttributeError:
|
||||
has_metaclass = None
|
||||
use_metaclass = None
|
||||
reason = 'no metaclasses'
|
||||
except TypeError:
|
||||
use_metaclass = None
|
||||
reason = 'new.instancemethod() bug'
|
||||
else:
|
||||
del A
|
||||
|
||||
del M
|
||||
del A
|
||||
|
||||
if not has_metaclass:
|
||||
if not use_metaclass:
|
||||
|
||||
def Dump(title):
|
||||
pass
|
||||
|
||||
class Memoized_Metaclass:
|
||||
# Just a place-holder so pre-metaclass Python versions don't
|
||||
# have to have special code for the Memoized classes.
|
||||
pass
|
||||
try:
|
||||
class Memoized_Metaclass(type):
|
||||
# Just a place-holder so pre-metaclass Python versions don't
|
||||
# have to have special code for the Memoized classes.
|
||||
pass
|
||||
except TypeError:
|
||||
class Memoized_Metaclass:
|
||||
# A place-holder so pre-metaclass Python versions don't
|
||||
# have to have special code for the Memoized classes.
|
||||
pass
|
||||
|
||||
def EnableMemoization():
|
||||
import SCons.Warnings
|
||||
msg = 'memoization is not supported in this version of Python (no metaclasses)'
|
||||
raise SCons.Warnings.NoMetaclassSupportWarning, msg
|
||||
msg = 'memoization is not supported in this version of Python (%s)'
|
||||
raise SCons.Warnings.NoMetaclassSupportWarning, msg % reason
|
||||
|
||||
else:
|
||||
|
|
@ -8,7 +8,7 @@ This creates a hash of global Aliases (dummy targets).
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ This creates a hash of global Aliases (dummy targets).
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Node/Alias.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Node/Alias.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import string
|
||||
import UserDict
|
||||
|
@ -74,6 +74,9 @@ class Alias(SCons.Node.Node):
|
|||
SCons.Node.Node.__init__(self)
|
||||
self.name = name
|
||||
|
||||
def str_for_display(self):
|
||||
return '"' + self.__str__() + '"'
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,7 @@ Python nodes.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ Python nodes.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Node/Python.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Node/Python.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Node
|
||||
|
||||
|
@ -56,9 +56,12 @@ class Value(SCons.Node.Node):
|
|||
if not built_value is None:
|
||||
self.built_value = built_value
|
||||
|
||||
def __str__(self):
|
||||
def str_for_display(self):
|
||||
return repr(self.value)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.value)
|
||||
|
||||
def make_ready(self):
|
||||
self.get_csig()
|
||||
|
|
@ -20,7 +20,7 @@ be able to depend on any other type of "thing."
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -42,11 +42,10 @@ be able to depend on any other type of "thing."
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Node/__init__.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import SCons.compat
|
||||
__revision__ = "src/engine/SCons/Node/__init__.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import copy
|
||||
from itertools import chain, izip
|
||||
import string
|
||||
import UserList
|
||||
|
||||
|
@ -75,7 +74,7 @@ executed = 4
|
|||
failed = 5
|
||||
|
||||
StateString = {
|
||||
0 : "0",
|
||||
0 : "no_state",
|
||||
1 : "pending",
|
||||
2 : "executing",
|
||||
3 : "up_to_date",
|
||||
|
@ -202,15 +201,16 @@ class Node:
|
|||
# a class. (Of course, we could always still do that in the
|
||||
# future if we had a good reason to...).
|
||||
self.sources = [] # source files used to build node
|
||||
self.sources_dict = {}
|
||||
self.sources_set = set()
|
||||
self._specific_sources = False
|
||||
self.depends = [] # explicit dependencies (from Depends)
|
||||
self.depends_dict = {}
|
||||
self.depends_set = set()
|
||||
self.ignore = [] # dependencies to ignore
|
||||
self.ignore_dict = {}
|
||||
self.ignore_set = set()
|
||||
self.prerequisites = SCons.Util.UniqueList()
|
||||
self.implicit = None # implicit (scanned) dependencies (None means not scanned yet)
|
||||
self.waiting_parents = {}
|
||||
self.waiting_s_e = {}
|
||||
self.waiting_parents = set()
|
||||
self.waiting_s_e = set()
|
||||
self.ref_count = 0
|
||||
self.wkids = None # Kids yet to walk, when it's an array
|
||||
|
||||
|
@ -220,12 +220,11 @@ class Node:
|
|||
self.noclean = 0
|
||||
self.nocache = 0
|
||||
self.always_build = None
|
||||
self.found_includes = {}
|
||||
self.includes = None
|
||||
self.attributes = self.Attrs() # Generic place to stick information about the Node.
|
||||
self.side_effect = 0 # true iff this node is a side effect
|
||||
self.side_effects = [] # the side effects of building this target
|
||||
self.linked = 0 # is this node linked to the build directory?
|
||||
self.linked = 0 # is this node linked to the variant directory?
|
||||
|
||||
self.clear_memoized_values()
|
||||
|
||||
|
@ -330,24 +329,29 @@ class Node:
|
|||
is out-of-date and must be rebuilt, but before actually calling
|
||||
the method to build the Node.
|
||||
|
||||
This default implemenation checks that all children either exist
|
||||
or are derived, and initializes the BuildInfo structure that
|
||||
will hold the information about how this node is, uh, built.
|
||||
This default implementation checks that explicit or implicit
|
||||
dependencies either exist or are derived, and initializes the
|
||||
BuildInfo structure that will hold the information about how
|
||||
this node is, uh, built.
|
||||
|
||||
(The existence of source files is checked separately by the
|
||||
Executor, which aggregates checks for all of the targets built
|
||||
by a specific action.)
|
||||
|
||||
Overriding this method allows for for a Node subclass to remove
|
||||
the underlying file from the file system. Note that subclass
|
||||
methods should call this base class method to get the child
|
||||
check and the BuildInfo structure.
|
||||
"""
|
||||
l = self.depends
|
||||
for d in self.depends:
|
||||
if d.missing():
|
||||
msg = "Explicit dependency `%s' not found, needed by target `%s'."
|
||||
raise SCons.Errors.StopError, msg % (d, self)
|
||||
if not self.implicit is None:
|
||||
l = l + self.implicit
|
||||
missing_sources = self.get_executor().get_missing_sources() \
|
||||
+ filter(lambda c: c.missing(), l)
|
||||
if missing_sources:
|
||||
desc = "Source `%s' not found, needed by target `%s'." % (missing_sources[0], self)
|
||||
raise SCons.Errors.StopError, desc
|
||||
|
||||
for i in self.implicit:
|
||||
if i.missing():
|
||||
msg = "Implicit dependency `%s' not found, needed by target `%s'."
|
||||
raise SCons.Errors.StopError, msg % (i, self)
|
||||
self.binfo = self.get_binfo()
|
||||
|
||||
def build(self, **kw):
|
||||
|
@ -373,9 +377,8 @@ class Node:
|
|||
|
||||
# Clear the implicit dependency caches of any Nodes
|
||||
# waiting for this Node to be built.
|
||||
for parent in self.waiting_parents.keys():
|
||||
for parent in self.waiting_parents:
|
||||
parent.implicit = None
|
||||
parent.del_binfo()
|
||||
|
||||
self.clear()
|
||||
|
||||
|
@ -399,7 +402,7 @@ class Node:
|
|||
#
|
||||
|
||||
def add_to_waiting_s_e(self, node):
|
||||
self.waiting_s_e[node] = 1
|
||||
self.waiting_s_e.add(node)
|
||||
|
||||
def add_to_waiting_parents(self, node):
|
||||
"""
|
||||
|
@ -410,37 +413,26 @@ class Node:
|
|||
True and False instead...)
|
||||
"""
|
||||
wp = self.waiting_parents
|
||||
if wp.has_key(node):
|
||||
result = 0
|
||||
else:
|
||||
result = 1
|
||||
wp[node] = 1
|
||||
return result
|
||||
|
||||
def call_for_all_waiting_parents(self, func):
|
||||
func(self)
|
||||
for parent in self.waiting_parents.keys():
|
||||
parent.call_for_all_waiting_parents(func)
|
||||
if node in wp:
|
||||
return 0
|
||||
wp.add(node)
|
||||
return 1
|
||||
|
||||
def postprocess(self):
|
||||
"""Clean up anything we don't need to hang onto after we've
|
||||
been built."""
|
||||
self.executor_cleanup()
|
||||
self.waiting_parents = {}
|
||||
self.waiting_parents = set()
|
||||
|
||||
def clear(self):
|
||||
"""Completely clear a Node of all its cached state (so that it
|
||||
can be re-evaluated by interfaces that do continuous integration
|
||||
builds).
|
||||
"""
|
||||
# Note in case it's important in the future: We also used to clear
|
||||
# the build information (the lists of dependencies) here like this:
|
||||
#
|
||||
# self.del_binfo()
|
||||
#
|
||||
# But we now rely on the fact that we're going to look at that
|
||||
# once before the build, and then store the results in the
|
||||
# .sconsign file after the build.
|
||||
# The del_binfo() call here isn't necessary for normal execution,
|
||||
# but is for interactive mode, where we might rebuild the same
|
||||
# target and need to start from scratch.
|
||||
self.del_binfo()
|
||||
self.clear_memoized_values()
|
||||
self.ninfo = self.new_ninfo()
|
||||
self.executor_cleanup()
|
||||
|
@ -449,7 +441,6 @@ class Node:
|
|||
except AttributeError:
|
||||
pass
|
||||
self.includes = None
|
||||
self.found_includes = {}
|
||||
|
||||
def clear_memoized_values(self):
|
||||
self._memo = {}
|
||||
|
@ -510,7 +501,7 @@ class Node:
|
|||
Returns true iff this node is derived (i.e. built).
|
||||
|
||||
This should return true only for nodes whose path should be in
|
||||
the build directory when duplicate=0 and should contribute their build
|
||||
the variant directory when duplicate=0 and should contribute their build
|
||||
signatures when they are used as source files to other derived files. For
|
||||
example: source with source builders are not derived in this sense,
|
||||
and hence should not return true.
|
||||
|
@ -597,9 +588,9 @@ class Node:
|
|||
def add_to_implicit(self, deps):
|
||||
if not hasattr(self, 'implicit') or self.implicit is None:
|
||||
self.implicit = []
|
||||
self.implicit_dict = {}
|
||||
self.implicit_set = set()
|
||||
self._children_reset()
|
||||
self._add_child(self.implicit, self.implicit_dict, deps)
|
||||
self._add_child(self.implicit, self.implicit_set, deps)
|
||||
|
||||
def scan(self):
|
||||
"""Scan this node's dependents for implicit dependencies."""
|
||||
|
@ -609,7 +600,7 @@ class Node:
|
|||
if not self.implicit is None:
|
||||
return
|
||||
self.implicit = []
|
||||
self.implicit_dict = {}
|
||||
self.implicit_set = set()
|
||||
self._children_reset()
|
||||
if not self.has_builder():
|
||||
return
|
||||
|
@ -638,9 +629,7 @@ class Node:
|
|||
# one of this node's sources has changed,
|
||||
# so we must recalculate the implicit deps:
|
||||
self.implicit = []
|
||||
self.implicit_dict = {}
|
||||
self._children_reset()
|
||||
self.del_binfo()
|
||||
self.implicit_set = set()
|
||||
|
||||
# Have the executor scan the sources.
|
||||
executor.scan_sources(self.builder.source_scanner)
|
||||
|
@ -713,33 +702,44 @@ class Node:
|
|||
self.binfo = binfo
|
||||
|
||||
executor = self.get_executor()
|
||||
|
||||
sources = executor.get_unignored_sources(self.ignore)
|
||||
|
||||
depends = self.depends
|
||||
implicit = self.implicit or []
|
||||
|
||||
if self.ignore:
|
||||
depends = filter(self.do_not_ignore, depends)
|
||||
implicit = filter(self.do_not_ignore, implicit)
|
||||
|
||||
def get_ninfo(node):
|
||||
return node.get_ninfo()
|
||||
|
||||
sourcesigs = map(get_ninfo, sources)
|
||||
dependsigs = map(get_ninfo, depends)
|
||||
implicitsigs = map(get_ninfo, implicit)
|
||||
ignore_set = self.ignore_set
|
||||
|
||||
if self.has_builder():
|
||||
binfo.bact = str(executor)
|
||||
binfo.bactsig = SCons.Util.MD5signature(executor.get_contents())
|
||||
|
||||
binfo.bsources = sources
|
||||
binfo.bdepends = depends
|
||||
binfo.bimplicit = implicit
|
||||
if self._specific_sources:
|
||||
sources = []
|
||||
for s in self.sources:
|
||||
if s not in ignore_set:
|
||||
sources.append(s)
|
||||
else:
|
||||
sources = executor.get_unignored_sources(self.ignore)
|
||||
seen = set()
|
||||
bsources = []
|
||||
bsourcesigs = []
|
||||
for s in sources:
|
||||
if not s in seen:
|
||||
seen.add(s)
|
||||
bsources.append(s)
|
||||
bsourcesigs.append(s.get_ninfo())
|
||||
binfo.bsources = bsources
|
||||
binfo.bsourcesigs = bsourcesigs
|
||||
|
||||
binfo.bsourcesigs = sourcesigs
|
||||
depends = self.depends
|
||||
dependsigs = []
|
||||
for d in depends:
|
||||
if d not in ignore_set:
|
||||
dependsigs.append(d.get_ninfo())
|
||||
binfo.bdepends = depends
|
||||
binfo.bdependsigs = dependsigs
|
||||
|
||||
implicit = self.implicit or []
|
||||
implicitsigs = []
|
||||
for i in implicit:
|
||||
if i not in ignore_set:
|
||||
implicitsigs.append(i.get_ninfo())
|
||||
binfo.bimplicit = implicit
|
||||
binfo.bimplicitsigs = implicitsigs
|
||||
|
||||
return binfo
|
||||
|
@ -823,7 +823,7 @@ class Node:
|
|||
def add_dependency(self, depend):
|
||||
"""Adds dependencies."""
|
||||
try:
|
||||
self._add_child(self.depends, self.depends_dict, depend)
|
||||
self._add_child(self.depends, self.depends_set, depend)
|
||||
except TypeError, e:
|
||||
e = e.args[0]
|
||||
if SCons.Util.is_List(e):
|
||||
|
@ -840,7 +840,7 @@ class Node:
|
|||
def add_ignore(self, depend):
|
||||
"""Adds dependencies to ignore."""
|
||||
try:
|
||||
self._add_child(self.ignore, self.ignore_dict, depend)
|
||||
self._add_child(self.ignore, self.ignore_set, depend)
|
||||
except TypeError, e:
|
||||
e = e.args[0]
|
||||
if SCons.Util.is_List(e):
|
||||
|
@ -851,8 +851,10 @@ class Node:
|
|||
|
||||
def add_source(self, source):
|
||||
"""Adds sources."""
|
||||
if self._specific_sources:
|
||||
return
|
||||
try:
|
||||
self._add_child(self.sources, self.sources_dict, source)
|
||||
self._add_child(self.sources, self.sources_set, source)
|
||||
except TypeError, e:
|
||||
e = e.args[0]
|
||||
if SCons.Util.is_List(e):
|
||||
|
@ -861,9 +863,9 @@ class Node:
|
|||
s = str(e)
|
||||
raise SCons.Errors.UserError("attempted to add a non-Node as source of %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e)))
|
||||
|
||||
def _add_child(self, collection, dict, child):
|
||||
"""Adds 'child' to 'collection', first checking 'dict' to see
|
||||
if it's already present."""
|
||||
def _add_child(self, collection, set, child):
|
||||
"""Adds 'child' to 'collection', first checking 'set' to see if it's
|
||||
already present."""
|
||||
#if type(child) is not type([]):
|
||||
# child = [child]
|
||||
#for c in child:
|
||||
|
@ -871,13 +873,17 @@ class Node:
|
|||
# raise TypeError, c
|
||||
added = None
|
||||
for c in child:
|
||||
if not dict.has_key(c):
|
||||
if c not in set:
|
||||
set.add(c)
|
||||
collection.append(c)
|
||||
dict[c] = 1
|
||||
added = 1
|
||||
if added:
|
||||
self._children_reset()
|
||||
|
||||
def set_specific_source(self, source):
|
||||
self.add_source(source)
|
||||
self._specific_sources = True
|
||||
|
||||
def add_wkid(self, wkid):
|
||||
"""Add a node to the list of kids waiting to be evaluated"""
|
||||
if self.wkids != None:
|
||||
|
@ -889,10 +895,55 @@ class Node:
|
|||
# build info that it's cached so we can re-calculate it.
|
||||
self.executor_cleanup()
|
||||
|
||||
def do_not_ignore(self, node):
|
||||
return node not in self.ignore
|
||||
memoizer_counters.append(SCons.Memoize.CountValue('_children_get'))
|
||||
|
||||
def _children_get(self):
|
||||
try:
|
||||
return self._memo['children_get']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# The return list may contain duplicate Nodes, especially in
|
||||
# source trees where there are a lot of repeated #includes
|
||||
# of a tangle of .h files. Profiling shows, however, that
|
||||
# eliminating the duplicates with a brute-force approach that
|
||||
# preserves the order (that is, something like:
|
||||
#
|
||||
# u = []
|
||||
# for n in list:
|
||||
# if n not in u:
|
||||
# u.append(n)"
|
||||
#
|
||||
# takes more cycles than just letting the underlying methods
|
||||
# hand back cached values if a Node's information is requested
|
||||
# multiple times. (Other methods of removing duplicates, like
|
||||
# using dictionary keys, lose the order, and the only ordered
|
||||
# dictionary patterns I found all ended up using "not in"
|
||||
# internally anyway...)
|
||||
if self.ignore_set:
|
||||
if self.implicit is None:
|
||||
iter = chain(self.sources,self.depends)
|
||||
else:
|
||||
iter = chain(self.sources, self.depends, self.implicit)
|
||||
|
||||
children = []
|
||||
for i in iter:
|
||||
if i not in self.ignore_set:
|
||||
children.append(i)
|
||||
else:
|
||||
if self.implicit is None:
|
||||
children = self.sources + self.depends
|
||||
else:
|
||||
children = self.sources + self.depends + self.implicit
|
||||
|
||||
self._memo['children_get'] = children
|
||||
return children
|
||||
|
||||
def all_children(self, scan=1):
|
||||
"""Return a list of all the node's direct children."""
|
||||
if scan:
|
||||
self.scan()
|
||||
|
||||
def _all_children_get(self):
|
||||
# The return list may contain duplicate Nodes, especially in
|
||||
# source trees where there are a lot of repeated #includes
|
||||
# of a tangle of .h files. Profiling shows, however, that
|
||||
|
@ -915,25 +966,6 @@ class Node:
|
|||
else:
|
||||
return self.sources + self.depends + self.implicit
|
||||
|
||||
memoizer_counters.append(SCons.Memoize.CountValue('_children_get'))
|
||||
|
||||
def _children_get(self):
|
||||
try:
|
||||
return self._memo['children_get']
|
||||
except KeyError:
|
||||
pass
|
||||
children = self._all_children_get()
|
||||
if self.ignore:
|
||||
children = filter(self.do_not_ignore, children)
|
||||
self._memo['children_get'] = children
|
||||
return children
|
||||
|
||||
def all_children(self, scan=1):
|
||||
"""Return a list of all the node's direct children."""
|
||||
if scan:
|
||||
self.scan()
|
||||
return self._all_children_get()
|
||||
|
||||
def children(self, scan=1):
|
||||
"""Return a list of the node's direct children, minus those
|
||||
that are ignored by this node."""
|
||||
|
@ -1013,9 +1045,10 @@ class Node:
|
|||
# entries to equal the new dependency list, for the benefit
|
||||
# of the loop below that updates node information.
|
||||
then.extend([None] * diff)
|
||||
if t: Trace(': old %s new %s' % (len(then), len(children)))
|
||||
result = True
|
||||
|
||||
for child, prev_ni in zip(children, then):
|
||||
for child, prev_ni in izip(children, then):
|
||||
if child.changed_since_last_build(self, prev_ni):
|
||||
if t: Trace(': %s changed' % child)
|
||||
result = True
|
||||
|
@ -1071,7 +1104,10 @@ class Node:
|
|||
env = self.get_build_env()
|
||||
for s in self.sources:
|
||||
scanner = self.get_source_scanner(s)
|
||||
path = self.get_build_scanner_path(scanner)
|
||||
if scanner:
|
||||
path = self.get_build_scanner_path(scanner)
|
||||
else:
|
||||
path = None
|
||||
def f(node, env=env, scanner=scanner, path=path):
|
||||
return node.get_found_includes(env, scanner, path)
|
||||
return SCons.Util.render_tree(s, f, 1)
|
||||
|
@ -1158,8 +1194,8 @@ class Node:
|
|||
new_bkids = new.bsources + new.bdepends + new.bimplicit
|
||||
new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs
|
||||
|
||||
osig = dict(zip(old_bkids, old_bkidsigs))
|
||||
nsig = dict(zip(new_bkids, new_bkidsigs))
|
||||
osig = dict(izip(old_bkids, old_bkidsigs))
|
||||
nsig = dict(izip(new_bkids, new_bkidsigs))
|
||||
|
||||
# The sources and dependencies we'll want to report are all stored
|
||||
# as relative paths to this target's directory, but we want to
|
||||
|
@ -1167,7 +1203,10 @@ class Node:
|
|||
# so we only print them after running them through this lambda
|
||||
# to turn them into the right relative Node and then return
|
||||
# its string.
|
||||
stringify = lambda s, E=self.dir.Entry: str(E(s))
|
||||
def stringify( s, E=self.dir.Entry ) :
|
||||
if hasattr( s, 'dir' ) :
|
||||
return str(E(s))
|
||||
return str(s)
|
||||
|
||||
lines = []
|
||||
|
44
scons/scons-local-1.2.0/SCons/Options/BoolOption.py
Normal file
44
scons/scons-local-1.2.0/SCons/Options/BoolOption.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Options/BoolOption.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Options module hierarchy
|
||||
|
||||
This is for backwards compatibility. The new equivalent is the Variables/
|
||||
class hierarchy. These will have deprecation warnings added (some day),
|
||||
and will then be removed entirely (some day).
|
||||
"""
|
||||
|
||||
import SCons.Variables
|
||||
import SCons.Warnings
|
||||
|
||||
warned = False
|
||||
|
||||
def BoolOption(*args, **kw):
|
||||
global warned
|
||||
if not warned:
|
||||
msg = "The BoolOption() function is deprecated; use the BoolVariable() function instead."
|
||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
|
||||
warned = True
|
||||
return apply(SCons.Variables.BoolVariable, args, kw)
|
44
scons/scons-local-1.2.0/SCons/Options/EnumOption.py
Normal file
44
scons/scons-local-1.2.0/SCons/Options/EnumOption.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Options/EnumOption.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Options module hierarchy
|
||||
|
||||
This is for backwards compatibility. The new equivalent is the Variables/
|
||||
class hierarchy. These will have deprecation warnings added (some day),
|
||||
and will then be removed entirely (some day).
|
||||
"""
|
||||
|
||||
import SCons.Variables
|
||||
import SCons.Warnings
|
||||
|
||||
warned = False
|
||||
|
||||
def EnumOption(*args, **kw):
|
||||
global warned
|
||||
if not warned:
|
||||
msg = "The EnumOption() function is deprecated; use the EnumVariable() function instead."
|
||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
|
||||
warned = True
|
||||
return apply(SCons.Variables.EnumVariable, args, kw)
|
44
scons/scons-local-1.2.0/SCons/Options/ListOption.py
Normal file
44
scons/scons-local-1.2.0/SCons/Options/ListOption.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Options/ListOption.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Options module hierarchy
|
||||
|
||||
This is for backwards compatibility. The new equivalent is the Variables/
|
||||
class hierarchy. These will have deprecation warnings added (some day),
|
||||
and will then be removed entirely (some day).
|
||||
"""
|
||||
|
||||
import SCons.Variables
|
||||
import SCons.Warnings
|
||||
|
||||
warned = False
|
||||
|
||||
def ListOption(*args, **kw):
|
||||
global warned
|
||||
if not warned:
|
||||
msg = "The ListOption() function is deprecated; use the ListVariable() function instead."
|
||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
|
||||
warned = True
|
||||
return apply(SCons.Variables.ListVariable, args, kw)
|
44
scons/scons-local-1.2.0/SCons/Options/PackageOption.py
Normal file
44
scons/scons-local-1.2.0/SCons/Options/PackageOption.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Options/PackageOption.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Options module hierarchy
|
||||
|
||||
This is for backwards compatibility. The new equivalent is the Variables/
|
||||
class hierarchy. These will have deprecation warnings added (some day),
|
||||
and will then be removed entirely (some day).
|
||||
"""
|
||||
|
||||
import SCons.Variables
|
||||
import SCons.Warnings
|
||||
|
||||
warned = False
|
||||
|
||||
def PackageOption(*args, **kw):
|
||||
global warned
|
||||
if not warned:
|
||||
msg = "The PackageOption() function is deprecated; use the PackageVariable() function instead."
|
||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
|
||||
warned = True
|
||||
return apply(SCons.Variables.PackageVariable, args, kw)
|
70
scons/scons-local-1.2.0/SCons/Options/PathOption.py
Normal file
70
scons/scons-local-1.2.0/SCons/Options/PathOption.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Options/PathOption.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Options module hierarchy
|
||||
|
||||
This is for backwards compatibility. The new equivalent is the Variables/
|
||||
class hierarchy. These will have deprecation warnings added (some day),
|
||||
and will then be removed entirely (some day).
|
||||
"""
|
||||
|
||||
import SCons.Variables
|
||||
import SCons.Warnings
|
||||
|
||||
warned = False
|
||||
|
||||
class _PathOptionClass:
|
||||
def warn(self):
|
||||
global warned
|
||||
if not warned:
|
||||
msg = "The PathOption() function is deprecated; use the PathVariable() function instead."
|
||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
|
||||
warned = True
|
||||
|
||||
def __call__(self, *args, **kw):
|
||||
self.warn()
|
||||
return apply(SCons.Variables.PathVariable, args, kw)
|
||||
|
||||
def PathAccept(self, *args, **kw):
|
||||
self.warn()
|
||||
return apply(SCons.Variables.PathVariable.PathAccept, args, kw)
|
||||
|
||||
def PathIsDir(self, *args, **kw):
|
||||
self.warn()
|
||||
return apply(SCons.Variables.PathVariable.PathIsDir, args, kw)
|
||||
|
||||
def PathIsDirCreate(self, *args, **kw):
|
||||
self.warn()
|
||||
return apply(SCons.Variables.PathVariable.PathIsDirCreate, args, kw)
|
||||
|
||||
def PathIsFile(self, *args, **kw):
|
||||
self.warn()
|
||||
return apply(SCons.Variables.PathVariable.PathIsFile, args, kw)
|
||||
|
||||
def PathExists(self, *args, **kw):
|
||||
self.warn()
|
||||
return apply(SCons.Variables.PathVariable.PathExists, args, kw)
|
||||
|
||||
PathOption = _PathOptionClass()
|
68
scons/scons-local-1.2.0/SCons/Options/__init__.py
Normal file
68
scons/scons-local-1.2.0/SCons/Options/__init__.py
Normal file
|
@ -0,0 +1,68 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Options/__init__.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Options module hierarchy
|
||||
|
||||
This is for backwards compatibility. The new equivalent is the Variables/
|
||||
class hierarchy. These will have deprecation warnings added (some day),
|
||||
and will then be removed entirely (some day).
|
||||
"""
|
||||
|
||||
import SCons.Variables
|
||||
import SCons.Warnings
|
||||
|
||||
from BoolOption import BoolOption # okay
|
||||
from EnumOption import EnumOption # okay
|
||||
from ListOption import ListOption # naja
|
||||
from PackageOption import PackageOption # naja
|
||||
from PathOption import PathOption # okay
|
||||
|
||||
warned = False
|
||||
|
||||
class Options(SCons.Variables.Variables):
|
||||
def __init__(self, *args, **kw):
|
||||
global warned
|
||||
if not warned:
|
||||
msg = "The Options class is deprecated; use the Variables class instead."
|
||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedOptionsWarning, msg)
|
||||
warned = True
|
||||
apply(SCons.Variables.Variables.__init__,
|
||||
(self,) + args,
|
||||
kw)
|
||||
|
||||
def AddOptions(self, *args, **kw):
|
||||
return apply(SCons.Variables.Variables.AddVariables,
|
||||
(self,) + args,
|
||||
kw)
|
||||
|
||||
def UnknownOptions(self, *args, **kw):
|
||||
return apply(SCons.Variables.Variables.UnknownVariables,
|
||||
(self,) + args,
|
||||
kw)
|
||||
|
||||
def FormatOptionHelpText(self, *args, **kw):
|
||||
return apply(SCons.Variables.Variables.FormatVariableHelpText,
|
||||
(self,) + args,
|
||||
kw)
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/PathList.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/PathList.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
__doc__ = """SCons.PathList
|
||||
|
||||
|
@ -59,7 +59,7 @@ def node_conv(obj):
|
|||
try:
|
||||
get = obj.get
|
||||
except AttributeError:
|
||||
if isinstance(obj, SCons.Node.Node):
|
||||
if isinstance(obj, SCons.Node.Node) or SCons.Util.is_Sequence( obj ):
|
||||
result = obj
|
||||
else:
|
||||
result = str(obj)
|
||||
|
@ -132,10 +132,9 @@ class _PathList:
|
|||
value = env.subst(value, target=target, source=source,
|
||||
conv=node_conv)
|
||||
if SCons.Util.is_Sequence(value):
|
||||
# It came back as a string or tuple, which in this
|
||||
# case usually means some variable expanded to an
|
||||
# actually Dir node. Concatenate the values.
|
||||
value = string.join(map(str, value), '')
|
||||
result.extend(value)
|
||||
continue
|
||||
|
||||
elif type == TYPE_OBJECT:
|
||||
value = node_conv(value)
|
||||
if value:
|
|
@ -20,7 +20,7 @@ their own platform definition.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -42,7 +42,7 @@ their own platform definition.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/__init__.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Platform/__init__.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import imp
|
||||
import os
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/aix.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Platform/aix.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os
|
||||
import string
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/cygwin.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Platform/cygwin.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import posix
|
||||
from SCons.Platform import TempFileMunge
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/darwin.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Platform/darwin.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import posix
|
||||
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/hpux.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Platform/hpux.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import posix
|
||||
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/irix.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Platform/irix.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import posix
|
||||
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/os2.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Platform/os2.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
def generate(env):
|
||||
if not env.has_key('ENV'):
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,12 +30,13 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/posix.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Platform/posix.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import errno
|
||||
import os
|
||||
import os.path
|
||||
import popen2
|
||||
import string
|
||||
import subprocess
|
||||
import sys
|
||||
import select
|
||||
|
||||
|
@ -50,7 +51,7 @@ exitvalmap = {
|
|||
def escape(arg):
|
||||
"escape shell special characters"
|
||||
slash = '\\'
|
||||
special = '"$'
|
||||
special = '"$()'
|
||||
|
||||
arg = string.replace(arg, slash, slash+slash)
|
||||
for c in special:
|
||||
|
@ -92,7 +93,7 @@ def _get_env_command(sh, escape, cmd, args, env):
|
|||
s = string.join(args)
|
||||
if env:
|
||||
l = ['env', '-'] + \
|
||||
map(lambda t, e=escape: t[0]+'='+e(t[1]), env.items()) + \
|
||||
map(lambda t, e=escape: e(t[0])+'='+e(t[1]), env.items()) + \
|
||||
[sh, '-c', escape(s)]
|
||||
s = string.join(l)
|
||||
return s
|
||||
|
@ -109,25 +110,31 @@ def fork_spawn(sh, escape, cmd, args, env):
|
|||
def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
|
||||
stdout_eof = stderr_eof = 0
|
||||
while not (stdout_eof and stderr_eof):
|
||||
(i,o,e) = select.select([cmd_stdout, cmd_stderr], [], [])
|
||||
if cmd_stdout in i:
|
||||
str = cmd_stdout.read()
|
||||
if len(str) == 0:
|
||||
stdout_eof = 1
|
||||
elif stdout != None:
|
||||
stdout.write(str)
|
||||
if cmd_stderr in i:
|
||||
str = cmd_stderr.read()
|
||||
if len(str) == 0:
|
||||
#sys.__stderr__.write( "stderr_eof=1\n" )
|
||||
stderr_eof = 1
|
||||
else:
|
||||
#sys.__stderr__.write( "str(stderr) = %s\n" % str )
|
||||
stderr.write(str)
|
||||
try:
|
||||
(i,o,e) = select.select([cmd_stdout, cmd_stderr], [], [])
|
||||
if cmd_stdout in i:
|
||||
str = cmd_stdout.read()
|
||||
if len(str) == 0:
|
||||
stdout_eof = 1
|
||||
elif stdout != None:
|
||||
stdout.write(str)
|
||||
if cmd_stderr in i:
|
||||
str = cmd_stderr.read()
|
||||
if len(str) == 0:
|
||||
#sys.__stderr__.write( "stderr_eof=1\n" )
|
||||
stderr_eof = 1
|
||||
else:
|
||||
#sys.__stderr__.write( "str(stderr) = %s\n" % str )
|
||||
stderr.write(str)
|
||||
except select.error, (_errno, _strerror):
|
||||
if _errno != errno.EINTR:
|
||||
raise
|
||||
|
||||
def exec_popen3(l, env, stdout, stderr):
|
||||
proc = popen2.Popen3(string.join(l), 1)
|
||||
process_cmd_output(proc.fromchild, proc.childerr, stdout, stderr)
|
||||
proc = subprocess.Popen(string.join(l),
|
||||
stdout=stdout,
|
||||
stderr=stderr,
|
||||
shell=True)
|
||||
stat = proc.wait()
|
||||
if stat & 0xff:
|
||||
return stat | 0x80
|
||||
|
@ -235,7 +242,7 @@ def generate(env):
|
|||
env['LIBSUFFIX'] = '.a'
|
||||
env['SHLIBPREFIX'] = '$LIBPREFIX'
|
||||
env['SHLIBSUFFIX'] = '.so'
|
||||
env['LIBPREFIXES'] = '$LIBPREFIX'
|
||||
env['LIBPREFIXES'] = [ '$LIBPREFIX' ]
|
||||
env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ]
|
||||
env['PSPAWN'] = pspawn
|
||||
env['SPAWN'] = spawn
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/sunos.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Platform/sunos.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import posix
|
||||
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/win32.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Platform/win32.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os
|
||||
import os.path
|
|
@ -4,7 +4,7 @@ Autoconf-like configuration support.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -26,9 +26,7 @@ Autoconf-like configuration support.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/SConf.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import SCons.compat
|
||||
__revision__ = "src/engine/SCons/SConf.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os
|
||||
import re
|
||||
|
@ -235,7 +233,9 @@ class SConfBuildTask(SCons.Taskmaster.Task):
|
|||
raise
|
||||
elif issubclass(exc_type, SCons.Errors.BuildError):
|
||||
# we ignore Build Errors (occurs, when a test doesn't pass)
|
||||
pass
|
||||
# Clear the exception to prevent the contained traceback
|
||||
# to build a reference cycle.
|
||||
self.exc_clear()
|
||||
else:
|
||||
self.display('Caught exception while building "%s":\n' %
|
||||
self.targets[0])
|
||||
|
@ -381,7 +381,7 @@ class SConfBase:
|
|||
e.g. custom_tests={'CheckPrivate':MyPrivateTest}, where MyPrivateTest
|
||||
defines a custom test.
|
||||
Note also the conf_dir and log_file arguments (you may want to
|
||||
build tests in the BuildDir, not in the SourceDir)
|
||||
build tests in the VariantDir, not in the SourceDir)
|
||||
"""
|
||||
global SConfFS
|
||||
if not SConfFS:
|
||||
|
@ -401,14 +401,19 @@ class SConfBase:
|
|||
|
||||
# add default tests
|
||||
default_tests = {
|
||||
'CheckCC' : CheckCC,
|
||||
'CheckCXX' : CheckCXX,
|
||||
'CheckSHCC' : CheckSHCC,
|
||||
'CheckSHCXX' : CheckSHCXX,
|
||||
'CheckFunc' : CheckFunc,
|
||||
'CheckType' : CheckType,
|
||||
'CheckTypeSize' : CheckTypeSize,
|
||||
'CheckDeclaration' : CheckDeclaration,
|
||||
'CheckHeader' : CheckHeader,
|
||||
'CheckCHeader' : CheckCHeader,
|
||||
'CheckCXXHeader' : CheckCXXHeader,
|
||||
'CheckLib' : CheckLib,
|
||||
'CheckLibWithHeader' : CheckLibWithHeader
|
||||
'CheckLibWithHeader' : CheckLibWithHeader,
|
||||
}
|
||||
self.AddTests(default_tests)
|
||||
self.AddTests(custom_tests)
|
||||
|
@ -425,6 +430,31 @@ class SConfBase:
|
|||
self._shutdown()
|
||||
return self.env
|
||||
|
||||
def Define(self, name, value = None, comment = None):
|
||||
"""
|
||||
Define a pre processor symbol name, with the optional given value in the
|
||||
current config header.
|
||||
|
||||
If value is None (default), then #define name is written. If value is not
|
||||
none, then #define name value is written.
|
||||
|
||||
comment is a string which will be put as a C comment in the
|
||||
header, to explain the meaning of the value (appropriate C comments /* and
|
||||
*/ will be put automatically."""
|
||||
lines = []
|
||||
if comment:
|
||||
comment_str = "/* %s */" % comment
|
||||
lines.append(comment_str)
|
||||
|
||||
if value is not None:
|
||||
define_str = "#define %s %s" % (name, value)
|
||||
else:
|
||||
define_str = "#define %s" % name
|
||||
lines.append(define_str)
|
||||
lines.append('')
|
||||
|
||||
self.config_h_text = self.config_h_text + string.join(lines, '\n')
|
||||
|
||||
def BuildNodes(self, nodes):
|
||||
"""
|
||||
Tries to build the given nodes immediately. Returns 1 on success,
|
||||
|
@ -797,6 +827,17 @@ class CheckContext:
|
|||
# TODO: should use self.vardict for $CC, $CPPFLAGS, etc.
|
||||
return not self.TryBuild(self.env.Object, text, ext)
|
||||
|
||||
def CompileSharedObject(self, text, ext):
|
||||
self.sconf.cached = 1
|
||||
# TODO: should use self.vardict for $SHCC, $CPPFLAGS, etc.
|
||||
return not self.TryBuild(self.env.SharedObject, text, ext)
|
||||
|
||||
def RunProg(self, text, ext):
|
||||
self.sconf.cached = 1
|
||||
# TODO: should use self.vardict for $CC, $CPPFLAGS, etc.
|
||||
st, out = self.TryRun(text, ext)
|
||||
return not st, out
|
||||
|
||||
def AppendLIBS(self, lib_name_list):
|
||||
oldLIBS = self.env.get( 'LIBS', [] )
|
||||
self.env.Append(LIBS = lib_name_list)
|
||||
|
@ -855,6 +896,13 @@ def CheckTypeSize(context, type_name, includes = "", language = None, expect = N
|
|||
context.did_show_result = 1
|
||||
return res
|
||||
|
||||
def CheckDeclaration(context, declaration, includes = "", language = None):
|
||||
res = SCons.Conftest.CheckDeclaration(context, declaration,
|
||||
includes = includes,
|
||||
language = language)
|
||||
context.did_show_result = 1
|
||||
return not res
|
||||
|
||||
def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'):
|
||||
# used by CheckHeader and CheckLibWithHeader to produce C - #include
|
||||
# statements from the specified header (list)
|
||||
|
@ -883,6 +931,22 @@ def CheckHeader(context, header, include_quotes = '<>', language = None):
|
|||
context.did_show_result = 1
|
||||
return not res
|
||||
|
||||
def CheckCC(context):
|
||||
res = SCons.Conftest.CheckCC(context)
|
||||
return not res
|
||||
|
||||
def CheckCXX(context):
|
||||
res = SCons.Conftest.CheckCXX(context)
|
||||
return not res
|
||||
|
||||
def CheckSHCC(context):
|
||||
res = SCons.Conftest.CheckSHCC(context)
|
||||
return not res
|
||||
|
||||
def CheckSHCXX(context):
|
||||
res = SCons.Conftest.CheckSHCXX(context)
|
||||
return not res
|
||||
|
||||
# Bram: Make this function obsolete? CheckHeader() is more generic.
|
||||
|
||||
def CheckCHeader(context, header, include_quotes = '""'):
|
|
@ -5,7 +5,7 @@ Writing and reading information to the .sconsign file or files.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,9 +27,7 @@ Writing and reading information to the .sconsign file or files.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/SConsign.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import SCons.compat
|
||||
__revision__ = "src/engine/SCons/SConsign.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import cPickle
|
||||
import os
|
126
scons/scons-local-1.2.0/SCons/Scanner/C.py
Normal file
126
scons/scons-local-1.2.0/SCons/Scanner/C.py
Normal file
|
@ -0,0 +1,126 @@
|
|||
"""SCons.Scanner.C
|
||||
|
||||
This module implements the depenency scanner for C/C++ code.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/C.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Node.FS
|
||||
import SCons.Scanner
|
||||
import SCons.Util
|
||||
|
||||
import SCons.cpp
|
||||
|
||||
class SConsCPPScanner(SCons.cpp.PreProcessor):
|
||||
"""
|
||||
SCons-specific subclass of the cpp.py module's processing.
|
||||
|
||||
We subclass this so that: 1) we can deal with files represented
|
||||
by Nodes, not strings; 2) we can keep track of the files that are
|
||||
missing.
|
||||
"""
|
||||
def __init__(self, *args, **kw):
|
||||
apply(SCons.cpp.PreProcessor.__init__, (self,)+args, kw)
|
||||
self.missing = []
|
||||
def initialize_result(self, fname):
|
||||
self.result = SCons.Util.UniqueList([fname])
|
||||
def finalize_result(self, fname):
|
||||
return self.result[1:]
|
||||
def find_include_file(self, t):
|
||||
keyword, quote, fname = t
|
||||
result = SCons.Node.FS.find_file(fname, self.searchpath[quote])
|
||||
if not result:
|
||||
self.missing.append((fname, self.current_file))
|
||||
return result
|
||||
def read_file(self, file):
|
||||
try:
|
||||
fp = open(str(file.rfile()))
|
||||
except EnvironmentError, e:
|
||||
self.missing.append((file, self.current_file))
|
||||
return ''
|
||||
else:
|
||||
return fp.read()
|
||||
|
||||
def dictify_CPPDEFINES(env):
|
||||
cppdefines = env.get('CPPDEFINES', {})
|
||||
if cppdefines is None:
|
||||
return {}
|
||||
if SCons.Util.is_Sequence(cppdefines):
|
||||
result = {}
|
||||
for c in cppdefines:
|
||||
if SCons.Util.is_Sequence(c):
|
||||
result[c[0]] = c[1]
|
||||
else:
|
||||
result[c] = None
|
||||
return result
|
||||
if not SCons.Util.is_Dict(cppdefines):
|
||||
return {cppdefines : None}
|
||||
return cppdefines
|
||||
|
||||
class SConsCPPScannerWrapper:
|
||||
"""
|
||||
The SCons wrapper around a cpp.py scanner.
|
||||
|
||||
This is the actual glue between the calling conventions of generic
|
||||
SCons scanners, and the (subclass of) cpp.py class that knows how
|
||||
to look for #include lines with reasonably real C-preprocessor-like
|
||||
evaluation of #if/#ifdef/#else/#elif lines.
|
||||
"""
|
||||
def __init__(self, name, variable):
|
||||
self.name = name
|
||||
self.path = SCons.Scanner.FindPathDirs(variable)
|
||||
def __call__(self, node, env, path = ()):
|
||||
cpp = SConsCPPScanner(current = node.get_dir(),
|
||||
cpppath = path,
|
||||
dict = dictify_CPPDEFINES(env))
|
||||
result = cpp(node)
|
||||
for included, includer in cpp.missing:
|
||||
fmt = "No dependency generated for file: %s (included from: %s) -- file not found"
|
||||
SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
|
||||
fmt % (included, includer))
|
||||
return result
|
||||
|
||||
def recurse_nodes(self, nodes):
|
||||
return nodes
|
||||
def select(self, node):
|
||||
return self
|
||||
|
||||
def CScanner():
|
||||
"""Return a prototype Scanner instance for scanning source files
|
||||
that use the C pre-processor"""
|
||||
|
||||
# Here's how we would (or might) use the CPP scanner code above that
|
||||
# knows how to evaluate #if/#ifdef/#else/#elif lines when searching
|
||||
# for #includes. This is commented out for now until we add the
|
||||
# right configurability to let users pick between the scanners.
|
||||
#return SConsCPPScannerWrapper("CScanner", "CPPPATH")
|
||||
|
||||
cs = SCons.Scanner.ClassicCPP("CScanner",
|
||||
"$CPPSUFFIXES",
|
||||
"CPPPATH",
|
||||
'^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")')
|
||||
return cs
|
|
@ -8,7 +8,7 @@ Coded by Andy Friesen
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,24 +30,39 @@ Coded by Andy Friesen
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/D.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Scanner/D.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import re
|
||||
import string
|
||||
|
||||
import SCons.Scanner
|
||||
|
||||
def DScanner():
|
||||
"""Return a prototype Scanner instance for scanning D source files"""
|
||||
ds = D(name = "DScanner",
|
||||
suffixes = '$DSUFFIXES',
|
||||
path_variable = 'DPATH',
|
||||
regex = 'import\s+([^\;]*)\;')
|
||||
ds = D()
|
||||
return ds
|
||||
|
||||
class D(SCons.Scanner.Classic):
|
||||
def __init__ (self):
|
||||
SCons.Scanner.Classic.__init__ (self,
|
||||
name = "DScanner",
|
||||
suffixes = '$DSUFFIXES',
|
||||
path_variable = 'DPATH',
|
||||
regex = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)\s*)*;')
|
||||
|
||||
self.cre2 = re.compile ('(?:import\s)?\s*([a-zA-Z0-9_.]+)\s*(?:,|;)', re.M)
|
||||
|
||||
def find_include(self, include, source_dir, path):
|
||||
# translate dots (package separators) to slashes
|
||||
inc = string.replace(include, '.', '/')
|
||||
|
||||
i = SCons.Node.FS.find_file(inc + '.d', (source_dir,) + path)
|
||||
if i is None:
|
||||
i = SCons.Node.FS.find_file (inc + '.di', (source_dir,) + path)
|
||||
return i, include
|
||||
|
||||
def find_include_names(self, node):
|
||||
includes = []
|
||||
for i in self.cre.findall(node.get_contents()):
|
||||
includes = includes + self.cre2.findall(i)
|
||||
return includes
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/Dir.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Scanner/Dir.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Node.FS
|
||||
import SCons.Scanner
|
|
@ -5,7 +5,7 @@ This module implements the dependency scanner for Fortran code.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ This module implements the dependency scanner for Fortran code.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/Fortran.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Scanner/Fortran.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import re
|
||||
import string
|
|
@ -6,7 +6,7 @@ Definition Language) files.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -28,7 +28,7 @@ Definition Language) files.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/IDL.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Scanner/IDL.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Node.FS
|
||||
import SCons.Scanner
|
334
scons/scons-local-1.2.0/SCons/Scanner/LaTeX.py
Normal file
334
scons/scons-local-1.2.0/SCons/Scanner/LaTeX.py
Normal file
|
@ -0,0 +1,334 @@
|
|||
"""SCons.Scanner.LaTeX
|
||||
|
||||
This module implements the dependency scanner for LaTeX code.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/LaTeX.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os.path
|
||||
import string
|
||||
import re
|
||||
|
||||
import SCons.Scanner
|
||||
import SCons.Util
|
||||
|
||||
# list of graphics file extensions for TeX and LaTeX
|
||||
TexGraphics = ['.eps', '.ps']
|
||||
LatexGraphics = ['.pdf', '.png', '.jpg', '.gif', '.tif']
|
||||
|
||||
# Used as a return value of modify_env_var if the variable is not set.
|
||||
class _Null:
|
||||
pass
|
||||
_null = _Null
|
||||
|
||||
# The user specifies the paths in env[variable], similar to other builders.
|
||||
# They may be relative and must be converted to absolute, as expected
|
||||
# by LaTeX and Co. The environment may already have some paths in
|
||||
# env['ENV'][var]. These paths are honored, but the env[var] paths have
|
||||
# higher precedence. All changes are un-done on exit.
|
||||
def modify_env_var(env, var, abspath):
|
||||
try:
|
||||
save = env['ENV'][var]
|
||||
except KeyError:
|
||||
save = _null
|
||||
env.PrependENVPath(var, abspath)
|
||||
try:
|
||||
if SCons.Util.is_List(env[var]):
|
||||
#TODO(1.5)
|
||||
#env.PrependENVPath(var, [os.path.abspath(str(p)) for p in env[var]])
|
||||
env.PrependENVPath(var, map(lambda p: os.path.abspath(str(p)), env[var]))
|
||||
else:
|
||||
# Split at os.pathsep to convert into absolute path
|
||||
#TODO(1.5) env.PrependENVPath(var, [os.path.abspath(p) for p in str(env[var]).split(os.pathsep)])
|
||||
env.PrependENVPath(var, map(lambda p: os.path.abspath(p), string.split(str(env[var]), os.pathsep)))
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# Convert into a string explicitly to append ":" (without which it won't search system
|
||||
# paths as well). The problem is that env.AppendENVPath(var, ":")
|
||||
# does not work, refuses to append ":" (os.pathsep).
|
||||
|
||||
if SCons.Util.is_List(env['ENV'][var]):
|
||||
# TODO(1.5)
|
||||
#env['ENV'][var] = os.pathsep.join(env['ENV'][var])
|
||||
env['ENV'][var] = string.join(env['ENV'][var], os.pathsep)
|
||||
# Append the trailing os.pathsep character here to catch the case with no env[var]
|
||||
env['ENV'][var] = env['ENV'][var] + os.pathsep
|
||||
|
||||
return save
|
||||
|
||||
class FindENVPathDirs:
|
||||
"""A class to bind a specific *PATH variable name to a function that
|
||||
will return all of the *path directories."""
|
||||
def __init__(self, variable):
|
||||
self.variable = variable
|
||||
def __call__(self, env, dir=None, target=None, source=None, argument=None):
|
||||
import SCons.PathList
|
||||
try:
|
||||
path = env['ENV'][self.variable]
|
||||
except KeyError:
|
||||
return ()
|
||||
|
||||
dir = dir or env.fs._cwd
|
||||
path = SCons.PathList.PathList(path).subst_path(env, target, source)
|
||||
return tuple(dir.Rfindalldirs(path))
|
||||
|
||||
|
||||
|
||||
def LaTeXScanner():
|
||||
"""Return a prototype Scanner instance for scanning LaTeX source files
|
||||
when built with latex.
|
||||
"""
|
||||
ds = LaTeX(name = "LaTeXScanner",
|
||||
suffixes = '$LATEXSUFFIXES',
|
||||
# in the search order, see below in LaTeX class docstring
|
||||
graphics_extensions = TexGraphics,
|
||||
recursive = 0)
|
||||
return ds
|
||||
|
||||
def PDFLaTeXScanner():
|
||||
"""Return a prototype Scanner instance for scanning LaTeX source files
|
||||
when built with pdflatex.
|
||||
"""
|
||||
ds = LaTeX(name = "PDFLaTeXScanner",
|
||||
suffixes = '$LATEXSUFFIXES',
|
||||
# in the search order, see below in LaTeX class docstring
|
||||
graphics_extensions = LatexGraphics,
|
||||
recursive = 0)
|
||||
return ds
|
||||
|
||||
class LaTeX(SCons.Scanner.Base):
|
||||
"""Class for scanning LaTeX files for included files.
|
||||
|
||||
Unlike most scanners, which use regular expressions that just
|
||||
return the included file name, this returns a tuple consisting
|
||||
of the keyword for the inclusion ("include", "includegraphics",
|
||||
"input", or "bibliography"), and then the file name itself.
|
||||
Based on a quick look at LaTeX documentation, it seems that we
|
||||
should append .tex suffix for the "include" keywords, append .tex if
|
||||
there is no extension for the "input" keyword, and need to add .bib
|
||||
for the "bibliography" keyword that does not accept extensions by itself.
|
||||
|
||||
Finally, if there is no extension for an "includegraphics" keyword
|
||||
latex will append .ps or .eps to find the file, while pdftex may use .pdf,
|
||||
.jpg, .tif, .mps, or .png.
|
||||
|
||||
The actual subset and search order may be altered by
|
||||
DeclareGraphicsExtensions command. This complication is ignored.
|
||||
The default order corresponds to experimentation with teTeX
|
||||
$ latex --version
|
||||
pdfeTeX 3.141592-1.21a-2.2 (Web2C 7.5.4)
|
||||
kpathsea version 3.5.4
|
||||
The order is:
|
||||
['.eps', '.ps'] for latex
|
||||
['.png', '.pdf', '.jpg', '.tif'].
|
||||
|
||||
Another difference is that the search path is determined by the type
|
||||
of the file being searched:
|
||||
env['TEXINPUTS'] for "input" and "include" keywords
|
||||
env['TEXINPUTS'] for "includegraphics" keyword
|
||||
env['BIBINPUTS'] for "bibliography" keyword
|
||||
env['BSTINPUTS'] for "bibliographystyle" keyword
|
||||
|
||||
FIXME: also look for the class or style in document[class|style]{}
|
||||
FIXME: also look for the argument of bibliographystyle{}
|
||||
"""
|
||||
keyword_paths = {'include': 'TEXINPUTS',
|
||||
'input': 'TEXINPUTS',
|
||||
'includegraphics': 'TEXINPUTS',
|
||||
'bibliography': 'BIBINPUTS',
|
||||
'bibliographystyle': 'BSTINPUTS',
|
||||
'usepackage': 'TEXINPUTS'}
|
||||
env_variables = SCons.Util.unique(keyword_paths.values())
|
||||
|
||||
def __init__(self, name, suffixes, graphics_extensions, *args, **kw):
|
||||
|
||||
# We have to include \n with the % we exclude from the first part
|
||||
# part of the regex because the expression is compiled with re.M.
|
||||
# Without the \n, the ^ could match the beginning of a *previous*
|
||||
# line followed by one or more newline characters (i.e. blank
|
||||
# lines), interfering with a match on the next line.
|
||||
regex = r'^[^%\n]*\\(include|includegraphics(?:\[[^\]]+\])?|input|bibliography|usepackage){([^}]*)}'
|
||||
self.cre = re.compile(regex, re.M)
|
||||
self.graphics_extensions = graphics_extensions
|
||||
|
||||
def _scan(node, env, path=(), self=self):
|
||||
node = node.rfile()
|
||||
if not node.exists():
|
||||
return []
|
||||
return self.scan(node, path)
|
||||
|
||||
class FindMultiPathDirs:
|
||||
"""The stock FindPathDirs function has the wrong granularity:
|
||||
it is called once per target, while we need the path that depends
|
||||
on what kind of included files is being searched. This wrapper
|
||||
hides multiple instances of FindPathDirs, one per the LaTeX path
|
||||
variable in the environment. When invoked, the function calculates
|
||||
and returns all the required paths as a dictionary (converted into
|
||||
a tuple to become hashable). Then the scan function converts it
|
||||
back and uses a dictionary of tuples rather than a single tuple
|
||||
of paths.
|
||||
"""
|
||||
def __init__(self, dictionary):
|
||||
self.dictionary = {}
|
||||
for k,n in dictionary.items():
|
||||
self.dictionary[k] = ( SCons.Scanner.FindPathDirs(n),
|
||||
FindENVPathDirs(n) )
|
||||
|
||||
def __call__(self, env, dir=None, target=None, source=None,
|
||||
argument=None):
|
||||
di = {}
|
||||
for k,(c,cENV) in self.dictionary.items():
|
||||
di[k] = ( c(env, dir=None, target=None, source=None,
|
||||
argument=None) ,
|
||||
cENV(env, dir=None, target=None, source=None,
|
||||
argument=None) )
|
||||
# To prevent "dict is not hashable error"
|
||||
return tuple(di.items())
|
||||
|
||||
class LaTeXScanCheck:
|
||||
"""Skip all but LaTeX source files, i.e., do not scan *.eps,
|
||||
*.pdf, *.jpg, etc.
|
||||
"""
|
||||
def __init__(self, suffixes):
|
||||
self.suffixes = suffixes
|
||||
def __call__(self, node, env):
|
||||
current = not node.has_builder() or node.is_up_to_date()
|
||||
scannable = node.get_suffix() in env.subst_list(self.suffixes)[0]
|
||||
# Returning false means that the file is not scanned.
|
||||
return scannable and current
|
||||
|
||||
kw['function'] = _scan
|
||||
kw['path_function'] = FindMultiPathDirs(LaTeX.keyword_paths)
|
||||
kw['recursive'] = 1
|
||||
kw['skeys'] = suffixes
|
||||
kw['scan_check'] = LaTeXScanCheck(suffixes)
|
||||
kw['name'] = name
|
||||
|
||||
apply(SCons.Scanner.Base.__init__, (self,) + args, kw)
|
||||
|
||||
def _latex_names(self, include):
|
||||
filename = include[1]
|
||||
if include[0] == 'input':
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
return [filename + '.tex']
|
||||
if (include[0] == 'include'):
|
||||
return [filename + '.tex']
|
||||
if include[0] == 'bibliography':
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
return [filename + '.bib']
|
||||
if include[0] == 'usepackage':
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
return [filename + '.sty']
|
||||
if include[0] == 'includegraphics':
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
#TODO(1.5) return [filename + e for e in self.graphics_extensions]
|
||||
return map(lambda e, f=filename: f+e, self.graphics_extensions)
|
||||
return [filename]
|
||||
|
||||
def sort_key(self, include):
|
||||
return SCons.Node.FS._my_normcase(str(include))
|
||||
|
||||
def find_include(self, include, source_dir, path):
|
||||
try:
|
||||
sub_path = path[include[0]]
|
||||
except (IndexError, KeyError):
|
||||
sub_path = ()
|
||||
try_names = self._latex_names(include)
|
||||
for n in try_names:
|
||||
# see if we find it using the path in env[var]
|
||||
i = SCons.Node.FS.find_file(n, (source_dir,) + sub_path[0])
|
||||
if i:
|
||||
return i, include
|
||||
# see if we find it using the path in env['ENV'][var]
|
||||
i = SCons.Node.FS.find_file(n, (source_dir,) + sub_path[1])
|
||||
if i:
|
||||
return i, include
|
||||
return i, include
|
||||
|
||||
def scan(self, node, path=()):
|
||||
# Modify the default scan function to allow for the regular
|
||||
# expression to return a comma separated list of file names
|
||||
# as can be the case with the bibliography keyword.
|
||||
|
||||
# Cache the includes list in node so we only scan it once:
|
||||
path_dict = dict(list(path))
|
||||
noopt_cre = re.compile('\[.*$')
|
||||
if node.includes != None:
|
||||
includes = node.includes
|
||||
else:
|
||||
includes = self.cre.findall(node.get_contents())
|
||||
# 1. Split comma-separated lines, e.g.
|
||||
# ('bibliography', 'phys,comp')
|
||||
# should become two entries
|
||||
# ('bibliography', 'phys')
|
||||
# ('bibliography', 'comp')
|
||||
# 2. Remove the options, e.g., such as
|
||||
# ('includegraphics[clip,width=0.7\\linewidth]', 'picture.eps')
|
||||
# should become
|
||||
# ('includegraphics', 'picture.eps')
|
||||
split_includes = []
|
||||
for include in includes:
|
||||
inc_type = noopt_cre.sub('', include[0])
|
||||
inc_list = string.split(include[1],',')
|
||||
for j in range(len(inc_list)):
|
||||
split_includes.append( (inc_type, inc_list[j]) )
|
||||
#
|
||||
includes = split_includes
|
||||
node.includes = includes
|
||||
|
||||
# This is a hand-coded DSU (decorate-sort-undecorate, or
|
||||
# Schwartzian transform) pattern. The sort key is the raw name
|
||||
# of the file as specifed on the \include, \input, etc. line.
|
||||
# TODO: what about the comment in the original Classic scanner:
|
||||
# """which lets
|
||||
# us keep the sort order constant regardless of whether the file
|
||||
# is actually found in a Repository or locally."""
|
||||
nodes = []
|
||||
source_dir = node.get_dir()
|
||||
for include in includes:
|
||||
#
|
||||
# Handle multiple filenames in include[1]
|
||||
#
|
||||
n, i = self.find_include(include, source_dir, path_dict)
|
||||
if n is None:
|
||||
# Do not bother with 'usepackage' warnings, as they most
|
||||
# likely refer to system-level files
|
||||
if include[0] != 'usepackage':
|
||||
SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
|
||||
"No dependency generated for file: %s (included from: %s) -- file not found" % (i, node))
|
||||
else:
|
||||
sortkey = self.sort_key(n)
|
||||
nodes.append((sortkey, n))
|
||||
#
|
||||
nodes.sort()
|
||||
nodes = map(lambda pair: pair[1], nodes)
|
||||
return nodes
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/Prog.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Scanner/Prog.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import string
|
||||
|
||||
|
@ -54,10 +54,8 @@ def scan(node, env, libpath = ()):
|
|||
return []
|
||||
if SCons.Util.is_String(libs):
|
||||
libs = string.split(libs)
|
||||
elif SCons.Util.is_List(libs):
|
||||
libs = SCons.Util.flatten(libs)
|
||||
else:
|
||||
libs = [libs]
|
||||
libs = SCons.Util.flatten(libs)
|
||||
|
||||
try:
|
||||
prefix = env['LIBPREFIXES']
|
|
@ -1,11 +1,12 @@
|
|||
"""SCons.Scanner.C
|
||||
"""SCons.Scanner.RC
|
||||
|
||||
This module implements the depenency scanner for C/C++ code.
|
||||
This module implements the depenency scanner for RC (Interface
|
||||
Definition Language) files.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,16 +28,22 @@ This module implements the depenency scanner for C/C++ code.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/C.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Scanner/RC.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Node.FS
|
||||
import SCons.Scanner
|
||||
import re
|
||||
|
||||
def CScanner():
|
||||
"""Return a prototype Scanner instance for scanning source files
|
||||
that use the C pre-processor"""
|
||||
cs = SCons.Scanner.ClassicCPP("CScanner",
|
||||
"$CPPSUFFIXES",
|
||||
"CPPPATH",
|
||||
'^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")')
|
||||
return cs
|
||||
def RCScan():
|
||||
"""Return a prototype Scanner instance for scanning RC source files"""
|
||||
|
||||
res_re= r'^(?:\s*#\s*(?:include)|' \
|
||||
'.*?\s+(?:ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)' \
|
||||
'\s*.*?)' \
|
||||
'\s*(<|"| )([^>"\s]+)(?:[>" ])*$'
|
||||
resScanner = SCons.Scanner.ClassicCPP( "ResourceScanner",
|
||||
"$RCSUFFIXES",
|
||||
"CPPPATH",
|
||||
res_re )
|
||||
|
||||
return resScanner
|
|
@ -5,7 +5,7 @@ The Scanner package for the SCons software construction utility.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ The Scanner package for the SCons software construction utility.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/__init__.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Scanner/__init__.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import re
|
||||
import string
|
||||
|
@ -67,7 +67,7 @@ class FindPathDirs:
|
|||
will return all of the *path directories."""
|
||||
def __init__(self, variable):
|
||||
self.variable = variable
|
||||
def __call__(self, env, dir, target=None, source=None, argument=None):
|
||||
def __call__(self, env, dir=None, target=None, source=None, argument=None):
|
||||
import SCons.PathList
|
||||
try:
|
||||
path = env[self.variable]
|
||||
|
@ -346,13 +346,16 @@ class Classic(Current):
|
|||
def sort_key(self, include):
|
||||
return SCons.Node.FS._my_normcase(include)
|
||||
|
||||
def find_include_names(self, node):
|
||||
return self.cre.findall(node.get_contents())
|
||||
|
||||
def scan(self, node, path=()):
|
||||
|
||||
# cache the includes list in node so we only scan it once:
|
||||
if node.includes != None:
|
||||
includes = node.includes
|
||||
else:
|
||||
includes = self.cre.findall(node.get_contents())
|
||||
includes = self.find_include_names (node)
|
||||
node.includes = includes
|
||||
|
||||
# This is a hand-coded DSU (decorate-sort-undecorate, or
|
376
scons/scons-local-1.2.0/SCons/Script/Interactive.py
Normal file
376
scons/scons-local-1.2.0/SCons/Script/Interactive.py
Normal file
|
@ -0,0 +1,376 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/Interactive.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
__doc__ = """
|
||||
SCons interactive mode
|
||||
"""
|
||||
|
||||
# TODO:
|
||||
#
|
||||
# This has the potential to grow into something with a really big life
|
||||
# of its own, which might or might not be a good thing. Nevertheless,
|
||||
# here are some enhancements that will probably be requested some day
|
||||
# and are worth keeping in mind (assuming this takes off):
|
||||
#
|
||||
# - A command to re-read / re-load the SConscript files. This may
|
||||
# involve allowing people to specify command-line options (e.g. -f,
|
||||
# -I, --no-site-dir) that affect how the SConscript files are read.
|
||||
#
|
||||
# - Additional command-line options on the "build" command.
|
||||
#
|
||||
# Of the supported options that seemed to make sense (after a quick
|
||||
# pass through the list), the ones that seemed likely enough to be
|
||||
# used are listed in the man page and have explicit test scripts.
|
||||
#
|
||||
# These had code changed in Script/Main.py to support them, but didn't
|
||||
# seem likely to be used regularly, so had no test scripts added:
|
||||
#
|
||||
# build --diskcheck=*
|
||||
# build --implicit-cache=*
|
||||
# build --implicit-deps-changed=*
|
||||
# build --implicit-deps-unchanged=*
|
||||
#
|
||||
# These look like they should "just work" with no changes to the
|
||||
# existing code, but like those above, look unlikely to be used and
|
||||
# therefore had no test scripts added:
|
||||
#
|
||||
# build --random
|
||||
#
|
||||
# These I'm not sure about. They might be useful for individual
|
||||
# "build" commands, and may even work, but they seem unlikely enough
|
||||
# that we'll wait until they're requested before spending any time on
|
||||
# writing test scripts for them, or investigating whether they work.
|
||||
#
|
||||
# build -q [??? is there a useful analog to the exit status?]
|
||||
# build --duplicate=
|
||||
# build --profile=
|
||||
# build --max-drift=
|
||||
# build --warn=*
|
||||
# build --Y
|
||||
#
|
||||
# - Most of the SCons command-line options that the "build" command
|
||||
# supports should be settable as default options that apply to all
|
||||
# subsequent "build" commands. Maybe a "set {option}" command that
|
||||
# maps to "SetOption('{option}')".
|
||||
#
|
||||
# - Need something in the 'help' command that prints the -h output.
|
||||
#
|
||||
# - A command to run the configure subsystem separately (must see how
|
||||
# this interacts with the new automake model).
|
||||
#
|
||||
# - Command-line completion of target names; maybe even of SCons options?
|
||||
# Completion is something that's supported by the Python cmd module,
|
||||
# so this should be doable without too much trouble.
|
||||
#
|
||||
|
||||
import cmd
|
||||
import copy
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import string
|
||||
import sys
|
||||
|
||||
try:
|
||||
import readline
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
class SConsInteractiveCmd(cmd.Cmd):
|
||||
"""\
|
||||
build [TARGETS] Build the specified TARGETS and their dependencies.
|
||||
'b' is a synonym.
|
||||
clean [TARGETS] Clean (remove) the specified TARGETS and their
|
||||
dependencies. 'c' is a synonym.
|
||||
exit Exit SCons interactive mode.
|
||||
help [COMMAND] Prints help for the specified COMMAND. 'h' and
|
||||
'?' are synonyms.
|
||||
shell [COMMANDLINE] Execute COMMANDLINE in a subshell. 'sh' and '!'
|
||||
are synonyms.
|
||||
version Prints SCons version information.
|
||||
"""
|
||||
|
||||
synonyms = {
|
||||
'b' : 'build',
|
||||
'c' : 'clean',
|
||||
'h' : 'help',
|
||||
'scons' : 'build',
|
||||
'sh' : 'shell',
|
||||
}
|
||||
|
||||
def __init__(self, **kw):
|
||||
cmd.Cmd.__init__(self)
|
||||
for key, val in kw.items():
|
||||
setattr(self, key, val)
|
||||
|
||||
if sys.platform == 'win32':
|
||||
self.shell_variable = 'COMSPEC'
|
||||
else:
|
||||
self.shell_variable = 'SHELL'
|
||||
|
||||
def default(self, argv):
|
||||
print "*** Unknown command: %s" % argv[0]
|
||||
|
||||
def onecmd(self, line):
|
||||
line = string.strip(line)
|
||||
if not line:
|
||||
print self.lastcmd
|
||||
return self.emptyline()
|
||||
self.lastcmd = line
|
||||
if line[0] == '!':
|
||||
line = 'shell ' + line[1:]
|
||||
elif line[0] == '?':
|
||||
line = 'help ' + line[1:]
|
||||
if os.sep == '\\':
|
||||
line = string.replace(line, '\\', '\\\\')
|
||||
argv = shlex.split(line)
|
||||
argv[0] = self.synonyms.get(argv[0], argv[0])
|
||||
if not argv[0]:
|
||||
return self.default(line)
|
||||
else:
|
||||
try:
|
||||
func = getattr(self, 'do_' + argv[0])
|
||||
except AttributeError:
|
||||
return self.default(argv)
|
||||
return func(argv)
|
||||
|
||||
def do_build(self, argv):
|
||||
"""\
|
||||
build [TARGETS] Build the specified TARGETS and their
|
||||
dependencies. 'b' is a synonym.
|
||||
"""
|
||||
import SCons.Node
|
||||
import SCons.SConsign
|
||||
import SCons.Script.Main
|
||||
|
||||
options = copy.deepcopy(self.options)
|
||||
|
||||
options, targets = self.parser.parse_args(argv[1:], values=options)
|
||||
|
||||
SCons.Script.COMMAND_LINE_TARGETS = targets
|
||||
|
||||
if targets:
|
||||
SCons.Script.BUILD_TARGETS = targets
|
||||
else:
|
||||
# If the user didn't specify any targets on the command line,
|
||||
# use the list of default targets.
|
||||
SCons.Script.BUILD_TARGETS = SCons.Script._build_plus_default
|
||||
|
||||
nodes = SCons.Script.Main._build_targets(self.fs,
|
||||
options,
|
||||
targets,
|
||||
self.target_top)
|
||||
|
||||
if not nodes:
|
||||
return
|
||||
|
||||
# Call each of the Node's alter_targets() methods, which may
|
||||
# provide additional targets that ended up as part of the build
|
||||
# (the canonical example being a VariantDir() when we're building
|
||||
# from a source directory) and which we therefore need their
|
||||
# state cleared, too.
|
||||
x = []
|
||||
for n in nodes:
|
||||
x.extend(n.alter_targets()[0])
|
||||
nodes.extend(x)
|
||||
|
||||
# Clean up so that we can perform the next build correctly.
|
||||
#
|
||||
# We do this by walking over all the children of the targets,
|
||||
# and clearing their state.
|
||||
#
|
||||
# We currently have to re-scan each node to find their
|
||||
# children, because built nodes have already been partially
|
||||
# cleared and don't remember their children. (In scons
|
||||
# 0.96.1 and earlier, this wasn't the case, and we didn't
|
||||
# have to re-scan the nodes.)
|
||||
#
|
||||
# Because we have to re-scan each node, we can't clear the
|
||||
# nodes as we walk over them, because we may end up rescanning
|
||||
# a cleared node as we scan a later node. Therefore, only
|
||||
# store the list of nodes that need to be cleared as we walk
|
||||
# the tree, and clear them in a separate pass.
|
||||
#
|
||||
# XXX: Someone more familiar with the inner workings of scons
|
||||
# may be able to point out a more efficient way to do this.
|
||||
|
||||
SCons.Script.Main.progress_display("scons: Clearing cached node information ...")
|
||||
|
||||
seen_nodes = {}
|
||||
|
||||
def get_unseen_children(node, parent, seen_nodes=seen_nodes):
|
||||
def is_unseen(node, seen_nodes=seen_nodes):
|
||||
return not seen_nodes.has_key(node)
|
||||
return filter(is_unseen, node.children(scan=1))
|
||||
|
||||
def add_to_seen_nodes(node, parent, seen_nodes=seen_nodes):
|
||||
seen_nodes[node] = 1
|
||||
|
||||
# If this file is in a VariantDir and has a
|
||||
# corresponding source file in the source tree, remember the
|
||||
# node in the source tree, too. This is needed in
|
||||
# particular to clear cached implicit dependencies on the
|
||||
# source file, since the scanner will scan it if the
|
||||
# VariantDir was created with duplicate=0.
|
||||
try:
|
||||
rfile_method = node.rfile
|
||||
except AttributeError:
|
||||
return
|
||||
else:
|
||||
rfile = rfile_method()
|
||||
if rfile != node:
|
||||
seen_nodes[rfile] = 1
|
||||
|
||||
for node in nodes:
|
||||
walker = SCons.Node.Walker(node,
|
||||
kids_func=get_unseen_children,
|
||||
eval_func=add_to_seen_nodes)
|
||||
n = walker.next()
|
||||
while n:
|
||||
n = walker.next()
|
||||
|
||||
for node in seen_nodes.keys():
|
||||
# Call node.clear() to clear most of the state
|
||||
node.clear()
|
||||
# node.clear() doesn't reset node.state, so call
|
||||
# node.set_state() to reset it manually
|
||||
node.set_state(SCons.Node.no_state)
|
||||
node.implicit = None
|
||||
|
||||
# Debug: Uncomment to verify that all Taskmaster reference
|
||||
# counts have been reset to zero.
|
||||
#if node.ref_count != 0:
|
||||
# from SCons.Debug import Trace
|
||||
# Trace('node %s, ref_count %s !!!\n' % (node, node.ref_count))
|
||||
|
||||
SCons.SConsign.Reset()
|
||||
SCons.Script.Main.progress_display("scons: done clearing node information.")
|
||||
|
||||
def do_clean(self, argv):
|
||||
"""\
|
||||
clean [TARGETS] Clean (remove) the specified TARGETS
|
||||
and their dependencies. 'c' is a synonym.
|
||||
"""
|
||||
return self.do_build(['build', '--clean'] + argv[1:])
|
||||
|
||||
def do_EOF(self, argv):
|
||||
print
|
||||
self.do_exit(argv)
|
||||
|
||||
def _do_one_help(self, arg):
|
||||
try:
|
||||
# If help_<arg>() exists, then call it.
|
||||
func = getattr(self, 'help_' + arg)
|
||||
except AttributeError:
|
||||
try:
|
||||
func = getattr(self, 'do_' + arg)
|
||||
except AttributeError:
|
||||
doc = None
|
||||
else:
|
||||
doc = self._doc_to_help(func)
|
||||
if doc:
|
||||
sys.stdout.write(doc + '\n')
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
doc = self.strip_initial_spaces(func())
|
||||
if doc:
|
||||
sys.stdout.write(doc + '\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
def _doc_to_help(self, obj):
|
||||
doc = obj.__doc__
|
||||
if doc is None:
|
||||
return ''
|
||||
return self._strip_initial_spaces(doc)
|
||||
|
||||
def _strip_initial_spaces(self, s):
|
||||
#lines = s.split('\n')
|
||||
lines = string.split(s, '\n')
|
||||
spaces = re.match(' *', lines[0]).group(0)
|
||||
#def strip_spaces(l):
|
||||
# if l.startswith(spaces):
|
||||
# l = l[len(spaces):]
|
||||
# return l
|
||||
#return '\n'.join([ strip_spaces(l) for l in lines ])
|
||||
def strip_spaces(l, spaces=spaces):
|
||||
if l[:len(spaces)] == spaces:
|
||||
l = l[len(spaces):]
|
||||
return l
|
||||
lines = map(strip_spaces, lines)
|
||||
return string.join(lines, '\n')
|
||||
|
||||
def do_exit(self, argv):
|
||||
"""\
|
||||
exit Exit SCons interactive mode.
|
||||
"""
|
||||
sys.exit(0)
|
||||
|
||||
def do_help(self, argv):
|
||||
"""\
|
||||
help [COMMAND] Prints help for the specified COMMAND. 'h'
|
||||
and '?' are synonyms.
|
||||
"""
|
||||
if argv[1:]:
|
||||
for arg in argv[1:]:
|
||||
if self._do_one_help(arg):
|
||||
break
|
||||
else:
|
||||
# If bare 'help' is called, print this class's doc
|
||||
# string (if it has one).
|
||||
doc = self._doc_to_help(self.__class__)
|
||||
if doc:
|
||||
sys.stdout.write(doc + '\n')
|
||||
sys.stdout.flush()
|
||||
|
||||
def do_shell(self, argv):
|
||||
"""\
|
||||
shell [COMMANDLINE] Execute COMMANDLINE in a subshell. 'sh' and
|
||||
'!' are synonyms.
|
||||
"""
|
||||
import subprocess
|
||||
argv = argv[1:]
|
||||
if not argv:
|
||||
argv = os.environ[self.shell_variable]
|
||||
try:
|
||||
p = subprocess.Popen(argv)
|
||||
except EnvironmentError, e:
|
||||
sys.stderr.write('scons: %s: %s\n' % (argv[0], e.strerror))
|
||||
else:
|
||||
p.wait()
|
||||
|
||||
def do_version(self, argv):
|
||||
"""\
|
||||
version Prints SCons version information.
|
||||
"""
|
||||
sys.stdout.write(self.parser.version + '\n')
|
||||
|
||||
def interact(fs, parser, options, targets, target_top):
|
||||
c = SConsInteractiveCmd(prompt = 'scons>>> ',
|
||||
fs = fs,
|
||||
parser = parser,
|
||||
options = options,
|
||||
targets = targets,
|
||||
target_top = target_top)
|
||||
c.cmdloop()
|
|
@ -12,7 +12,7 @@ it goes here.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -34,9 +34,7 @@ it goes here.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/Main.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import SCons.compat
|
||||
__revision__ = "src/engine/SCons/Script/Main.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
@ -68,6 +66,18 @@ import SCons.Taskmaster
|
|||
import SCons.Util
|
||||
import SCons.Warnings
|
||||
|
||||
import SCons.Script.Interactive
|
||||
|
||||
def fetch_win32_parallel_msg():
|
||||
# A subsidiary function that exists solely to isolate this import
|
||||
# so we don't have to pull it in on all platforms, and so that an
|
||||
# in-line "import" statement in the _main() function below doesn't
|
||||
# cause warnings about local names shadowing use of the 'SCons'
|
||||
# globl in nest scopes and UnboundLocalErrors and the like in some
|
||||
# versions (2.1) of Python.
|
||||
import SCons.Platform.win32
|
||||
return SCons.Platform.win32.parallel_msg
|
||||
|
||||
#
|
||||
|
||||
class SConsPrintHelpException(Exception):
|
||||
|
@ -156,49 +166,60 @@ class BuildTask(SCons.Taskmaster.Task):
|
|||
self.progress(self.targets[0])
|
||||
return SCons.Taskmaster.Task.prepare(self)
|
||||
|
||||
def execute(self):
|
||||
for target in self.targets:
|
||||
if target.get_state() == SCons.Node.up_to_date:
|
||||
continue
|
||||
if target.has_builder() and not hasattr(target.builder, 'status'):
|
||||
if print_time:
|
||||
start_time = time.time()
|
||||
global first_command_start
|
||||
if first_command_start is None:
|
||||
first_command_start = start_time
|
||||
SCons.Taskmaster.Task.execute(self)
|
||||
if print_time:
|
||||
global cumulative_command_time
|
||||
global last_command_end
|
||||
finish_time = time.time()
|
||||
last_command_end = finish_time
|
||||
cumulative_command_time = cumulative_command_time+finish_time-start_time
|
||||
sys.stdout.write("Command execution time: %f seconds\n"%(finish_time-start_time))
|
||||
break
|
||||
def needs_execute(self):
|
||||
target = self.targets[0]
|
||||
if target.get_state() == SCons.Node.executing:
|
||||
return True
|
||||
else:
|
||||
if self.top and target.has_builder():
|
||||
display("scons: `%s' is up to date." % str(self.node))
|
||||
return False
|
||||
|
||||
def execute(self):
|
||||
if print_time:
|
||||
start_time = time.time()
|
||||
global first_command_start
|
||||
if first_command_start is None:
|
||||
first_command_start = start_time
|
||||
SCons.Taskmaster.Task.execute(self)
|
||||
if print_time:
|
||||
global cumulative_command_time
|
||||
global last_command_end
|
||||
finish_time = time.time()
|
||||
last_command_end = finish_time
|
||||
cumulative_command_time = cumulative_command_time+finish_time-start_time
|
||||
sys.stdout.write("Command execution time: %f seconds\n"%(finish_time-start_time))
|
||||
|
||||
def do_failed(self, status=2):
|
||||
_BuildFailures.append(self.exception[1])
|
||||
global exit_status
|
||||
global this_build_status
|
||||
if self.options.ignore_errors:
|
||||
SCons.Taskmaster.Task.executed(self)
|
||||
elif self.options.keep_going:
|
||||
SCons.Taskmaster.Task.fail_continue(self)
|
||||
exit_status = status
|
||||
this_build_status = status
|
||||
else:
|
||||
SCons.Taskmaster.Task.fail_stop(self)
|
||||
exit_status = status
|
||||
this_build_status = status
|
||||
|
||||
def executed(self):
|
||||
t = self.targets[0]
|
||||
if self.top and not t.has_builder() and not t.side_effect:
|
||||
if not t.exists():
|
||||
sys.stderr.write("scons: *** Do not know how to make target `%s'." % t)
|
||||
errstr="Do not know how to make target `%s'." % t
|
||||
sys.stderr.write("scons: *** " + errstr)
|
||||
if not self.options.keep_going:
|
||||
sys.stderr.write(" Stop.")
|
||||
sys.stderr.write("\n")
|
||||
try:
|
||||
raise SCons.Errors.BuildError(t, errstr)
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
self.exception_set()
|
||||
self.do_failed()
|
||||
else:
|
||||
print "scons: Nothing to be done for `%s'." % t
|
||||
|
@ -210,54 +231,55 @@ class BuildTask(SCons.Taskmaster.Task):
|
|||
# Handle the failure of a build task. The primary purpose here
|
||||
# is to display the various types of Errors and Exceptions
|
||||
# appropriately.
|
||||
status = 2
|
||||
exc_info = self.exc_info()
|
||||
try:
|
||||
t, e, tb = exc_info
|
||||
except ValueError:
|
||||
t, e = exc_info
|
||||
tb = None
|
||||
|
||||
if t is None:
|
||||
# The Taskmaster didn't record an exception for this Task;
|
||||
# see if the sys module has one.
|
||||
t, e = sys.exc_info()[:2]
|
||||
try:
|
||||
t, e, tb = sys.exc_info()[:]
|
||||
except ValueError:
|
||||
t, e = exc_info
|
||||
tb = None
|
||||
|
||||
def nodestring(n):
|
||||
if not SCons.Util.is_List(n):
|
||||
n = [ n ]
|
||||
return string.join(map(str, n), ', ')
|
||||
# Deprecated string exceptions will have their string stored
|
||||
# in the first entry of the tuple.
|
||||
if e is None:
|
||||
e = t
|
||||
|
||||
buildError = SCons.Errors.convert_to_BuildError(e)
|
||||
if not buildError.node:
|
||||
buildError.node = self.node
|
||||
|
||||
node = buildError.node
|
||||
if not SCons.Util.is_List(node):
|
||||
node = [ node ]
|
||||
nodename = string.join(map(str, node), ', ')
|
||||
|
||||
errfmt = "scons: *** [%s] %s\n"
|
||||
sys.stderr.write(errfmt % (nodename, buildError))
|
||||
|
||||
if t == SCons.Errors.BuildError:
|
||||
tname = nodestring(e.node)
|
||||
errstr = e.errstr
|
||||
if e.filename:
|
||||
errstr = e.filename + ': ' + errstr
|
||||
sys.stderr.write(errfmt % (tname, errstr))
|
||||
elif t == SCons.Errors.TaskmasterException:
|
||||
tname = nodestring(e.node)
|
||||
sys.stderr.write(errfmt % (tname, e.errstr))
|
||||
type, value, trace = e.exc_info
|
||||
if (buildError.exc_info[2] and buildError.exc_info[1] and
|
||||
# TODO(1.5)
|
||||
#not isinstance(
|
||||
# buildError.exc_info[1],
|
||||
# (EnvironmentError, SCons.Errors.StopError, SCons.Errors.UserError))):
|
||||
not isinstance(buildError.exc_info[1], EnvironmentError) and
|
||||
not isinstance(buildError.exc_info[1], SCons.Errors.StopError) and
|
||||
not isinstance(buildError.exc_info[1], SCons.Errors.UserError)):
|
||||
type, value, trace = buildError.exc_info
|
||||
traceback.print_exception(type, value, trace)
|
||||
elif t == SCons.Errors.ExplicitExit:
|
||||
status = e.status
|
||||
tname = nodestring(e.node)
|
||||
errstr = 'Explicit exit, status %s' % status
|
||||
sys.stderr.write(errfmt % (tname, errstr))
|
||||
else:
|
||||
if e is None:
|
||||
e = t
|
||||
s = str(e)
|
||||
if t == SCons.Errors.StopError and not self.options.keep_going:
|
||||
s = s + ' Stop.'
|
||||
sys.stderr.write("scons: *** %s\n" % s)
|
||||
elif tb and print_stacktrace:
|
||||
sys.stderr.write("scons: internal stack trace:\n")
|
||||
traceback.print_tb(tb, file=sys.stderr)
|
||||
|
||||
if tb and print_stacktrace:
|
||||
sys.stderr.write("scons: internal stack trace:\n")
|
||||
traceback.print_tb(tb, file=sys.stderr)
|
||||
|
||||
self.do_failed(status)
|
||||
self.exception = (e, buildError, tb) # type, value, traceback
|
||||
self.do_failed(buildError.exitstatus)
|
||||
|
||||
self.exc_clear()
|
||||
|
||||
|
@ -366,7 +388,9 @@ class QuestionTask(SCons.Taskmaster.Task):
|
|||
if self.targets[0].get_state() != SCons.Node.up_to_date or \
|
||||
(self.top and not self.targets[0].exists()):
|
||||
global exit_status
|
||||
global this_build_status
|
||||
exit_status = 1
|
||||
this_build_status = 1
|
||||
self.tm.stop()
|
||||
|
||||
def executed(self):
|
||||
|
@ -392,6 +416,16 @@ class TreePrinter:
|
|||
SCons.Util.print_tree(t, func, prune=self.prune, showtags=s)
|
||||
|
||||
|
||||
def python_version_string():
|
||||
return string.split(sys.version)[0]
|
||||
|
||||
def python_version_unsupported(version=sys.version_info):
|
||||
return version < (1, 5, 2)
|
||||
|
||||
def python_version_deprecated(version=sys.version_info):
|
||||
return version < (2, 2, 0)
|
||||
|
||||
|
||||
# Global variables
|
||||
|
||||
print_objects = 0
|
||||
|
@ -400,7 +434,8 @@ print_stacktrace = 0
|
|||
print_time = 0
|
||||
sconscript_time = 0
|
||||
cumulative_command_time = 0
|
||||
exit_status = 0 # exit status, assume success by default
|
||||
exit_status = 0 # final exit status, assume success by default
|
||||
this_build_status = 0 # "exit status" of an individual build
|
||||
num_jobs = None
|
||||
delayed_warnings = []
|
||||
|
||||
|
@ -566,57 +601,14 @@ def _scons_internal_error():
|
|||
traceback.print_exc()
|
||||
sys.exit(2)
|
||||
|
||||
def _setup_warn(arg):
|
||||
"""The --warn option. An argument to this option
|
||||
should be of the form <warning-class> or no-<warning-class>.
|
||||
The warning class is munged in order to get an actual class
|
||||
name from the SCons.Warnings module to enable or disable.
|
||||
The supplied <warning-class> is split on hyphens, each element
|
||||
is captialized, then smushed back together. Then the string
|
||||
"SCons.Warnings." is added to the front and "Warning" is added
|
||||
to the back to get the fully qualified class name.
|
||||
|
||||
For example, --warn=deprecated will enable the
|
||||
SCons.Warnings.DeprecatedWarning class.
|
||||
|
||||
--warn=no-dependency will disable the
|
||||
SCons.Warnings.DependencyWarning class.
|
||||
|
||||
As a special case, --warn=all and --warn=no-all
|
||||
will enable or disable (respectively) the base
|
||||
class of all warnings, which is SCons.Warning.Warning."""
|
||||
|
||||
elems = string.split(string.lower(arg), '-')
|
||||
enable = 1
|
||||
if elems[0] == 'no':
|
||||
enable = 0
|
||||
del elems[0]
|
||||
|
||||
if len(elems) == 1 and elems[0] == 'all':
|
||||
class_name = "Warning"
|
||||
else:
|
||||
def _capitalize(s):
|
||||
if s[:5] == "scons":
|
||||
return "SCons" + s[5:]
|
||||
else:
|
||||
return string.capitalize(s)
|
||||
class_name = string.join(map(_capitalize, elems), '') + "Warning"
|
||||
try:
|
||||
clazz = getattr(SCons.Warnings, class_name)
|
||||
except AttributeError:
|
||||
sys.stderr.write("No warning type: '%s'\n" % arg)
|
||||
else:
|
||||
if enable:
|
||||
SCons.Warnings.enableWarningClass(clazz)
|
||||
else:
|
||||
SCons.Warnings.suppressWarningClass(clazz)
|
||||
|
||||
def _SConstruct_exists(dirname='', repositories=[]):
|
||||
def _SConstruct_exists(dirname='', repositories=[], filelist=None):
|
||||
"""This function checks that an SConstruct file exists in a directory.
|
||||
If so, it returns the path of the file. By default, it checks the
|
||||
current directory.
|
||||
"""
|
||||
for file in ['SConstruct', 'Sconstruct', 'sconstruct']:
|
||||
if not filelist:
|
||||
filelist = ['SConstruct', 'Sconstruct', 'sconstruct']
|
||||
for file in filelist:
|
||||
sfile = os.path.join(dirname, file)
|
||||
if os.path.isfile(sfile):
|
||||
return sfile
|
||||
|
@ -730,8 +722,8 @@ def version_string(label, module):
|
|||
module.__buildsys__)
|
||||
|
||||
def _main(parser):
|
||||
import SCons
|
||||
global exit_status
|
||||
global this_build_status
|
||||
|
||||
options = parser.values
|
||||
|
||||
|
@ -745,17 +737,22 @@ def _main(parser):
|
|||
default_warnings = [ SCons.Warnings.CorruptSConsignWarning,
|
||||
SCons.Warnings.DeprecatedWarning,
|
||||
SCons.Warnings.DuplicateEnvironmentWarning,
|
||||
SCons.Warnings.FutureReservedVariableWarning,
|
||||
SCons.Warnings.LinkWarning,
|
||||
SCons.Warnings.MissingSConscriptWarning,
|
||||
SCons.Warnings.NoMD5ModuleWarning,
|
||||
SCons.Warnings.NoMetaclassSupportWarning,
|
||||
SCons.Warnings.NoObjectCountWarning,
|
||||
SCons.Warnings.NoParallelSupportWarning,
|
||||
SCons.Warnings.MisleadingKeywordsWarning, ]
|
||||
SCons.Warnings.MisleadingKeywordsWarning,
|
||||
SCons.Warnings.ReservedVariableWarning,
|
||||
SCons.Warnings.StackSizeWarning,
|
||||
]
|
||||
|
||||
for warning in default_warnings:
|
||||
SCons.Warnings.enableWarningClass(warning)
|
||||
SCons.Warnings._warningOut = _scons_internal_warning
|
||||
if options.warn:
|
||||
_setup_warn(options.warn)
|
||||
SCons.Warnings.process_warn_strings(options.warn)
|
||||
|
||||
# Now that we have the warnings configuration set up, we can actually
|
||||
# issue (or suppress) any warnings about warning-worthy things that
|
||||
|
@ -788,13 +785,15 @@ def _main(parser):
|
|||
if options.climb_up:
|
||||
target_top = '.' # directory to prepend to targets
|
||||
script_dir = os.getcwd() # location of script
|
||||
while script_dir and not _SConstruct_exists(script_dir, options.repository):
|
||||
while script_dir and not _SConstruct_exists(script_dir,
|
||||
options.repository,
|
||||
options.file):
|
||||
script_dir, last_part = os.path.split(script_dir)
|
||||
if last_part:
|
||||
target_top = os.path.join(last_part, target_top)
|
||||
else:
|
||||
script_dir = ''
|
||||
if script_dir:
|
||||
if script_dir and script_dir != os.getcwd():
|
||||
display("scons: Entering directory `%s'" % script_dir)
|
||||
os.chdir(script_dir)
|
||||
|
||||
|
@ -813,7 +812,8 @@ def _main(parser):
|
|||
if options.file:
|
||||
scripts.extend(options.file)
|
||||
if not scripts:
|
||||
sfile = _SConstruct_exists(repositories=options.repository)
|
||||
sfile = _SConstruct_exists(repositories=options.repository,
|
||||
filelist=options.file)
|
||||
if sfile:
|
||||
scripts.append(sfile)
|
||||
|
||||
|
@ -835,10 +835,10 @@ def _main(parser):
|
|||
SCons.Node.implicit_cache = options.implicit_cache
|
||||
SCons.Node.implicit_deps_changed = options.implicit_deps_changed
|
||||
SCons.Node.implicit_deps_unchanged = options.implicit_deps_unchanged
|
||||
|
||||
if options.no_exec:
|
||||
SCons.SConf.dryrun = 1
|
||||
SCons.Action.execute_actions = None
|
||||
CleanTask.execute = CleanTask.show
|
||||
if options.question:
|
||||
SCons.SConf.dryrun = 1
|
||||
if options.clean:
|
||||
|
@ -850,19 +850,6 @@ def _main(parser):
|
|||
|
||||
if options.no_progress or options.silent:
|
||||
progress_display.set_mode(0)
|
||||
if options.silent:
|
||||
display.set_mode(0)
|
||||
if options.silent:
|
||||
SCons.Action.print_actions = None
|
||||
|
||||
if options.cache_disable:
|
||||
SCons.CacheDir.CacheDir = SCons.Util.Null()
|
||||
if options.cache_debug:
|
||||
SCons.CacheDir.cache_debug = options.cache_debug
|
||||
if options.cache_force:
|
||||
SCons.CacheDir.cache_force = True
|
||||
if options.cache_show:
|
||||
SCons.CacheDir.cache_show = True
|
||||
|
||||
if options.site_dir:
|
||||
_load_site_scons_dir(d, options.site_dir)
|
||||
|
@ -887,7 +874,18 @@ def _main(parser):
|
|||
SCons.Script._Add_Targets(targets + parser.rargs)
|
||||
SCons.Script._Add_Arguments(xmit_args)
|
||||
|
||||
sys.stdout = SCons.Util.Unbuffered(sys.stdout)
|
||||
# If stdout is not a tty, replace it with a wrapper object to call flush
|
||||
# after every write.
|
||||
#
|
||||
# Tty devices automatically flush after every newline, so the replacement
|
||||
# isn't necessary. Furthermore, if we replace sys.stdout, the readline
|
||||
# module will no longer work. This affects the behavior during
|
||||
# --interactive mode. --interactive should only be used when stdin and
|
||||
# stdout refer to a tty.
|
||||
if not sys.stdout.isatty():
|
||||
sys.stdout = SCons.Util.Unbuffered(sys.stdout)
|
||||
if not sys.stderr.isatty():
|
||||
sys.stderr = SCons.Util.Unbuffered(sys.stderr)
|
||||
|
||||
memory_stats.append('before reading SConscript files:')
|
||||
count_stats.append(('pre-', 'read'))
|
||||
|
@ -902,7 +900,7 @@ def _main(parser):
|
|||
SCons.Script._SConscript._SConscript(fs, script)
|
||||
except SCons.Errors.StopError, e:
|
||||
# We had problems reading an SConscript file, such as it
|
||||
# couldn't be copied in to the BuildDir. Since we're just
|
||||
# couldn't be copied in to the VariantDir. Since we're just
|
||||
# reading SConscript files and haven't started building
|
||||
# things yet, stop regardless of whether they used -i or -k
|
||||
# or anything else.
|
||||
|
@ -917,6 +915,26 @@ def _main(parser):
|
|||
memory_stats.append('after reading SConscript files:')
|
||||
count_stats.append(('post-', 'read'))
|
||||
|
||||
# Re-{enable,disable} warnings in case they disabled some in
|
||||
# the SConscript file.
|
||||
#
|
||||
# We delay enabling the PythonVersionWarning class until here so that,
|
||||
# if they explicity disabled it in either in the command line or in
|
||||
# $SCONSFLAGS, or in the SConscript file, then the search through
|
||||
# the list of deprecated warning classes will find that disabling
|
||||
# first and not issue the warning.
|
||||
SCons.Warnings.enableWarningClass(SCons.Warnings.PythonVersionWarning)
|
||||
SCons.Warnings.process_warn_strings(options.warn)
|
||||
|
||||
# Now that we've read the SConscript files, we can check for the
|
||||
# warning about deprecated Python versions--delayed until here
|
||||
# in case they disabled the warning in the SConscript files.
|
||||
if python_version_deprecated():
|
||||
msg = "Support for pre-2.2 Python (%s) is deprecated.\n" + \
|
||||
" If this will cause hardship, contact dev@scons.tigris.org."
|
||||
SCons.Warnings.warn(SCons.Warnings.PythonVersionWarning,
|
||||
msg % python_version_string())
|
||||
|
||||
if not options.help:
|
||||
SCons.SConf.CreateConfigHBuilder(SCons.Defaults.DefaultEnvironment())
|
||||
|
||||
|
@ -943,7 +961,7 @@ def _main(parser):
|
|||
|
||||
# Change directory to the top-level SConstruct directory, then tell
|
||||
# the Node.FS subsystem that we're all done reading the SConscript
|
||||
# files and calling Repository() and BuildDir() and changing
|
||||
# files and calling Repository() and VariantDir() and changing
|
||||
# directories and the like, so it can go ahead and start memoizing
|
||||
# the string values of file system nodes.
|
||||
|
||||
|
@ -957,6 +975,49 @@ def _main(parser):
|
|||
SCons.Node.FS.set_duplicate(options.duplicate)
|
||||
fs.set_max_drift(options.max_drift)
|
||||
|
||||
SCons.Job.explicit_stack_size = options.stack_size
|
||||
|
||||
if options.md5_chunksize:
|
||||
SCons.Node.FS.File.md5_chunksize = options.md5_chunksize
|
||||
|
||||
platform = SCons.Platform.platform_module()
|
||||
|
||||
if options.interactive:
|
||||
SCons.Script.Interactive.interact(fs, OptionsParser, options,
|
||||
targets, target_top)
|
||||
|
||||
else:
|
||||
|
||||
# Build the targets
|
||||
nodes = _build_targets(fs, options, targets, target_top)
|
||||
if not nodes:
|
||||
exit_status = 2
|
||||
|
||||
def _build_targets(fs, options, targets, target_top):
|
||||
|
||||
global this_build_status
|
||||
this_build_status = 0
|
||||
|
||||
progress_display.set_mode(not (options.no_progress or options.silent))
|
||||
display.set_mode(not options.silent)
|
||||
SCons.Action.print_actions = not options.silent
|
||||
SCons.Action.execute_actions = not options.no_exec
|
||||
SCons.Node.FS.do_store_info = not options.no_exec
|
||||
SCons.SConf.dryrun = options.no_exec
|
||||
|
||||
if options.diskcheck:
|
||||
SCons.Node.FS.set_diskcheck(options.diskcheck)
|
||||
|
||||
SCons.CacheDir.cache_enabled = not options.cache_disable
|
||||
SCons.CacheDir.cache_debug = options.cache_debug
|
||||
SCons.CacheDir.cache_force = options.cache_force
|
||||
SCons.CacheDir.cache_show = options.cache_show
|
||||
|
||||
if options.no_exec:
|
||||
CleanTask.execute = CleanTask.show
|
||||
else:
|
||||
CleanTask.execute = CleanTask.remove
|
||||
|
||||
lookup_top = None
|
||||
if targets or SCons.Script.BUILD_TARGETS != SCons.Script._build_plus_default:
|
||||
# They specified targets on the command line or modified
|
||||
|
@ -1003,7 +1064,7 @@ def _main(parser):
|
|||
|
||||
if not targets:
|
||||
sys.stderr.write("scons: *** No targets specified and no Default() targets found. Stop.\n")
|
||||
sys.exit(2)
|
||||
return None
|
||||
|
||||
def Entry(x, ltop=lookup_top, ttop=target_top, fs=fs):
|
||||
if isinstance(x, SCons.Node.Node):
|
||||
|
@ -1046,7 +1107,7 @@ def _main(parser):
|
|||
opening_message = "Cleaning targets ..."
|
||||
closing_message = "done cleaning targets."
|
||||
if options.keep_going:
|
||||
closing_message = "done cleaning targets (errors occurred during clean)."
|
||||
failure_message = "done cleaning targets (errors occurred during clean)."
|
||||
else:
|
||||
failure_message = "cleaning terminated because of errors."
|
||||
except AttributeError:
|
||||
|
@ -1091,29 +1152,43 @@ def _main(parser):
|
|||
msg = "parallel builds are unsupported by this version of Python;\n" + \
|
||||
"\tignoring -j or num_jobs option.\n"
|
||||
elif sys.platform == 'win32':
|
||||
import SCons.Platform.win32
|
||||
msg = SCons.Platform.win32.parallel_msg
|
||||
msg = fetch_win32_parallel_msg()
|
||||
if msg:
|
||||
SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg)
|
||||
|
||||
memory_stats.append('before building targets:')
|
||||
count_stats.append(('pre-', 'build'))
|
||||
|
||||
try:
|
||||
progress_display("scons: " + opening_message)
|
||||
jobs.run()
|
||||
finally:
|
||||
jobs.cleanup()
|
||||
if exit_status:
|
||||
def jobs_postfunc(
|
||||
jobs=jobs,
|
||||
options=options,
|
||||
closing_message=closing_message,
|
||||
failure_message=failure_message
|
||||
):
|
||||
if jobs.were_interrupted():
|
||||
progress_display("scons: Build interrupted.")
|
||||
global exit_status
|
||||
global this_build_status
|
||||
exit_status = 2
|
||||
this_build_status = 2
|
||||
|
||||
if this_build_status:
|
||||
progress_display("scons: " + failure_message)
|
||||
else:
|
||||
progress_display("scons: " + closing_message)
|
||||
if not options.no_exec:
|
||||
if jobs.were_interrupted():
|
||||
progress_display("scons: writing .sconsign file.")
|
||||
SCons.SConsign.write()
|
||||
|
||||
progress_display("scons: " + opening_message)
|
||||
jobs.run(postfunc = jobs_postfunc)
|
||||
|
||||
memory_stats.append('after building targets:')
|
||||
count_stats.append(('post-', 'build'))
|
||||
|
||||
return nodes
|
||||
|
||||
def _exec_main(parser, values):
|
||||
sconsflags = os.environ.get('SCONSFLAGS', '')
|
||||
all_args = string.split(sconsflags) + sys.argv[1:]
|
||||
|
@ -1124,7 +1199,10 @@ def _exec_main(parser, values):
|
|||
import pdb
|
||||
pdb.Pdb().runcall(_main, parser)
|
||||
elif options.profile_file:
|
||||
from profile import Profile
|
||||
try:
|
||||
from cProfile import Profile
|
||||
except ImportError, e:
|
||||
from profile import Profile
|
||||
|
||||
# Some versions of Python 2.4 shipped a profiler that had the
|
||||
# wrong 'c_exception' entry in its dispatch table. Make sure
|
||||
|
@ -1155,17 +1233,25 @@ def main():
|
|||
global exit_status
|
||||
global first_command_start
|
||||
|
||||
# Check up front for a Python version we do not support. We
|
||||
# delay the check for deprecated Python versions until later,
|
||||
# after the SConscript files have been read, in case they
|
||||
# disable that warning.
|
||||
if python_version_unsupported():
|
||||
msg = "scons: *** SCons version %s does not run under Python version %s.\n"
|
||||
sys.stderr.write(msg % (SCons.__version__, python_version_string()))
|
||||
sys.exit(1)
|
||||
|
||||
parts = ["SCons by Steven Knight et al.:\n"]
|
||||
try:
|
||||
import __main__
|
||||
parts.append(version_string("script", __main__))
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
except (ImportError, AttributeError):
|
||||
# On Windows there is no scons.py, so there is no
|
||||
# __main__.__version__, hence there is no script version.
|
||||
pass
|
||||
parts.append(version_string("engine", SCons))
|
||||
parts.append("Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation")
|
||||
parts.append("Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation")
|
||||
version = string.join(parts, '')
|
||||
|
||||
import SConsOptions
|
||||
|
@ -1180,7 +1266,7 @@ def main():
|
|||
if s:
|
||||
exit_status = s
|
||||
except KeyboardInterrupt:
|
||||
print "Build interrupted."
|
||||
print("scons: Build interrupted.")
|
||||
sys.exit(2)
|
||||
except SyntaxError, e:
|
||||
_scons_syntax_error(e)
|
||||
|
@ -1191,6 +1277,8 @@ def main():
|
|||
except SConsPrintHelpException:
|
||||
parser.print_help()
|
||||
exit_status = 0
|
||||
except SCons.Errors.BuildError, e:
|
||||
exit_status = e.exitstatus
|
||||
except:
|
||||
# An exception here is likely a builtin Python exception Python
|
||||
# code in an SConscript file. Show them precisely what the
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,15 +21,21 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/SConsOptions.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import SCons.compat
|
||||
__revision__ = "src/engine/SCons/Script/SConsOptions.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import optparse
|
||||
import re
|
||||
import string
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
try:
|
||||
no_hyphen_re = re.compile(r'(\s+|(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))')
|
||||
except re.error:
|
||||
# Pre-2.0 Python versions don't have the (?<= negative
|
||||
# look-behind assertion.
|
||||
no_hyphen_re = re.compile(r'(\s+|-*\w{2,}-(?=\w{2,}))')
|
||||
|
||||
try:
|
||||
from gettext import gettext
|
||||
except ImportError:
|
||||
|
@ -38,6 +44,7 @@ except ImportError:
|
|||
_ = gettext
|
||||
|
||||
import SCons.Node.FS
|
||||
import SCons.Warnings
|
||||
|
||||
OptionValueError = optparse.OptionValueError
|
||||
SUPPRESS_HELP = optparse.SUPPRESS_HELP
|
||||
|
@ -119,9 +126,12 @@ class SConsValues(optparse.Values):
|
|||
'help',
|
||||
'implicit_cache',
|
||||
'max_drift',
|
||||
'md5_chunksize',
|
||||
'no_exec',
|
||||
'num_jobs',
|
||||
'random',
|
||||
'stack_size',
|
||||
'warn',
|
||||
]
|
||||
|
||||
def set_option(self, name, value):
|
||||
|
@ -163,6 +173,21 @@ class SConsValues(optparse.Values):
|
|||
# Set this right away so it can affect the rest of the
|
||||
# file/Node lookups while processing the SConscript files.
|
||||
SCons.Node.FS.set_diskcheck(value)
|
||||
elif name == 'stack_size':
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
raise SCons.Errors.UserError, "An integer is required: %s"%repr(value)
|
||||
elif name == 'md5_chunksize':
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
raise SCons.Errors.UserError, "An integer is required: %s"%repr(value)
|
||||
elif name == 'warn':
|
||||
if SCons.Util.is_String(value):
|
||||
value = [value]
|
||||
value = self.__SConscript_settings__.get(name, []) + value
|
||||
SCons.Warnings.process_warn_strings(value)
|
||||
|
||||
self.__SConscript_settings__[name] = value
|
||||
|
||||
|
@ -369,8 +394,16 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
|
|||
def format_option(self, option):
|
||||
"""
|
||||
A copy of the normal optparse.IndentedHelpFormatter.format_option()
|
||||
method, snarfed so we can set the subsequent_indent on the
|
||||
textwrap.wrap() call below...
|
||||
method. This has been snarfed so we can modify text wrapping to
|
||||
out liking:
|
||||
|
||||
-- add our own regular expression that doesn't break on hyphens
|
||||
(so things like --no-print-directory don't get broken);
|
||||
|
||||
-- wrap the list of options themselves when it's too long
|
||||
(the wrapper.fill(opts) call below);
|
||||
|
||||
-- set the subsequent_indent when wrapping the help_text.
|
||||
"""
|
||||
# The help for each option consists of two parts:
|
||||
# * the opt strings and metavars
|
||||
|
@ -397,7 +430,11 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
|
|||
|
||||
opt_width = self.help_position - self.current_indent - 2
|
||||
if len(opts) > opt_width:
|
||||
opts = "%*s%s\n" % (self.current_indent, "", opts)
|
||||
wrapper = textwrap.TextWrapper(width=self.width,
|
||||
initial_indent = ' ',
|
||||
subsequent_indent = ' ')
|
||||
wrapper.wordsep_re = no_hyphen_re
|
||||
opts = wrapper.fill(opts) + '\n'
|
||||
indent_first = self.help_position
|
||||
else: # start help on same line as opts
|
||||
opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts)
|
||||
|
@ -415,8 +452,10 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
|
|||
help_text = expand_default(option)
|
||||
|
||||
# SCons: indent every line of the help text but the first.
|
||||
help_lines = textwrap.wrap(help_text, self.help_width,
|
||||
subsequent_indent = ' ')
|
||||
wrapper = textwrap.TextWrapper(width=self.help_width,
|
||||
subsequent_indent = ' ')
|
||||
wrapper.wordsep_re = no_hyphen_re
|
||||
help_lines = wrapper.wrap(help_text)
|
||||
result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
|
||||
for line in help_lines[1:]:
|
||||
result.append("%*s%s\n" % (self.help_position, "", line))
|
||||
|
@ -466,6 +505,7 @@ def Parser(version):
|
|||
usage="usage: scons [OPTION] [TARGET] ...",)
|
||||
|
||||
op.preserve_unknown_options = True
|
||||
op.version = version
|
||||
|
||||
# Add the options to the parser we just created.
|
||||
#
|
||||
|
@ -489,8 +529,13 @@ def Parser(version):
|
|||
# options ignored for compatibility
|
||||
def opt_ignore(option, opt, value, parser):
|
||||
sys.stderr.write("Warning: ignoring %s option\n" % opt)
|
||||
op.add_option("-b", "-m", "-S", "-t",
|
||||
"--no-keep-going", "--stop", "--touch",
|
||||
op.add_option("-b", "-d", "-e", "-m", "-S", "-t", "-w",
|
||||
"--environment-overrides",
|
||||
"--no-keep-going",
|
||||
"--no-print-directory",
|
||||
"--print-directory",
|
||||
"--stop",
|
||||
"--touch",
|
||||
action="callback", callback=opt_ignore,
|
||||
help="Ignored for compatibility.")
|
||||
|
||||
|
@ -543,42 +588,38 @@ def Parser(version):
|
|||
help = opt_config_help,
|
||||
metavar="MODE")
|
||||
|
||||
def opt_not_yet(option, opt, value, parser):
|
||||
sys.stderr.write("Warning: the %s option is not yet implemented\n" % opt)
|
||||
sys.exit(0)
|
||||
op.add_option('-d',
|
||||
action="callback", callback=opt_not_yet,
|
||||
help = "Print file dependency information.")
|
||||
|
||||
op.add_option('-D',
|
||||
dest="climb_up", default=None,
|
||||
action="store_const", const=2,
|
||||
help="Search up directory tree for SConstruct, "
|
||||
"build all Default() targets.")
|
||||
|
||||
debug_options = ["count", "dtree", "explain", "findlibs",
|
||||
"includes", "memoizer", "memory", "objects",
|
||||
"pdb", "presub", "stacktrace", "stree",
|
||||
"time", "tree"]
|
||||
|
||||
deprecated_debug_options = {
|
||||
"nomemoizer" : ' and has no effect',
|
||||
"dtree" : '; please use --tree=derived instead',
|
||||
"nomemoizer" : ' and has no effect',
|
||||
"stree" : '; please use --tree=all,status instead',
|
||||
"tree" : '; please use --tree=all instead',
|
||||
}
|
||||
|
||||
debug_options = ["count", "explain", "findlibs",
|
||||
"includes", "memoizer", "memory", "objects",
|
||||
"pdb", "presub", "stacktrace",
|
||||
"time"] + deprecated_debug_options.keys()
|
||||
|
||||
def opt_debug(option, opt, value, parser,
|
||||
debug_options=debug_options,
|
||||
deprecated_debug_options=deprecated_debug_options):
|
||||
if value in debug_options:
|
||||
parser.values.debug.append(value)
|
||||
elif value in deprecated_debug_options.keys():
|
||||
try:
|
||||
parser.values.delayed_warnings
|
||||
except AttributeError:
|
||||
parser.values.delayed_warnings = []
|
||||
msg = deprecated_debug_options[value]
|
||||
w = "The --debug=%s option is deprecated%s." % (value, msg)
|
||||
t = (SCons.Warnings.DeprecatedWarning, w)
|
||||
parser.values.delayed_warnings.append(t)
|
||||
if value in deprecated_debug_options.keys():
|
||||
try:
|
||||
parser.values.delayed_warnings
|
||||
except AttributeError:
|
||||
parser.values.delayed_warnings = []
|
||||
msg = deprecated_debug_options[value]
|
||||
w = "The --debug=%s option is deprecated%s." % (value, msg)
|
||||
t = (SCons.Warnings.DeprecatedWarning, w)
|
||||
parser.values.delayed_warnings.append(t)
|
||||
else:
|
||||
raise OptionValueError("Warning: %s is not a valid debug type" % value)
|
||||
opt_debug_help = "Print various types of debugging information: %s." \
|
||||
|
@ -667,6 +708,11 @@ def Parser(version):
|
|||
action="callback", callback=opt_implicit_deps,
|
||||
help="Ignore changes in implicit dependencies.")
|
||||
|
||||
op.add_option('--interact', '--interactive',
|
||||
dest='interactive', default=False,
|
||||
action="store_true",
|
||||
help="Run in interactive mode.")
|
||||
|
||||
op.add_option('-j', '--jobs',
|
||||
nargs=1, type="int",
|
||||
dest="num_jobs", default=1,
|
||||
|
@ -686,6 +732,13 @@ def Parser(version):
|
|||
help="Set maximum system clock drift to N seconds.",
|
||||
metavar="N")
|
||||
|
||||
op.add_option('--md5-chunksize',
|
||||
nargs=1, type="int",
|
||||
dest='md5_chunksize', default=SCons.Node.FS.File.md5_chunksize,
|
||||
action="store",
|
||||
help="Set chunk-size for MD5 signature computation to N kilobytes.",
|
||||
metavar="N")
|
||||
|
||||
op.add_option('-n', '--no-exec', '--just-print', '--dry-run', '--recon',
|
||||
dest='no_exec', default=False,
|
||||
action="store_true",
|
||||
|
@ -730,6 +783,13 @@ def Parser(version):
|
|||
help="Use DIR instead of the usual site_scons dir.",
|
||||
metavar="DIR")
|
||||
|
||||
op.add_option('--stack-size',
|
||||
nargs=1, type="int",
|
||||
dest='stack_size',
|
||||
action="store",
|
||||
help="Set the stack size of the threads used to run jobs to N kilobytes.",
|
||||
metavar="N")
|
||||
|
||||
op.add_option('--taskmastertrace',
|
||||
nargs=1,
|
||||
dest="taskmastertrace_file", default=None,
|
||||
|
@ -777,17 +837,22 @@ def Parser(version):
|
|||
help="Search up directory tree for SConstruct, "
|
||||
"build Default() targets from local SConscript.")
|
||||
|
||||
def opt_version(option, opt, value, parser, version=version):
|
||||
sys.stdout.write(version + '\n')
|
||||
def opt_version(option, opt, value, parser):
|
||||
sys.stdout.write(parser.version + '\n')
|
||||
sys.exit(0)
|
||||
op.add_option("-v", "--version",
|
||||
action="callback", callback=opt_version,
|
||||
help="Print the SCons version number and exit.")
|
||||
|
||||
def opt_warn(option, opt, value, parser, tree_options=tree_options):
|
||||
if SCons.Util.is_String(value):
|
||||
value = string.split(value, ',')
|
||||
parser.values.warn.extend(value)
|
||||
|
||||
op.add_option('--warn', '--warning',
|
||||
nargs=1,
|
||||
dest="warn", default=None,
|
||||
action="store",
|
||||
nargs=1, type="string",
|
||||
dest="warn", default=[],
|
||||
action="callback", callback=opt_warn,
|
||||
help="Enable or disable warnings.",
|
||||
metavar="WARNING-SPEC")
|
||||
|
||||
|
@ -802,11 +867,12 @@ def Parser(version):
|
|||
# we don't want to change. These all get a "the -X option is not
|
||||
# yet implemented" message and don't show up in the help output.
|
||||
|
||||
op.add_option('-e', '--environment-overrides',
|
||||
dest="environment_overrides",
|
||||
action="callback", callback=opt_not_yet,
|
||||
# help="Environment variables override makefiles."
|
||||
help=SUPPRESS_HELP)
|
||||
def opt_not_yet(option, opt, value, parser):
|
||||
msg = "Warning: the %s option is not yet implemented\n" % opt
|
||||
sys.stderr.write(msg)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
op.add_option('-l', '--load-average', '--max-load',
|
||||
nargs=1, type="int",
|
||||
dest="load_average", default=0,
|
||||
|
@ -853,16 +919,6 @@ def Parser(version):
|
|||
dest="no_builtin_rules",
|
||||
# help="Clear default environments and variables."
|
||||
help=SUPPRESS_HELP)
|
||||
op.add_option('-w', '--print-directory',
|
||||
action="callback", callback=opt_not_yet,
|
||||
dest="print_directory",
|
||||
# help="Print the current directory."
|
||||
help=SUPPRESS_HELP)
|
||||
op.add_option('--no-print-directory',
|
||||
action="callback", callback=opt_not_yet,
|
||||
dest="no_print_directory",
|
||||
# help="Turn off -w, even if it was turned on implicitly."
|
||||
help=SUPPRESS_HELP)
|
||||
op.add_option('--write-filenames',
|
||||
nargs=1, type="string",
|
||||
dest="write_filenames",
|
|
@ -6,7 +6,7 @@ files.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -28,7 +28,7 @@ files.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/SConscript.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Script/SConscript.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons
|
||||
import SCons.Action
|
||||
|
@ -39,7 +39,6 @@ import SCons.Errors
|
|||
import SCons.Node
|
||||
import SCons.Node.Alias
|
||||
import SCons.Node.FS
|
||||
import SCons.Options
|
||||
import SCons.Platform
|
||||
import SCons.SConf
|
||||
import SCons.Script.Main
|
||||
|
@ -82,7 +81,10 @@ def get_calling_namespaces():
|
|||
"""Return the locals and globals for the function that called
|
||||
into this module in the current call stack."""
|
||||
try: 1/0
|
||||
except ZeroDivisionError: frame = sys.exc_info()[2].tb_frame
|
||||
except ZeroDivisionError:
|
||||
# Don't start iterating with the current stack-frame to
|
||||
# prevent creating reference cycles (f_back is safe).
|
||||
frame = sys.exc_info()[2].tb_frame.f_back
|
||||
|
||||
# Find the first frame that *isn't* from this file. This means
|
||||
# that we expect all of the SCons frames that implement an Export()
|
||||
|
@ -141,7 +143,8 @@ call_stack = []
|
|||
def Return(*vars, **kw):
|
||||
retval = []
|
||||
try:
|
||||
for var in vars:
|
||||
fvars = SCons.Util.flatten(vars)
|
||||
for var in fvars:
|
||||
for v in string.split(var):
|
||||
retval.append(call_stack[-1].globals[v])
|
||||
except KeyError, x:
|
||||
|
@ -276,7 +279,20 @@ def _SConscript(fs, *files, **kw):
|
|||
fs.chdir(frame.prev_dir, change_os_dir=0)
|
||||
rdir = frame.prev_dir.rdir()
|
||||
rdir._create() # Make sure there's a directory there.
|
||||
os.chdir(rdir.get_abspath())
|
||||
try:
|
||||
os.chdir(rdir.get_abspath())
|
||||
except OSError, e:
|
||||
# We still couldn't chdir there, so raise the error,
|
||||
# but only if actions are being executed.
|
||||
#
|
||||
# If the -n option was used, the directory would *not*
|
||||
# have been created and we should just carry on and
|
||||
# let things muddle through. This isn't guaranteed
|
||||
# to work if the SConscript files are reading things
|
||||
# from disk (for example), but it should work well
|
||||
# enough for most configurations.
|
||||
if SCons.Action.execute_actions:
|
||||
raise e
|
||||
|
||||
results.append(frame.retval)
|
||||
|
||||
|
@ -403,16 +419,16 @@ class SConsEnvironment(SCons.Environment.Base):
|
|||
if kw.get('exports'):
|
||||
exports.extend(self.Split(kw['exports']))
|
||||
|
||||
build_dir = kw.get('build_dir')
|
||||
if build_dir:
|
||||
variant_dir = kw.get('variant_dir') or kw.get('build_dir')
|
||||
if variant_dir:
|
||||
if len(files) != 1:
|
||||
raise SCons.Errors.UserError, \
|
||||
"Invalid SConscript() usage - can only specify one SConscript with a build_dir"
|
||||
"Invalid SConscript() usage - can only specify one SConscript with a variant_dir"
|
||||
duplicate = kw.get('duplicate', 1)
|
||||
src_dir = kw.get('src_dir')
|
||||
if not src_dir:
|
||||
src_dir, fname = os.path.split(str(files[0]))
|
||||
files = [os.path.join(str(build_dir), fname)]
|
||||
files = [os.path.join(str(variant_dir), fname)]
|
||||
else:
|
||||
if not isinstance(src_dir, SCons.Node.Node):
|
||||
src_dir = self.fs.Dir(src_dir)
|
||||
|
@ -422,11 +438,11 @@ class SConsEnvironment(SCons.Environment.Base):
|
|||
if fn.is_under(src_dir):
|
||||
# Get path relative to the source directory.
|
||||
fname = fn.get_path(src_dir)
|
||||
files = [os.path.join(str(build_dir), fname)]
|
||||
files = [os.path.join(str(variant_dir), fname)]
|
||||
else:
|
||||
files = [fn.abspath]
|
||||
kw['src_dir'] = build_dir
|
||||
self.fs.BuildDir(build_dir, src_dir, duplicate)
|
||||
kw['src_dir'] = variant_dir
|
||||
self.fs.VariantDir(variant_dir, src_dir, duplicate)
|
||||
|
||||
return (files, exports)
|
||||
|
|
@ -12,7 +12,7 @@ it goes here.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -34,7 +34,7 @@ it goes here.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/__init__.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Script/__init__.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import time
|
||||
start_time = time.time()
|
||||
|
@ -84,6 +84,7 @@ import SCons.SConf
|
|||
import SCons.Subst
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
import SCons.Variables
|
||||
import SCons.Defaults
|
||||
|
||||
import Main
|
||||
|
@ -138,22 +139,31 @@ call_stack = _SConscript.call_stack
|
|||
Action = SCons.Action.Action
|
||||
AddMethod = SCons.Util.AddMethod
|
||||
AllowSubstExceptions = SCons.Subst.SetAllowableExceptions
|
||||
BoolOption = SCons.Options.BoolOption
|
||||
Builder = SCons.Builder.Builder
|
||||
Configure = _SConscript.Configure
|
||||
EnumOption = SCons.Options.EnumOption
|
||||
Environment = SCons.Environment.Environment
|
||||
#OptParser = SCons.SConsOptions.OptParser
|
||||
FindPathDirs = SCons.Scanner.FindPathDirs
|
||||
ListOption = SCons.Options.ListOption
|
||||
PackageOption = SCons.Options.PackageOption
|
||||
PathOption = SCons.Options.PathOption
|
||||
Platform = SCons.Platform.Platform
|
||||
Return = _SConscript.Return
|
||||
Scanner = SCons.Scanner.Base
|
||||
Tool = SCons.Tool.Tool
|
||||
WhereIs = SCons.Util.WhereIs
|
||||
|
||||
#
|
||||
BoolVariable = SCons.Variables.BoolVariable
|
||||
EnumVariable = SCons.Variables.EnumVariable
|
||||
ListVariable = SCons.Variables.ListVariable
|
||||
PackageVariable = SCons.Variables.PackageVariable
|
||||
PathVariable = SCons.Variables.PathVariable
|
||||
|
||||
# Deprecated names that will go away some day.
|
||||
BoolOption = SCons.Options.BoolOption
|
||||
EnumOption = SCons.Options.EnumOption
|
||||
ListOption = SCons.Options.ListOption
|
||||
PackageOption = SCons.Options.PackageOption
|
||||
PathOption = SCons.Options.PathOption
|
||||
|
||||
# Action factories.
|
||||
Chmod = SCons.Defaults.Chmod
|
||||
Copy = SCons.Defaults.Copy
|
||||
|
@ -262,6 +272,9 @@ def HelpFunction(text):
|
|||
sconscript_reading = 0
|
||||
|
||||
#
|
||||
def Variables(files=[], args=ARGUMENTS):
|
||||
return SCons.Variables.Variables(files, args)
|
||||
|
||||
def Options(files=[], args=ARGUMENTS):
|
||||
return SCons.Options.Options(files, args)
|
||||
|
||||
|
@ -321,6 +334,7 @@ GlobalDefaultEnvironmentFunctions = [
|
|||
'Tag',
|
||||
'TargetSignatures',
|
||||
'Value',
|
||||
'VariantDir',
|
||||
]
|
||||
|
||||
GlobalDefaultBuilders = [
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Sig.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Sig.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Sig module hierarchy
|
||||
|
|
@ -5,7 +5,7 @@ SCons string substitution.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,9 +27,7 @@ SCons string substitution.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Subst.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import SCons.compat
|
||||
__revision__ = "src/engine/SCons/Subst.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import re
|
||||
import string
|
||||
|
@ -39,11 +37,11 @@ import UserString
|
|||
|
||||
import SCons.Errors
|
||||
|
||||
from SCons.Util import is_String, is_List, is_Tuple
|
||||
from SCons.Util import is_String, is_Sequence
|
||||
|
||||
# Indexed by the SUBST_* constants below.
|
||||
_strconv = [SCons.Util.to_String,
|
||||
SCons.Util.to_String,
|
||||
_strconv = [SCons.Util.to_String_for_subst,
|
||||
SCons.Util.to_String_for_subst,
|
||||
SCons.Util.to_String_for_signature]
|
||||
|
||||
|
||||
|
@ -188,7 +186,7 @@ class NLWrapper:
|
|||
list = self.list
|
||||
if list is None:
|
||||
list = []
|
||||
elif not is_List(list) and not is_Tuple(list):
|
||||
elif not is_Sequence(list):
|
||||
list = [list]
|
||||
# The map(self.func) call is what actually turns
|
||||
# a list into appropriate proxies.
|
||||
|
@ -203,10 +201,10 @@ class Targets_or_Sources(UserList.UserList):
|
|||
wrapping a NLWrapper. This class handles the different methods used
|
||||
to access the list, calling the NLWrapper to create proxies on demand.
|
||||
|
||||
Note that we subclass UserList.UserList purely so that the is_List()
|
||||
function will identify an object of this class as a list during
|
||||
variable expansion. We're not really using any UserList.UserList
|
||||
methods in practice.
|
||||
Note that we subclass UserList.UserList purely so that the
|
||||
is_Sequence() function will identify an object of this class as
|
||||
a list during variable expansion. We're not really using any
|
||||
UserList.UserList methods in practice.
|
||||
"""
|
||||
def __init__(self, nl):
|
||||
self.nl = nl
|
||||
|
@ -272,7 +270,13 @@ def subst_dict(target, source):
|
|||
dict = {}
|
||||
|
||||
if target:
|
||||
tnl = NLWrapper(target, lambda x: x.get_subst_proxy())
|
||||
def get_tgt_subst_proxy(thing):
|
||||
try:
|
||||
subst_proxy = thing.get_subst_proxy()
|
||||
except AttributeError:
|
||||
subst_proxy = thing # probably a string, just return it
|
||||
return subst_proxy
|
||||
tnl = NLWrapper(target, get_tgt_subst_proxy)
|
||||
dict['TARGETS'] = Targets_or_Sources(tnl)
|
||||
dict['TARGET'] = Target_or_Source(tnl)
|
||||
else:
|
||||
|
@ -287,7 +291,10 @@ def subst_dict(target, source):
|
|||
pass
|
||||
else:
|
||||
node = rfile()
|
||||
return node.get_subst_proxy()
|
||||
try:
|
||||
return node.get_subst_proxy()
|
||||
except AttributeError:
|
||||
return node # probably a String, just return it
|
||||
snl = NLWrapper(source, get_src_subst_proxy)
|
||||
dict['SOURCES'] = Targets_or_Sources(snl)
|
||||
dict['SOURCE'] = Target_or_Source(snl)
|
||||
|
@ -312,6 +319,25 @@ _remove = re.compile(r'\$\([^\$]*(\$[^\)][^\$]*)*\$\)')
|
|||
# Indexed by the SUBST_* constants above.
|
||||
_regex_remove = [ _rm, None, _remove ]
|
||||
|
||||
def _rm_list(list):
|
||||
#return [ l for l in list if not l in ('$(', '$)') ]
|
||||
return filter(lambda l: not l in ('$(', '$)'), list)
|
||||
|
||||
def _remove_list(list):
|
||||
result = []
|
||||
do_append = result.append
|
||||
for l in list:
|
||||
if l == '$(':
|
||||
do_append = lambda x: None
|
||||
elif l == '$)':
|
||||
do_append = result.append
|
||||
else:
|
||||
do_append(l)
|
||||
return result
|
||||
|
||||
# Indexed by the SUBST_* constants above.
|
||||
_list_remove = [ _rm_list, None, _remove_list ]
|
||||
|
||||
# Regular expressions for splitting strings and handling substitutions,
|
||||
# for use by the scons_subst() and scons_subst_list() functions:
|
||||
#
|
||||
|
@ -342,7 +368,8 @@ _separate_args = re.compile(r'(%s|\s+|[^\s\$]+|\$)' % _dollar_exps_str)
|
|||
_space_sep = re.compile(r'[\t ]+(?![^{]*})')
|
||||
|
||||
def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None):
|
||||
"""Expand a string containing construction variable substitutions.
|
||||
"""Expand a string or list containing construction variable
|
||||
substitutions.
|
||||
|
||||
This is the work-horse function for substitutions in file names
|
||||
and the like. The companion scons_subst_list() function (below)
|
||||
|
@ -427,11 +454,10 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
|
|||
var = string.split(key, '.')[0]
|
||||
lv[var] = ''
|
||||
return self.substitute(s, lv)
|
||||
elif is_List(s) or is_Tuple(s):
|
||||
elif is_Sequence(s):
|
||||
def func(l, conv=self.conv, substitute=self.substitute, lvars=lvars):
|
||||
return conv(substitute(l, lvars))
|
||||
r = map(func, s)
|
||||
return string.join(r)
|
||||
return map(func, s)
|
||||
elif callable(s):
|
||||
try:
|
||||
s = s(target=self.target,
|
||||
|
@ -458,6 +484,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
|
|||
separate tokens.
|
||||
"""
|
||||
if is_String(args) and not isinstance(args, CmdStringHolder):
|
||||
args = str(args) # In case it's a UserString.
|
||||
try:
|
||||
def sub_match(match, conv=self.conv, expand=self.expand, lvars=lvars):
|
||||
return conv(expand(match.group(1), lvars))
|
||||
|
@ -472,11 +499,10 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
|
|||
result = []
|
||||
for a in args:
|
||||
result.append(self.conv(self.expand(a, lvars)))
|
||||
try:
|
||||
result = string.join(result, '')
|
||||
except TypeError:
|
||||
if len(result) == 1:
|
||||
result = result[0]
|
||||
if len(result) == 1:
|
||||
result = result[0]
|
||||
else:
|
||||
result = string.join(map(str, result), '')
|
||||
return result
|
||||
else:
|
||||
return self.expand(args, lvars)
|
||||
|
@ -524,6 +550,10 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
|
|||
# Compress strings of white space characters into
|
||||
# a single space.
|
||||
result = string.strip(_space_sep.sub(' ', result))
|
||||
elif is_Sequence(result):
|
||||
remove = _list_remove[mode]
|
||||
if remove:
|
||||
result = remove(result)
|
||||
|
||||
return result
|
||||
|
||||
|
@ -542,7 +572,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
|
|||
# except KeyError:
|
||||
# Subst_List_Strings[strSubst] = 1
|
||||
# import SCons.Debug
|
||||
# SCons.Debug.caller(1)
|
||||
# SCons.Debug.caller_trace(1)
|
||||
class ListSubber(UserList.UserList):
|
||||
"""A class to construct the results of a scons_subst_list() call.
|
||||
|
||||
|
@ -634,7 +664,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
|
|||
lv[var] = ''
|
||||
self.substitute(s, lv, 0)
|
||||
self.this_word()
|
||||
elif is_List(s) or is_Tuple(s):
|
||||
elif is_Sequence(s):
|
||||
for a in s:
|
||||
self.substitute(a, lvars, 1)
|
||||
self.next_word()
|
||||
|
@ -666,6 +696,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
|
|||
"""
|
||||
|
||||
if is_String(args) and not isinstance(args, CmdStringHolder):
|
||||
args = str(args) # In case it's a UserString.
|
||||
args = _separate_args.findall(args)
|
||||
for a in args:
|
||||
if a[0] in ' \t\n\r\f\v':
|
||||
|
@ -827,18 +858,18 @@ def scons_subst_once(strSubst, env, key):
|
|||
a = match.group(1)
|
||||
if a in matchlist:
|
||||
a = val
|
||||
if is_List(a) or is_Tuple(a):
|
||||
if is_Sequence(a):
|
||||
return string.join(map(str, a))
|
||||
else:
|
||||
return str(a)
|
||||
|
||||
if is_List(strSubst) or is_Tuple(strSubst):
|
||||
if is_Sequence(strSubst):
|
||||
result = []
|
||||
for arg in strSubst:
|
||||
if is_String(arg):
|
||||
if arg in matchlist:
|
||||
arg = val
|
||||
if is_List(arg) or is_Tuple(arg):
|
||||
if is_Sequence(arg):
|
||||
result.extend(arg)
|
||||
else:
|
||||
result.append(arg)
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -48,20 +48,24 @@ interface and the SCons build engine. There are two key classes here:
|
|||
target(s) that it decides need to be evaluated and/or built.
|
||||
"""
|
||||
|
||||
__revision__ = "src/engine/SCons/Taskmaster.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import SCons.compat
|
||||
__revision__ = "src/engine/SCons/Taskmaster.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
from itertools import chain
|
||||
import operator
|
||||
import string
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
import SCons.Node
|
||||
import SCons.Errors
|
||||
import SCons.Node
|
||||
|
||||
StateString = SCons.Node.StateString
|
||||
|
||||
NODE_NO_STATE = SCons.Node.no_state
|
||||
NODE_PENDING = SCons.Node.pending
|
||||
NODE_EXECUTING = SCons.Node.executing
|
||||
NODE_UP_TO_DATE = SCons.Node.up_to_date
|
||||
NODE_EXECUTED = SCons.Node.executed
|
||||
NODE_FAILED = SCons.Node.failed
|
||||
|
||||
|
||||
# A subsystem for recording stats about how different Nodes are handled by
|
||||
|
@ -134,6 +138,10 @@ class Task:
|
|||
self.node = node
|
||||
self.exc_clear()
|
||||
|
||||
def trace_message(self, method, node, description='node'):
|
||||
fmt = '%-20s %s %s\n'
|
||||
return fmt % (method + ':', description, self.tm.trace_node(node))
|
||||
|
||||
def display(self, message):
|
||||
"""
|
||||
Hook to allow the calling interface to display a message.
|
||||
|
@ -155,6 +163,8 @@ class Task:
|
|||
unlink underlying files and make all necessary directories before
|
||||
the Action is actually called to build the targets.
|
||||
"""
|
||||
T = self.tm.trace
|
||||
if T: T.write(self.trace_message('Task.prepare()', self.node))
|
||||
|
||||
# Now that it's the appropriate time, give the TaskMaster a
|
||||
# chance to raise any exceptions it encountered while preparing
|
||||
|
@ -165,6 +175,17 @@ class Task:
|
|||
self.display(self.tm.message)
|
||||
self.tm.message = None
|
||||
|
||||
# Let the targets take care of any necessary preparations.
|
||||
# This includes verifying that all of the necessary sources
|
||||
# and dependencies exist, removing the target file(s), etc.
|
||||
#
|
||||
# As of April 2008, the get_executor().prepare() method makes
|
||||
# sure that all of the aggregate sources necessary to build this
|
||||
# Task's target(s) exist in one up-front check. The individual
|
||||
# target t.prepare() methods check that each target's explicit
|
||||
# or implicit dependencies exists, and also initialize the
|
||||
# .sconsign info.
|
||||
self.targets[0].get_executor().prepare()
|
||||
for t in self.targets:
|
||||
t.prepare()
|
||||
for s in t.side_effects:
|
||||
|
@ -175,6 +196,17 @@ class Task:
|
|||
"""
|
||||
return self.node
|
||||
|
||||
def needs_execute(self):
|
||||
"""
|
||||
Called to determine whether the task's execute() method should
|
||||
be run.
|
||||
|
||||
This method allows one to skip the somethat costly execution
|
||||
of the execute() method in a seperate thread. For example,
|
||||
that would be unnecessary for up-to-date targets.
|
||||
"""
|
||||
return True
|
||||
|
||||
def execute(self):
|
||||
"""
|
||||
Called to execute the task.
|
||||
|
@ -183,6 +215,8 @@ class Task:
|
|||
so only do thread safe stuff here. Do thread unsafe stuff in
|
||||
prepare(), executed() or failed().
|
||||
"""
|
||||
T = self.tm.trace
|
||||
if T: T.write(self.trace_message('Task.execute()', self.node))
|
||||
|
||||
try:
|
||||
everything_was_cached = 1
|
||||
|
@ -192,8 +226,6 @@ class Task:
|
|||
break
|
||||
if not everything_was_cached:
|
||||
self.targets[0].build()
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except SystemExit:
|
||||
exc_value = sys.exc_info()[1]
|
||||
raise SCons.Errors.ExplicitExit(self.targets[0], exc_value.code)
|
||||
|
@ -201,9 +233,11 @@ class Task:
|
|||
raise
|
||||
except SCons.Errors.BuildError:
|
||||
raise
|
||||
except:
|
||||
raise SCons.Errors.TaskmasterException(self.targets[0],
|
||||
sys.exc_info())
|
||||
except Exception, e:
|
||||
buildError = SCons.Errors.convert_to_BuildError(e)
|
||||
buildError.node = self.targets[0]
|
||||
buildError.exc_info = sys.exc_info()
|
||||
raise buildError
|
||||
|
||||
def executed_without_callbacks(self):
|
||||
"""
|
||||
|
@ -211,11 +245,15 @@ class Task:
|
|||
and the Taskmaster instance doesn't want to call
|
||||
the Node's callback methods.
|
||||
"""
|
||||
T = self.tm.trace
|
||||
if T: T.write(self.trace_message('Task.executed_without_callbacks()',
|
||||
self.node))
|
||||
|
||||
for t in self.targets:
|
||||
if t.get_state() == SCons.Node.executing:
|
||||
if t.get_state() == NODE_EXECUTING:
|
||||
for side_effect in t.side_effects:
|
||||
side_effect.set_state(SCons.Node.no_state)
|
||||
t.set_state(SCons.Node.executed)
|
||||
side_effect.set_state(NODE_NO_STATE)
|
||||
t.set_state(NODE_EXECUTED)
|
||||
|
||||
def executed_with_callbacks(self):
|
||||
"""
|
||||
|
@ -230,11 +268,15 @@ class Task:
|
|||
post-visit actions that must take place regardless of whether
|
||||
or not the target was an actual built target or a source Node.
|
||||
"""
|
||||
T = self.tm.trace
|
||||
if T: T.write(self.trace_message('Task.executed_with_callbacks()',
|
||||
self.node))
|
||||
|
||||
for t in self.targets:
|
||||
if t.get_state() == SCons.Node.executing:
|
||||
if t.get_state() == NODE_EXECUTING:
|
||||
for side_effect in t.side_effects:
|
||||
side_effect.set_state(SCons.Node.no_state)
|
||||
t.set_state(SCons.Node.executed)
|
||||
side_effect.set_state(NODE_NO_STATE)
|
||||
t.set_state(NODE_EXECUTED)
|
||||
t.built()
|
||||
t.visited()
|
||||
|
||||
|
@ -243,15 +285,32 @@ class Task:
|
|||
def failed(self):
|
||||
"""
|
||||
Default action when a task fails: stop the build.
|
||||
|
||||
Note: Although this function is normally invoked on nodes in
|
||||
the executing state, it might also be invoked on up-to-date
|
||||
nodes when using Configure().
|
||||
"""
|
||||
self.fail_stop()
|
||||
|
||||
def fail_stop(self):
|
||||
"""
|
||||
Explicit stop-the-build failure.
|
||||
|
||||
This sets failure status on the target nodes and all of
|
||||
their dependent parent nodes.
|
||||
|
||||
Note: Although this function is normally invoked on nodes in
|
||||
the executing state, it might also be invoked on up-to-date
|
||||
nodes when using Configure().
|
||||
"""
|
||||
for t in self.targets:
|
||||
t.set_state(SCons.Node.failed)
|
||||
T = self.tm.trace
|
||||
if T: T.write(self.trace_message('Task.failed_stop()', self.node))
|
||||
|
||||
# Invoke will_not_build() to clean-up the pending children
|
||||
# list.
|
||||
self.tm.will_not_build(self.targets, lambda n: n.set_state(NODE_FAILED))
|
||||
|
||||
# Tell the taskmaster to not start any new tasks
|
||||
self.tm.stop()
|
||||
|
||||
# We're stopping because of a build failure, but give the
|
||||
|
@ -266,12 +325,15 @@ class Task:
|
|||
|
||||
This sets failure status on the target nodes and all of
|
||||
their dependent parent nodes.
|
||||
|
||||
Note: Although this function is normally invoked on nodes in
|
||||
the executing state, it might also be invoked on up-to-date
|
||||
nodes when using Configure().
|
||||
"""
|
||||
for t in self.targets:
|
||||
# Set failure state on all of the parents that were dependent
|
||||
# on this failed build.
|
||||
def set_state(node): node.set_state(SCons.Node.failed)
|
||||
t.call_for_all_waiting_parents(set_state)
|
||||
T = self.tm.trace
|
||||
if T: T.write(self.trace_message('Task.failed_continue()', self.node))
|
||||
|
||||
self.tm.will_not_build(self.targets, lambda n: n.set_state(NODE_FAILED))
|
||||
|
||||
def make_ready_all(self):
|
||||
"""
|
||||
|
@ -280,11 +342,14 @@ class Task:
|
|||
This is used when the interface needs every target Node to be
|
||||
visited--the canonical example being the "scons -c" option.
|
||||
"""
|
||||
T = self.tm.trace
|
||||
if T: T.write(self.trace_message('Task.make_ready_all()', self.node))
|
||||
|
||||
self.out_of_date = self.targets[:]
|
||||
for t in self.targets:
|
||||
t.disambiguate().set_state(SCons.Node.executing)
|
||||
t.disambiguate().set_state(NODE_EXECUTING)
|
||||
for s in t.side_effects:
|
||||
s.set_state(SCons.Node.executing)
|
||||
s.set_state(NODE_EXECUTING)
|
||||
|
||||
def make_ready_current(self):
|
||||
"""
|
||||
|
@ -293,7 +358,12 @@ class Task:
|
|||
|
||||
This is the default behavior for building only what's necessary.
|
||||
"""
|
||||
T = self.tm.trace
|
||||
if T: T.write(self.trace_message('Task.make_ready_current()',
|
||||
self.node))
|
||||
|
||||
self.out_of_date = []
|
||||
needs_executing = False
|
||||
for t in self.targets:
|
||||
try:
|
||||
t.disambiguate().make_ready()
|
||||
|
@ -301,13 +371,24 @@ class Task:
|
|||
(not t.always_build and t.is_up_to_date())
|
||||
except EnvironmentError, e:
|
||||
raise SCons.Errors.BuildError(node=t, errstr=e.strerror, filename=e.filename)
|
||||
if is_up_to_date:
|
||||
t.set_state(SCons.Node.up_to_date)
|
||||
else:
|
||||
|
||||
if not is_up_to_date:
|
||||
self.out_of_date.append(t)
|
||||
t.set_state(SCons.Node.executing)
|
||||
needs_executing = True
|
||||
|
||||
if needs_executing:
|
||||
for t in self.targets:
|
||||
t.set_state(NODE_EXECUTING)
|
||||
for s in t.side_effects:
|
||||
s.set_state(SCons.Node.executing)
|
||||
s.set_state(NODE_EXECUTING)
|
||||
else:
|
||||
for t in self.targets:
|
||||
# We must invoke visited() to ensure that the node
|
||||
# information has been computed before allowing the
|
||||
# parent nodes to execute. (That could occur in a
|
||||
# parallel build...)
|
||||
t.visited()
|
||||
t.set_state(NODE_UP_TO_DATE)
|
||||
|
||||
make_ready = make_ready_current
|
||||
|
||||
|
@ -321,6 +402,8 @@ class Task:
|
|||
waiting parent Nodes, or Nodes waiting on a common side effect,
|
||||
that can be put back on the candidates list.
|
||||
"""
|
||||
T = self.tm.trace
|
||||
if T: T.write(self.trace_message('Task.postprocess()', self.node))
|
||||
|
||||
# We may have built multiple targets, some of which may have
|
||||
# common parents waiting for this build. Count up how many
|
||||
|
@ -331,24 +414,34 @@ class Task:
|
|||
|
||||
targets = set(self.targets)
|
||||
|
||||
pending_children = self.tm.pending_children
|
||||
parents = {}
|
||||
for t in targets:
|
||||
for p in t.waiting_parents.keys():
|
||||
# A node can only be in the pending_children set if it has
|
||||
# some waiting_parents.
|
||||
if t.waiting_parents:
|
||||
if T: T.write(self.trace_message('Task.postprocess()',
|
||||
t,
|
||||
'removing'))
|
||||
pending_children.discard(t)
|
||||
for p in t.waiting_parents:
|
||||
parents[p] = parents.get(p, 0) + 1
|
||||
|
||||
for t in targets:
|
||||
for s in t.side_effects:
|
||||
if s.get_state() == SCons.Node.executing:
|
||||
s.set_state(SCons.Node.no_state)
|
||||
for p in s.waiting_parents.keys():
|
||||
if not parents.has_key(p):
|
||||
parents[p] = 1
|
||||
for p in s.waiting_s_e.keys():
|
||||
if s.get_state() == NODE_EXECUTING:
|
||||
s.set_state(NODE_NO_STATE)
|
||||
for p in s.waiting_parents:
|
||||
parents[p] = parents.get(p, 0) + 1
|
||||
for p in s.waiting_s_e:
|
||||
if p.ref_count == 0:
|
||||
self.tm.candidates.append(p)
|
||||
|
||||
for p, subtract in parents.items():
|
||||
p.ref_count = p.ref_count - subtract
|
||||
if T: T.write(self.trace_message('Task.postprocess()',
|
||||
p,
|
||||
'adjusted parent ref count'))
|
||||
if p.ref_count == 0:
|
||||
self.tm.candidates.append(p)
|
||||
|
||||
|
@ -409,12 +502,15 @@ class Task:
|
|||
raise exc_type, exc_value, exc_traceback
|
||||
|
||||
|
||||
def find_cycle(stack):
|
||||
if stack[0] == stack[-1]:
|
||||
return stack
|
||||
for n in stack[-1].waiting_parents.keys():
|
||||
def find_cycle(stack, visited):
|
||||
if stack[-1] in visited:
|
||||
return None
|
||||
visited.add(stack[-1])
|
||||
for n in stack[-1].waiting_parents:
|
||||
stack.append(n)
|
||||
if find_cycle(stack):
|
||||
if stack[0] == stack[-1]:
|
||||
return stack
|
||||
if find_cycle(stack, visited):
|
||||
return stack
|
||||
stack.pop()
|
||||
return None
|
||||
|
@ -437,6 +533,7 @@ class Taskmaster:
|
|||
self.message = None
|
||||
self.trace = trace
|
||||
self.next_candidate = self.find_next_candidate
|
||||
self.pending_children = set()
|
||||
|
||||
def find_next_candidate(self):
|
||||
"""
|
||||
|
@ -477,9 +574,104 @@ class Taskmaster:
|
|||
def no_next_candidate(self):
|
||||
"""
|
||||
Stops Taskmaster processing by not returning a next candidate.
|
||||
|
||||
Note that we have to clean-up the Taskmaster candidate list
|
||||
because the cycle detection depends on the fact all nodes have
|
||||
been processed somehow.
|
||||
"""
|
||||
while self.candidates:
|
||||
candidates = self.candidates
|
||||
self.candidates = []
|
||||
self.will_not_build(candidates)
|
||||
return None
|
||||
|
||||
def _validate_pending_children(self):
|
||||
"""
|
||||
Validate the content of the pending_children set. Assert if an
|
||||
internal error is found.
|
||||
|
||||
This function is used strictly for debugging the taskmaster by
|
||||
checking that no invariants are violated. It is not used in
|
||||
normal operation.
|
||||
|
||||
The pending_children set is used to detect cycles in the
|
||||
dependency graph. We call a "pending child" a child that is
|
||||
found in the "pending" state when checking the dependencies of
|
||||
its parent node.
|
||||
|
||||
A pending child can occur when the Taskmaster completes a loop
|
||||
through a cycle. For example, lets imagine a graph made of
|
||||
three node (A, B and C) making a cycle. The evaluation starts
|
||||
at node A. The taskmaster first consider whether node A's
|
||||
child B is up-to-date. Then, recursively, node B needs to
|
||||
check whether node C is up-to-date. This leaves us with a
|
||||
dependency graph looking like:
|
||||
|
||||
Next candidate \
|
||||
\
|
||||
Node A (Pending) --> Node B(Pending) --> Node C (NoState)
|
||||
^ |
|
||||
| |
|
||||
+-------------------------------------+
|
||||
|
||||
Now, when the Taskmaster examines the Node C's child Node A,
|
||||
it finds that Node A is in the "pending" state. Therefore,
|
||||
Node A is a pending child of node C.
|
||||
|
||||
Pending children indicate that the Taskmaster has potentially
|
||||
loop back through a cycle. We say potentially because it could
|
||||
also occur when a DAG is evaluated in parallel. For example,
|
||||
consider the following graph:
|
||||
|
||||
|
||||
Node A (Pending) --> Node B(Pending) --> Node C (Pending) --> ...
|
||||
| ^
|
||||
| |
|
||||
+----------> Node D (NoState) --------+
|
||||
/
|
||||
Next candidate /
|
||||
|
||||
The Taskmaster first evaluates the nodes A, B, and C and
|
||||
starts building some children of node C. Assuming, that the
|
||||
maximum parallel level has not been reached, the Taskmaster
|
||||
will examine Node D. It will find that Node C is a pending
|
||||
child of Node D.
|
||||
|
||||
In summary, evaluating a graph with a cycle will always
|
||||
involve a pending child at one point. A pending child might
|
||||
indicate either a cycle or a diamond-shaped DAG. Only a
|
||||
fraction of the nodes ends-up being a "pending child" of
|
||||
another node. This keeps the pending_children set small in
|
||||
practice.
|
||||
|
||||
We can differentiate between the two cases if we wait until
|
||||
the end of the build. At this point, all the pending children
|
||||
nodes due to a diamond-shaped DAG will have been properly
|
||||
built (or will have failed to build). But, the pending
|
||||
children involved in a cycle will still be in the pending
|
||||
state.
|
||||
|
||||
The taskmaster removes nodes from the pending_children set as
|
||||
soon as a pending_children node moves out of the pending
|
||||
state. This also helps to keep the pending_children set small.
|
||||
"""
|
||||
|
||||
for n in self.pending_children:
|
||||
assert n.state in (NODE_PENDING, NODE_EXECUTING), \
|
||||
(str(n), StateString[n.state])
|
||||
assert len(n.waiting_parents) != 0, (str(n), len(n.waiting_parents))
|
||||
for p in n.waiting_parents:
|
||||
assert p.ref_count > 0, (str(n), str(p), p.ref_count)
|
||||
|
||||
|
||||
def trace_message(self, message):
|
||||
return 'Taskmaster: %s\n' % message
|
||||
|
||||
def trace_node(self, node):
|
||||
return '<%-10s %-3s %s>' % (StateString[node.get_state()],
|
||||
node.ref_count,
|
||||
repr(str(node)))
|
||||
|
||||
def _find_next_ready_node(self):
|
||||
"""
|
||||
Finds the next node that is ready to be built.
|
||||
|
@ -505,15 +697,25 @@ class Taskmaster:
|
|||
self.ready_exc = None
|
||||
|
||||
T = self.trace
|
||||
if T: T.write('\n' + self.trace_message('Looking for a node to evaluate'))
|
||||
|
||||
while 1:
|
||||
node = self.next_candidate()
|
||||
if node is None:
|
||||
if T: T.write(self.trace_message('No candidate anymore.') + '\n')
|
||||
return None
|
||||
|
||||
node = node.disambiguate()
|
||||
state = node.get_state()
|
||||
|
||||
# For debugging only:
|
||||
#
|
||||
# try:
|
||||
# self._validate_pending_children()
|
||||
# except:
|
||||
# self.ready_exc = sys.exc_info()
|
||||
# return node
|
||||
|
||||
if CollectStats:
|
||||
if not hasattr(node, 'stats'):
|
||||
node.stats = Stats()
|
||||
|
@ -523,119 +725,138 @@ class Taskmaster:
|
|||
else:
|
||||
S = None
|
||||
|
||||
if T: T.write('Taskmaster: %s:' % repr(str(node)))
|
||||
if T: T.write(self.trace_message(' Considering node %s and its children:' % self.trace_node(node)))
|
||||
|
||||
# Skip this node if it has already been evaluated:
|
||||
if state > SCons.Node.pending:
|
||||
if state == NODE_NO_STATE:
|
||||
# Mark this node as being on the execution stack:
|
||||
node.set_state(NODE_PENDING)
|
||||
elif state > NODE_PENDING:
|
||||
# Skip this node if it has already been evaluated:
|
||||
if S: S.already_handled = S.already_handled + 1
|
||||
if T: T.write(' already handled (%s)\n' % StateString[state])
|
||||
if T: T.write(self.trace_message(' already handled (executed)'))
|
||||
continue
|
||||
|
||||
# Mark this node as being on the execution stack:
|
||||
node.set_state(SCons.Node.pending)
|
||||
|
||||
try:
|
||||
children = node.children() + node.prerequisites
|
||||
children = node.children()
|
||||
except SystemExit:
|
||||
exc_value = sys.exc_info()[1]
|
||||
e = SCons.Errors.ExplicitExit(node, exc_value.code)
|
||||
self.ready_exc = (SCons.Errors.ExplicitExit, e)
|
||||
if T: T.write(' SystemExit\n')
|
||||
if T: T.write(self.trace_message(' SystemExit'))
|
||||
return node
|
||||
except KeyboardInterrupt:
|
||||
if T: T.write(' KeyboardInterrupt\n')
|
||||
raise
|
||||
except:
|
||||
except Exception, e:
|
||||
# We had a problem just trying to figure out the
|
||||
# children (like a child couldn't be linked in to a
|
||||
# BuildDir, or a Scanner threw something). Arrange to
|
||||
# VariantDir, or a Scanner threw something). Arrange to
|
||||
# raise the exception when the Task is "executed."
|
||||
self.ready_exc = sys.exc_info()
|
||||
if S: S.problem = S.problem + 1
|
||||
if T: T.write(' exception\n')
|
||||
if T: T.write(self.trace_message(' exception %s while scanning children.\n' % e))
|
||||
return node
|
||||
|
||||
if T and children:
|
||||
c = map(str, children)
|
||||
c.sort()
|
||||
T.write(' children:\n %s\n ' % c)
|
||||
children_not_visited = []
|
||||
children_pending = set()
|
||||
children_not_ready = []
|
||||
children_failed = False
|
||||
|
||||
childstate = map(lambda N: (N, N.get_state()), children)
|
||||
for child in chain(children,node.prerequisites):
|
||||
childstate = child.get_state()
|
||||
|
||||
if T: T.write(self.trace_message(' ' + self.trace_node(child)))
|
||||
|
||||
if childstate == NODE_NO_STATE:
|
||||
children_not_visited.append(child)
|
||||
elif childstate == NODE_PENDING:
|
||||
children_pending.add(child)
|
||||
elif childstate == NODE_FAILED:
|
||||
children_failed = True
|
||||
|
||||
if childstate <= NODE_EXECUTING:
|
||||
children_not_ready.append(child)
|
||||
|
||||
|
||||
# These nodes have not even been visited yet. Add
|
||||
# them to the list so that on some next pass we can
|
||||
# take a stab at evaluating them (or their children).
|
||||
children_not_visited.reverse()
|
||||
self.candidates.extend(self.order(children_not_visited))
|
||||
#if T and children_not_visited:
|
||||
# T.write(self.trace_message(' adding to candidates: %s' % map(str, children_not_visited)))
|
||||
# T.write(self.trace_message(' candidates now: %s\n' % map(str, self.candidates)))
|
||||
|
||||
# Skip this node if any of its children have failed.
|
||||
#
|
||||
# This catches the case where we're descending a top-level
|
||||
# target and one of our children failed while trying to be
|
||||
# built by a *previous* descent of an earlier top-level
|
||||
# target.
|
||||
#
|
||||
# It can also occur if a node is reused in multiple
|
||||
# targets. One first descends though the one of the
|
||||
# target, the next time occurs through the other target.
|
||||
#
|
||||
# Note that we can only have failed_children if the
|
||||
# --keep-going flag was used, because without it the build
|
||||
# will stop before diving in the other branch.
|
||||
#
|
||||
# Note that even if one of the children fails, we still
|
||||
# added the other children to the list of candidate nodes
|
||||
# to keep on building (--keep-going).
|
||||
if children_failed:
|
||||
node.set_state(NODE_FAILED)
|
||||
|
||||
# Skip this node if any of its children have failed. This
|
||||
# catches the case where we're descending a top-level target
|
||||
# and one of our children failed while trying to be built
|
||||
# by a *previous* descent of an earlier top-level target.
|
||||
failed_children = filter(lambda I: I[1] == SCons.Node.failed,
|
||||
childstate)
|
||||
if failed_children:
|
||||
node.set_state(SCons.Node.failed)
|
||||
if S: S.child_failed = S.child_failed + 1
|
||||
if T:
|
||||
c = map(str, failed_children)
|
||||
c.sort()
|
||||
T.write(' children failed:\n %s\n' % c)
|
||||
if T: T.write(self.trace_message('****** %s\n' % self.trace_node(node)))
|
||||
continue
|
||||
|
||||
# Detect dependency cycles:
|
||||
pending_nodes = filter(lambda I: I[1] == SCons.Node.pending, childstate)
|
||||
if pending_nodes:
|
||||
for p in pending_nodes:
|
||||
cycle = find_cycle([p[0], node])
|
||||
if cycle:
|
||||
desc = "Dependency cycle: " + string.join(map(str, cycle), " -> ")
|
||||
if T: T.write(' dependency cycle\n')
|
||||
raise SCons.Errors.UserError, desc
|
||||
if children_not_ready:
|
||||
for child in children_not_ready:
|
||||
# We're waiting on one or more derived targets
|
||||
# that have not yet finished building.
|
||||
if S: S.not_built = S.not_built + 1
|
||||
|
||||
not_built = filter(lambda I: I[1] <= SCons.Node.executing, childstate)
|
||||
if not_built:
|
||||
# We're waiting on one or more derived targets that have
|
||||
# not yet finished building.
|
||||
# Add this node to the waiting parents lists of
|
||||
# anything we're waiting on, with a reference
|
||||
# count so we can be put back on the list for
|
||||
# re-evaluation when they've all finished.
|
||||
node.ref_count = node.ref_count + child.add_to_waiting_parents(node)
|
||||
if T: T.write(self.trace_message(' adjusted ref count: %s, child %s' %
|
||||
(self.trace_node(node), repr(str(child)))))
|
||||
|
||||
not_visited = filter(lambda I: not I[1], not_built)
|
||||
if not_visited:
|
||||
# Some of them haven't even been visited yet.
|
||||
# Add them to the list so that on some next pass
|
||||
# we can take a stab at evaluating them (or
|
||||
# their children).
|
||||
not_visited = map(lambda I: I[0], not_visited)
|
||||
not_visited.reverse()
|
||||
self.candidates.extend(self.order(not_visited))
|
||||
|
||||
n_b_nodes = map(lambda I: I[0], not_built)
|
||||
|
||||
# Add this node to the waiting parents lists of anything
|
||||
# we're waiting on, with a reference count so we can be
|
||||
# put back on the list for re-evaluation when they've
|
||||
# all finished.
|
||||
map(lambda n, P=node: n.add_to_waiting_parents(P), n_b_nodes)
|
||||
node.ref_count = len(set(n_b_nodes))
|
||||
|
||||
if S: S.not_built = S.not_built + 1
|
||||
if T:
|
||||
c = map(str, n_b_nodes)
|
||||
c.sort()
|
||||
T.write(' waiting on unfinished children:\n %s\n' % c)
|
||||
for pc in children_pending:
|
||||
T.write(self.trace_message(' adding %s to the pending children set\n' %
|
||||
self.trace_node(pc)))
|
||||
self.pending_children = self.pending_children | children_pending
|
||||
|
||||
continue
|
||||
|
||||
# Skip this node if it has side-effects that are
|
||||
# currently being built:
|
||||
side_effects = filter(lambda N:
|
||||
N.get_state() == SCons.Node.executing,
|
||||
node.side_effects)
|
||||
if side_effects:
|
||||
map(lambda n, P=node: n.add_to_waiting_s_e(P), side_effects)
|
||||
wait_side_effects = False
|
||||
for se in node.side_effects:
|
||||
if se.get_state() == NODE_EXECUTING:
|
||||
se.add_to_waiting_s_e(node)
|
||||
wait_side_effects = True
|
||||
|
||||
if wait_side_effects:
|
||||
if S: S.side_effects = S.side_effects + 1
|
||||
if T:
|
||||
c = map(str, side_effects)
|
||||
c.sort()
|
||||
T.write(' waiting on side effects:\n %s\n' % c)
|
||||
continue
|
||||
|
||||
# The default when we've gotten through all of the checks above:
|
||||
# this node is ready to be built.
|
||||
if S: S.build = S.build + 1
|
||||
if T: T.write(' evaluating %s\n' % node)
|
||||
if T: T.write(self.trace_message('Evaluating %s\n' %
|
||||
self.trace_node(node)))
|
||||
|
||||
# For debugging only:
|
||||
#
|
||||
# try:
|
||||
# self._validate_pending_children()
|
||||
# except:
|
||||
# self.ready_exc = sys.exc_info()
|
||||
# return node
|
||||
|
||||
return node
|
||||
|
||||
return None
|
||||
|
@ -657,11 +878,9 @@ class Taskmaster:
|
|||
task = self.tasker(self, tlist, node in self.original_top, node)
|
||||
try:
|
||||
task.make_ready()
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except:
|
||||
# We had a problem just trying to get this task ready (like
|
||||
# a child couldn't be linked in to a BuildDir when deciding
|
||||
# a child couldn't be linked in to a VariantDir when deciding
|
||||
# whether this node is current). Arrange to raise the
|
||||
# exception when the Task is "executed."
|
||||
self.ready_exc = sys.exc_info()
|
||||
|
@ -673,8 +892,94 @@ class Taskmaster:
|
|||
|
||||
return task
|
||||
|
||||
def will_not_build(self, nodes, node_func=lambda n: None):
|
||||
"""
|
||||
Perform clean-up about nodes that will never be built. Invokes
|
||||
a user defined function on all of these nodes (including all
|
||||
of their parents).
|
||||
"""
|
||||
|
||||
T = self.trace
|
||||
|
||||
pending_children = self.pending_children
|
||||
|
||||
to_visit = set(nodes)
|
||||
pending_children = pending_children - to_visit
|
||||
|
||||
if T:
|
||||
for n in nodes:
|
||||
T.write(self.trace_message(' removing node %s from the pending children set\n' %
|
||||
self.trace_node(n)))
|
||||
try:
|
||||
while 1:
|
||||
try:
|
||||
node = to_visit.pop()
|
||||
except AttributeError:
|
||||
# Python 1.5.2
|
||||
if len(to_visit):
|
||||
node = to_visit[0]
|
||||
to_visit.remove(node)
|
||||
else:
|
||||
break
|
||||
|
||||
node_func(node)
|
||||
|
||||
# Prune recursion by flushing the waiting children
|
||||
# list immediately.
|
||||
parents = node.waiting_parents
|
||||
node.waiting_parents = set()
|
||||
|
||||
to_visit = to_visit | parents
|
||||
pending_children = pending_children - parents
|
||||
|
||||
for p in parents:
|
||||
p.ref_count = p.ref_count - 1
|
||||
if T: T.write(self.trace_message(' removing parent %s from the pending children set\n' %
|
||||
self.trace_node(p)))
|
||||
except KeyError:
|
||||
# The container to_visit has been emptied.
|
||||
pass
|
||||
|
||||
# We have the stick back the pending_children list into the
|
||||
# task master because the python 1.5.2 compatibility does not
|
||||
# allow us to use in-place updates
|
||||
self.pending_children = pending_children
|
||||
|
||||
def stop(self):
|
||||
"""
|
||||
Stops the current build completely.
|
||||
"""
|
||||
self.next_candidate = self.no_next_candidate
|
||||
|
||||
def cleanup(self):
|
||||
"""
|
||||
Check for dependency cycles.
|
||||
"""
|
||||
if not self.pending_children:
|
||||
return
|
||||
|
||||
# TODO(1.5)
|
||||
#nclist = [ (n, find_cycle([n], set())) for n in self.pending_children ]
|
||||
nclist = map(lambda n: (n, find_cycle([n], set())), self.pending_children)
|
||||
|
||||
# TODO(1.5)
|
||||
#genuine_cycles = [
|
||||
# node for node, cycle in nclist
|
||||
# if cycle or node.get_state() != NODE_EXECUTED
|
||||
#]
|
||||
genuine_cycles = filter(lambda t: t[1] or t[0].get_state() != NODE_EXECUTED, nclist)
|
||||
if not genuine_cycles:
|
||||
# All of the "cycles" found were single nodes in EXECUTED state,
|
||||
# which is to say, they really weren't cycles. Just return.
|
||||
return
|
||||
|
||||
desc = 'Found dependency cycle(s):\n'
|
||||
for node, cycle in nclist:
|
||||
if cycle:
|
||||
desc = desc + " " + string.join(map(str, cycle), " -> ") + "\n"
|
||||
else:
|
||||
desc = desc + \
|
||||
" Internal Error: no cycle found for node %s (%s) in state %s\n" % \
|
||||
(node, repr(node), StateString[node.get_state()])
|
||||
|
||||
raise SCons.Errors.UserError, desc
|
|
@ -10,7 +10,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -32,7 +32,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/386asm.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/386asm.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
from SCons.Tool.PharLapCommon import addPharLapPaths
|
||||
import SCons.Util
|
|
@ -10,7 +10,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -32,7 +32,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/BitKeeper.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/BitKeeper.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/CVS.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/CVS.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
241
scons/scons-local-1.2.0/SCons/Tool/FortranCommon.py
Normal file
241
scons/scons-local-1.2.0/SCons/Tool/FortranCommon.py
Normal file
|
@ -0,0 +1,241 @@
|
|||
"""SCons.Tool.FortranCommon
|
||||
|
||||
Stuff for processing Fortran, common to all fortran dialects.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/FortranCommon.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import re
|
||||
import string
|
||||
import os.path
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Defaults
|
||||
import SCons.Scanner.Fortran
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
|
||||
def isfortran(env, source):
|
||||
"""Return 1 if any of code in source has fortran files in it, 0
|
||||
otherwise."""
|
||||
try:
|
||||
fsuffixes = env['FORTRANSUFFIXES']
|
||||
except KeyError:
|
||||
# If no FORTRANSUFFIXES, no fortran tool, so there is no need to look
|
||||
# for fortran sources.
|
||||
return 0
|
||||
|
||||
if not source:
|
||||
# Source might be None for unusual cases like SConf.
|
||||
return 0
|
||||
for s in source:
|
||||
if s.sources:
|
||||
ext = os.path.splitext(str(s.sources[0]))[1]
|
||||
if ext in fsuffixes:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
def _fortranEmitter(target, source, env):
|
||||
node = source[0].rfile()
|
||||
if not node.exists() and not node.is_derived():
|
||||
print "Could not locate " + str(node.name)
|
||||
return ([], [])
|
||||
mod_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(\w+)"""
|
||||
cre = re.compile(mod_regex,re.M)
|
||||
# Retrieve all USE'd module names
|
||||
modules = cre.findall(node.get_contents())
|
||||
# Remove unique items from the list
|
||||
modules = SCons.Util.unique(modules)
|
||||
# Convert module name to a .mod filename
|
||||
suffix = env.subst('$FORTRANMODSUFFIX', target=target, source=source)
|
||||
moddir = env.subst('$FORTRANMODDIR', target=target, source=source)
|
||||
modules = map(lambda x, s=suffix: string.lower(x) + s, modules)
|
||||
for m in modules:
|
||||
target.append(env.fs.File(m, moddir))
|
||||
return (target, source)
|
||||
|
||||
def FortranEmitter(target, source, env):
|
||||
target, source = _fortranEmitter(target, source, env)
|
||||
return SCons.Defaults.StaticObjectEmitter(target, source, env)
|
||||
|
||||
def ShFortranEmitter(target, source, env):
|
||||
target, source = _fortranEmitter(target, source, env)
|
||||
return SCons.Defaults.SharedObjectEmitter(target, source, env)
|
||||
|
||||
def ComputeFortranSuffixes(suffixes, ppsuffixes):
|
||||
"""suffixes are fortran source files, and ppsuffixes the ones to be
|
||||
pre-processed. Both should be sequences, not strings."""
|
||||
assert len(suffixes) > 0
|
||||
s = suffixes[0]
|
||||
sup = string.upper(s)
|
||||
upper_suffixes = map(string.upper, suffixes)
|
||||
if SCons.Util.case_sensitive_suffixes(s, sup):
|
||||
ppsuffixes.extend(upper_suffixes)
|
||||
else:
|
||||
suffixes.extend(upper_suffixes)
|
||||
|
||||
def CreateDialectActions(dialect):
|
||||
"""Create dialect specific actions."""
|
||||
CompAction = SCons.Action.Action('$%sCOM ' % dialect, '$%sCOMSTR' % dialect)
|
||||
CompPPAction = SCons.Action.Action('$%sPPCOM ' % dialect, '$%sPPCOMSTR' % dialect)
|
||||
ShCompAction = SCons.Action.Action('$SH%sCOM ' % dialect, '$SH%sCOMSTR' % dialect)
|
||||
ShCompPPAction = SCons.Action.Action('$SH%sPPCOM ' % dialect, '$SH%sPPCOMSTR' % dialect)
|
||||
|
||||
return CompAction, CompPPAction, ShCompAction, ShCompPPAction
|
||||
|
||||
def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_module = 0):
|
||||
"""Add dialect specific construction variables."""
|
||||
ComputeFortranSuffixes(suffixes, ppsuffixes)
|
||||
|
||||
fscan = SCons.Scanner.Fortran.FortranScan("%sPATH" % dialect)
|
||||
|
||||
for suffix in suffixes + ppsuffixes:
|
||||
SCons.Tool.SourceFileScanner.add_scanner(suffix, fscan)
|
||||
|
||||
env.AppendUnique(FORTRANSUFFIXES = suffixes + ppsuffixes)
|
||||
|
||||
compaction, compppaction, shcompaction, shcompppaction = \
|
||||
CreateDialectActions(dialect)
|
||||
|
||||
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
|
||||
|
||||
for suffix in suffixes:
|
||||
static_obj.add_action(suffix, compaction)
|
||||
shared_obj.add_action(suffix, shcompaction)
|
||||
static_obj.add_emitter(suffix, FortranEmitter)
|
||||
shared_obj.add_emitter(suffix, ShFortranEmitter)
|
||||
|
||||
for suffix in ppsuffixes:
|
||||
static_obj.add_action(suffix, compppaction)
|
||||
shared_obj.add_action(suffix, shcompppaction)
|
||||
static_obj.add_emitter(suffix, FortranEmitter)
|
||||
shared_obj.add_emitter(suffix, ShFortranEmitter)
|
||||
|
||||
if not env.has_key('%sFLAGS' % dialect):
|
||||
env['%sFLAGS' % dialect] = SCons.Util.CLVar('')
|
||||
|
||||
if not env.has_key('SH%sFLAGS' % dialect):
|
||||
env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS' % dialect)
|
||||
|
||||
# If a tool does not define fortran prefix/suffix for include path, use C ones
|
||||
if not env.has_key('INC%sPREFIX' % dialect):
|
||||
env['INC%sPREFIX' % dialect] = '$INCPREFIX'
|
||||
|
||||
if not env.has_key('INC%sSUFFIX' % dialect):
|
||||
env['INC%sSUFFIX' % dialect] = '$INCSUFFIX'
|
||||
|
||||
env['_%sINCFLAGS' % dialect] = '$( ${_concat(INC%sPREFIX, %sPATH, INC%sSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)' % (dialect, dialect, dialect)
|
||||
|
||||
if support_module == 1:
|
||||
env['%sCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect)
|
||||
env['%sPPCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect)
|
||||
env['SH%sCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect)
|
||||
env['SH%sPPCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $_FORTRANMODFLAG $SOURCES' % (dialect, dialect, dialect)
|
||||
else:
|
||||
env['%sCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect)
|
||||
env['%sPPCOM' % dialect] = '$%s -o $TARGET -c $%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect)
|
||||
env['SH%sCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect)
|
||||
env['SH%sPPCOM' % dialect] = '$SH%s -o $TARGET -c $SH%sFLAGS $CPPFLAGS $_CPPDEFFLAGS $_%sINCFLAGS $SOURCES' % (dialect, dialect, dialect)
|
||||
|
||||
def add_fortran_to_env(env):
|
||||
"""Add Builders and construction variables for Fortran to an Environment."""
|
||||
try:
|
||||
FortranSuffixes = env['FORTRANFILESUFFIXES']
|
||||
except KeyError:
|
||||
FortranSuffixes = ['.f', '.for', '.ftn']
|
||||
|
||||
#print "Adding %s to fortran suffixes" % FortranSuffixes
|
||||
try:
|
||||
FortranPPSuffixes = env['FORTRANPPFILESUFFIXES']
|
||||
except KeyError:
|
||||
FortranPPSuffixes = ['.fpp', '.FPP']
|
||||
|
||||
DialectAddToEnv(env, "FORTRAN", FortranSuffixes,
|
||||
FortranPPSuffixes, support_module = 1)
|
||||
|
||||
env['FORTRANMODPREFIX'] = '' # like $LIBPREFIX
|
||||
env['FORTRANMODSUFFIX'] = '.mod' # like $LIBSUFFIX
|
||||
|
||||
env['FORTRANMODDIR'] = '' # where the compiler should place .mod files
|
||||
env['FORTRANMODDIRPREFIX'] = '' # some prefix to $FORTRANMODDIR - similar to $INCPREFIX
|
||||
env['FORTRANMODDIRSUFFIX'] = '' # some suffix to $FORTRANMODDIR - similar to $INCSUFFIX
|
||||
env['_FORTRANMODFLAG'] = '$( ${_concat(FORTRANMODDIRPREFIX, FORTRANMODDIR, FORTRANMODDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||
|
||||
def add_f77_to_env(env):
|
||||
"""Add Builders and construction variables for f77 to an Environment."""
|
||||
try:
|
||||
F77Suffixes = env['F77FILESUFFIXES']
|
||||
except KeyError:
|
||||
F77Suffixes = ['.f77']
|
||||
|
||||
#print "Adding %s to f77 suffixes" % F77Suffixes
|
||||
try:
|
||||
F77PPSuffixes = env['F77PPFILESUFFIXES']
|
||||
except KeyError:
|
||||
F77PPSuffixes = []
|
||||
|
||||
DialectAddToEnv(env, "F77", F77Suffixes, F77PPSuffixes)
|
||||
|
||||
def add_f90_to_env(env):
|
||||
"""Add Builders and construction variables for f90 to an Environment."""
|
||||
try:
|
||||
F90Suffixes = env['F90FILESUFFIXES']
|
||||
except KeyError:
|
||||
F90Suffixes = ['.f90']
|
||||
|
||||
#print "Adding %s to f90 suffixes" % F90Suffixes
|
||||
try:
|
||||
F90PPSuffixes = env['F90PPFILESUFFIXES']
|
||||
except KeyError:
|
||||
F90PPSuffixes = []
|
||||
|
||||
DialectAddToEnv(env, "F90", F90Suffixes, F90PPSuffixes,
|
||||
support_module = 1)
|
||||
|
||||
def add_f95_to_env(env):
|
||||
"""Add Builders and construction variables for f95 to an Environment."""
|
||||
try:
|
||||
F95Suffixes = env['F95FILESUFFIXES']
|
||||
except KeyError:
|
||||
F95Suffixes = ['.f95']
|
||||
|
||||
#print "Adding %s to f95 suffixes" % F95Suffixes
|
||||
try:
|
||||
F95PPSuffixes = env['F95PPFILESUFFIXES']
|
||||
except KeyError:
|
||||
F95PPSuffixes = []
|
||||
|
||||
DialectAddToEnv(env, "F95", F95Suffixes, F95PPSuffixes,
|
||||
support_module = 1)
|
||||
|
||||
def add_all_to_env(env):
|
||||
"""Add builders and construction variables for all supported fortran
|
||||
dialects."""
|
||||
add_fortran_to_env(env)
|
||||
add_f77_to_env(env)
|
||||
add_f90_to_env(env)
|
||||
add_f95_to_env(env)
|
|
@ -5,7 +5,7 @@ Stuff for processing Java.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ Stuff for processing Java.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/JavaCommon.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/JavaCommon.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
@ -49,14 +49,16 @@ if java_parsing:
|
|||
# double-backslashes;
|
||||
# a single-line comment "//";
|
||||
# single or double quotes preceeded by a backslash;
|
||||
# single quotes, double quotes, open or close braces, semi-colons;
|
||||
# single quotes, double quotes, open or close braces, semi-colons,
|
||||
# periods, open or close parentheses;
|
||||
# floating-point numbers;
|
||||
# any alphanumeric token (keyword, class name, specifier);
|
||||
# any alphanumeric token surrounded by angle brackets (generics);
|
||||
# the multi-line comment begin and end tokens /* and */;
|
||||
# array declarations "[]";
|
||||
# semi-colons;
|
||||
# periods.
|
||||
# array declarations "[]".
|
||||
_reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.\(\)]|' +
|
||||
r'[A-Za-z_][\w\$\.]*|/\*|\*/|\[\])')
|
||||
r'\d*\.\d*|[A-Za-z_][\w\$\.]*|<[A-Za-z_]\w+>|' +
|
||||
r'/\*|\*/|\[\])')
|
||||
|
||||
class OuterState:
|
||||
"""The initial state for parsing a Java file for classes,
|
||||
|
@ -73,6 +75,7 @@ if java_parsing:
|
|||
self.stackBrackets = []
|
||||
self.brackets = 0
|
||||
self.nextAnon = 1
|
||||
self.localClasses = []
|
||||
self.stackAnonClassBrackets = []
|
||||
self.anonStacksStack = [[0]]
|
||||
self.package = None
|
||||
|
@ -124,6 +127,7 @@ if java_parsing:
|
|||
if len(self.stackBrackets) and \
|
||||
self.brackets == self.stackBrackets[-1]:
|
||||
self.listOutputs.append(string.join(self.listClasses, '$'))
|
||||
self.localClasses.pop()
|
||||
self.listClasses.pop()
|
||||
self.anonStacksStack.pop()
|
||||
self.stackBrackets.pop()
|
||||
|
@ -199,6 +203,8 @@ if java_parsing:
|
|||
return IgnoreState('*/', self)
|
||||
elif token == '\n':
|
||||
return self
|
||||
elif token[0] == '<' and token[-1] == '>':
|
||||
return self
|
||||
elif token == '(':
|
||||
self.brace_level = self.brace_level + 1
|
||||
return self
|
||||
|
@ -236,6 +242,20 @@ if java_parsing:
|
|||
# the next non-whitespace token should be the name of the class
|
||||
if token == '\n':
|
||||
return self
|
||||
# If that's an inner class which is declared in a method, it
|
||||
# requires an index prepended to the class-name, e.g.
|
||||
# 'Foo$1Inner' (Tigris Issue 2087)
|
||||
if self.outer_state.localClasses and \
|
||||
self.outer_state.stackBrackets[-1] > \
|
||||
self.outer_state.stackBrackets[-2]+1:
|
||||
locals = self.outer_state.localClasses[-1]
|
||||
try:
|
||||
idx = locals[token]
|
||||
locals[token] = locals[token]+1
|
||||
except KeyError:
|
||||
locals[token] = 1
|
||||
token = str(locals[token]) + token
|
||||
self.outer_state.localClasses.append({})
|
||||
self.outer_state.listClasses.append(token)
|
||||
self.outer_state.anonStacksStack.append([0])
|
||||
return self.outer_state
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/Perforce.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/Perforce.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os
|
||||
|
|
@ -7,7 +7,7 @@ Phar Lap ETS tool chain. Right now, this is linkloc and
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -29,7 +29,7 @@ Phar Lap ETS tool chain. Right now, this is linkloc and
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/PharLapCommon.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/PharLapCommon.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os
|
||||
import os.path
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/RCS.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/RCS.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/SCCS.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/SCCS.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/Subversion.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/Subversion.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os.path
|
||||
|
|
@ -14,7 +14,7 @@ tool definition.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -36,7 +36,7 @@ tool definition.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/__init__.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/__init__.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import imp
|
||||
import sys
|
||||
|
@ -55,6 +55,7 @@ DefaultToolpath=[]
|
|||
CScanner = SCons.Scanner.C.CScanner()
|
||||
DScanner = SCons.Scanner.D.DScanner()
|
||||
LaTeXScanner = SCons.Scanner.LaTeX.LaTeXScanner()
|
||||
PDFLaTeXScanner = SCons.Scanner.LaTeX.PDFLaTeXScanner()
|
||||
ProgramScanner = SCons.Scanner.Prog.ProgramScanner()
|
||||
SourceFileScanner = SCons.Scanner.Base({}, name='SourceFileScanner')
|
||||
|
||||
|
@ -76,8 +77,13 @@ for suffix in CSuffixes:
|
|||
for suffix in DSuffixes:
|
||||
SourceFileScanner.add_scanner(suffix, DScanner)
|
||||
|
||||
# FIXME: what should be done here? Two scanners scan the same extensions,
|
||||
# but look for different files, e.g., "picture.eps" vs. "picture.pdf".
|
||||
# The builders for DVI and PDF explicitly reference their scanners
|
||||
# I think that means this is not needed???
|
||||
for suffix in LaTeXSuffixes:
|
||||
SourceFileScanner.add_scanner(suffix, LaTeXScanner)
|
||||
SourceFileScanner.add_scanner(suffix, LaTeXScanner)
|
||||
SourceFileScanner.add_scanner(suffix, PDFLaTeXScanner)
|
||||
|
||||
class Tool:
|
||||
def __init__(self, name, toolpath=[], **kw):
|
||||
|
@ -136,7 +142,7 @@ class Tool:
|
|||
file.close()
|
||||
return module
|
||||
except ImportError, e:
|
||||
if e!="No module named %s"%self.name:
|
||||
if str(e)!="No module named %s"%self.name:
|
||||
raise SCons.Errors.EnvironmentError, e
|
||||
try:
|
||||
import zipimport
|
||||
|
@ -163,10 +169,10 @@ class Tool:
|
|||
kw = self.init_kw
|
||||
env.Append(TOOLS = [ self.name ])
|
||||
if hasattr(self, 'options'):
|
||||
from SCons.Options import Options
|
||||
import SCons.Variables
|
||||
if not env.has_key('options'):
|
||||
from SCons.Script import ARGUMENTS
|
||||
env['options']=Options(args=ARGUMENTS)
|
||||
env['options']=SCons.Variables.Variables(args=ARGUMENTS)
|
||||
opts=env['options']
|
||||
|
||||
self.options(opts)
|
||||
|
@ -422,32 +428,33 @@ def CreateJavaFileBuilder(env):
|
|||
env['JAVASUFFIX'] = '.java'
|
||||
return java_file
|
||||
|
||||
class ToolInitializer:
|
||||
class ToolInitializerMethod:
|
||||
"""
|
||||
A class for delayed initialization of Tools modules.
|
||||
|
||||
This is intended to be added to a construction environment in
|
||||
place of the method(s) normally called for a Builder (env.Object,
|
||||
env.StaticObject, etc.). When called, it searches the specified
|
||||
list of tools, applies the first one that exists to the construction
|
||||
environment, and calls whatever builder was (presumably) added the
|
||||
construction environment in our place.
|
||||
This is added to a construction environment in place of a
|
||||
method(s) normally called for a Builder (env.Object, env.StaticObject,
|
||||
etc.). When called, it has its associated ToolInitializer
|
||||
object search the specified list of tools and apply the first
|
||||
one that exists to the construction environment. It then calls
|
||||
whatever builder was (presumably) added to the construction
|
||||
environment in place of this particular instance.
|
||||
"""
|
||||
def __init__(self, name, tools):
|
||||
def __init__(self, name, initializer):
|
||||
"""
|
||||
Note: we store the tool name as __name__ so it can be used by
|
||||
the class that attaches this to a construction environment.
|
||||
"""
|
||||
self.__name__ = name
|
||||
if not SCons.Util.is_List(tools):
|
||||
tools = [tools]
|
||||
self.tools = tools
|
||||
def __call__(self, env, *args, **kw):
|
||||
for t in self.tools:
|
||||
tool = SCons.Tool.Tool(t)
|
||||
if tool.exists(env):
|
||||
env.Tool(tool)
|
||||
break
|
||||
self.initializer = initializer
|
||||
|
||||
def get_builder(self, env):
|
||||
"""
|
||||
Returns the appropriate real Builder for this method name
|
||||
after having the associated ToolInitializer object apply
|
||||
the appropriate Tool module.
|
||||
"""
|
||||
builder = getattr(env, self.__name__)
|
||||
|
||||
self.initializer.apply_tools(env)
|
||||
|
||||
builder = getattr(env, self.__name__)
|
||||
if builder is self:
|
||||
|
@ -455,21 +462,79 @@ class ToolInitializer:
|
|||
# for this name was found (or possibly there's a mismatch
|
||||
# between the name we were called by and the Builder name
|
||||
# added by the Tool module).
|
||||
#
|
||||
# (Eventually this is where we'll put a more informative
|
||||
# error message about the inability to find that tool
|
||||
# as cut over more Builders+Tools to using this.
|
||||
return [], []
|
||||
return None
|
||||
|
||||
# Let the construction environment remove the added method
|
||||
# so we no longer copy and re-bind this method when the
|
||||
# construction environment gets cloned.
|
||||
env.RemoveMethod(self)
|
||||
self.initializer.remove_methods(env)
|
||||
|
||||
return builder
|
||||
|
||||
def __call__(self, env, *args, **kw):
|
||||
"""
|
||||
"""
|
||||
builder = self.get_builder(env)
|
||||
if builder is None:
|
||||
return [], []
|
||||
return apply(builder, args, kw)
|
||||
|
||||
class ToolInitializer:
|
||||
"""
|
||||
A class for delayed initialization of Tools modules.
|
||||
|
||||
Instances of this class associate a list of Tool modules with
|
||||
a list of Builder method names that will be added by those Tool
|
||||
modules. As part of instantiating this object for a particular
|
||||
construction environment, we also add the appropriate
|
||||
ToolInitializerMethod objects for the various Builder methods
|
||||
that we want to use to delay Tool searches until necessary.
|
||||
"""
|
||||
def __init__(self, env, tools, names):
|
||||
if not SCons.Util.is_List(tools):
|
||||
tools = [tools]
|
||||
if not SCons.Util.is_List(names):
|
||||
names = [names]
|
||||
self.env = env
|
||||
self.tools = tools
|
||||
self.names = names
|
||||
self.methods = {}
|
||||
for name in names:
|
||||
method = ToolInitializerMethod(name, self)
|
||||
self.methods[name] = method
|
||||
env.AddMethod(method)
|
||||
|
||||
def remove_methods(self, env):
|
||||
"""
|
||||
Removes the methods that were added by the tool initialization
|
||||
so we no longer copy and re-bind them when the construction
|
||||
environment gets cloned.
|
||||
"""
|
||||
for method in self.methods.values():
|
||||
env.RemoveMethod(method)
|
||||
|
||||
def apply_tools(self, env):
|
||||
"""
|
||||
Searches the list of associated Tool modules for one that
|
||||
exists, and applies that to the construction environment.
|
||||
"""
|
||||
for t in self.tools:
|
||||
tool = SCons.Tool.Tool(t)
|
||||
if tool.exists(env):
|
||||
env.Tool(tool)
|
||||
return
|
||||
|
||||
# If we fall through here, there was no tool module found.
|
||||
# This is where we can put an informative error message
|
||||
# about the inability to find the tool. We'll start doing
|
||||
# this as we cut over more pre-defined Builder+Tools to use
|
||||
# the ToolInitializer class.
|
||||
|
||||
def Initializers(env):
|
||||
env.AddMethod(ToolInitializer('Install', 'install'))
|
||||
env.AddMethod(ToolInitializer('InstallAs', 'install'))
|
||||
ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs'])
|
||||
def Install(self, *args, **kw):
|
||||
return apply(self._InternalInstall, args, kw)
|
||||
def InstallAs(self, *args, **kw):
|
||||
return apply(self._InternalInstallAs, args, kw)
|
||||
env.AddMethod(Install)
|
||||
env.AddMethod(InstallAs)
|
||||
|
||||
def FindTool(tools, env):
|
||||
for tool in tools:
|
||||
|
@ -496,7 +561,7 @@ def tool_list(platform, env):
|
|||
c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ]
|
||||
cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'c++', 'bcc32' ]
|
||||
assemblers = ['masm', 'nasm', 'gas', '386asm' ]
|
||||
fortran_compilers = ['g77', 'ifl', 'cvf', 'f95', 'f90', 'fortran']
|
||||
fortran_compilers = ['gfortran', 'g77', 'ifl', 'cvf', 'f95', 'f90', 'fortran']
|
||||
ars = ['mslib', 'ar', 'tlib']
|
||||
elif str(platform) == 'os2':
|
||||
"prefer IBM tools on OS/2"
|
||||
|
@ -520,7 +585,8 @@ def tool_list(platform, env):
|
|||
c_compilers = ['suncc', 'gcc', 'cc']
|
||||
cxx_compilers = ['sunc++', 'g++', 'c++']
|
||||
assemblers = ['as', 'gas']
|
||||
fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran']
|
||||
fortran_compilers = ['sunf95', 'sunf90', 'sunf77', 'f95', 'f90', 'f77',
|
||||
'gfortran', 'g77', 'fortran']
|
||||
ars = ['sunar']
|
||||
elif str(platform) == 'hpux':
|
||||
"prefer aCC tools on HP-UX"
|
||||
|
@ -544,7 +610,7 @@ def tool_list(platform, env):
|
|||
c_compilers = ['gcc', 'cc']
|
||||
cxx_compilers = ['g++', 'c++']
|
||||
assemblers = ['as']
|
||||
fortran_compilers = ['f95', 'f90', 'g77']
|
||||
fortran_compilers = ['gfortran', 'f95', 'f90', 'g77']
|
||||
ars = ['ar']
|
||||
else:
|
||||
"prefer GNU tools on all other platforms"
|
||||
|
@ -552,7 +618,7 @@ def tool_list(platform, env):
|
|||
c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc']
|
||||
cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++']
|
||||
assemblers = ['gas', 'nasm', 'masm']
|
||||
fortran_compilers = ['f95', 'f90', 'g77', 'ifort', 'ifl', 'fortran']
|
||||
fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77']
|
||||
ars = ['ar', 'mslib']
|
||||
|
||||
c_compiler = FindTool(c_compilers, env) or c_compilers[0]
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/aixc++.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/aixc++.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os.path
|
||||
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/aixcc.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/aixcc.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os.path
|
||||
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/aixf77.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/aixf77.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os.path
|
||||
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/aixlink.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/aixlink.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os
|
||||
import os.path
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,23 +31,25 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/applelink.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/applelink.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Util
|
||||
|
||||
import gnulink
|
||||
# Even though the Mac is based on the GNU toolchain, it doesn't understand
|
||||
# the -rpath option, so we use the "link" tool instead of "gnulink".
|
||||
import link
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for applelink to an
|
||||
Environment."""
|
||||
gnulink.generate(env)
|
||||
link.generate(env)
|
||||
|
||||
env['FRAMEWORKPATHPREFIX'] = '-F'
|
||||
env['_FRAMEWORKPATH'] = '${_concat(FRAMEWORKPATHPREFIX, FRAMEWORKPATH, "", __env__)}'
|
||||
env['_FRAMEWORKS'] = '${_concat("-framework ", FRAMEWORKS, "", __env__)}'
|
||||
env['LINKCOM'] = env['LINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS'
|
||||
env['LINKCOM'] = env['LINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS'
|
||||
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -dynamiclib')
|
||||
env['SHLINKCOM'] = env['SHLINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS'
|
||||
env['SHLINKCOM'] = env['SHLINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS'
|
||||
|
||||
# override the default for loadable modules, which are different
|
||||
# on OS X than dynamic shared libs. echoing what XCode does for
|
||||
|
@ -60,5 +62,4 @@ def generate(env):
|
|||
|
||||
|
||||
def exists(env):
|
||||
import sys
|
||||
return sys.platform == 'darwin'
|
||||
return env['PLATFORM'] == 'darwin'
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/ar.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/ar.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Defaults
|
||||
import SCons.Tool
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/as.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/as.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Defaults
|
||||
import SCons.Tool
|
||||
|
@ -40,7 +40,7 @@ import SCons.Util
|
|||
assemblers = ['as']
|
||||
|
||||
ASSuffixes = ['.s', '.asm', '.ASM']
|
||||
ASPPSuffixes = ['.spp', '.SPP']
|
||||
ASPPSuffixes = ['.spp', '.SPP', '.sx']
|
||||
if SCons.Util.case_sensitive_suffixes('.s', '.S'):
|
||||
ASPPSuffixes.extend(['.S'])
|
||||
else:
|
|
@ -5,7 +5,7 @@ XXX
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ XXX
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/bcc32.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/bcc32.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os
|
||||
import os.path
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/c++.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/c++.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os.path
|
||||
|
||||
|
@ -73,11 +73,11 @@ def generate(env):
|
|||
SCons.Tool.cc.add_common_cc_variables(env)
|
||||
|
||||
env['CXX'] = 'c++'
|
||||
env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
|
||||
env['CXXCOM'] = '$CXX -o $TARGET -c $CXXFLAGS $_CCCOMCOM $SOURCES'
|
||||
env['CXXFLAGS'] = SCons.Util.CLVar('')
|
||||
env['CXXCOM'] = '$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS $_CCCOMCOM $SOURCES'
|
||||
env['SHCXX'] = '$CXX'
|
||||
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
|
||||
env['SHCXXCOM'] = '$SHCXX -o $TARGET -c $SHCXXFLAGS $_CCCOMCOM $SOURCES'
|
||||
env['SHCXXCOM'] = '$SHCXX -o $TARGET -c $SHCXXFLAGS $SHCCFLAGS $_CCCOMCOM $SOURCES'
|
||||
|
||||
env['CPPDEFPREFIX'] = '-D'
|
||||
env['CPPDEFSUFFIX'] = ''
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/cc.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/cc.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Tool
|
||||
import SCons.Defaults
|
|
@ -5,7 +5,7 @@ Tool-specific initialization for the Compaq Visual Fortran compiler.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ Tool-specific initialization for the Compaq Visual Fortran compiler.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/cvf.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/cvf.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import fortran
|
||||
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/default.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/default.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Tool
|
||||
|
|
@ -14,14 +14,15 @@ use absolute paths. To hack around it, add '#/blah'. This will link
|
|||
blah.lib from the directory where SConstruct resides.
|
||||
|
||||
Compiler variables:
|
||||
DC - The name of the D compiler to use. Defaults to dmd.
|
||||
DC - The name of the D compiler to use. Defaults to dmd or gdmd,
|
||||
whichever is found.
|
||||
DPATH - List of paths to search for import modules.
|
||||
DVERSIONS - List of version tags to enable when compiling.
|
||||
DDEBUG - List of debug tags to enable when compiling.
|
||||
|
||||
Linker related variables:
|
||||
LIBS - List of library files to link in.
|
||||
DLINK - Name of the linker to use. Defaults to dmd.
|
||||
DLINK - Name of the linker to use. Defaults to dmd or gdmd.
|
||||
DLINKFLAGS - List of linker flags.
|
||||
|
||||
Lib tool variables:
|
||||
|
@ -31,7 +32,7 @@ Lib tool variables:
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -53,7 +54,7 @@ Lib tool variables:
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/dmd.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/dmd.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os
|
||||
import string
|
||||
|
@ -93,7 +94,8 @@ def generate(env):
|
|||
static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter)
|
||||
shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter)
|
||||
|
||||
env['DC'] = 'dmd'
|
||||
dc = env.Detect(['dmd', 'gdmd'])
|
||||
env['DC'] = dc
|
||||
env['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -of$TARGET $SOURCES'
|
||||
env['_DINCFLAGS'] = '$( ${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||
env['_DVERFLAGS'] = '$( ${_concat(DVERPREFIX, DVERSIONS, DVERSUFFIX, __env__)} $)'
|
||||
|
@ -105,14 +107,15 @@ def generate(env):
|
|||
env['DVERSIONS'] = []
|
||||
env['DDEBUG'] = []
|
||||
|
||||
# Add the path to the standard library.
|
||||
# This is merely for the convenience of the dependency scanner.
|
||||
dmd_path = env.WhereIs('dmd')
|
||||
if dmd_path:
|
||||
x = string.rindex(dmd_path, 'dmd')
|
||||
phobosDir = dmd_path[:x] + '/../src/phobos'
|
||||
if os.path.isdir(phobosDir):
|
||||
env.Append(DPATH = [phobosDir])
|
||||
if dc:
|
||||
# Add the path to the standard library.
|
||||
# This is merely for the convenience of the dependency scanner.
|
||||
dmd_path = env.WhereIs(dc)
|
||||
if dmd_path:
|
||||
x = string.rindex(dmd_path, dc)
|
||||
phobosDir = dmd_path[:x] + '/../src/phobos'
|
||||
if os.path.isdir(phobosDir):
|
||||
env.Append(DPATH = [phobosDir])
|
||||
|
||||
env['DINCPREFIX'] = '-I'
|
||||
env['DINCSUFFIX'] = ''
|
||||
|
@ -191,14 +194,17 @@ def generate(env):
|
|||
env['SMART_LINKCOM'] = smart_link[linkcom]
|
||||
except KeyError:
|
||||
def _smartLink(source, target, env, for_signature,
|
||||
defaultLinker=linkcom):
|
||||
defaultLinker=linkcom, dc=dc):
|
||||
if isD(source):
|
||||
try:
|
||||
libs = env['LIBS']
|
||||
except KeyError:
|
||||
libs = []
|
||||
if 'phobos' not in libs:
|
||||
env.Append(LIBS = ['phobos'])
|
||||
if dc is 'dmd':
|
||||
env.Append(LIBS = ['phobos'])
|
||||
elif dc is 'gdmd':
|
||||
env.Append(LIBS = ['gphobos'])
|
||||
if 'pthread' not in libs:
|
||||
env.Append(LIBS = ['pthread'])
|
||||
if 'm' not in libs:
|
||||
|
@ -209,4 +215,4 @@ def generate(env):
|
|||
env['LINKCOM'] = '$SMART_LINKCOM '
|
||||
|
||||
def exists(env):
|
||||
return env.Detect('dmd')
|
||||
return env.Detect(['dmd', 'gdmd'])
|
|
@ -5,7 +5,7 @@ Common DVI Builder definition for various other Tool modules that use it.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ Common DVI Builder definition for various other Tool modules that use it.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/dvi.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/dvi.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Builder
|
||||
import SCons.Tool
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,14 +31,54 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/dvipdf.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/dvipdf.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Defaults
|
||||
import SCons.Tool.pdf
|
||||
import SCons.Tool.tex
|
||||
import SCons.Util
|
||||
|
||||
_null = SCons.Scanner.LaTeX._null
|
||||
|
||||
def DviPdfPsFunction(XXXDviAction, target = None, source= None, env=None):
|
||||
"""A builder for DVI files that sets the TEXPICTS environment
|
||||
variable before running dvi2ps or dvipdf."""
|
||||
|
||||
try:
|
||||
abspath = source[0].attributes.path
|
||||
except AttributeError :
|
||||
abspath = ''
|
||||
|
||||
saved_env = SCons.Scanner.LaTeX.modify_env_var(env, 'TEXPICTS', abspath)
|
||||
|
||||
result = XXXDviAction(target, source, env)
|
||||
|
||||
if saved_env is _null:
|
||||
try:
|
||||
del env['ENV']['TEXPICTS']
|
||||
except KeyError:
|
||||
pass # was never set
|
||||
else:
|
||||
env['ENV']['TEXPICTS'] = saved_env
|
||||
|
||||
return result
|
||||
|
||||
def DviPdfFunction(target = None, source= None, env=None):
|
||||
result = DviPdfPsFunction(PDFAction,target,source,env)
|
||||
return result
|
||||
|
||||
def DviPdfStrFunction(target = None, source= None, env=None):
|
||||
"""A strfunction for dvipdf that returns the appropriate
|
||||
command string for the no_exec options."""
|
||||
if env.GetOption("no_exec"):
|
||||
result = env.subst('$DVIPDFCOM',0,target,source)
|
||||
else:
|
||||
result = ''
|
||||
return result
|
||||
|
||||
PDFAction = None
|
||||
DVIPDFAction = None
|
||||
|
||||
def PDFEmitter(target, source, env):
|
||||
"""Strips any .aux or .log files from the input source list.
|
||||
|
@ -57,11 +97,15 @@ def generate(env):
|
|||
if PDFAction is None:
|
||||
PDFAction = SCons.Action.Action('$DVIPDFCOM', '$DVIPDFCOMSTR')
|
||||
|
||||
global DVIPDFAction
|
||||
if DVIPDFAction is None:
|
||||
DVIPDFAction = SCons.Action.Action(DviPdfFunction, strfunction = DviPdfStrFunction)
|
||||
|
||||
import pdf
|
||||
pdf.generate(env)
|
||||
|
||||
bld = env['BUILDERS']['PDF']
|
||||
bld.add_action('.dvi', PDFAction)
|
||||
bld.add_action('.dvi', DVIPDFAction)
|
||||
bld.add_emitter('.dvi', PDFEmitter)
|
||||
|
||||
env['DVIPDF'] = 'dvipdf'
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,13 +31,28 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/dvips.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/dvips.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
||||
import SCons.Tool.dvipdf
|
||||
import SCons.Util
|
||||
|
||||
def DviPsFunction(target = None, source= None, env=None):
|
||||
result = SCons.Tool.dvipdf.DviPdfPsFunction(PSAction,target,source,env)
|
||||
return result
|
||||
|
||||
def DviPsStrFunction(target = None, source= None, env=None):
|
||||
"""A strfunction for dvipdf that returns the appropriate
|
||||
command string for the no_exec options."""
|
||||
if env.GetOption("no_exec"):
|
||||
result = env.subst('$PSCOM',0,target,source)
|
||||
else:
|
||||
result = ''
|
||||
return result
|
||||
|
||||
PSAction = None
|
||||
DVIPSAction = None
|
||||
PSBuilder = None
|
||||
|
||||
def generate(env):
|
||||
|
@ -46,19 +61,24 @@ def generate(env):
|
|||
if PSAction is None:
|
||||
PSAction = SCons.Action.Action('$PSCOM', '$PSCOMSTR')
|
||||
|
||||
global DVIPSAction
|
||||
if DVIPSAction is None:
|
||||
DVIPSAction = SCons.Action.Action(DviPsFunction, strfunction = DviPsStrFunction)
|
||||
|
||||
global PSBuilder
|
||||
if PSBuilder is None:
|
||||
PSBuilder = SCons.Builder.Builder(action = PSAction,
|
||||
prefix = '$PSPREFIX',
|
||||
suffix = '$PSSUFFIX',
|
||||
src_suffix = '.dvi',
|
||||
src_builder = 'DVI')
|
||||
src_builder = 'DVI',
|
||||
single_source=True)
|
||||
|
||||
env['BUILDERS']['PostScript'] = PSBuilder
|
||||
|
||||
env['DVIPS'] = 'dvips'
|
||||
env['DVIPSFLAGS'] = SCons.Util.CLVar('')
|
||||
# I'm not quite sure I got the directories and filenames right for build_dir
|
||||
# I'm not quite sure I got the directories and filenames right for variant_dir
|
||||
# We need to be in the correct directory for the sake of latex \includegraphics eps included files.
|
||||
env['PSCOM'] = 'cd ${TARGET.dir} && $DVIPS $DVIPSFLAGS -o ${TARGET.file} ${SOURCE.file}'
|
||||
env['PSPREFIX'] = ''
|
56
scons/scons-local-1.2.0/SCons/Tool/f77.py
Normal file
56
scons/scons-local-1.2.0/SCons/Tool/f77.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
"""engine.SCons.Tool.f77
|
||||
|
||||
Tool-specific initialization for the generic Posix f77 Fortran compiler.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/f77.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Defaults
|
||||
import SCons.Scanner.Fortran
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env
|
||||
|
||||
compilers = ['f77']
|
||||
|
||||
def generate(env):
|
||||
add_all_to_env(env)
|
||||
add_f77_to_env(env)
|
||||
|
||||
fcomp = env.Detect(compilers) or 'f77'
|
||||
env['F77'] = fcomp
|
||||
env['SHF77'] = fcomp
|
||||
|
||||
env['FORTRAN'] = fcomp
|
||||
env['SHFORTRAN'] = fcomp
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
|
@ -1,6 +1,6 @@
|
|||
"""engine.SCons.Tool.g77
|
||||
"""engine.SCons.Tool.f90
|
||||
|
||||
Tool-specific initialization for g77.
|
||||
Tool-specific initialization for the generic Posix f90 Fortran compiler.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,17 +31,26 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/g77.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/f90.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import f77
|
||||
import SCons.Defaults
|
||||
import SCons.Scanner.Fortran
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
from SCons.Tool.FortranCommon import add_all_to_env, add_f90_to_env
|
||||
|
||||
compilers = ['g77', 'f77']
|
||||
compilers = ['f90']
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for g77 to an Environment."""
|
||||
f77.generate(env)
|
||||
add_all_to_env(env)
|
||||
add_f90_to_env(env)
|
||||
|
||||
env['_FORTRAND'] = env.Detect(compilers) or 'g77'
|
||||
fc = env.Detect(compilers) or 'f90'
|
||||
env['F90'] = fc
|
||||
env['SHF90'] = fc
|
||||
|
||||
env['FORTRAN'] = fc
|
||||
env['SHFORTRAN'] = fc
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
57
scons/scons-local-1.2.0/SCons/Tool/f95.py
Normal file
57
scons/scons-local-1.2.0/SCons/Tool/f95.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
"""engine.SCons.Tool.f95
|
||||
|
||||
Tool-specific initialization for the generic Posix f95 Fortran compiler.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/f95.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Defaults
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
import fortran
|
||||
from SCons.Tool.FortranCommon import add_all_to_env, add_f95_to_env
|
||||
|
||||
compilers = ['f95']
|
||||
|
||||
def generate(env):
|
||||
add_all_to_env(env)
|
||||
add_f95_to_env(env)
|
||||
|
||||
fcomp = env.Detect(compilers) or 'f95'
|
||||
env['F95'] = fcomp
|
||||
env['SHF95'] = fcomp
|
||||
|
||||
env['FORTRAN'] = fcomp
|
||||
env['SHFORTRAN'] = fcomp
|
||||
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/filesystem.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/filesystem.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons
|
||||
from SCons.Tool.install import copyFunc
|
57
scons/scons-local-1.2.0/SCons/Tool/fortran.py
Normal file
57
scons/scons-local-1.2.0/SCons/Tool/fortran.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
"""SCons.Tool.fortran
|
||||
|
||||
Tool-specific initialization for a generic Posix f77/f90 Fortran compiler.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/fortran.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import re
|
||||
import string
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Defaults
|
||||
import SCons.Scanner.Fortran
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
from SCons.Tool.FortranCommon import add_all_to_env, add_fortran_to_env
|
||||
|
||||
compilers = ['f95', 'f90', 'f77']
|
||||
|
||||
def generate(env):
|
||||
add_all_to_env(env)
|
||||
add_fortran_to_env(env)
|
||||
|
||||
fc = env.Detect(compilers) or 'f77'
|
||||
env['SHFORTRAN'] = fc
|
||||
env['FORTRAN'] = fc
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,12 +31,12 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/g++.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/g++.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import os.path
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
import SCons.Defaults
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
|
||||
|
@ -53,35 +53,32 @@ def generate(env):
|
|||
env['CXX'] = env.Detect(compilers)
|
||||
|
||||
# platform specific settings
|
||||
if env['PLATFORM'] == 'cygwin':
|
||||
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
|
||||
elif env['PLATFORM'] == 'aix':
|
||||
# Original line from Christian Engel added -DPIC:
|
||||
#env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -DPIC -mminimal-toc')
|
||||
if env['PLATFORM'] == 'aix':
|
||||
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -mminimal-toc')
|
||||
env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
|
||||
env['SHOBJSUFFIX'] = '$OBJSUFFIX'
|
||||
elif env['PLATFORM'] == 'hpux':
|
||||
# Original line from Christian Engel added -DPIC:
|
||||
#env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -fPIC -DPIC')
|
||||
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -fPIC')
|
||||
env['SHOBJSUFFIX'] = '.pic.o'
|
||||
elif env['PLATFORM'] == 'sunos':
|
||||
# Original line from Christian Engel added -DPIC:
|
||||
#env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -fPIC -DPIC')
|
||||
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -fPIC')
|
||||
env['SHOBJSUFFIX'] = '.pic.o'
|
||||
else:
|
||||
# Original line from Christian Engel added -DPIC:
|
||||
#env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -fPIC -DPIC')
|
||||
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -fPIC')
|
||||
# determine compiler version
|
||||
if env['CXX']:
|
||||
line = os.popen(env['CXX'] + ' --version').readline()
|
||||
#pipe = SCons.Action._subproc(env, [env['CXX'], '-dumpversion'],
|
||||
pipe = SCons.Action._subproc(env, [env['CXX'], '--version'],
|
||||
stdin = 'devnull',
|
||||
stderr = 'devnull',
|
||||
stdout = subprocess.PIPE)
|
||||
if pipe.wait() != 0: return
|
||||
# -dumpversion was added in GCC 3.0. As long as we're supporting
|
||||
# GCC versions older than that, we should use --version and a
|
||||
# regular expression.
|
||||
#line = pipe.stdout.read().strip()
|
||||
#if line:
|
||||
# env['CXXVERSION'] = line
|
||||
line = pipe.stdout.readline()
|
||||
match = re.search(r'[0-9]+(\.[0-9]+)+', line)
|
||||
if match:
|
||||
env['CXXVERSION'] = match.group(0)
|
||||
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
67
scons/scons-local-1.2.0/SCons/Tool/g77.py
Normal file
67
scons/scons-local-1.2.0/SCons/Tool/g77.py
Normal file
|
@ -0,0 +1,67 @@
|
|||
"""engine.SCons.Tool.g77
|
||||
|
||||
Tool-specific initialization for g77.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/g77.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Util
|
||||
from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env
|
||||
|
||||
compilers = ['g77', 'f77']
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for g77 to an Environment."""
|
||||
add_all_to_env(env)
|
||||
add_f77_to_env(env)
|
||||
|
||||
fcomp = env.Detect(compilers) or 'g77'
|
||||
if env['PLATFORM'] in ['cygwin', 'win32']:
|
||||
env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS')
|
||||
env['SHF77FLAGS'] = SCons.Util.CLVar('$F77FLAGS')
|
||||
else:
|
||||
env['SHFORTRANFLAGS'] = SCons.Util.CLVar('$FORTRANFLAGS -fPIC')
|
||||
env['SHF77FLAGS'] = SCons.Util.CLVar('$F77FLAGS -fPIC')
|
||||
|
||||
env['FORTRAN'] = fcomp
|
||||
env['SHFORTRAN'] = '$FORTRAN'
|
||||
|
||||
env['F77'] = fcomp
|
||||
env['SHF77'] = '$F77'
|
||||
|
||||
env['INCFORTRANPREFIX'] = "-I"
|
||||
env['INCFORTRANSUFFIX'] = ""
|
||||
|
||||
env['INCF77PREFIX'] = "-I"
|
||||
env['INCF77SUFFIX'] = ""
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/gas.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/gas.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
as_module = __import__('as', globals(), locals(), [])
|
||||
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,13 +31,14 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/gcc.py 2523 2007/12/12 09:37:41 knight"
|
||||
|
||||
import SCons.Util
|
||||
__revision__ = "src/engine/SCons/Tool/gcc.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import cc
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
import SCons.Util
|
||||
|
||||
compilers = ['gcc', 'cc']
|
||||
|
||||
|
@ -52,7 +53,19 @@ def generate(env):
|
|||
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC')
|
||||
# determine compiler version
|
||||
if env['CC']:
|
||||
line = os.popen(env['CC'] + ' --version').readline()
|
||||
#pipe = SCons.Action._subproc(env, [env['CC'], '-dumpversion'],
|
||||
pipe = SCons.Action._subproc(env, [env['CC'], '--version'],
|
||||
stdin = 'devnull',
|
||||
stderr = 'devnull',
|
||||
stdout = subprocess.PIPE)
|
||||
if pipe.wait() != 0: return
|
||||
# -dumpversion was added in GCC 3.0. As long as we're supporting
|
||||
# GCC versions older than that, we should use --version and a
|
||||
# regular expression.
|
||||
#line = pipe.stdout.read().strip()
|
||||
#if line:
|
||||
# env['CCVERSION'] = line
|
||||
line = pipe.stdout.readline()
|
||||
match = re.search(r'[0-9]+(\.[0-9]+)+', line)
|
||||
if match:
|
||||
env['CCVERSION'] = match.group(0)
|
58
scons/scons-local-1.2.0/SCons/Tool/gfortran.py
Normal file
58
scons/scons-local-1.2.0/SCons/Tool/gfortran.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
"""SCons.Tool.gfortran
|
||||
|
||||
Tool-specific initialization for gfortran, the GNU Fortran 95/Fortran
|
||||
2003 compiler.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/gfortran.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Util
|
||||
|
||||
import fortran
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for gfortran to an
|
||||
Environment."""
|
||||
fortran.generate(env)
|
||||
|
||||
for dialect in ['F77', 'F90', 'FORTRAN', 'F95']:
|
||||
env['%s' % dialect] = 'gfortran'
|
||||
env['SH%s' % dialect] = '$%s' % dialect
|
||||
if env['PLATFORM'] in ['cygwin', 'win32']:
|
||||
env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS' % dialect)
|
||||
else:
|
||||
env['SH%sFLAGS' % dialect] = SCons.Util.CLVar('$%sFLAGS -fPIC' % dialect)
|
||||
|
||||
env['INC%sPREFIX' % dialect] = "-I"
|
||||
env['INC%sSUFFIX' % dialect] = ""
|
||||
|
||||
def exists(env):
|
||||
return env.Detect('gfortran')
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/gnulink.py 2523 2007/12/12 09:37:41 knight"
|
||||
__revision__ = "src/engine/SCons/Tool/gnulink.py 3842 2008/12/20 22:59:52 scons"
|
||||
|
||||
import SCons.Util
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue