+ 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:
|
# All of the following options may be modified at the command-line, for example:
|
||||||
# `python scons/scons PREFIX=/opt`
|
# `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('CXX', 'The C++ compiler to use (defaults to g++).', 'g++')
|
||||||
opts.Add('PREFIX', 'The install path "prefix"', '/usr/local')
|
opts.Add('PREFIX', 'The install path "prefix"', '/usr/local')
|
||||||
opts.Add(PathOption('BOOST_INCLUDES', 'Search path for boost include files', '/usr/include'))
|
opts.Add(PathVariable('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_LIBS', 'Search path for boost library files', '/usr/' + LIBDIR_SCHEMA))
|
||||||
opts.Add('BOOST_TOOLKIT','Specify boost toolkit, e.g., gcc41.','',False)
|
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_ABI', 'Specify boost ABI, e.g., d.','',False)
|
||||||
opts.Add('BOOST_VERSION','Specify boost version, e.g., 1_35.','',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(('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(('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(PathVariable('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(PathVariable('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(PathVariable('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(PathVariable('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(PathVariable('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(PathVariable('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(PathVariable('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(PathVariable('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(PathVariable('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(PathVariable('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(PathVariable('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(PathVariable('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(PathVariable('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(PathVariable('GDAL_LIBS', 'Search path for GDAL library files', '/usr/' + LIBDIR_SCHEMA))
|
||||||
opts.Add(PathOption('PYTHON','Python executable', sys.executable))
|
opts.Add(PathVariable('PYTHON','Python executable', sys.executable))
|
||||||
opts.Add(ListOption('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster','gdal']))
|
opts.Add(ListVariable('INPUT_PLUGINS','Input drivers to include','all',['postgis','shape','raster','gdal']))
|
||||||
opts.Add(ListOption('BINDINGS','Language bindings to build','all',['python']))
|
opts.Add(ListVariable('BINDINGS','Language bindings to build','all',['python']))
|
||||||
opts.Add(BoolOption('DEBUG', 'Compile a debug version of mapnik', 'False'))
|
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('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(EnumVariable('THREADING','Set threading support','multi', ['multi','single']))
|
||||||
opts.Add(EnumOption('XMLPARSER','Set xml parser ','tinyxml', ['tinyxml','spirit','libxml2']))
|
opts.Add(EnumVariable('XMLPARSER','Set xml parser ','tinyxml', ['tinyxml','spirit','libxml2']))
|
||||||
opts.Add(BoolOption('INTERNAL_LIBAGG', 'Use provided libagg', 'True'))
|
opts.Add(BoolVariable('INTERNAL_LIBAGG', 'Use provided libagg', 'True'))
|
||||||
|
|
||||||
env = Environment(ENV=os.environ, options=opts)
|
env = Environment(ENV=os.environ, options=opts)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
This copyright and license do not apply to any other software
|
This copyright and license do not apply to any other software
|
||||||
with which this software may have been included.
|
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
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
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
|
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.
|
a pre-substitution command for debugging purposes.
|
||||||
|
|
||||||
get_contents()
|
get_contents()
|
||||||
Fetches the "contents" of an Action for signature calculation.
|
Fetches the "contents" of an Action for signature calculation
|
||||||
This is what gets MD5 checksumm'ed to decide if a target needs
|
plus the varlist. This is what gets MD5 checksummed to decide
|
||||||
to be rebuilt because its action changed.
|
if a target needs to be rebuilt because its action changed.
|
||||||
|
|
||||||
genstring()
|
genstring()
|
||||||
Returns a string representation of the Action *without*
|
Returns a string representation of the Action *without*
|
||||||
|
@ -57,6 +57,10 @@ this module:
|
||||||
pre-substitution representations, and *then* execute an action
|
pre-substitution representations, and *then* execute an action
|
||||||
without worrying about the specific Actions involved.
|
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()
|
strfunction()
|
||||||
Returns a substituted string representation of the Action.
|
Returns a substituted string representation of the Action.
|
||||||
This is used by the _ActionAction.show() command to display the
|
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, 2008 The SCons Foundation
|
||||||
# Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 The SCons Foundation
|
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# 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 dis
|
||||||
import os
|
import os
|
||||||
import os.path
|
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
|
import subprocess
|
||||||
|
|
||||||
from SCons.Debug import logInstanceCreation
|
from SCons.Debug import logInstanceCreation
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
import SCons.Executor
|
import SCons.Executor
|
||||||
import SCons.Util
|
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
|
pass
|
||||||
|
|
||||||
_null = _Null
|
|
||||||
|
|
||||||
print_actions = 1
|
print_actions = 1
|
||||||
execute_actions = 1
|
execute_actions = 1
|
||||||
print_actions_presub = 0
|
print_actions_presub = 0
|
||||||
|
|
||||||
default_ENV = None
|
|
||||||
|
|
||||||
def rfile(n):
|
def rfile(n):
|
||||||
try:
|
try:
|
||||||
return n.rfile()
|
return n.rfile()
|
||||||
|
@ -150,6 +154,141 @@ else:
|
||||||
i = i+1
|
i = i+1
|
||||||
return string.join(result, '')
|
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):
|
def _actionAppend(act1, act2):
|
||||||
# This function knows how to slap two actions together.
|
# This function knows how to slap two actions together.
|
||||||
# Mainly, it handles ListActions by concatenating into
|
# Mainly, it handles ListActions by concatenating into
|
||||||
|
@ -169,7 +308,34 @@ def _actionAppend(act1, act2):
|
||||||
else:
|
else:
|
||||||
return ListAction([ a1, a2 ])
|
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
|
"""This is the actual "implementation" for the
|
||||||
Action factory method, below. This handles the
|
Action factory method, below. This handles the
|
||||||
fact that passing lists to Action() itself has
|
fact that passing lists to Action() itself has
|
||||||
|
@ -182,8 +348,11 @@ def _do_create_action(act, *args, **kw):
|
||||||
|
|
||||||
if isinstance(act, ActionBase):
|
if isinstance(act, ActionBase):
|
||||||
return act
|
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):
|
if callable(act):
|
||||||
try:
|
try:
|
||||||
gen = kw['generator']
|
gen = kw['generator']
|
||||||
|
@ -194,8 +363,9 @@ def _do_create_action(act, *args, **kw):
|
||||||
action_type = CommandGeneratorAction
|
action_type = CommandGeneratorAction
|
||||||
else:
|
else:
|
||||||
action_type = FunctionAction
|
action_type = FunctionAction
|
||||||
return apply(action_type, (act,)+args, kw)
|
return action_type(act, kw)
|
||||||
if SCons.Util.is_String(act):
|
|
||||||
|
if is_String(act):
|
||||||
var=SCons.Util.get_environment_var(act)
|
var=SCons.Util.get_environment_var(act)
|
||||||
if var:
|
if var:
|
||||||
# This looks like a string that is purely an Environment
|
# 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
|
# of that Environment variable, so a user could put something
|
||||||
# like a function or a CommandGenerator in that variable
|
# like a function or a CommandGenerator in that variable
|
||||||
# instead of a string.
|
# instead of a string.
|
||||||
return apply(LazyAction, (var,)+args, kw)
|
return LazyAction(var, kw)
|
||||||
commands = string.split(str(act), '\n')
|
commands = string.split(str(act), '\n')
|
||||||
if len(commands) == 1:
|
if len(commands) == 1:
|
||||||
return apply(CommandAction, (commands[0],)+args, kw)
|
#TODO(1.5) return CommandAction(commands[0], **kw)
|
||||||
else:
|
return apply(CommandAction, (commands[0],), kw)
|
||||||
listCmdActions = map(lambda x, args=args, kw=kw:
|
# The list of string commands may include a LazyAction, so we
|
||||||
apply(CommandAction, (x,)+args, kw),
|
# reprocess them via _do_create_list_action.
|
||||||
commands)
|
return _do_create_list_action(commands, kw)
|
||||||
return ListAction(listCmdActions)
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def Action(act, *args, **kw):
|
def _do_create_list_action(act, kw):
|
||||||
"""A factory for action objects."""
|
"""A factory for list actions. Convert the input list into Actions
|
||||||
if SCons.Util.is_List(act):
|
and then wrap them in a ListAction."""
|
||||||
acts = map(lambda a, args=args, kw=kw:
|
acts = []
|
||||||
apply(_do_create_action, (a,)+args, kw),
|
for a in act:
|
||||||
act)
|
aa = _do_create_action(a, kw)
|
||||||
acts = filter(None, acts)
|
if aa is not None: acts.append(aa)
|
||||||
if len(acts) == 1:
|
if not acts:
|
||||||
|
return None
|
||||||
|
elif len(acts) == 1:
|
||||||
return acts[0]
|
return acts[0]
|
||||||
else:
|
else:
|
||||||
return ListAction(acts)
|
return ListAction(acts)
|
||||||
else:
|
|
||||||
return apply(_do_create_action, (act,)+args, kw)
|
def Action(act, *args, **kw):
|
||||||
|
"""A factory for action objects."""
|
||||||
|
# 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:
|
class ActionBase:
|
||||||
"""Base class for all types of action objects that can be held by
|
"""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):
|
def genstring(self, target, source, env):
|
||||||
return str(self)
|
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):
|
def __add__(self, other):
|
||||||
return _actionAppend(self, other)
|
return _actionAppend(self, other)
|
||||||
|
|
||||||
|
@ -265,9 +453,16 @@ class ActionBase:
|
||||||
|
|
||||||
class _ActionAction(ActionBase):
|
class _ActionAction(ActionBase):
|
||||||
"""Base class for actions that create output objects."""
|
"""Base class for actions that create output objects."""
|
||||||
def __init__(self, strfunction=_null, presub=_null, chdir=None, exitstatfunc=None, **kw):
|
def __init__(self, cmdstr=_null, strfunction=_null, varlist=(),
|
||||||
if not strfunction is _null:
|
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.strfunction = strfunction
|
||||||
|
self.varlist = varlist
|
||||||
self.presub = presub
|
self.presub = presub
|
||||||
self.chdir = chdir
|
self.chdir = chdir
|
||||||
if not exitstatfunc:
|
if not exitstatfunc:
|
||||||
|
@ -283,16 +478,16 @@ class _ActionAction(ActionBase):
|
||||||
show=_null,
|
show=_null,
|
||||||
execute=_null,
|
execute=_null,
|
||||||
chdir=_null):
|
chdir=_null):
|
||||||
if not SCons.Util.is_List(target):
|
if not is_List(target):
|
||||||
target = [target]
|
target = [target]
|
||||||
if not SCons.Util.is_List(source):
|
if not is_List(source):
|
||||||
source = [source]
|
source = [source]
|
||||||
|
|
||||||
if exitstatfunc is _null: exitstatfunc = self.exitstatfunc
|
|
||||||
if presub is _null:
|
if presub is _null:
|
||||||
presub = self.presub
|
presub = self.presub
|
||||||
if presub is _null:
|
if presub is _null:
|
||||||
presub = print_actions_presub
|
presub = print_actions_presub
|
||||||
|
if exitstatfunc is _null: exitstatfunc = self.exitstatfunc
|
||||||
if show is _null: show = print_actions
|
if show is _null: show = print_actions
|
||||||
if execute is _null: execute = execute_actions
|
if execute is _null: execute = execute_actions
|
||||||
if chdir is _null: chdir = self.chdir
|
if chdir is _null: chdir = self.chdir
|
||||||
|
@ -302,19 +497,19 @@ class _ActionAction(ActionBase):
|
||||||
try:
|
try:
|
||||||
chdir = str(chdir.abspath)
|
chdir = str(chdir.abspath)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
if not SCons.Util.is_String(chdir):
|
if not is_String(chdir):
|
||||||
chdir = str(target[0].dir)
|
chdir = str(target[0].dir)
|
||||||
if presub:
|
if presub:
|
||||||
t = string.join(map(str, target), ' and ')
|
t = string.join(map(str, target), ' and ')
|
||||||
l = string.join(self.presub_lines(env), '\n ')
|
l = string.join(self.presub_lines(env), '\n ')
|
||||||
out = "Building %s with action:\n %s\n" % (t, l)
|
out = "Building %s with action:\n %s\n" % (t, l)
|
||||||
sys.stdout.write(out)
|
sys.stdout.write(out)
|
||||||
s = None
|
cmd = None
|
||||||
if show and self.strfunction:
|
if show and self.strfunction:
|
||||||
s = self.strfunction(target, source, env)
|
cmd = self.strfunction(target, source, env)
|
||||||
if s:
|
if cmd:
|
||||||
if chdir:
|
if chdir:
|
||||||
s = ('os.chdir(%s)\n' % repr(chdir)) + s
|
cmd = ('os.chdir(%s)\n' % repr(chdir)) + cmd
|
||||||
try:
|
try:
|
||||||
get = env.get
|
get = env.get
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -323,7 +518,7 @@ class _ActionAction(ActionBase):
|
||||||
print_func = get('PRINT_CMD_LINE_FUNC')
|
print_func = get('PRINT_CMD_LINE_FUNC')
|
||||||
if not print_func:
|
if not print_func:
|
||||||
print_func = self.print_cmd_line
|
print_func = self.print_cmd_line
|
||||||
print_func(s, target, source, env)
|
print_func(cmd, target, source, env)
|
||||||
stat = 0
|
stat = 0
|
||||||
if execute:
|
if execute:
|
||||||
if chdir:
|
if chdir:
|
||||||
|
@ -341,7 +536,7 @@ class _ActionAction(ActionBase):
|
||||||
finally:
|
finally:
|
||||||
if save_cwd:
|
if save_cwd:
|
||||||
os.chdir(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)
|
print_func('os.chdir(%s)' % repr(save_cwd), target, source, env)
|
||||||
|
|
||||||
return stat
|
return stat
|
||||||
|
@ -357,9 +552,87 @@ def _string_from_cmd_list(cmd_list):
|
||||||
cl.append(arg)
|
cl.append(arg)
|
||||||
return string.join(cl)
|
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 CommandAction(_ActionAction):
|
||||||
"""Class for command-execution actions."""
|
"""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
|
# 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
|
# single item it should be the command string to execute; if a
|
||||||
# list then it should be the words of the command string to
|
# list then it should be the words of the command string to
|
||||||
|
@ -371,25 +644,16 @@ class CommandAction(_ActionAction):
|
||||||
# variables.
|
# variables.
|
||||||
if __debug__: logInstanceCreation(self, 'Action.CommandAction')
|
if __debug__: logInstanceCreation(self, 'Action.CommandAction')
|
||||||
|
|
||||||
if not cmdstr is None:
|
#TODO(1.5) _ActionAction.__init__(self, **kw)
|
||||||
if callable(cmdstr):
|
apply(_ActionAction.__init__, (self,), kw)
|
||||||
args = (cmdstr,)+args
|
if is_List(cmd):
|
||||||
elif not SCons.Util.is_String(cmdstr):
|
if filter(is_List, cmd):
|
||||||
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):
|
|
||||||
raise TypeError, "CommandAction should be given only " \
|
raise TypeError, "CommandAction should be given only " \
|
||||||
"a single command"
|
"a single command"
|
||||||
self.cmd_list = cmd
|
self.cmd_list = cmd
|
||||||
self.cmdstr = cmdstr
|
|
||||||
|
|
||||||
def __str__(self):
|
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 string.join(map(str, self.cmd_list), ' ')
|
||||||
return str(self.cmd_list)
|
return str(self.cmd_list)
|
||||||
|
|
||||||
|
@ -412,7 +676,9 @@ class CommandAction(_ActionAction):
|
||||||
return result, ignore, silent
|
return result, ignore, silent
|
||||||
|
|
||||||
def strfunction(self, target, source, env):
|
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
|
from SCons.Subst import SUBST_RAW
|
||||||
c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
||||||
if c:
|
if c:
|
||||||
|
@ -431,11 +697,8 @@ class CommandAction(_ActionAction):
|
||||||
handle lists of commands, even though that's not how we use it
|
handle lists of commands, even though that's not how we use it
|
||||||
externally.
|
externally.
|
||||||
"""
|
"""
|
||||||
from SCons.Subst import escape_list
|
escape_list = SCons.Subst.escape_list
|
||||||
import SCons.Util
|
flatten_sequence = SCons.Util.flatten_sequence
|
||||||
flatten = SCons.Util.flatten
|
|
||||||
is_String = SCons.Util.is_String
|
|
||||||
is_List = SCons.Util.is_List
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
shell = env['SHELL']
|
shell = env['SHELL']
|
||||||
|
@ -452,14 +715,7 @@ class CommandAction(_ActionAction):
|
||||||
|
|
||||||
escape = env.get('ESCAPE', lambda x: x)
|
escape = env.get('ESCAPE', lambda x: x)
|
||||||
|
|
||||||
try:
|
ENV = get_default_ENV(env)
|
||||||
ENV = env['ENV']
|
|
||||||
except KeyError:
|
|
||||||
global default_ENV
|
|
||||||
if not default_ENV:
|
|
||||||
import SCons.Environment
|
|
||||||
default_ENV = SCons.Environment.Environment()['ENV']
|
|
||||||
ENV = default_ENV
|
|
||||||
|
|
||||||
# Ensure that the ENV values are all strings:
|
# Ensure that the ENV values are all strings:
|
||||||
for key, value in ENV.items():
|
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
|
# If the value is a list, then we assume it is a
|
||||||
# path list, because that's a pretty common list-like
|
# path list, because that's a pretty common list-like
|
||||||
# value to stick in an environment variable:
|
# value to stick in an environment variable:
|
||||||
value = flatten(value)
|
value = flatten_sequence(value)
|
||||||
ENV[key] = string.join(map(str, value), os.pathsep)
|
ENV[key] = string.join(map(str, value), os.pathsep)
|
||||||
else:
|
else:
|
||||||
# If it isn't a string or a list, then we just coerce
|
# If it isn't a string or a list, then we just coerce
|
||||||
|
@ -492,7 +748,7 @@ class CommandAction(_ActionAction):
|
||||||
command=cmd_line)
|
command=cmd_line)
|
||||||
return 0
|
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.
|
"""Return the signature contents of this action's command line.
|
||||||
|
|
||||||
This strips $(-$) and everything in between the string,
|
This strips $(-$) and everything in between the string,
|
||||||
|
@ -500,7 +756,7 @@ class CommandAction(_ActionAction):
|
||||||
"""
|
"""
|
||||||
from SCons.Subst import SUBST_SIG
|
from SCons.Subst import SUBST_SIG
|
||||||
cmd = self.cmd_list
|
cmd = self.cmd_list
|
||||||
if SCons.Util.is_List(cmd):
|
if is_List(cmd):
|
||||||
cmd = string.join(map(str, cmd))
|
cmd = string.join(map(str, cmd))
|
||||||
else:
|
else:
|
||||||
cmd = str(cmd)
|
cmd = str(cmd)
|
||||||
|
@ -508,7 +764,7 @@ class CommandAction(_ActionAction):
|
||||||
|
|
||||||
def get_implicit_deps(self, target, source, env):
|
def get_implicit_deps(self, target, source, env):
|
||||||
icd = env.get('IMPLICIT_COMMAND_DEPENDENCIES', True)
|
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)
|
icd = env.subst(icd)
|
||||||
if not icd or icd in ('0', 'None'):
|
if not icd or icd in ('0', 'None'):
|
||||||
return []
|
return []
|
||||||
|
@ -524,20 +780,21 @@ class CommandAction(_ActionAction):
|
||||||
|
|
||||||
class CommandGeneratorAction(ActionBase):
|
class CommandGeneratorAction(ActionBase):
|
||||||
"""Class for command-generator actions."""
|
"""Class for command-generator actions."""
|
||||||
def __init__(self, generator, *args, **kw):
|
def __init__(self, generator, kw):
|
||||||
if __debug__: logInstanceCreation(self, 'Action.CommandGeneratorAction')
|
if __debug__: logInstanceCreation(self, 'Action.CommandGeneratorAction')
|
||||||
self.generator = generator
|
self.generator = generator
|
||||||
self.gen_args = args
|
|
||||||
self.gen_kw = kw
|
self.gen_kw = kw
|
||||||
|
self.varlist = kw.get('varlist', ())
|
||||||
|
|
||||||
def _generate(self, target, source, env, for_signature):
|
def _generate(self, target, source, env, for_signature):
|
||||||
# ensure that target is a list, to make it easier to write
|
# ensure that target is a list, to make it easier to write
|
||||||
# generator functions:
|
# generator functions:
|
||||||
if not SCons.Util.is_List(target):
|
if not is_List(target):
|
||||||
target = [target]
|
target = [target]
|
||||||
|
|
||||||
ret = self.generator(target=target, source=source, env=env, for_signature=for_signature)
|
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:
|
if not gen_cmd:
|
||||||
raise SCons.Errors.UserError("Object returned from command generator: %s cannot be used to create an Action." % repr(ret))
|
raise SCons.Errors.UserError("Object returned from command generator: %s cannot be used to create an Action." % repr(ret))
|
||||||
return gen_cmd
|
return gen_cmd
|
||||||
|
@ -561,13 +818,13 @@ class CommandGeneratorAction(ActionBase):
|
||||||
return act(target, source, env, exitstatfunc, presub,
|
return act(target, source, env, exitstatfunc, presub,
|
||||||
show, execute, chdir)
|
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.
|
"""Return the signature contents of this action's command line.
|
||||||
|
|
||||||
This strips $(-$) and everything in between the string,
|
This strips $(-$) and everything in between the string,
|
||||||
since those parts don't affect signatures.
|
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):
|
def get_implicit_deps(self, target, source, env):
|
||||||
return self._generate(target, source, env, 1).get_implicit_deps(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):
|
class LazyAction(CommandGeneratorAction, CommandAction):
|
||||||
|
|
||||||
def __init__(self, var, *args, **kw):
|
def __init__(self, var, kw):
|
||||||
if __debug__: logInstanceCreation(self, 'Action.LazyAction')
|
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.var = SCons.Util.to_String(var)
|
||||||
self.gen_args = args
|
|
||||||
self.gen_kw = kw
|
self.gen_kw = kw
|
||||||
|
|
||||||
def get_parent_class(self, env):
|
def get_parent_class(self, env):
|
||||||
c = env.get(self.var)
|
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 CommandAction
|
||||||
return CommandGeneratorAction
|
return CommandGeneratorAction
|
||||||
|
|
||||||
def _generate_cache(self, env):
|
def _generate_cache(self, env):
|
||||||
c = env.get(self.var, '')
|
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:
|
if not gen_cmd:
|
||||||
raise SCons.Errors.UserError("$%s value %s cannot be used to create an Action." % (self.var, repr(c)))
|
raise SCons.Errors.UserError("$%s value %s cannot be used to create an Action." % (self.var, repr(c)))
|
||||||
return gen_cmd
|
return gen_cmd
|
||||||
|
@ -619,33 +877,34 @@ class LazyAction(CommandGeneratorAction, CommandAction):
|
||||||
def __call__(self, target, source, env, *args, **kw):
|
def __call__(self, target, source, env, *args, **kw):
|
||||||
args = (self, target, source, env) + args
|
args = (self, target, source, env) + args
|
||||||
c = self.get_parent_class(env)
|
c = self.get_parent_class(env)
|
||||||
|
#TODO(1.5) return c.__call__(*args, **kw)
|
||||||
return apply(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)
|
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 FunctionAction(_ActionAction):
|
||||||
"""Class for Python function actions."""
|
"""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 __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
|
self.execfunction = execfunction
|
||||||
apply(_ActionAction.__init__, (self,)+args, kw)
|
try:
|
||||||
self.varlist = kw.get('varlist', [])
|
self.funccontents = _callable_contents(execfunction)
|
||||||
self.cmdstr = cmdstr
|
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):
|
def function_name(self):
|
||||||
try:
|
try:
|
||||||
|
@ -659,14 +918,20 @@ class FunctionAction(_ActionAction):
|
||||||
def strfunction(self, target, source, env):
|
def strfunction(self, target, source, env):
|
||||||
if self.cmdstr is None:
|
if self.cmdstr is None:
|
||||||
return None
|
return None
|
||||||
if not self.cmdstr is _null:
|
if self.cmdstr is not _null:
|
||||||
from SCons.Subst import SUBST_RAW
|
from SCons.Subst import SUBST_RAW
|
||||||
c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
||||||
if c:
|
if c:
|
||||||
return c
|
return c
|
||||||
def array(a):
|
def array(a):
|
||||||
def quote(s):
|
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), ", ") + ']'
|
return '[' + string.join(map(quote, a), ", ") + ']'
|
||||||
try:
|
try:
|
||||||
strfunc = self.execfunction.strfunction
|
strfunc = self.execfunction.strfunction
|
||||||
|
@ -689,73 +954,49 @@ class FunctionAction(_ActionAction):
|
||||||
return "%s(target, source, env)" % name
|
return "%s(target, source, env)" % name
|
||||||
|
|
||||||
def execute(self, target, source, env):
|
def execute(self, target, source, env):
|
||||||
|
exc_info = (None,None,None)
|
||||||
|
try:
|
||||||
rsources = map(rfile, source)
|
rsources = map(rfile, source)
|
||||||
try:
|
try:
|
||||||
result = self.execfunction(target=target, source=rsources, env=env)
|
result = self.execfunction(target=target, source=rsources, env=env)
|
||||||
except EnvironmentError, e:
|
except KeyboardInterrupt, e:
|
||||||
# If an IOError/OSError happens, raise a BuildError.
|
raise
|
||||||
# Report the name of the file or directory that caused the
|
except SystemExit, e:
|
||||||
# error, which might be different from the target being built
|
raise
|
||||||
# (for example, failure to create the directory in which the
|
except Exception, e:
|
||||||
# target file will appear).
|
result = e
|
||||||
try: filename = e.filename
|
exc_info = sys.exc_info()
|
||||||
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:
|
if result:
|
||||||
msg = "Error %s" % result
|
result = SCons.Errors.convert_to_BuildError(result, exc_info)
|
||||||
result = SCons.Errors.BuildError(errstr=msg,
|
result.node=target
|
||||||
status=result,
|
result.action=self
|
||||||
action=self,
|
result.command=self.strfunction(target, source, env)
|
||||||
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
|
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_contents(self, target, source, env):
|
|
||||||
"""Return the signature contents of this callable action.
|
|
||||||
|
|
||||||
By providing direct access to the code object of the
|
def get_presig(self, target, source, env):
|
||||||
function, Python makes this extremely easy. Hooray!
|
"""Return the signature contents of this callable action."""
|
||||||
|
|
||||||
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:
|
try:
|
||||||
# Test if execfunction is a function.
|
return self.gc(target, source, env)
|
||||||
code = execfunction.func_code.co_code
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
return self.funccontents
|
||||||
# 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)))
|
|
||||||
|
|
||||||
def get_implicit_deps(self, target, source, env):
|
def get_implicit_deps(self, target, source, env):
|
||||||
return []
|
return []
|
||||||
|
@ -769,6 +1010,9 @@ class ListAction(ActionBase):
|
||||||
return x
|
return x
|
||||||
return Action(x)
|
return Action(x)
|
||||||
self.list = map(list_of_actions, list)
|
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):
|
def genstring(self, target, source, env):
|
||||||
return string.join(map(lambda a, t=target, s=source, e=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')
|
return string.join(map(str, self.list), '\n')
|
||||||
|
|
||||||
def presub_lines(self, env):
|
def presub_lines(self, env):
|
||||||
return SCons.Util.flatten(map(lambda a, env=env:
|
return SCons.Util.flatten_sequence(
|
||||||
a.presub_lines(env),
|
map(lambda a, env=env: a.presub_lines(env), self.list))
|
||||||
self.list))
|
|
||||||
|
|
||||||
def get_contents(self, target, source, env):
|
def get_presig(self, target, source, env):
|
||||||
"""Return the signature contents of this action list.
|
"""Return the signature contents of this action list.
|
||||||
|
|
||||||
Simple concatenation of the signatures of the elements.
|
Simple concatenation of the signatures of the elements.
|
||||||
|
@ -822,6 +1065,7 @@ class ActionCaller:
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kw = kw
|
self.kw = kw
|
||||||
|
|
||||||
def get_contents(self, target, source, env):
|
def get_contents(self, target, source, env):
|
||||||
actfunc = self.parent.actfunc
|
actfunc = self.parent.actfunc
|
||||||
try:
|
try:
|
||||||
|
@ -837,33 +1081,50 @@ class ActionCaller:
|
||||||
contents = str(actfunc)
|
contents = str(actfunc)
|
||||||
contents = remove_set_lineno_codes(contents)
|
contents = remove_set_lineno_codes(contents)
|
||||||
return contents
|
return contents
|
||||||
|
|
||||||
def subst(self, s, target, source, env):
|
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
|
# Special-case hack: Let a custom function wrapped in an
|
||||||
# ActionCaller get at the environment through which the action
|
# ActionCaller get at the environment through which the action
|
||||||
# was called by using this hard-coded value as a special return.
|
# was called by using this hard-coded value as a special return.
|
||||||
if s == '$__env__':
|
if s == '$__env__':
|
||||||
return env
|
return env
|
||||||
elif SCons.Util.is_String(s):
|
elif is_String(s):
|
||||||
return env.subst(s, 0, target, source)
|
return env.subst(s, 1, target, source)
|
||||||
return self.parent.convert(s)
|
return self.parent.convert(s)
|
||||||
|
|
||||||
def subst_args(self, target, source, env):
|
def subst_args(self, target, source, env):
|
||||||
return map(lambda x, self=self, t=target, s=source, e=env:
|
return map(lambda x, self=self, t=target, s=source, e=env:
|
||||||
self.subst(x, t, s, e),
|
self.subst(x, t, s, e),
|
||||||
self.args)
|
self.args)
|
||||||
|
|
||||||
def subst_kw(self, target, source, env):
|
def subst_kw(self, target, source, env):
|
||||||
kw = {}
|
kw = {}
|
||||||
for key in self.kw.keys():
|
for key in self.kw.keys():
|
||||||
kw[key] = self.subst(self.kw[key], target, source, env)
|
kw[key] = self.subst(self.kw[key], target, source, env)
|
||||||
return kw
|
return kw
|
||||||
|
|
||||||
def __call__(self, target, source, env):
|
def __call__(self, target, source, env):
|
||||||
args = self.subst_args(target, source, env)
|
args = self.subst_args(target, source, env)
|
||||||
kw = self.subst_kw(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)
|
return apply(self.parent.actfunc, args, kw)
|
||||||
|
|
||||||
def strfunction(self, target, source, env):
|
def strfunction(self, target, source, env):
|
||||||
args = self.subst_args(target, source, env)
|
args = self.subst_args(target, source, env)
|
||||||
kw = self.subst_kw(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)
|
return apply(self.parent.strfunc, args, kw)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
#TODO(1.5) return self.parent.strfunc(*self.args, **self.kw)
|
||||||
return apply(self.parent.strfunc, self.args, self.kw)
|
return apply(self.parent.strfunc, self.args, self.kw)
|
||||||
|
|
||||||
class ActionFactory:
|
class ActionFactory:
|
||||||
|
@ -879,6 +1140,7 @@ class ActionFactory:
|
||||||
self.actfunc = actfunc
|
self.actfunc = actfunc
|
||||||
self.strfunc = strfunc
|
self.strfunc = strfunc
|
||||||
self.convert = convert
|
self.convert = convert
|
||||||
|
|
||||||
def __call__(self, *args, **kw):
|
def __call__(self, *args, **kw):
|
||||||
ac = ActionCaller(self, args, kw)
|
ac = ActionCaller(self, args, kw)
|
||||||
action = Action(ac, strfunction=ac.strfunction)
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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"
|
__revision__ = "src/engine/SCons/Builder.py 3842 2008/12/20 22:59:52 scons"
|
||||||
|
|
||||||
import SCons.compat
|
|
||||||
|
|
||||||
import UserDict
|
import UserDict
|
||||||
import UserList
|
import UserList
|
||||||
|
@ -234,7 +232,7 @@ def Builder(**kw):
|
||||||
if kw.has_key('generator'):
|
if kw.has_key('generator'):
|
||||||
if kw.has_key('action'):
|
if kw.has_key('action'):
|
||||||
raise UserError, "You must not specify both an action and a generator."
|
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']
|
del kw['generator']
|
||||||
elif kw.has_key('action'):
|
elif kw.has_key('action'):
|
||||||
source_ext_match = kw.get('source_ext_match', 1)
|
source_ext_match = kw.get('source_ext_match', 1)
|
||||||
|
@ -242,7 +240,7 @@ def Builder(**kw):
|
||||||
del kw['source_ext_match']
|
del kw['source_ext_match']
|
||||||
if SCons.Util.is_Dict(kw['action']):
|
if SCons.Util.is_Dict(kw['action']):
|
||||||
composite = DictCmdGenerator(kw['action'], source_ext_match)
|
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()
|
kw['src_suffix'] = composite.src_suffixes()
|
||||||
else:
|
else:
|
||||||
kw['action'] = SCons.Action.Action(kw['action'])
|
kw['action'] = SCons.Action.Action(kw['action'])
|
||||||
|
@ -363,7 +361,7 @@ class BuilderBase:
|
||||||
name = None,
|
name = None,
|
||||||
chdir = _null,
|
chdir = _null,
|
||||||
is_explicit = 1,
|
is_explicit = 1,
|
||||||
src_builder = [],
|
src_builder = None,
|
||||||
ensure_suffix = False,
|
ensure_suffix = False,
|
||||||
**overrides):
|
**overrides):
|
||||||
if __debug__: logInstanceCreation(self, 'Builder.BuilderBase')
|
if __debug__: logInstanceCreation(self, 'Builder.BuilderBase')
|
||||||
|
@ -410,7 +408,9 @@ class BuilderBase:
|
||||||
self.executor_kw['chdir'] = chdir
|
self.executor_kw['chdir'] = chdir
|
||||||
self.is_explicit = is_explicit
|
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 ]
|
src_builder = [ src_builder ]
|
||||||
self.src_builder = src_builder
|
self.src_builder = src_builder
|
||||||
|
|
||||||
|
@ -505,7 +505,7 @@ class BuilderBase:
|
||||||
tlist = [ t_from_s(pre, suf, splitext) ]
|
tlist = [ t_from_s(pre, suf, splitext) ]
|
||||||
else:
|
else:
|
||||||
target = self._adjustixes(target, pre, suf, self.ensure_suffix)
|
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:
|
if self.emitter:
|
||||||
# The emitter is going to do str(node), but because we're
|
# The emitter is going to do str(node), but because we're
|
||||||
|
@ -712,14 +712,9 @@ class BuilderBase:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
|
for s in SCons.Util.flatten(source):
|
||||||
if SCons.Util.is_List(source):
|
|
||||||
source = SCons.Util.flatten(source)
|
|
||||||
else:
|
|
||||||
source = [source]
|
|
||||||
for s in source:
|
|
||||||
if SCons.Util.is_String(s):
|
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:
|
if not match_suffix and not '.' in s:
|
||||||
src_suf = self.get_src_suffix(env)
|
src_suf = self.get_src_suffix(env)
|
||||||
s = self._adjustixes(s, None, src_suf)[0]
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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__ = """
|
__doc__ = """
|
||||||
CacheDir support
|
CacheDir support
|
||||||
|
@ -34,6 +34,7 @@ import sys
|
||||||
|
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
|
|
||||||
|
cache_enabled = True
|
||||||
cache_debug = False
|
cache_debug = False
|
||||||
cache_force = False
|
cache_force = False
|
||||||
cache_show = False
|
cache_show = False
|
||||||
|
@ -129,31 +130,33 @@ class CacheDir:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
msg = "No hashlib or MD5 module available, CacheDir() not supported"
|
msg = "No hashlib or MD5 module available, CacheDir() not supported"
|
||||||
SCons.Warnings.warn(SCons.Warnings.NoMD5ModuleWarning, msg)
|
SCons.Warnings.warn(SCons.Warnings.NoMD5ModuleWarning, msg)
|
||||||
|
self.path = None
|
||||||
else:
|
else:
|
||||||
self.path = path
|
self.path = path
|
||||||
|
self.current_cache_debug = None
|
||||||
|
self.debugFP = None
|
||||||
|
|
||||||
def CacheDebugWrite(self, fmt, target, cachefile):
|
def CacheDebug(self, fmt, target, cachefile):
|
||||||
self.debugFP.write(fmt % (target, os.path.split(cachefile)[1]))
|
if cache_debug != self.current_cache_debug:
|
||||||
|
|
||||||
def CacheDebugQuiet(self, fmt, target, cachefile):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def CacheDebugInit(self, fmt, target, cachefile):
|
|
||||||
if cache_debug:
|
|
||||||
if cache_debug == '-':
|
if cache_debug == '-':
|
||||||
self.debugFP = sys.stdout
|
self.debugFP = sys.stdout
|
||||||
else:
|
elif cache_debug:
|
||||||
self.debugFP = open(cache_debug, 'w')
|
self.debugFP = open(cache_debug, 'w')
|
||||||
self.CacheDebug = self.CacheDebugWrite
|
|
||||||
self.CacheDebug(fmt, target, cachefile)
|
|
||||||
else:
|
else:
|
||||||
self.CacheDebug = self.CacheDebugQuiet
|
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):
|
def cachepath(self, node):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
if not self.is_enabled():
|
||||||
|
return None, None
|
||||||
|
|
||||||
sig = node.get_cachedir_bsig()
|
sig = node.get_cachedir_bsig()
|
||||||
subdir = string.upper(sig[0])
|
subdir = string.upper(sig[0])
|
||||||
dir = os.path.join(self.path, subdir)
|
dir = os.path.join(self.path, subdir)
|
||||||
|
@ -184,6 +187,9 @@ class CacheDir:
|
||||||
execute the CacheRetrieveFunc and then have the latter
|
execute the CacheRetrieveFunc and then have the latter
|
||||||
explicitly check SCons.Action.execute_actions itself.
|
explicitly check SCons.Action.execute_actions itself.
|
||||||
"""
|
"""
|
||||||
|
if not self.is_enabled():
|
||||||
|
return False
|
||||||
|
|
||||||
retrieved = False
|
retrieved = False
|
||||||
|
|
||||||
if cache_show:
|
if cache_show:
|
||||||
|
@ -202,16 +208,10 @@ class CacheDir:
|
||||||
return retrieved
|
return retrieved
|
||||||
|
|
||||||
def push(self, node):
|
def push(self, node):
|
||||||
|
if not self.is_enabled():
|
||||||
|
return
|
||||||
return CachePush(node, [], node.get_build_env())
|
return CachePush(node, [], node.get_build_env())
|
||||||
|
|
||||||
def push_if_forced(self, node):
|
def push_if_forced(self, node):
|
||||||
if cache_force:
|
if cache_force:
|
||||||
return self.push(node)
|
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)
|
_YesNoResult(context, ret, None, text)
|
||||||
return ret
|
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):
|
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))
|
context.Display("Checking for %s function %s()... " % (lang, function_name))
|
||||||
ret = context.BuildProg(text, suffix)
|
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
|
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))
|
context.Display("Checking for %s header file %s... " % (lang, header_name))
|
||||||
ret = context.CompileProg(text, suffix)
|
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
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
@ -310,7 +408,8 @@ int main() {
|
||||||
|
|
||||||
context.Display("Checking for %s type %s... " % (lang, type_name))
|
context.Display("Checking for %s type %s... " % (lang, type_name))
|
||||||
ret = context.BuildProg(text, suffix)
|
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:
|
if ret and fallback and context.headerfilename:
|
||||||
f = open(context.headerfilename, "a")
|
f = open(context.headerfilename, "a")
|
||||||
f.write("typedef %s %s;\n" % (fallback, type_name))
|
f.write("typedef %s %s;\n" % (fallback, type_name))
|
||||||
|
@ -371,11 +470,11 @@ int main()
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# XXX: Try* vs CompileProg ?
|
st = context.CompileProg(src % (type_name, expect), suffix)
|
||||||
st = context.TryCompile(src % (type_name, expect), suffix)
|
if not st:
|
||||||
if st:
|
|
||||||
_Have(context, "SIZEOF_" + type_name, str(expect))
|
|
||||||
context.Display("yes\n")
|
context.Display("yes\n")
|
||||||
|
_Have(context, "SIZEOF_%s" % type_name, expect,
|
||||||
|
"The size of `%s', as computed by sizeof." % type_name)
|
||||||
return expect
|
return expect
|
||||||
else:
|
else:
|
||||||
context.Display("no\n")
|
context.Display("no\n")
|
||||||
|
@ -400,21 +499,78 @@ int main() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
ret = context.TryRun(src, suffix)
|
st, out = context.RunProg(src, suffix)
|
||||||
st = ret[0]
|
|
||||||
try:
|
try:
|
||||||
size = int(ret[1])
|
size = int(out)
|
||||||
_Have(context, "SIZEOF_" + type_name, str(size))
|
|
||||||
context.Display("%d\n" % size)
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
# If cannot convert output of test prog to an integer (the size),
|
||||||
|
# something went wront, so just fail
|
||||||
|
st = 1
|
||||||
size = 0
|
size = 0
|
||||||
_LogFailed(context, src, st)
|
|
||||||
context.Display(" Failed !\n")
|
if not st:
|
||||||
if st:
|
context.Display("yes\n")
|
||||||
|
_Have(context, "SIZEOF_%s" % type_name, size,
|
||||||
|
"The size of `%s', as computed by sizeof." % type_name)
|
||||||
return size
|
return size
|
||||||
else:
|
else:
|
||||||
|
context.Display("no\n")
|
||||||
|
_LogFailed(context, src, st)
|
||||||
return 0
|
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,
|
def CheckLib(context, libs, func_name = None, header = None,
|
||||||
extra_libs = None, call = None, language = None, autoadd = 1):
|
extra_libs = None, call = None, language = None, autoadd = 1):
|
||||||
"""
|
"""
|
||||||
|
@ -509,7 +665,8 @@ return 0;
|
||||||
|
|
||||||
ret = context.BuildProg(text, suffix)
|
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):
|
if oldLIBS != -1 and (ret or not autoadd):
|
||||||
context.SetLIBS(oldLIBS)
|
context.SetLIBS(oldLIBS)
|
||||||
|
|
||||||
|
@ -522,15 +679,17 @@ return 0;
|
||||||
# END OF PUBLIC FUNCTIONS
|
# 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.
|
Handle the result of a test with a "yes" or "no" result.
|
||||||
"ret" is the return value: empty if OK, error message when not.
|
"ret" is the return value: empty if OK, error message when not.
|
||||||
"key" is the name of the symbol to be defined (HAVE_foo).
|
"key" is the name of the symbol to be defined (HAVE_foo).
|
||||||
"text" is the source code of the program used for testing.
|
"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:
|
if key:
|
||||||
_Have(context, key, not ret)
|
_Have(context, key, not ret, comment)
|
||||||
if ret:
|
if ret:
|
||||||
context.Display("no\n")
|
context.Display("no\n")
|
||||||
_LogFailed(context, text, ret)
|
_LogFailed(context, text, ret)
|
||||||
|
@ -538,7 +697,7 @@ def _YesNoResult(context, ret, key, text):
|
||||||
context.Display("yes\n")
|
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.
|
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-
|
"key" is a "HAVE_abc" name. It is turned into all CAPITALS and non-
|
||||||
|
@ -566,12 +725,17 @@ def _Have(context, key, have):
|
||||||
else:
|
else:
|
||||||
line = "#define %s %s\n" % (key_up, str(have))
|
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:
|
if context.headerfilename:
|
||||||
f = open(context.headerfilename, "a")
|
f = open(context.headerfilename, "a")
|
||||||
f.write(line)
|
f.write(lines)
|
||||||
f.close()
|
f.close()
|
||||||
elif hasattr(context,'config_h'):
|
elif hasattr(context,'config_h'):
|
||||||
context.config_h = context.config_h + line
|
context.config_h = context.config_h + lines
|
||||||
|
|
||||||
|
|
||||||
def _LogFailed(context, text, msg):
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 os
|
||||||
import string
|
import string
|
||||||
|
@ -115,39 +115,57 @@ else:
|
||||||
res = resource.getrusage(resource.RUSAGE_SELF)
|
res = resource.getrusage(resource.RUSAGE_SELF)
|
||||||
return res[4]
|
return res[4]
|
||||||
|
|
||||||
|
# returns caller's stack
|
||||||
|
def caller_stack(*backlist):
|
||||||
caller_dicts = {}
|
|
||||||
|
|
||||||
def caller(*backlist):
|
|
||||||
import traceback
|
import traceback
|
||||||
if not backlist:
|
if not backlist:
|
||||||
backlist = [0]
|
backlist = [0]
|
||||||
result = []
|
result = []
|
||||||
for back in backlist:
|
for back in backlist:
|
||||||
tb = traceback.extract_stack(limit=3+back)
|
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]
|
key = tb[0][:3]
|
||||||
entry[key] = entry.get(key, 0) + 1
|
|
||||||
result.append('%s:%d(%s)' % func_shorten(key))
|
result.append('%s:%d(%s)' % func_shorten(key))
|
||||||
return result
|
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):
|
def dump_caller_counts(file=sys.stdout):
|
||||||
keys = caller_dicts.keys()
|
keys = caller_bases.keys()
|
||||||
keys.sort()
|
keys.sort()
|
||||||
for k in keys:
|
for k in keys:
|
||||||
file.write("Callers of %s:%d(%s):\n" % func_shorten(k))
|
file.write("Callers of %s:%d(%s), %d calls:\n"
|
||||||
counts = caller_dicts[k]
|
% (func_shorten(k) + (caller_bases[k],)))
|
||||||
callers = counts.keys()
|
_dump_one_caller(k, file)
|
||||||
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)
|
|
||||||
|
|
||||||
shorten_list = [
|
shorten_list = [
|
||||||
( '/scons/SCons/', 1),
|
( '/scons/SCons/', 1),
|
||||||
|
@ -168,10 +186,8 @@ def func_shorten(func_tuple):
|
||||||
if i >= 0:
|
if i >= 0:
|
||||||
if t[1]:
|
if t[1]:
|
||||||
i = i + len(t[0])
|
i = i + len(t[0])
|
||||||
f = f[i:]
|
return (f[i:],)+func_tuple[1:]
|
||||||
break
|
return func_tuple
|
||||||
return (f,)+func_tuple[1:]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TraceFP = {}
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 os.path
|
||||||
import shutil
|
import shutil
|
||||||
import stat
|
import stat
|
||||||
|
import string
|
||||||
import time
|
import time
|
||||||
import types
|
import types
|
||||||
import sys
|
import sys
|
||||||
|
@ -93,7 +94,7 @@ def DefaultEnvironment(*args, **kw):
|
||||||
_default_env.Decider('timestamp-match')
|
_default_env.Decider('timestamp-match')
|
||||||
global DefaultEnvironment
|
global DefaultEnvironment
|
||||||
DefaultEnvironment = _fetch_DefaultEnvironment
|
DefaultEnvironment = _fetch_DefaultEnvironment
|
||||||
_default_env._CacheDir = SCons.CacheDir.Null()
|
_default_env._CacheDir_path = None
|
||||||
return _default_env
|
return _default_env
|
||||||
|
|
||||||
# Emitters for setting the shared attribute on object files,
|
# Emitters for setting the shared attribute on object files,
|
||||||
|
@ -157,19 +158,36 @@ LdModuleLinkAction = SCons.Action.Action("$LDMODULECOM", "$LDMODULECOMSTR")
|
||||||
# ways by creating ActionFactory instances.
|
# ways by creating ActionFactory instances.
|
||||||
ActionFactory = SCons.Action.ActionFactory
|
ActionFactory = SCons.Action.ActionFactory
|
||||||
|
|
||||||
def chmod_func(path, mode):
|
def get_paths_str(dest):
|
||||||
return os.chmod(str(path), mode)
|
# 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,
|
def chmod_func(dest, mode):
|
||||||
lambda dest, mode: 'Chmod("%s", 0%o)' % (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):
|
def copy_func(dest, src):
|
||||||
|
SCons.Node.FS.invalidate_node_memos(dest)
|
||||||
if SCons.Util.is_List(src) and os.path.isdir(dest):
|
if SCons.Util.is_List(src) and os.path.isdir(dest):
|
||||||
for file in src:
|
for file in src:
|
||||||
shutil.copy(file, dest)
|
shutil.copy2(file, dest)
|
||||||
return 0
|
return 0
|
||||||
elif os.path.isfile(src):
|
elif os.path.isfile(src):
|
||||||
return shutil.copy(src, dest)
|
return shutil.copy2(src, dest)
|
||||||
else:
|
else:
|
||||||
return shutil.copytree(src, dest, 1)
|
return shutil.copytree(src, dest, 1)
|
||||||
|
|
||||||
|
@ -177,29 +195,50 @@ Copy = ActionFactory(copy_func,
|
||||||
lambda dest, src: 'Copy("%s", "%s")' % (dest, src),
|
lambda dest, src: 'Copy("%s", "%s")' % (dest, src),
|
||||||
convert=str)
|
convert=str)
|
||||||
|
|
||||||
def delete_func(entry, must_exist=0):
|
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)
|
entry = str(entry)
|
||||||
if not must_exist and not os.path.exists(entry):
|
if not must_exist and not os.path.exists(entry):
|
||||||
return None
|
continue
|
||||||
if not os.path.exists(entry) or os.path.isfile(entry):
|
if not os.path.exists(entry) or os.path.isfile(entry):
|
||||||
return os.unlink(entry)
|
os.unlink(entry)
|
||||||
|
continue
|
||||||
else:
|
else:
|
||||||
return shutil.rmtree(entry, 1)
|
shutil.rmtree(entry, 1)
|
||||||
|
continue
|
||||||
|
|
||||||
def delete_strfunc(entry, must_exist=0):
|
def delete_strfunc(dest, must_exist=0):
|
||||||
return 'Delete("%s")' % entry
|
return 'Delete(%s)' % get_paths_str(dest)
|
||||||
|
|
||||||
Delete = ActionFactory(delete_func, delete_strfunc)
|
Delete = ActionFactory(delete_func, delete_strfunc)
|
||||||
|
|
||||||
Mkdir = ActionFactory(os.makedirs,
|
def mkdir_func(dest):
|
||||||
lambda dir: 'Mkdir("%s")' % dir,
|
SCons.Node.FS.invalidate_node_memos(dest)
|
||||||
convert=str)
|
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),
|
lambda dest, src: 'Move("%s", "%s")' % (dest, src),
|
||||||
convert=str)
|
convert=str)
|
||||||
|
|
||||||
def touch_func(file):
|
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)
|
file = str(file)
|
||||||
mtime = int(time.time())
|
mtime = int(time.time())
|
||||||
if os.path.exists(file):
|
if os.path.exists(file):
|
||||||
|
@ -207,10 +246,10 @@ def touch_func(file):
|
||||||
else:
|
else:
|
||||||
open(file, 'w')
|
open(file, 'w')
|
||||||
atime = mtime
|
atime = mtime
|
||||||
return os.utime(file, (atime, mtime))
|
os.utime(file, (atime, mtime))
|
||||||
|
|
||||||
Touch = ActionFactory(touch_func,
|
Touch = ActionFactory(touch_func,
|
||||||
lambda file: 'Touch("%s")' % file)
|
lambda file: 'Touch(%s)' % get_paths_str(file))
|
||||||
|
|
||||||
# Internal utility functions
|
# Internal utility functions
|
||||||
|
|
||||||
|
@ -224,9 +263,6 @@ def _concat(prefix, list, suffix, env, f=lambda x: x, target=None, source=None):
|
||||||
if not list:
|
if not list:
|
||||||
return 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))
|
l = f(SCons.PathList.PathList(list).subst_path(env, target, source))
|
||||||
if not l is None:
|
if not l is None:
|
||||||
list = l
|
list = l
|
||||||
|
@ -270,7 +306,7 @@ def _concat_ixes(prefix, list, suffix, env):
|
||||||
|
|
||||||
return result
|
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
|
This is a wrapper around _concat()/_concat_ixes() that checks for the
|
||||||
existence of prefixes or suffixes on list elements and strips them
|
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:
|
else:
|
||||||
c = _concat_ixes
|
c = _concat_ixes
|
||||||
|
|
||||||
if SCons.Util.is_List(list):
|
stripprefixes = map(env.subst, SCons.Util.flatten(stripprefixes))
|
||||||
list = SCons.Util.flatten(list)
|
stripsuffixes = map(env.subst, SCons.Util.flatten(stripsuffixes))
|
||||||
|
|
||||||
lsp = len(stripprefix)
|
|
||||||
lss = len(stripsuffix)
|
|
||||||
stripped = []
|
stripped = []
|
||||||
for l in SCons.PathList.PathList(list).subst_path(env, None, None):
|
for l in SCons.PathList.PathList(list).subst_path(env, None, None):
|
||||||
if isinstance(l, SCons.Node.FS.File):
|
if isinstance(l, SCons.Node.FS.File):
|
||||||
stripped.append(l)
|
stripped.append(l)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if not SCons.Util.is_String(l):
|
if not SCons.Util.is_String(l):
|
||||||
l = str(l)
|
l = str(l)
|
||||||
|
|
||||||
|
for stripprefix in stripprefixes:
|
||||||
|
lsp = len(stripprefix)
|
||||||
if l[:lsp] == stripprefix:
|
if l[:lsp] == stripprefix:
|
||||||
l = l[lsp:]
|
l = l[lsp:]
|
||||||
|
# Do not strip more than one prefix
|
||||||
|
break
|
||||||
|
|
||||||
|
for stripsuffix in stripsuffixes:
|
||||||
|
lss = len(stripsuffix)
|
||||||
if l[-lss:] == stripsuffix:
|
if l[-lss:] == stripsuffix:
|
||||||
l = l[:-lss]
|
l = l[:-lss]
|
||||||
|
# Do not strip more than one suffix
|
||||||
|
break
|
||||||
|
|
||||||
stripped.append(l)
|
stripped.append(l)
|
||||||
|
|
||||||
return c(prefix, stripped, suffix, env)
|
return c(prefix, stripped, suffix, env)
|
||||||
|
@ -378,7 +424,10 @@ class Variable_Method_Caller:
|
||||||
self.method = method
|
self.method = method
|
||||||
def __call__(self, *args, **kw):
|
def __call__(self, *args, **kw):
|
||||||
try: 1/0
|
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
|
variable = self.variable
|
||||||
while frame:
|
while frame:
|
||||||
if frame.f_locals.has_key(variable):
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 copy
|
||||||
import os
|
import os
|
||||||
import os.path
|
import sys
|
||||||
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
import string
|
import string
|
||||||
from UserDict import UserDict
|
from UserDict import UserDict
|
||||||
|
@ -64,6 +65,10 @@ class _Null:
|
||||||
|
|
||||||
_null = _Null
|
_null = _Null
|
||||||
|
|
||||||
|
_warn_copy_deprecated = True
|
||||||
|
_warn_source_signatures_deprecated = True
|
||||||
|
_warn_target_signatures_deprecated = True
|
||||||
|
|
||||||
CleanTargets = {}
|
CleanTargets = {}
|
||||||
CalculatorArgs = {}
|
CalculatorArgs = {}
|
||||||
|
|
||||||
|
@ -100,24 +105,40 @@ def apply_tools(env, tools, toolpath):
|
||||||
else:
|
else:
|
||||||
env.Tool(tool)
|
env.Tool(tool)
|
||||||
|
|
||||||
# These names are controlled by SCons; users should never set or override
|
# These names are (or will be) controlled by SCons; users should never
|
||||||
# them. This warning can optionally be turned off, but scons will still
|
# set or override them. This warning can optionally be turned off,
|
||||||
# ignore the illegal variable names even if it's off.
|
# but scons will still ignore the illegal variable names even if it's off.
|
||||||
reserved_construction_var_names = \
|
reserved_construction_var_names = [
|
||||||
['TARGET', 'TARGETS', 'SOURCE', 'SOURCES']
|
'SOURCE',
|
||||||
|
'SOURCES',
|
||||||
|
'TARGET',
|
||||||
|
'TARGETS',
|
||||||
|
]
|
||||||
|
|
||||||
|
future_reserved_construction_var_names = [
|
||||||
|
'CHANGED_SOURCES',
|
||||||
|
'CHANGED_TARGETS',
|
||||||
|
'UNCHANGED_SOURCES',
|
||||||
|
'UNCHANGED_TARGETS',
|
||||||
|
]
|
||||||
|
|
||||||
def copy_non_reserved_keywords(dict):
|
def copy_non_reserved_keywords(dict):
|
||||||
result = semi_deepcopy(dict)
|
result = semi_deepcopy(dict)
|
||||||
for k in result.keys():
|
for k in result.keys():
|
||||||
if k in reserved_construction_var_names:
|
if k in reserved_construction_var_names:
|
||||||
SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning,
|
msg = "Ignoring attempt to set reserved variable `$%s'"
|
||||||
"Ignoring attempt to set reserved variable `%s'" % k)
|
SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % k)
|
||||||
del result[k]
|
del result[k]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _set_reserved(env, key, value):
|
def _set_reserved(env, key, value):
|
||||||
msg = "Ignoring attempt to set reserved variable `%s'" % key
|
msg = "Ignoring attempt to set reserved variable `$%s'"
|
||||||
SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg)
|
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):
|
def _set_BUILDERS(env, key, value):
|
||||||
try:
|
try:
|
||||||
|
@ -137,6 +158,24 @@ def _set_SCANNERS(env, key, value):
|
||||||
env._dict[key] = value
|
env._dict[key] = value
|
||||||
env.scanner_map_delete()
|
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
|
# The following is partly based on code in a comment added by Peter
|
||||||
|
@ -225,7 +264,7 @@ class BuilderWrapper(MethodWrapper):
|
||||||
elif name == 'builder':
|
elif name == 'builder':
|
||||||
return self.method
|
return self.method
|
||||||
else:
|
else:
|
||||||
return self.__dict__[name]
|
raise AttributeError, name
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
if name == 'env':
|
if name == 'env':
|
||||||
|
@ -279,6 +318,18 @@ class BuilderDict(UserDict):
|
||||||
for i, v in dict.items():
|
for i, v in dict.items():
|
||||||
self.__setitem__(i, v)
|
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:
|
class SubstitutionEnvironment:
|
||||||
"""Base class for different flavors of construction environments.
|
"""Base class for different flavors of construction environments.
|
||||||
|
|
||||||
|
@ -329,9 +380,16 @@ class SubstitutionEnvironment:
|
||||||
self._special_set = {}
|
self._special_set = {}
|
||||||
for key in reserved_construction_var_names:
|
for key in reserved_construction_var_names:
|
||||||
self._special_set[key] = _set_reserved
|
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['BUILDERS'] = _set_BUILDERS
|
||||||
self._special_set['SCANNERS'] = _set_SCANNERS
|
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):
|
def __cmp__(self, other):
|
||||||
return cmp(self._dict, other._dict)
|
return cmp(self._dict, other._dict)
|
||||||
|
|
||||||
|
@ -346,11 +404,27 @@ class SubstitutionEnvironment:
|
||||||
return self._dict[key]
|
return self._dict[key]
|
||||||
|
|
||||||
def __setitem__(self, key, value):
|
def __setitem__(self, key, value):
|
||||||
special = self._special_set.get(key)
|
# This is heavily used. This implementation is the best we have
|
||||||
if special:
|
# according to the timings in bench/env.__setitem__.py.
|
||||||
special(self, key, value)
|
#
|
||||||
|
# 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:
|
else:
|
||||||
if not SCons.Util.is_valid_construction_var(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
|
raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key
|
||||||
self._dict[key] = value
|
self._dict[key] = value
|
||||||
|
|
||||||
|
@ -361,6 +435,9 @@ class SubstitutionEnvironment:
|
||||||
def has_key(self, key):
|
def has_key(self, key):
|
||||||
return self._dict.has_key(key)
|
return self._dict.has_key(key)
|
||||||
|
|
||||||
|
def __contains__(self, key):
|
||||||
|
return self._dict.__contains__(key)
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
return self._dict.items()
|
return self._dict.items()
|
||||||
|
|
||||||
|
@ -373,10 +450,7 @@ class SubstitutionEnvironment:
|
||||||
if not args:
|
if not args:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if SCons.Util.is_List(args):
|
|
||||||
args = SCons.Util.flatten(args)
|
args = SCons.Util.flatten(args)
|
||||||
else:
|
|
||||||
args = [args]
|
|
||||||
|
|
||||||
nodes = []
|
nodes = []
|
||||||
for v in args:
|
for v in args:
|
||||||
|
@ -465,7 +539,7 @@ class SubstitutionEnvironment:
|
||||||
try:
|
try:
|
||||||
get = obj.get
|
get = obj.get
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
obj = SCons.Util.to_String_for_subst(obj)
|
||||||
else:
|
else:
|
||||||
obj = get()
|
obj = get()
|
||||||
return obj
|
return obj
|
||||||
|
@ -481,7 +555,7 @@ class SubstitutionEnvironment:
|
||||||
# We have an object plus a string, or multiple
|
# We have an object plus a string, or multiple
|
||||||
# objects that we need to smush together. No choice
|
# objects that we need to smush together. No choice
|
||||||
# but to make them into a string.
|
# 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:
|
else:
|
||||||
p = s(p)
|
p = s(p)
|
||||||
r.append(p)
|
r.append(p)
|
||||||
|
@ -491,24 +565,21 @@ class SubstitutionEnvironment:
|
||||||
|
|
||||||
def backtick(self, command):
|
def backtick(self, command):
|
||||||
import subprocess
|
import subprocess
|
||||||
if SCons.Util.is_List(command):
|
# common arguments
|
||||||
p = subprocess.Popen(command,
|
kw = { 'stdin' : 'devnull',
|
||||||
stdout=subprocess.PIPE,
|
'stdout' : subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE,
|
'stderr' : subprocess.PIPE,
|
||||||
universal_newlines=True)
|
'universal_newlines' : True,
|
||||||
else:
|
}
|
||||||
p = subprocess.Popen(command,
|
# if the command is a list, assume it's been quoted
|
||||||
stdout=subprocess.PIPE,
|
# othewise force a shell
|
||||||
stderr=subprocess.PIPE,
|
if not SCons.Util.is_List(command): kw['shell'] = True
|
||||||
universal_newlines=True,
|
# run constructed command
|
||||||
shell=True)
|
#TODO(1.5) p = SCons.Action._subproc(self, command, **kw)
|
||||||
out = p.stdout.read()
|
p = apply(SCons.Action._subproc, (self, command), kw)
|
||||||
p.stdout.close()
|
out,err = p.communicate()
|
||||||
err = p.stderr.read()
|
|
||||||
p.stderr.close()
|
|
||||||
status = p.wait()
|
status = p.wait()
|
||||||
if err:
|
if err:
|
||||||
import sys
|
|
||||||
sys.stderr.write(err)
|
sys.stderr.write(err)
|
||||||
if status:
|
if status:
|
||||||
raise OSError("'%s' exited %d" % (command, 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
|
environment, and doesn't even create a wrapper object if there
|
||||||
are no overrides.
|
are no overrides.
|
||||||
"""
|
"""
|
||||||
if overrides:
|
if not overrides: return self
|
||||||
o = copy_non_reserved_keywords(overrides)
|
o = copy_non_reserved_keywords(overrides)
|
||||||
|
if not o: return self
|
||||||
overrides = {}
|
overrides = {}
|
||||||
|
merges = None
|
||||||
for key, value in o.items():
|
for key, value in o.items():
|
||||||
overrides[key] = SCons.Subst.scons_subst_once(value, self, key)
|
if key == 'parse_flags':
|
||||||
if overrides:
|
merges = value
|
||||||
env = OverrideEnvironment(self, overrides)
|
|
||||||
return env
|
|
||||||
else:
|
else:
|
||||||
return self
|
overrides[key] = SCons.Subst.scons_subst_once(value, self, key)
|
||||||
|
env = OverrideEnvironment(self, overrides)
|
||||||
|
if merges: env.MergeFlags(merges)
|
||||||
|
return env
|
||||||
|
|
||||||
def ParseFlags(self, *flags):
|
def ParseFlags(self, *flags):
|
||||||
"""
|
"""
|
||||||
|
@ -709,13 +783,16 @@ class SubstitutionEnvironment:
|
||||||
do_parse(arg, do_parse)
|
do_parse(arg, do_parse)
|
||||||
return dict
|
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
|
Merge the dict in args into the construction variables of this
|
||||||
is not a dict, it is converted into a dict using ParseFlags.
|
env, or the passed-in dict. If args is not a dict, it is
|
||||||
If unique is not set, the flags are appended rather than merged.
|
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):
|
if not SCons.Util.is_Dict(args):
|
||||||
args = self.ParseFlags(args)
|
args = self.ParseFlags(args)
|
||||||
if not unique:
|
if not unique:
|
||||||
|
@ -763,6 +840,26 @@ class SubstitutionEnvironment:
|
||||||
self[key] = t
|
self[key] = t
|
||||||
return self
|
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.
|
# Used by the FindSourceFiles() method, below.
|
||||||
# Stuck here for support of pre-2.2 Python versions.
|
# Stuck here for support of pre-2.2 Python versions.
|
||||||
def build_source(ss, result):
|
def build_source(ss, result):
|
||||||
|
@ -819,7 +916,8 @@ class Base(SubstitutionEnvironment):
|
||||||
platform=None,
|
platform=None,
|
||||||
tools=None,
|
tools=None,
|
||||||
toolpath=None,
|
toolpath=None,
|
||||||
options=None,
|
variables=None,
|
||||||
|
parse_flags = None,
|
||||||
**kw):
|
**kw):
|
||||||
"""
|
"""
|
||||||
Initialization of a basic SCons construction environment,
|
Initialization of a basic SCons construction environment,
|
||||||
|
@ -862,14 +960,19 @@ class Base(SubstitutionEnvironment):
|
||||||
self._dict['PLATFORM'] = str(platform)
|
self._dict['PLATFORM'] = str(platform)
|
||||||
platform(self)
|
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
|
# environment before calling the tools, because they may use
|
||||||
# some of them during initialization.
|
# 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)
|
apply(self.Replace, (), kw)
|
||||||
keys = kw.keys()
|
keys = kw.keys()
|
||||||
if options:
|
if variables:
|
||||||
keys = keys + options.keys()
|
keys = keys + variables.keys()
|
||||||
options.Update(self)
|
variables.Update(self)
|
||||||
|
|
||||||
save = {}
|
save = {}
|
||||||
for k in keys:
|
for k in keys:
|
||||||
|
@ -888,12 +991,15 @@ class Base(SubstitutionEnvironment):
|
||||||
tools = ['default']
|
tools = ['default']
|
||||||
apply_tools(self, tools, toolpath)
|
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
|
# to the environment, since the values the user set explicitly
|
||||||
# should override any values set by the tools.
|
# should override any values set by the tools.
|
||||||
for key, val in save.items():
|
for key, val in save.items():
|
||||||
self._dict[key] = val
|
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.
|
# Utility methods that are primarily for internal use by SCons.
|
||||||
# These begin with lower-case letters.
|
# These begin with lower-case letters.
|
||||||
|
@ -909,10 +1015,17 @@ class Base(SubstitutionEnvironment):
|
||||||
|
|
||||||
def get_CacheDir(self):
|
def get_CacheDir(self):
|
||||||
try:
|
try:
|
||||||
return self._CacheDir
|
path = self._CacheDir_path
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
cd = SCons.Defaults.DefaultEnvironment()._CacheDir
|
path = SCons.Defaults.DefaultEnvironment()._CacheDir_path
|
||||||
self._CacheDir = cd
|
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
|
return cd
|
||||||
|
|
||||||
def get_factory(self, factory, default='File'):
|
def get_factory(self, factory, default='File'):
|
||||||
|
@ -1085,31 +1198,39 @@ class Base(SubstitutionEnvironment):
|
||||||
orig[val] = None
|
orig[val] = None
|
||||||
self.scanner_map_delete(kw)
|
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'
|
"""Append path elements to the path 'name' in the 'ENV'
|
||||||
dictionary for this environment. Will only add any particular
|
dictionary for this environment. Will only add any particular
|
||||||
path once, and will normpath and normcase all paths to help
|
path once, and will normpath and normcase all paths to help
|
||||||
assure this. This can also handle the case where the env
|
assure this. This can also handle the case where the env
|
||||||
variable is a list instead of a string.
|
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 = ''
|
orig = ''
|
||||||
if self._dict.has_key(envname) and self._dict[envname].has_key(name):
|
if self._dict.has_key(envname) and self._dict[envname].has_key(name):
|
||||||
orig = self._dict[envname][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):
|
if not self._dict.has_key(envname):
|
||||||
self._dict[envname] = {}
|
self._dict[envname] = {}
|
||||||
|
|
||||||
self._dict[envname][name] = nv
|
self._dict[envname][name] = nv
|
||||||
|
|
||||||
def AppendUnique(self, **kw):
|
def AppendUnique(self, delete_existing=0, **kw):
|
||||||
"""Append values to existing construction variables
|
"""Append values to existing construction variables
|
||||||
in an Environment, if they're not already there.
|
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)
|
kw = copy_non_reserved_keywords(kw)
|
||||||
for key, val in kw.items():
|
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):
|
if not self._dict.has_key(key) or self._dict[key] in ('', None):
|
||||||
self._dict[key] = val
|
self._dict[key] = val
|
||||||
elif SCons.Util.is_Dict(self._dict[key]) and \
|
elif SCons.Util.is_Dict(self._dict[key]) and \
|
||||||
|
@ -1119,6 +1240,9 @@ class Base(SubstitutionEnvironment):
|
||||||
dk = self._dict[key]
|
dk = self._dict[key]
|
||||||
if not SCons.Util.is_List(dk):
|
if not SCons.Util.is_List(dk):
|
||||||
dk = [dk]
|
dk = [dk]
|
||||||
|
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)
|
val = filter(lambda x, dk=dk: x not in dk, val)
|
||||||
self._dict[key] = dk + val
|
self._dict[key] = dk + val
|
||||||
else:
|
else:
|
||||||
|
@ -1126,13 +1250,19 @@ class Base(SubstitutionEnvironment):
|
||||||
if SCons.Util.is_List(dk):
|
if SCons.Util.is_List(dk):
|
||||||
# By elimination, val is not a list. Since dk is a
|
# By elimination, val is not a list. Since dk is a
|
||||||
# list, wrap val in a list first.
|
# list, wrap val in a list first.
|
||||||
|
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:
|
if not val in dk:
|
||||||
self._dict[key] = dk + [val]
|
self._dict[key] = dk + [val]
|
||||||
else:
|
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)
|
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
|
"""Return a copy of a construction Environment. The
|
||||||
copy is like a Python "deep copy"--that is, independent
|
copy is like a Python "deep copy"--that is, independent
|
||||||
copies are made recursively of each objects--except that
|
copies are made recursively of each objects--except that
|
||||||
|
@ -1150,8 +1280,13 @@ class Base(SubstitutionEnvironment):
|
||||||
else:
|
else:
|
||||||
clone._dict['BUILDERS'] = BuilderDict(cbd, clone)
|
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 = []
|
clone.added_methods = []
|
||||||
for mw in self.added_methods:
|
for mw in self.added_methods:
|
||||||
|
if mw == getattr(self, mw.name):
|
||||||
clone.added_methods.append(mw.clone(clone))
|
clone.added_methods.append(mw.clone(clone))
|
||||||
|
|
||||||
clone._memo = {}
|
clone._memo = {}
|
||||||
|
@ -1169,10 +1304,18 @@ class Base(SubstitutionEnvironment):
|
||||||
# apply them again in case the tools overwrote them
|
# apply them again in case the tools overwrote them
|
||||||
apply(clone.Replace, (), new)
|
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')
|
if __debug__: logInstanceCreation(self, 'Environment.EnvironmentClone')
|
||||||
return clone
|
return clone
|
||||||
|
|
||||||
def Copy(self, *args, **kw):
|
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)
|
return apply(self.Clone, args, kw)
|
||||||
|
|
||||||
def _changed_build(self, dependency, target, prev_ni):
|
def _changed_build(self, dependency, target, prev_ni):
|
||||||
|
@ -1410,31 +1553,39 @@ class Base(SubstitutionEnvironment):
|
||||||
orig[val] = None
|
orig[val] = None
|
||||||
self.scanner_map_delete(kw)
|
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'
|
"""Prepend path elements to the path 'name' in the 'ENV'
|
||||||
dictionary for this environment. Will only add any particular
|
dictionary for this environment. Will only add any particular
|
||||||
path once, and will normpath and normcase all paths to help
|
path once, and will normpath and normcase all paths to help
|
||||||
assure this. This can also handle the case where the env
|
assure this. This can also handle the case where the env
|
||||||
variable is a list instead of a string.
|
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 = ''
|
orig = ''
|
||||||
if self._dict.has_key(envname) and self._dict[envname].has_key(name):
|
if self._dict.has_key(envname) and self._dict[envname].has_key(name):
|
||||||
orig = self._dict[envname][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):
|
if not self._dict.has_key(envname):
|
||||||
self._dict[envname] = {}
|
self._dict[envname] = {}
|
||||||
|
|
||||||
self._dict[envname][name] = nv
|
self._dict[envname][name] = nv
|
||||||
|
|
||||||
def PrependUnique(self, **kw):
|
def PrependUnique(self, delete_existing=0, **kw):
|
||||||
"""Append values to existing construction variables
|
"""Prepend values to existing construction variables
|
||||||
in an Environment, if they're not already there.
|
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)
|
kw = copy_non_reserved_keywords(kw)
|
||||||
for key, val in kw.items():
|
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):
|
if not self._dict.has_key(key) or self._dict[key] in ('', None):
|
||||||
self._dict[key] = val
|
self._dict[key] = val
|
||||||
elif SCons.Util.is_Dict(self._dict[key]) and \
|
elif SCons.Util.is_Dict(self._dict[key]) and \
|
||||||
|
@ -1444,6 +1595,9 @@ class Base(SubstitutionEnvironment):
|
||||||
dk = self._dict[key]
|
dk = self._dict[key]
|
||||||
if not SCons.Util.is_List(dk):
|
if not SCons.Util.is_List(dk):
|
||||||
dk = [dk]
|
dk = [dk]
|
||||||
|
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)
|
val = filter(lambda x, dk=dk: x not in dk, val)
|
||||||
self._dict[key] = val + dk
|
self._dict[key] = val + dk
|
||||||
else:
|
else:
|
||||||
|
@ -1451,9 +1605,15 @@ class Base(SubstitutionEnvironment):
|
||||||
if SCons.Util.is_List(dk):
|
if SCons.Util.is_List(dk):
|
||||||
# By elimination, val is not a list. Since dk is a
|
# By elimination, val is not a list. Since dk is a
|
||||||
# list, wrap val in a list first.
|
# list, wrap val in a list first.
|
||||||
|
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:
|
if not val in dk:
|
||||||
self._dict[key] = [val] + dk
|
self._dict[key] = [val] + dk
|
||||||
else:
|
else:
|
||||||
|
if delete_existing:
|
||||||
|
dk = filter(lambda x, val=val: x not in val, dk)
|
||||||
self._dict[key] = val + dk
|
self._dict[key] = val + dk
|
||||||
self.scanner_map_delete(kw)
|
self.scanner_map_delete(kw)
|
||||||
|
|
||||||
|
@ -1532,6 +1692,7 @@ class Base(SubstitutionEnvironment):
|
||||||
pass
|
pass
|
||||||
elif SCons.Util.is_String(pathext):
|
elif SCons.Util.is_String(pathext):
|
||||||
pathext = self.subst(pathext)
|
pathext = self.subst(pathext)
|
||||||
|
prog = self.subst(prog)
|
||||||
path = SCons.Util.WhereIs(prog, path, pathext, reject)
|
path = SCons.Util.WhereIs(prog, path, pathext, reject)
|
||||||
if path: return path
|
if path: return path
|
||||||
return None
|
return None
|
||||||
|
@ -1634,10 +1795,11 @@ class Base(SubstitutionEnvironment):
|
||||||
t.set_always_build()
|
t.set_always_build()
|
||||||
return tlist
|
return tlist
|
||||||
|
|
||||||
def BuildDir(self, build_dir, src_dir, duplicate=1):
|
def BuildDir(self, *args, **kw):
|
||||||
build_dir = self.arg2nodes(build_dir, self.fs.Dir)[0]
|
if kw.has_key('build_dir'):
|
||||||
src_dir = self.arg2nodes(src_dir, self.fs.Dir)[0]
|
kw['variant_dir'] = kw['build_dir']
|
||||||
self.fs.BuildDir(build_dir, src_dir, duplicate)
|
del kw['build_dir']
|
||||||
|
return apply(self.VariantDir, args, kw)
|
||||||
|
|
||||||
def Builder(self, **kw):
|
def Builder(self, **kw):
|
||||||
nkw = self.subst_kw(kw)
|
nkw = self.subst_kw(kw)
|
||||||
|
@ -1645,10 +1807,9 @@ class Base(SubstitutionEnvironment):
|
||||||
|
|
||||||
def CacheDir(self, path):
|
def CacheDir(self, path):
|
||||||
import SCons.CacheDir
|
import SCons.CacheDir
|
||||||
if path is None:
|
if not path is None:
|
||||||
self._CacheDir = SCons.CacheDir.Null()
|
path = self.subst(path)
|
||||||
else:
|
self._CacheDir_path = path
|
||||||
self._CacheDir = SCons.CacheDir.CacheDir(self.subst(path))
|
|
||||||
|
|
||||||
def Clean(self, targets, files):
|
def Clean(self, targets, files):
|
||||||
global CleanTargets
|
global CleanTargets
|
||||||
|
@ -1699,7 +1860,13 @@ class Base(SubstitutionEnvironment):
|
||||||
def Dir(self, name, *args, **kw):
|
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):
|
def NoClean(self, *targets):
|
||||||
"""Tags a target so that it will not be cleaned by -c"""
|
"""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):
|
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):
|
def Environment(self, **kw):
|
||||||
return apply(SCons.Environment.Environment, [], self.subst_kw(kw))
|
return apply(SCons.Environment.Environment, [], self.subst_kw(kw))
|
||||||
|
@ -1733,6 +1906,10 @@ class Base(SubstitutionEnvironment):
|
||||||
action = apply(self.Action, (action,) + args, kw)
|
action = apply(self.Action, (action,) + args, kw)
|
||||||
result = action([], [], self)
|
result = action([], [], self)
|
||||||
if isinstance(result, SCons.Errors.BuildError):
|
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
|
return result.status
|
||||||
else:
|
else:
|
||||||
return result
|
return result
|
||||||
|
@ -1740,7 +1917,13 @@ class Base(SubstitutionEnvironment):
|
||||||
def File(self, name, *args, **kw):
|
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):
|
def FindFile(self, file, dirs):
|
||||||
file = self.subst(file)
|
file = self.subst(file)
|
||||||
|
@ -1819,6 +2002,11 @@ class Base(SubstitutionEnvironment):
|
||||||
name = self.subst(name)
|
name = self.subst(name)
|
||||||
if not os.path.isabs(name):
|
if not os.path.isabs(name):
|
||||||
name = os.path.join(str(self.fs.SConstruct_dir), 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)
|
SCons.SConsign.File(name, dbm_module)
|
||||||
|
|
||||||
def SideEffect(self, side_effect, target):
|
def SideEffect(self, side_effect, target):
|
||||||
|
@ -1845,6 +2033,12 @@ class Base(SubstitutionEnvironment):
|
||||||
return entries
|
return entries
|
||||||
|
|
||||||
def SourceSignatures(self, type):
|
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)
|
type = self.subst(type)
|
||||||
self.src_sig_type = type
|
self.src_sig_type = type
|
||||||
if type == 'MD5':
|
if type == 'MD5':
|
||||||
|
@ -1875,6 +2069,12 @@ class Base(SubstitutionEnvironment):
|
||||||
return [self.subst(arg)]
|
return [self.subst(arg)]
|
||||||
|
|
||||||
def TargetSignatures(self, type):
|
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)
|
type = self.subst(type)
|
||||||
self.tgt_sig_type = type
|
self.tgt_sig_type = type
|
||||||
if type in ('MD5', 'content'):
|
if type in ('MD5', 'content'):
|
||||||
|
@ -1895,6 +2095,11 @@ class Base(SubstitutionEnvironment):
|
||||||
"""
|
"""
|
||||||
return SCons.Node.Python.Value(value, built_value)
|
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='.'):
|
def FindSourceFiles(self, node='.'):
|
||||||
""" returns a list of all source files.
|
""" returns a list of all source files.
|
||||||
"""
|
"""
|
||||||
|
@ -1978,7 +2183,7 @@ class OverrideEnvironment(Base):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return self.__dict__['__subject'].__getitem__(key)
|
return self.__dict__['__subject'].__getitem__(key)
|
||||||
def __setitem__(self, key, value):
|
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
|
raise SCons.Errors.UserError, "Illegal construction variable `%s'" % key
|
||||||
self.__dict__['overrides'][key] = value
|
self.__dict__['overrides'][key] = value
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key):
|
||||||
|
@ -2007,6 +2212,10 @@ class OverrideEnvironment(Base):
|
||||||
return 1
|
return 1
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return self.__dict__['__subject'].has_key(key)
|
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):
|
def Dictionary(self):
|
||||||
"""Emulates the items() method of dictionaries."""
|
"""Emulates the items() method of dictionaries."""
|
||||||
d = self.__dict__['__subject'].Dictionary().copy()
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
import string
|
||||||
|
|
||||||
|
@ -134,7 +134,11 @@ class Executor:
|
||||||
raise status
|
raise status
|
||||||
elif status:
|
elif status:
|
||||||
msg = "Error %s" % 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
|
return status
|
||||||
|
|
||||||
# use extra indirection because with new-style objects (Python 2.2
|
# use extra indirection because with new-style objects (Python 2.2
|
||||||
|
@ -160,6 +164,16 @@ class Executor:
|
||||||
self.sources_need_sorting = False
|
self.sources_need_sorting = False
|
||||||
return self.sources
|
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):
|
def add_pre_action(self, action):
|
||||||
self.pre_actions.append(action)
|
self.pre_actions.append(action)
|
||||||
|
|
||||||
|
@ -221,28 +235,28 @@ class Executor:
|
||||||
This essentially short-circuits an N*M scan of the sources for
|
This essentially short-circuits an N*M scan of the sources for
|
||||||
each individual target, which is a hell of a lot more efficient.
|
each individual target, which is a hell of a lot more efficient.
|
||||||
"""
|
"""
|
||||||
map(lambda N: N.disambiguate(), node_list)
|
|
||||||
|
|
||||||
env = self.get_build_env()
|
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 = []
|
deps = []
|
||||||
for node, scanner, path in scanner_path_list:
|
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(node.get_implicit_deps(env, scanner, path))
|
||||||
|
|
||||||
deps.extend(self.get_implicit_deps())
|
deps.extend(self.get_implicit_deps())
|
||||||
|
@ -250,11 +264,6 @@ class Executor:
|
||||||
for tgt in self.targets:
|
for tgt in self.targets:
|
||||||
tgt.add_to_implicit(deps)
|
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=()):
|
def _get_unignored_sources_key(self, ignore=()):
|
||||||
return tuple(ignore)
|
return tuple(ignore)
|
||||||
|
|
||||||
|
@ -317,10 +326,25 @@ class Executor:
|
||||||
result.extend(act.get_implicit_deps(self.targets, self.get_sources(), build_env))
|
result.extend(act.get_implicit_deps(self.targets, self.get_sources(), build_env))
|
||||||
return result
|
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
|
"""A null Executor, with a null build Environment, that does
|
||||||
nothing when the rest of the methods call it.
|
nothing when the rest of the methods call it.
|
||||||
|
|
||||||
|
@ -330,20 +354,40 @@ class Null(_Executor):
|
||||||
"""
|
"""
|
||||||
def __init__(self, *args, **kw):
|
def __init__(self, *args, **kw):
|
||||||
if __debug__: logInstanceCreation(self, 'Executor.Null')
|
if __debug__: logInstanceCreation(self, 'Executor.Null')
|
||||||
kw['action'] = []
|
self.targets = kw['targets']
|
||||||
apply(_Executor.__init__, (self,), kw)
|
|
||||||
def get_build_env(self):
|
def get_build_env(self):
|
||||||
import SCons.Util
|
return get_NullEnvironment()
|
||||||
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()
|
|
||||||
def get_build_scanner_path(self):
|
def get_build_scanner_path(self):
|
||||||
return None
|
return None
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
pass
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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:
|
class Jobs:
|
||||||
"""An instance of this class initializes N jobs, and provides
|
"""An instance of this class initializes N jobs, and provides
|
||||||
|
@ -54,8 +82,12 @@ class Jobs:
|
||||||
|
|
||||||
self.job = None
|
self.job = None
|
||||||
if num > 1:
|
if num > 1:
|
||||||
|
stack_size = explicit_stack_size
|
||||||
|
if stack_size is None:
|
||||||
|
stack_size = default_stack_size
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.job = Parallel(taskmaster, num)
|
self.job = Parallel(taskmaster, num, stack_size)
|
||||||
self.num_jobs = num
|
self.num_jobs = num
|
||||||
except NameError:
|
except NameError:
|
||||||
pass
|
pass
|
||||||
|
@ -63,21 +95,71 @@ class Jobs:
|
||||||
self.job = Serial(taskmaster)
|
self.job = Serial(taskmaster)
|
||||||
self.num_jobs = 1
|
self.num_jobs = 1
|
||||||
|
|
||||||
def run(self):
|
def run(self, postfunc=lambda: None):
|
||||||
"""run the job"""
|
"""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:
|
try:
|
||||||
self.job.start()
|
self.job.start()
|
||||||
except KeyboardInterrupt:
|
finally:
|
||||||
# mask any further keyboard interrupts so that scons
|
postfunc()
|
||||||
# can shutdown cleanly:
|
self._reset_sig_handler()
|
||||||
# (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
|
|
||||||
|
|
||||||
def cleanup(self):
|
def were_interrupted(self):
|
||||||
self.job.cleanup()
|
"""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:
|
class Serial:
|
||||||
"""This class is used to execute tasks in series, and is more efficient
|
"""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)."""
|
execute (e.g. execute() raised an exception)."""
|
||||||
|
|
||||||
self.taskmaster = taskmaster
|
self.taskmaster = taskmaster
|
||||||
|
self.interrupted = InterruptState()
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""Start the job. This will begin pulling tasks from the taskmaster
|
"""Start the job. This will begin pulling tasks from the taskmaster
|
||||||
|
@ -112,11 +195,18 @@ class Serial:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
task.prepare()
|
task.prepare()
|
||||||
|
if task.needs_execute():
|
||||||
task.execute()
|
task.execute()
|
||||||
except KeyboardInterrupt:
|
except:
|
||||||
raise
|
if self.interrupted():
|
||||||
|
try:
|
||||||
|
raise SCons.Errors.BuildError(
|
||||||
|
task.targets[0], errstr=interrupt_msg)
|
||||||
except:
|
except:
|
||||||
task.exception_set()
|
task.exception_set()
|
||||||
|
else:
|
||||||
|
task.exception_set()
|
||||||
|
|
||||||
# Let the failed() callback function arrange for the
|
# Let the failed() callback function arrange for the
|
||||||
# build to stop if that's appropriate.
|
# build to stop if that's appropriate.
|
||||||
task.failed()
|
task.failed()
|
||||||
|
@ -124,9 +214,8 @@ class Serial:
|
||||||
task.executed()
|
task.executed()
|
||||||
|
|
||||||
task.postprocess()
|
task.postprocess()
|
||||||
|
self.taskmaster.cleanup()
|
||||||
|
|
||||||
def cleanup(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Trap import failure so that everything in the Job module but the
|
# Trap import failure so that everything in the Job module but the
|
||||||
# Parallel class (and its dependent classes) will work if the interpreter
|
# 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
|
dequeues the task, executes it, and posts a tuple including the task
|
||||||
and a boolean indicating whether the task executed successfully. """
|
and a boolean indicating whether the task executed successfully. """
|
||||||
|
|
||||||
def __init__(self, requestQueue, resultsQueue):
|
def __init__(self, requestQueue, resultsQueue, interrupted):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
self.setDaemon(1)
|
self.setDaemon(1)
|
||||||
self.requestQueue = requestQueue
|
self.requestQueue = requestQueue
|
||||||
self.resultsQueue = resultsQueue
|
self.resultsQueue = resultsQueue
|
||||||
|
self.interrupted = interrupted
|
||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while 1:
|
while 1:
|
||||||
task = self.requestQueue.get()
|
task = self.requestQueue.get()
|
||||||
|
|
||||||
if not task:
|
if task is None:
|
||||||
# The "None" value is used as a sentinel by
|
# The "None" value is used as a sentinel by
|
||||||
# ThreadPool.cleanup(). This indicates that there
|
# ThreadPool.cleanup(). This indicates that there
|
||||||
# are no more tasks, so we should quit.
|
# are no more tasks, so we should quit.
|
||||||
break
|
break
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
if self.interrupted():
|
||||||
|
raise SCons.Errors.BuildError(
|
||||||
|
task.targets[0], errstr=interrupt_msg)
|
||||||
task.execute()
|
task.execute()
|
||||||
except KeyboardInterrupt:
|
|
||||||
# be explicit here for test/interrupts.py
|
|
||||||
ok = False
|
|
||||||
except:
|
except:
|
||||||
task.exception_set()
|
task.exception_set()
|
||||||
ok = False
|
ok = False
|
||||||
|
@ -175,27 +265,49 @@ else:
|
||||||
class ThreadPool:
|
class ThreadPool:
|
||||||
"""This class is responsible for spawning and managing worker threads."""
|
"""This class is responsible for spawning and managing worker threads."""
|
||||||
|
|
||||||
def __init__(self, num):
|
def __init__(self, num, stack_size, interrupted):
|
||||||
"""Create the request and reply queues, and 'num' worker threads."""
|
"""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.requestQueue = Queue.Queue(0)
|
||||||
self.resultsQueue = 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
|
# Create worker threads
|
||||||
self.workers = []
|
self.workers = []
|
||||||
for _ in range(num):
|
for _ in range(num):
|
||||||
worker = Worker(self.requestQueue, self.resultsQueue)
|
worker = Worker(self.requestQueue, self.resultsQueue, interrupted)
|
||||||
self.workers.append(worker)
|
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."""
|
"""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."""
|
"""Remove and return a result tuple from the results queue."""
|
||||||
return self.resultsQueue.get(block)
|
return self.resultsQueue.get()
|
||||||
|
|
||||||
def preparation_failed(self, obj):
|
def preparation_failed(self, task):
|
||||||
self.resultsQueue.put((obj, False))
|
self.resultsQueue.put((task, False))
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
"""
|
"""
|
||||||
|
@ -233,7 +345,7 @@ else:
|
||||||
This class is thread safe.
|
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.
|
"""Create a new parallel job given a taskmaster.
|
||||||
|
|
||||||
The taskmaster's next_task() method should return the next
|
The taskmaster's next_task() method should return the next
|
||||||
|
@ -249,7 +361,8 @@ else:
|
||||||
multiple tasks simultaneously. """
|
multiple tasks simultaneously. """
|
||||||
|
|
||||||
self.taskmaster = taskmaster
|
self.taskmaster = taskmaster
|
||||||
self.tp = ThreadPool(num)
|
self.interrupted = InterruptState()
|
||||||
|
self.tp = ThreadPool(num, stack_size, self.interrupted)
|
||||||
|
|
||||||
self.maxjobs = num
|
self.maxjobs = num
|
||||||
|
|
||||||
|
@ -269,22 +382,21 @@ else:
|
||||||
if task is None:
|
if task is None:
|
||||||
break
|
break
|
||||||
|
|
||||||
# prepare task for execution
|
|
||||||
try:
|
try:
|
||||||
|
# prepare task for execution
|
||||||
task.prepare()
|
task.prepare()
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except:
|
except:
|
||||||
# Let the failed() callback function arrange
|
|
||||||
# for the build to stop if that's appropriate.
|
|
||||||
task.exception_set()
|
task.exception_set()
|
||||||
self.tp.preparation_failed(task)
|
task.failed()
|
||||||
jobs = jobs + 1
|
task.postprocess()
|
||||||
continue
|
else:
|
||||||
|
if task.needs_execute():
|
||||||
# dispatch task
|
# dispatch task
|
||||||
self.tp.put(task)
|
self.tp.put(task)
|
||||||
jobs = jobs + 1
|
jobs = jobs + 1
|
||||||
|
else:
|
||||||
|
task.executed()
|
||||||
|
task.postprocess()
|
||||||
|
|
||||||
if not task and not jobs: break
|
if not task and not jobs: break
|
||||||
|
|
||||||
|
@ -292,11 +404,20 @@ else:
|
||||||
# back and put the next batch of tasks on the queue.
|
# back and put the next batch of tasks on the queue.
|
||||||
while 1:
|
while 1:
|
||||||
task, ok = self.tp.get()
|
task, ok = self.tp.get()
|
||||||
|
|
||||||
jobs = jobs - 1
|
jobs = jobs - 1
|
||||||
|
|
||||||
if ok:
|
if ok:
|
||||||
task.executed()
|
task.executed()
|
||||||
else:
|
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.failed()
|
||||||
|
|
||||||
task.postprocess()
|
task.postprocess()
|
||||||
|
@ -304,5 +425,5 @@ else:
|
||||||
if self.tp.resultsQueue.empty():
|
if self.tp.resultsQueue.empty():
|
||||||
break
|
break
|
||||||
|
|
||||||
def cleanup(self):
|
|
||||||
self.tp.cleanup()
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
__doc__ = """Memoizer
|
||||||
|
|
||||||
|
@ -217,33 +217,47 @@ class Memoizer:
|
||||||
|
|
||||||
class M:
|
class M:
|
||||||
def __init__(cls, name, bases, cls_dict):
|
def __init__(cls, name, bases, cls_dict):
|
||||||
cls.has_metaclass = 1
|
cls.use_metaclass = 1
|
||||||
|
def fake_method(self):
|
||||||
|
pass
|
||||||
|
new.instancemethod(fake_method, None, cls)
|
||||||
|
|
||||||
|
try:
|
||||||
class A:
|
class A:
|
||||||
__metaclass__ = M
|
__metaclass__ = M
|
||||||
|
|
||||||
try:
|
use_metaclass = A.use_metaclass
|
||||||
has_metaclass = A.has_metaclass
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
has_metaclass = None
|
use_metaclass = None
|
||||||
|
reason = 'no metaclasses'
|
||||||
del M
|
except TypeError:
|
||||||
|
use_metaclass = None
|
||||||
|
reason = 'new.instancemethod() bug'
|
||||||
|
else:
|
||||||
del A
|
del A
|
||||||
|
|
||||||
if not has_metaclass:
|
del M
|
||||||
|
|
||||||
|
if not use_metaclass:
|
||||||
|
|
||||||
def Dump(title):
|
def Dump(title):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Memoized_Metaclass:
|
try:
|
||||||
|
class Memoized_Metaclass(type):
|
||||||
# Just a place-holder so pre-metaclass Python versions don't
|
# Just a place-holder so pre-metaclass Python versions don't
|
||||||
# have to have special code for the Memoized classes.
|
# have to have special code for the Memoized classes.
|
||||||
pass
|
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():
|
def EnableMemoization():
|
||||||
import SCons.Warnings
|
import SCons.Warnings
|
||||||
msg = 'memoization is not supported in this version of Python (no metaclasses)'
|
msg = 'memoization is not supported in this version of Python (%s)'
|
||||||
raise SCons.Warnings.NoMetaclassSupportWarning, msg
|
raise SCons.Warnings.NoMetaclassSupportWarning, msg % reason
|
||||||
|
|
||||||
else:
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 string
|
||||||
import UserDict
|
import UserDict
|
||||||
|
@ -74,6 +74,9 @@ class Alias(SCons.Node.Node):
|
||||||
SCons.Node.Node.__init__(self)
|
SCons.Node.Node.__init__(self)
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
|
def str_for_display(self):
|
||||||
|
return '"' + self.__str__() + '"'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
|
@ -11,7 +11,7 @@ that can be used by scripts or modules looking for the canonical default.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#
|
#
|
||||||
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -33,9 +33,10 @@ that can be used by scripts or modules looking for the canonical default.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Node/FS.py 2523 2007/12/12 09:37:41 knight"
|
__revision__ = "src/engine/SCons/Node/FS.py 3842 2008/12/20 22:59:52 scons"
|
||||||
|
|
||||||
import fnmatch
|
import fnmatch
|
||||||
|
from itertools import izip
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
||||||
|
@ -58,6 +59,25 @@ import SCons.Warnings
|
||||||
|
|
||||||
from SCons.Debug import Trace
|
from SCons.Debug import Trace
|
||||||
|
|
||||||
|
do_store_info = True
|
||||||
|
|
||||||
|
|
||||||
|
class EntryProxyAttributeError(AttributeError):
|
||||||
|
"""
|
||||||
|
An AttributeError subclass for recording and displaying the name
|
||||||
|
of the underlying Entry involved in an AttributeError exception.
|
||||||
|
"""
|
||||||
|
def __init__(self, entry_proxy, attribute):
|
||||||
|
AttributeError.__init__(self)
|
||||||
|
self.entry_proxy = entry_proxy
|
||||||
|
self.attribute = attribute
|
||||||
|
def __str__(self):
|
||||||
|
entry = self.entry_proxy.get()
|
||||||
|
fmt = "%s instance %s has no attribute %s"
|
||||||
|
return fmt % (entry.__class__.__name__,
|
||||||
|
repr(entry.name),
|
||||||
|
repr(self.attribute))
|
||||||
|
|
||||||
# The max_drift value: by default, use a cached signature value for
|
# The max_drift value: by default, use a cached signature value for
|
||||||
# any file that's been untouched for more than two days.
|
# any file that's been untouched for more than two days.
|
||||||
default_max_drift = 2*24*60*60
|
default_max_drift = 2*24*60*60
|
||||||
|
@ -73,10 +93,10 @@ default_max_drift = 2*24*60*60
|
||||||
#
|
#
|
||||||
# A number of the above factors, however, can be set after we've already
|
# A number of the above factors, however, can be set after we've already
|
||||||
# been asked to return a string for a Node, because a Repository() or
|
# been asked to return a string for a Node, because a Repository() or
|
||||||
# BuildDir() call or the like may not occur until later in SConscript
|
# VariantDir() call or the like may not occur until later in SConscript
|
||||||
# files. So this variable controls whether we bother trying to save
|
# files. So this variable controls whether we bother trying to save
|
||||||
# string values for Nodes. The wrapper interface can set this whenever
|
# string values for Nodes. The wrapper interface can set this whenever
|
||||||
# they're done mucking with Repository and BuildDir and the other stuff,
|
# they're done mucking with Repository and VariantDir and the other stuff,
|
||||||
# to let this module know it can start returning saved string values
|
# to let this module know it can start returning saved string values
|
||||||
# for Nodes.
|
# for Nodes.
|
||||||
#
|
#
|
||||||
|
@ -222,8 +242,6 @@ def LinkFunc(target, source, env):
|
||||||
if func == Link_Funcs[-1]:
|
if func == Link_Funcs[-1]:
|
||||||
# exception of the last link method (copy) are fatal
|
# exception of the last link method (copy) are fatal
|
||||||
raise
|
raise
|
||||||
else:
|
|
||||||
pass
|
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
Link = SCons.Action.Action(LinkFunc, None)
|
Link = SCons.Action.Action(LinkFunc, None)
|
||||||
|
@ -445,7 +463,7 @@ class EntryProxy(SCons.Util.Proxy):
|
||||||
|
|
||||||
def __get_srcdir(self):
|
def __get_srcdir(self):
|
||||||
"""Returns the directory containing the source node linked to this
|
"""Returns the directory containing the source node linked to this
|
||||||
node via BuildDir(), or the directory of this node if not linked."""
|
node via VariantDir(), or the directory of this node if not linked."""
|
||||||
return EntryProxy(self.get().srcnode().dir)
|
return EntryProxy(self.get().srcnode().dir)
|
||||||
|
|
||||||
def __get_rsrcnode(self):
|
def __get_rsrcnode(self):
|
||||||
|
@ -453,7 +471,7 @@ class EntryProxy(SCons.Util.Proxy):
|
||||||
|
|
||||||
def __get_rsrcdir(self):
|
def __get_rsrcdir(self):
|
||||||
"""Returns the directory containing the source node linked to this
|
"""Returns the directory containing the source node linked to this
|
||||||
node via BuildDir(), or the directory of this node if not linked."""
|
node via VariantDir(), or the directory of this node if not linked."""
|
||||||
return EntryProxy(self.get().srcnode().rfile().dir)
|
return EntryProxy(self.get().srcnode().rfile().dir)
|
||||||
|
|
||||||
def __get_dir(self):
|
def __get_dir(self):
|
||||||
|
@ -482,16 +500,11 @@ class EntryProxy(SCons.Util.Proxy):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
attr = SCons.Util.Proxy.__getattr__(self, name)
|
attr = SCons.Util.Proxy.__getattr__(self, name)
|
||||||
except AttributeError:
|
except AttributeError, e:
|
||||||
entry = self.get()
|
# Raise our own AttributeError subclass with an
|
||||||
classname = string.split(str(entry.__class__), '.')[-1]
|
# overridden __str__() method that identifies the
|
||||||
if classname[-2:] == "'>":
|
# name of the entry that caused the exception.
|
||||||
# new-style classes report their name as:
|
raise EntryProxyAttributeError(self, name)
|
||||||
# "<class 'something'>"
|
|
||||||
# instead of the classic classes:
|
|
||||||
# "something"
|
|
||||||
classname = classname[:-2]
|
|
||||||
raise AttributeError, "%s instance '%s' has no attribute '%s'" % (classname, entry.name, name)
|
|
||||||
return attr
|
return attr
|
||||||
else:
|
else:
|
||||||
return attr_function(self)
|
return attr_function(self)
|
||||||
|
@ -543,6 +556,9 @@ class Base(SCons.Node.Node):
|
||||||
self.cwd = None # will hold the SConscript directory for target nodes
|
self.cwd = None # will hold the SConscript directory for target nodes
|
||||||
self.duplicate = directory.duplicate
|
self.duplicate = directory.duplicate
|
||||||
|
|
||||||
|
def str_for_display(self):
|
||||||
|
return '"' + self.__str__() + '"'
|
||||||
|
|
||||||
def must_be_same(self, klass):
|
def must_be_same(self, klass):
|
||||||
"""
|
"""
|
||||||
This node, which already existed, is being looked up as the
|
This node, which already existed, is being looked up as the
|
||||||
|
@ -586,7 +602,7 @@ class Base(SCons.Node.Node):
|
||||||
if self.duplicate or self.is_derived():
|
if self.duplicate or self.is_derived():
|
||||||
return self.get_path()
|
return self.get_path()
|
||||||
srcnode = self.srcnode()
|
srcnode = self.srcnode()
|
||||||
if srcnode.stat() is None and not self.stat() is None:
|
if srcnode.stat() is None and self.stat() is not None:
|
||||||
result = self.get_path()
|
result = self.get_path()
|
||||||
else:
|
else:
|
||||||
result = srcnode.get_path()
|
result = srcnode.get_path()
|
||||||
|
@ -601,7 +617,7 @@ class Base(SCons.Node.Node):
|
||||||
# values that the underlying stat() method saved.
|
# values that the underlying stat() method saved.
|
||||||
try: del self._memo['stat']
|
try: del self._memo['stat']
|
||||||
except KeyError: pass
|
except KeyError: pass
|
||||||
if not self is srcnode:
|
if self is not srcnode:
|
||||||
try: del srcnode._memo['stat']
|
try: del srcnode._memo['stat']
|
||||||
except KeyError: pass
|
except KeyError: pass
|
||||||
return result
|
return result
|
||||||
|
@ -619,7 +635,7 @@ class Base(SCons.Node.Node):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def exists(self):
|
def exists(self):
|
||||||
return not self.stat() is None
|
return self.stat() is not None
|
||||||
|
|
||||||
def rexists(self):
|
def rexists(self):
|
||||||
return self.rfile().exists()
|
return self.rfile().exists()
|
||||||
|
@ -636,11 +652,11 @@ class Base(SCons.Node.Node):
|
||||||
|
|
||||||
def isdir(self):
|
def isdir(self):
|
||||||
st = self.stat()
|
st = self.stat()
|
||||||
return not st is None and stat.S_ISDIR(st[stat.ST_MODE])
|
return st is not None and stat.S_ISDIR(st[stat.ST_MODE])
|
||||||
|
|
||||||
def isfile(self):
|
def isfile(self):
|
||||||
st = self.stat()
|
st = self.stat()
|
||||||
return not st is None and stat.S_ISREG(st[stat.ST_MODE])
|
return st is not None and stat.S_ISREG(st[stat.ST_MODE])
|
||||||
|
|
||||||
if hasattr(os, 'symlink'):
|
if hasattr(os, 'symlink'):
|
||||||
def islink(self):
|
def islink(self):
|
||||||
|
@ -880,10 +896,10 @@ class Entry(Base):
|
||||||
def must_be_same(self, klass):
|
def must_be_same(self, klass):
|
||||||
"""Called to make sure a Node is a Dir. Since we're an
|
"""Called to make sure a Node is a Dir. Since we're an
|
||||||
Entry, we can morph into one."""
|
Entry, we can morph into one."""
|
||||||
if not self.__class__ is klass:
|
if self.__class__ is not klass:
|
||||||
self.__class__ = klass
|
self.__class__ = klass
|
||||||
self._morph()
|
self._morph()
|
||||||
self.clear
|
self.clear()
|
||||||
|
|
||||||
# The following methods can get called before the Taskmaster has
|
# The following methods can get called before the Taskmaster has
|
||||||
# had a chance to call disambiguate() directly to see if this Entry
|
# had a chance to call disambiguate() directly to see if this Entry
|
||||||
|
@ -904,7 +920,7 @@ class Entry(Base):
|
||||||
|
|
||||||
def rel_path(self, other):
|
def rel_path(self, other):
|
||||||
d = self.disambiguate()
|
d = self.disambiguate()
|
||||||
if d.__class__ == Entry:
|
if d.__class__ is Entry:
|
||||||
raise "rel_path() could not disambiguate File/Dir"
|
raise "rel_path() could not disambiguate File/Dir"
|
||||||
return d.rel_path(other)
|
return d.rel_path(other)
|
||||||
|
|
||||||
|
@ -1059,7 +1075,7 @@ class FS(LocalFS):
|
||||||
"""
|
"""
|
||||||
curr=self._cwd
|
curr=self._cwd
|
||||||
try:
|
try:
|
||||||
if not dir is None:
|
if dir is not None:
|
||||||
self._cwd = dir
|
self._cwd = dir
|
||||||
if change_os_dir:
|
if change_os_dir:
|
||||||
os.chdir(dir.abspath)
|
os.chdir(dir.abspath)
|
||||||
|
@ -1197,21 +1213,21 @@ class FS(LocalFS):
|
||||||
"""
|
"""
|
||||||
return self._lookup(name, directory, Dir, create)
|
return self._lookup(name, directory, Dir, create)
|
||||||
|
|
||||||
def BuildDir(self, build_dir, src_dir, duplicate=1):
|
def VariantDir(self, variant_dir, src_dir, duplicate=1):
|
||||||
"""Link the supplied build directory to the source directory
|
"""Link the supplied variant directory to the source directory
|
||||||
for purposes of building files."""
|
for purposes of building files."""
|
||||||
|
|
||||||
if not isinstance(src_dir, SCons.Node.Node):
|
if not isinstance(src_dir, SCons.Node.Node):
|
||||||
src_dir = self.Dir(src_dir)
|
src_dir = self.Dir(src_dir)
|
||||||
if not isinstance(build_dir, SCons.Node.Node):
|
if not isinstance(variant_dir, SCons.Node.Node):
|
||||||
build_dir = self.Dir(build_dir)
|
variant_dir = self.Dir(variant_dir)
|
||||||
if src_dir.is_under(build_dir):
|
if src_dir.is_under(variant_dir):
|
||||||
raise SCons.Errors.UserError, "Source directory cannot be under build directory."
|
raise SCons.Errors.UserError, "Source directory cannot be under variant directory."
|
||||||
if build_dir.srcdir:
|
if variant_dir.srcdir:
|
||||||
if build_dir.srcdir == src_dir:
|
if variant_dir.srcdir == src_dir:
|
||||||
return # We already did this.
|
return # We already did this.
|
||||||
raise SCons.Errors.UserError, "'%s' already has a source directory: '%s'."%(build_dir, build_dir.srcdir)
|
raise SCons.Errors.UserError, "'%s' already has a source directory: '%s'."%(variant_dir, variant_dir.srcdir)
|
||||||
build_dir.link(src_dir, duplicate)
|
variant_dir.link(src_dir, duplicate)
|
||||||
|
|
||||||
def Repository(self, *dirs):
|
def Repository(self, *dirs):
|
||||||
"""Specify Repository directories to search."""
|
"""Specify Repository directories to search."""
|
||||||
|
@ -1220,11 +1236,11 @@ class FS(LocalFS):
|
||||||
d = self.Dir(d)
|
d = self.Dir(d)
|
||||||
self.Top.addRepository(d)
|
self.Top.addRepository(d)
|
||||||
|
|
||||||
def build_dir_target_climb(self, orig, dir, tail):
|
def variant_dir_target_climb(self, orig, dir, tail):
|
||||||
"""Create targets in corresponding build directories
|
"""Create targets in corresponding variant directories
|
||||||
|
|
||||||
Climb the directory tree, and look up path names
|
Climb the directory tree, and look up path names
|
||||||
relative to any linked build directories we find.
|
relative to any linked variant directories we find.
|
||||||
|
|
||||||
Even though this loops and walks up the tree, we don't memoize
|
Even though this loops and walks up the tree, we don't memoize
|
||||||
the return value because this is really only used to process
|
the return value because this is really only used to process
|
||||||
|
@ -1232,10 +1248,10 @@ class FS(LocalFS):
|
||||||
"""
|
"""
|
||||||
targets = []
|
targets = []
|
||||||
message = None
|
message = None
|
||||||
fmt = "building associated BuildDir targets: %s"
|
fmt = "building associated VariantDir targets: %s"
|
||||||
start_dir = dir
|
start_dir = dir
|
||||||
while dir:
|
while dir:
|
||||||
for bd in dir.build_dirs:
|
for bd in dir.variant_dirs:
|
||||||
if start_dir.is_under(bd):
|
if start_dir.is_under(bd):
|
||||||
# If already in the build-dir location, don't reflect
|
# If already in the build-dir location, don't reflect
|
||||||
return [orig], fmt % str(orig)
|
return [orig], fmt % str(orig)
|
||||||
|
@ -1314,7 +1330,7 @@ class Dir(Base):
|
||||||
self.cwd = self
|
self.cwd = self
|
||||||
self.searched = 0
|
self.searched = 0
|
||||||
self._sconsign = None
|
self._sconsign = None
|
||||||
self.build_dirs = []
|
self.variant_dirs = []
|
||||||
self.root = self.dir.root
|
self.root = self.dir.root
|
||||||
|
|
||||||
# Don't just reset the executor, replace its action list,
|
# Don't just reset the executor, replace its action list,
|
||||||
|
@ -1342,7 +1358,7 @@ class Dir(Base):
|
||||||
del node._srcreps
|
del node._srcreps
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
if duplicate != None:
|
if duplicate is not None:
|
||||||
node.duplicate=duplicate
|
node.duplicate=duplicate
|
||||||
|
|
||||||
def __resetDuplicate(self, node):
|
def __resetDuplicate(self, node):
|
||||||
|
@ -1361,8 +1377,7 @@ class Dir(Base):
|
||||||
Looks up or creates a directory node named 'name' relative to
|
Looks up or creates a directory node named 'name' relative to
|
||||||
this directory.
|
this directory.
|
||||||
"""
|
"""
|
||||||
dir = self.fs.Dir(name, self, create)
|
return self.fs.Dir(name, self, create)
|
||||||
return dir
|
|
||||||
|
|
||||||
def File(self, name):
|
def File(self, name):
|
||||||
"""
|
"""
|
||||||
|
@ -1385,16 +1400,16 @@ class Dir(Base):
|
||||||
a path containing '..'), an absolute path name, a top-relative
|
a path containing '..'), an absolute path name, a top-relative
|
||||||
('#foo') path name, or any kind of object.
|
('#foo') path name, or any kind of object.
|
||||||
"""
|
"""
|
||||||
name = self.labspath + '/' + name
|
name = self.entry_labspath(name)
|
||||||
return self.root._lookup_abs(name, klass, create)
|
return self.root._lookup_abs(name, klass, create)
|
||||||
|
|
||||||
def link(self, srcdir, duplicate):
|
def link(self, srcdir, duplicate):
|
||||||
"""Set this directory as the build directory for the
|
"""Set this directory as the variant directory for the
|
||||||
supplied source directory."""
|
supplied source directory."""
|
||||||
self.srcdir = srcdir
|
self.srcdir = srcdir
|
||||||
self.duplicate = duplicate
|
self.duplicate = duplicate
|
||||||
self.__clearRepositoryCache(duplicate)
|
self.__clearRepositoryCache(duplicate)
|
||||||
srcdir.build_dirs.append(self)
|
srcdir.variant_dirs.append(self)
|
||||||
|
|
||||||
def getRepositories(self):
|
def getRepositories(self):
|
||||||
"""Returns a list of repositories for this directory.
|
"""Returns a list of repositories for this directory.
|
||||||
|
@ -1407,7 +1422,7 @@ class Dir(Base):
|
||||||
|
|
||||||
def get_all_rdirs(self):
|
def get_all_rdirs(self):
|
||||||
try:
|
try:
|
||||||
return self._memo['get_all_rdirs']
|
return list(self._memo['get_all_rdirs'])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -1423,7 +1438,7 @@ class Dir(Base):
|
||||||
fname = dir.name + os.sep + fname
|
fname = dir.name + os.sep + fname
|
||||||
dir = dir.up()
|
dir = dir.up()
|
||||||
|
|
||||||
self._memo['get_all_rdirs'] = result
|
self._memo['get_all_rdirs'] = list(result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -1467,11 +1482,9 @@ class Dir(Base):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if self is other:
|
if self is other:
|
||||||
|
|
||||||
result = '.'
|
result = '.'
|
||||||
|
|
||||||
elif not other in self.path_elements:
|
elif not other in self.path_elements:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
other_dir = other.get_dir()
|
other_dir = other.get_dir()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -1485,9 +1498,7 @@ class Dir(Base):
|
||||||
result = other.name
|
result = other.name
|
||||||
else:
|
else:
|
||||||
result = dir_rel_path + os.sep + other.name
|
result = dir_rel_path + os.sep + other.name
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
i = self.path_elements.index(other) + 1
|
i = self.path_elements.index(other) + 1
|
||||||
|
|
||||||
path_elems = ['..'] * (len(self.path_elements) - i) \
|
path_elems = ['..'] * (len(self.path_elements) - i) \
|
||||||
|
@ -1538,7 +1549,7 @@ class Dir(Base):
|
||||||
def build(self, **kw):
|
def build(self, **kw):
|
||||||
"""A null "builder" for directories."""
|
"""A null "builder" for directories."""
|
||||||
global MkdirBuilder
|
global MkdirBuilder
|
||||||
if not self.builder is MkdirBuilder:
|
if self.builder is not MkdirBuilder:
|
||||||
apply(SCons.Node.Node.build, [self,], kw)
|
apply(SCons.Node.Node.build, [self,], kw)
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -1554,10 +1565,9 @@ class Dir(Base):
|
||||||
if parent.exists():
|
if parent.exists():
|
||||||
break
|
break
|
||||||
listDirs.append(parent)
|
listDirs.append(parent)
|
||||||
p = parent.up()
|
parent = parent.up()
|
||||||
if p is None:
|
else:
|
||||||
raise SCons.Errors.StopError, parent.path
|
raise SCons.Errors.StopError, parent.path
|
||||||
parent = p
|
|
||||||
listDirs.reverse()
|
listDirs.reverse()
|
||||||
for dirnode in listDirs:
|
for dirnode in listDirs:
|
||||||
try:
|
try:
|
||||||
|
@ -1577,22 +1587,37 @@ class Dir(Base):
|
||||||
|
|
||||||
def multiple_side_effect_has_builder(self):
|
def multiple_side_effect_has_builder(self):
|
||||||
global MkdirBuilder
|
global MkdirBuilder
|
||||||
return not self.builder is MkdirBuilder and self.has_builder()
|
return self.builder is not MkdirBuilder and self.has_builder()
|
||||||
|
|
||||||
def alter_targets(self):
|
def alter_targets(self):
|
||||||
"""Return any corresponding targets in a build directory.
|
"""Return any corresponding targets in a variant directory.
|
||||||
"""
|
"""
|
||||||
return self.fs.build_dir_target_climb(self, self, [])
|
return self.fs.variant_dir_target_climb(self, self, [])
|
||||||
|
|
||||||
def scanner_key(self):
|
def scanner_key(self):
|
||||||
"""A directory does not get scanned."""
|
"""A directory does not get scanned."""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_contents(self):
|
def get_contents(self):
|
||||||
"""Return aggregate contents of all our children."""
|
"""Return content signatures and names of all our children
|
||||||
contents = map(lambda n: n.get_contents(), self.children())
|
separated by new-lines. Ensure that the nodes are sorted."""
|
||||||
|
contents = []
|
||||||
|
name_cmp = lambda a, b: cmp(a.name, b.name)
|
||||||
|
sorted_children = self.children()[:]
|
||||||
|
sorted_children.sort(name_cmp)
|
||||||
|
for node in sorted_children:
|
||||||
|
contents.append('%s %s\n' % (node.get_csig(), node.name))
|
||||||
return string.join(contents, '')
|
return string.join(contents, '')
|
||||||
|
|
||||||
|
def get_csig(self):
|
||||||
|
"""Compute the content signature for Directory nodes. In
|
||||||
|
general, this is not needed and the content signature is not
|
||||||
|
stored in the DirNodeInfo. However, if get_contents on a Dir
|
||||||
|
node is called which has a child directory, the child
|
||||||
|
directory should return the hash of its contents."""
|
||||||
|
contents = self.get_contents()
|
||||||
|
return SCons.Util.MD5signature(contents)
|
||||||
|
|
||||||
def do_duplicate(self, src):
|
def do_duplicate(self, src):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -1601,7 +1626,7 @@ class Dir(Base):
|
||||||
def is_up_to_date(self):
|
def is_up_to_date(self):
|
||||||
"""If any child is not up-to-date, then this directory isn't,
|
"""If any child is not up-to-date, then this directory isn't,
|
||||||
either."""
|
either."""
|
||||||
if not self.builder is MkdirBuilder and not self.exists():
|
if self.builder is not MkdirBuilder and not self.exists():
|
||||||
return 0
|
return 0
|
||||||
up_to_date = SCons.Node.up_to_date
|
up_to_date = SCons.Node.up_to_date
|
||||||
for kid in self.children():
|
for kid in self.children():
|
||||||
|
@ -1696,7 +1721,7 @@ class Dir(Base):
|
||||||
for dir in self.srcdir_list():
|
for dir in self.srcdir_list():
|
||||||
if self.is_under(dir):
|
if self.is_under(dir):
|
||||||
# We shouldn't source from something in the build path;
|
# We shouldn't source from something in the build path;
|
||||||
# build_dir is probably under src_dir, in which case
|
# variant_dir is probably under src_dir, in which case
|
||||||
# we are reflecting.
|
# we are reflecting.
|
||||||
break
|
break
|
||||||
if dir.entry_exists_on_disk(name):
|
if dir.entry_exists_on_disk(name):
|
||||||
|
@ -1761,7 +1786,10 @@ class Dir(Base):
|
||||||
if self.entry_exists_on_disk(name):
|
if self.entry_exists_on_disk(name):
|
||||||
try: return self.Dir(name)
|
try: return self.Dir(name)
|
||||||
except TypeError: pass
|
except TypeError: pass
|
||||||
|
node = self.srcdir_duplicate(name)
|
||||||
|
if isinstance(node, File):
|
||||||
return None
|
return None
|
||||||
|
return node
|
||||||
|
|
||||||
def file_on_disk(self, name):
|
def file_on_disk(self, name):
|
||||||
if self.entry_exists_on_disk(name) or \
|
if self.entry_exists_on_disk(name) or \
|
||||||
|
@ -1771,7 +1799,7 @@ class Dir(Base):
|
||||||
except TypeError: pass
|
except TypeError: pass
|
||||||
node = self.srcdir_duplicate(name)
|
node = self.srcdir_duplicate(name)
|
||||||
if isinstance(node, Dir):
|
if isinstance(node, Dir):
|
||||||
node = None
|
return None
|
||||||
return node
|
return node
|
||||||
|
|
||||||
def walk(self, func, arg):
|
def walk(self, func, arg):
|
||||||
|
@ -1823,8 +1851,8 @@ class Dir(Base):
|
||||||
|
|
||||||
The "source" argument, when true, specifies that corresponding
|
The "source" argument, when true, specifies that corresponding
|
||||||
source Nodes must be returned if you're globbing in a build
|
source Nodes must be returned if you're globbing in a build
|
||||||
directory (initialized with BuildDir()). The default behavior
|
directory (initialized with VariantDir()). The default behavior
|
||||||
is to return Nodes local to the BuildDir().
|
is to return Nodes local to the VariantDir().
|
||||||
|
|
||||||
The "strings" argument, when true, returns the matches as strings,
|
The "strings" argument, when true, returns the matches as strings,
|
||||||
not Nodes. The strings are path names relative to this directory.
|
not Nodes. The strings are path names relative to this directory.
|
||||||
|
@ -1846,6 +1874,7 @@ class Dir(Base):
|
||||||
if strings:
|
if strings:
|
||||||
r = map(lambda x, d=str(dir): os.path.join(d, x), r)
|
r = map(lambda x, d=str(dir): os.path.join(d, x), r)
|
||||||
result.extend(r)
|
result.extend(r)
|
||||||
|
result.sort(lambda a, b: cmp(str(a), str(b)))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _glob1(self, pattern, ondisk=True, source=False, strings=False):
|
def _glob1(self, pattern, ondisk=True, source=False, strings=False):
|
||||||
|
@ -1863,6 +1892,7 @@ class Dir(Base):
|
||||||
for srcdir in self.srcdir_list():
|
for srcdir in self.srcdir_list():
|
||||||
search_dir_list.extend(srcdir.get_all_rdirs())
|
search_dir_list.extend(srcdir.get_all_rdirs())
|
||||||
|
|
||||||
|
selfEntry = self.Entry
|
||||||
names = []
|
names = []
|
||||||
for dir in search_dir_list:
|
for dir in search_dir_list:
|
||||||
# We use the .name attribute from the Node because the keys of
|
# We use the .name attribute from the Node because the keys of
|
||||||
|
@ -1872,12 +1902,15 @@ class Dir(Base):
|
||||||
entry_names = filter(lambda n: n not in ('.', '..'), dir.entries.keys())
|
entry_names = filter(lambda n: n not in ('.', '..'), dir.entries.keys())
|
||||||
node_names = map(lambda n, e=dir.entries: e[n].name, entry_names)
|
node_names = map(lambda n, e=dir.entries: e[n].name, entry_names)
|
||||||
names.extend(node_names)
|
names.extend(node_names)
|
||||||
|
if not strings:
|
||||||
|
# Make sure the working directory (self) actually has
|
||||||
|
# entries for all Nodes in repositories or variant dirs.
|
||||||
|
map(selfEntry, node_names)
|
||||||
if ondisk:
|
if ondisk:
|
||||||
try:
|
try:
|
||||||
disk_names = os.listdir(dir.abspath)
|
disk_names = os.listdir(dir.abspath)
|
||||||
except os.error:
|
except os.error:
|
||||||
pass
|
continue
|
||||||
else:
|
|
||||||
names.extend(disk_names)
|
names.extend(disk_names)
|
||||||
if not strings:
|
if not strings:
|
||||||
# We're going to return corresponding Nodes in
|
# We're going to return corresponding Nodes in
|
||||||
|
@ -1892,11 +1925,13 @@ class Dir(Base):
|
||||||
#disk_names = [ d for d in disk_names if d[0] != '.' ]
|
#disk_names = [ d for d in disk_names if d[0] != '.' ]
|
||||||
disk_names = filter(lambda x: x[0] != '.', disk_names)
|
disk_names = filter(lambda x: x[0] != '.', disk_names)
|
||||||
disk_names = fnmatch.filter(disk_names, pattern)
|
disk_names = fnmatch.filter(disk_names, pattern)
|
||||||
rep_nodes = map(dir.Entry, disk_names)
|
dirEntry = dir.Entry
|
||||||
#rep_nodes = [ n.disambiguate() for n in rep_nodes ]
|
for name in disk_names:
|
||||||
rep_nodes = map(lambda n: n.disambiguate(), rep_nodes)
|
# Add './' before disk filename so that '#' at
|
||||||
for node, name in zip(rep_nodes, disk_names):
|
# beginning of filename isn't interpreted.
|
||||||
n = self.Entry(name)
|
name = './' + name
|
||||||
|
node = dirEntry(name).disambiguate()
|
||||||
|
n = selfEntry(name)
|
||||||
if n.__class__ != node.__class__:
|
if n.__class__ != node.__class__:
|
||||||
n.__class__ = node.__class__
|
n.__class__ = node.__class__
|
||||||
n._morph()
|
n._morph()
|
||||||
|
@ -1940,7 +1975,7 @@ class RootDir(Dir):
|
||||||
# except for the "lookup abspath," which does not have the
|
# except for the "lookup abspath," which does not have the
|
||||||
# drive letter.
|
# drive letter.
|
||||||
self.abspath = name + os.sep
|
self.abspath = name + os.sep
|
||||||
self.labspath = '/'
|
self.labspath = ''
|
||||||
self.path = name + os.sep
|
self.path = name + os.sep
|
||||||
self.tpath = name + os.sep
|
self.tpath = name + os.sep
|
||||||
self._morph()
|
self._morph()
|
||||||
|
@ -1951,6 +1986,7 @@ class RootDir(Dir):
|
||||||
# os.path.normpath() seems to preserve double slashes at the
|
# os.path.normpath() seems to preserve double slashes at the
|
||||||
# beginning of a path (presumably for UNC path names), but
|
# beginning of a path (presumably for UNC path names), but
|
||||||
# collapses triple slashes to a single slash.
|
# collapses triple slashes to a single slash.
|
||||||
|
self._lookupDict[''] = self
|
||||||
self._lookupDict['/'] = self
|
self._lookupDict['/'] = self
|
||||||
self._lookupDict['//'] = self
|
self._lookupDict['//'] = self
|
||||||
self._lookupDict[os.sep] = self
|
self._lookupDict[os.sep] = self
|
||||||
|
@ -1988,13 +2024,14 @@ class RootDir(Dir):
|
||||||
dir_name, file_name = os.path.split(p)
|
dir_name, file_name = os.path.split(p)
|
||||||
dir_node = self._lookup_abs(dir_name, Dir)
|
dir_node = self._lookup_abs(dir_name, Dir)
|
||||||
result = klass(file_name, dir_node, self.fs)
|
result = klass(file_name, dir_node, self.fs)
|
||||||
self._lookupDict[k] = result
|
|
||||||
dir_node.entries[_my_normcase(file_name)] = result
|
|
||||||
dir_node.implicit = None
|
|
||||||
|
|
||||||
# Double-check on disk (as configured) that the Node we
|
# Double-check on disk (as configured) that the Node we
|
||||||
# created matches whatever is out there in the real world.
|
# created matches whatever is out there in the real world.
|
||||||
result.diskcheck_match()
|
result.diskcheck_match()
|
||||||
|
|
||||||
|
self._lookupDict[k] = result
|
||||||
|
dir_node.entries[_my_normcase(file_name)] = result
|
||||||
|
dir_node.implicit = None
|
||||||
else:
|
else:
|
||||||
# There is already a Node for this path name. Allow it to
|
# There is already a Node for this path name. Allow it to
|
||||||
# complain if we were looking for an inappropriate type.
|
# complain if we were looking for an inappropriate type.
|
||||||
|
@ -2008,7 +2045,7 @@ class RootDir(Dir):
|
||||||
return self.abspath + name
|
return self.abspath + name
|
||||||
|
|
||||||
def entry_labspath(self, name):
|
def entry_labspath(self, name):
|
||||||
return self.labspath + name
|
return '/' + name
|
||||||
|
|
||||||
def entry_path(self, name):
|
def entry_path(self, name):
|
||||||
return self.path + name
|
return self.path + name
|
||||||
|
@ -2106,10 +2143,9 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
|
||||||
strings = getattr(self, nattr)
|
strings = getattr(self, nattr)
|
||||||
nodeinfos = getattr(self, sattr)
|
nodeinfos = getattr(self, sattr)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
continue
|
||||||
else:
|
|
||||||
nodes = []
|
nodes = []
|
||||||
for s, ni in zip(strings, nodeinfos):
|
for s, ni in izip(strings, nodeinfos):
|
||||||
if not isinstance(s, SCons.Node.Node):
|
if not isinstance(s, SCons.Node.Node):
|
||||||
s = ni.str_to_node(s)
|
s = ni.str_to_node(s)
|
||||||
nodes.append(s)
|
nodes.append(s)
|
||||||
|
@ -2118,7 +2154,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
|
||||||
result = []
|
result = []
|
||||||
bkids = self.bsources + self.bdepends + self.bimplicit
|
bkids = self.bsources + self.bdepends + self.bimplicit
|
||||||
bkidsigs = self.bsourcesigs + self.bdependsigs + self.bimplicitsigs
|
bkidsigs = self.bsourcesigs + self.bdependsigs + self.bimplicitsigs
|
||||||
for bkid, bkidsig in zip(bkids, bkidsigs):
|
for bkid, bkidsig in izip(bkids, bkidsigs):
|
||||||
result.append(str(bkid) + ': ' +
|
result.append(str(bkid) + ': ' +
|
||||||
string.join(bkidsig.format(names=names), ' '))
|
string.join(bkidsig.format(names=names), ' '))
|
||||||
result.append('%s [%s]' % (self.bactsig, self.bact))
|
result.append('%s [%s]' % (self.bactsig, self.bact))
|
||||||
|
@ -2133,6 +2169,8 @@ class File(Base):
|
||||||
NodeInfo = FileNodeInfo
|
NodeInfo = FileNodeInfo
|
||||||
BuildInfo = FileBuildInfo
|
BuildInfo = FileBuildInfo
|
||||||
|
|
||||||
|
md5_chunksize = 64
|
||||||
|
|
||||||
def diskcheck_match(self):
|
def diskcheck_match(self):
|
||||||
diskcheck_match(self, self.isdir,
|
diskcheck_match(self, self.isdir,
|
||||||
"Directory %s found where file expected.")
|
"Directory %s found where file expected.")
|
||||||
|
@ -2144,23 +2182,25 @@ class File(Base):
|
||||||
|
|
||||||
def Entry(self, name):
|
def Entry(self, name):
|
||||||
"""Create an entry node named 'name' relative to
|
"""Create an entry node named 'name' relative to
|
||||||
the SConscript directory of this file."""
|
the directory of this file."""
|
||||||
return self.cwd.Entry(name)
|
return self.dir.Entry(name)
|
||||||
|
|
||||||
def Dir(self, name, create=True):
|
def Dir(self, name, create=True):
|
||||||
"""Create a directory node named 'name' relative to
|
"""Create a directory node named 'name' relative to
|
||||||
the SConscript directory of this file."""
|
the directory of this file."""
|
||||||
return self.cwd.Dir(name, create)
|
return self.dir.Dir(name, create=create)
|
||||||
|
|
||||||
def Dirs(self, pathlist):
|
def Dirs(self, pathlist):
|
||||||
"""Create a list of directories relative to the SConscript
|
"""Create a list of directories relative to the SConscript
|
||||||
directory of this file."""
|
directory of this file."""
|
||||||
|
# TODO(1.5)
|
||||||
|
# return [self.Dir(p) for p in pathlist]
|
||||||
return map(lambda p, s=self: s.Dir(p), pathlist)
|
return map(lambda p, s=self: s.Dir(p), pathlist)
|
||||||
|
|
||||||
def File(self, name):
|
def File(self, name):
|
||||||
"""Create a file node named 'name' relative to
|
"""Create a file node named 'name' relative to
|
||||||
the SConscript directory of this file."""
|
the directory of this file."""
|
||||||
return self.cwd.File(name)
|
return self.dir.File(name)
|
||||||
|
|
||||||
#def generate_build_dict(self):
|
#def generate_build_dict(self):
|
||||||
# """Return an appropriate dictionary of values for building
|
# """Return an appropriate dictionary of values for building
|
||||||
|
@ -2203,6 +2243,23 @@ class File(Base):
|
||||||
raise
|
raise
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
def get_content_hash(self):
|
||||||
|
"""
|
||||||
|
Compute and return the MD5 hash for this file.
|
||||||
|
"""
|
||||||
|
if not self.rexists():
|
||||||
|
return SCons.Util.MD5signature('')
|
||||||
|
fname = self.rfile().abspath
|
||||||
|
try:
|
||||||
|
cs = SCons.Util.MD5filesignature(fname,
|
||||||
|
chunksize=SCons.Node.FS.File.md5_chunksize*1024)
|
||||||
|
except EnvironmentError, e:
|
||||||
|
if not e.filename:
|
||||||
|
e.filename = fname
|
||||||
|
raise
|
||||||
|
return cs
|
||||||
|
|
||||||
|
|
||||||
memoizer_counters.append(SCons.Memoize.CountValue('get_size'))
|
memoizer_counters.append(SCons.Memoize.CountValue('get_size'))
|
||||||
|
|
||||||
def get_size(self):
|
def get_size(self):
|
||||||
|
@ -2242,6 +2299,7 @@ class File(Base):
|
||||||
# This accomodates "chained builds" where a file that's a target
|
# This accomodates "chained builds" where a file that's a target
|
||||||
# in one build (SConstruct file) is a source in a different build.
|
# in one build (SConstruct file) is a source in a different build.
|
||||||
# See test/chained-build.py for the use case.
|
# See test/chained-build.py for the use case.
|
||||||
|
if do_store_info:
|
||||||
self.dir.sconsign().store_info(self.name, self)
|
self.dir.sconsign().store_info(self.name, self)
|
||||||
|
|
||||||
convert_copy_attrs = [
|
convert_copy_attrs = [
|
||||||
|
@ -2336,16 +2394,14 @@ class File(Base):
|
||||||
try:
|
try:
|
||||||
value = getattr(old_entry, attr)
|
value = getattr(old_entry, attr)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
continue
|
||||||
else:
|
|
||||||
setattr(binfo, attr, value)
|
setattr(binfo, attr, value)
|
||||||
delattr(old_entry, attr)
|
delattr(old_entry, attr)
|
||||||
for attr in self.convert_sig_attrs:
|
for attr in self.convert_sig_attrs:
|
||||||
try:
|
try:
|
||||||
sig_list = getattr(old_entry, attr)
|
sig_list = getattr(old_entry, attr)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
continue
|
||||||
else:
|
|
||||||
value = []
|
value = []
|
||||||
for sig in sig_list:
|
for sig in sig_list:
|
||||||
ninfo = self.new_ninfo()
|
ninfo = self.new_ninfo()
|
||||||
|
@ -2368,7 +2424,7 @@ class File(Base):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sconsign_entry = self.dir.sconsign().get_entry(self.name)
|
sconsign_entry = self.dir.sconsign().get_entry(self.name)
|
||||||
except (KeyError, OSError):
|
except (KeyError, EnvironmentError):
|
||||||
import SCons.SConsign
|
import SCons.SConsign
|
||||||
sconsign_entry = SCons.SConsign.SConsignEntry()
|
sconsign_entry = SCons.SConsign.SConsignEntry()
|
||||||
sconsign_entry.binfo = self.new_binfo()
|
sconsign_entry.binfo = self.new_binfo()
|
||||||
|
@ -2419,6 +2475,7 @@ class File(Base):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if scanner:
|
if scanner:
|
||||||
|
# result = [n.disambiguate() for n in scanner(self, env, path)]
|
||||||
result = scanner(self, env, path)
|
result = scanner(self, env, path)
|
||||||
result = map(lambda N: N.disambiguate(), result)
|
result = map(lambda N: N.disambiguate(), result)
|
||||||
else:
|
else:
|
||||||
|
@ -2469,38 +2526,20 @@ class File(Base):
|
||||||
self.get_build_env().get_CacheDir().push_if_forced(self)
|
self.get_build_env().get_CacheDir().push_if_forced(self)
|
||||||
|
|
||||||
ninfo = self.get_ninfo()
|
ninfo = self.get_ninfo()
|
||||||
old = self.get_stored_info()
|
|
||||||
|
|
||||||
csig = None
|
|
||||||
mtime = self.get_timestamp()
|
|
||||||
size = self.get_size()
|
|
||||||
|
|
||||||
max_drift = self.fs.max_drift
|
|
||||||
if max_drift > 0:
|
|
||||||
if (time.time() - mtime) > max_drift:
|
|
||||||
try:
|
|
||||||
n = old.ninfo
|
|
||||||
if n.timestamp and n.csig and n.timestamp == mtime:
|
|
||||||
csig = n.csig
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
elif max_drift == 0:
|
|
||||||
try:
|
|
||||||
csig = old.ninfo.csig
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
csig = self.get_max_drift_csig()
|
||||||
if csig:
|
if csig:
|
||||||
ninfo.csig = csig
|
ninfo.csig = csig
|
||||||
|
|
||||||
ninfo.timestamp = mtime
|
ninfo.timestamp = self.get_timestamp()
|
||||||
ninfo.size = size
|
ninfo.size = self.get_size()
|
||||||
|
|
||||||
if not self.has_builder():
|
if not self.has_builder():
|
||||||
# This is a source file, but it might have been a target file
|
# This is a source file, but it might have been a target file
|
||||||
# in another build that included more of the DAG. Copy
|
# in another build that included more of the DAG. Copy
|
||||||
# any build information that's stored in the .sconsign file
|
# any build information that's stored in the .sconsign file
|
||||||
# into our binfo object so it doesn't get lost.
|
# into our binfo object so it doesn't get lost.
|
||||||
|
old = self.get_stored_info()
|
||||||
self.get_binfo().__dict__.update(old.binfo.__dict__)
|
self.get_binfo().__dict__.update(old.binfo.__dict__)
|
||||||
|
|
||||||
self.store_info()
|
self.store_info()
|
||||||
|
@ -2540,14 +2579,14 @@ class File(Base):
|
||||||
scb = self.sbuilder
|
scb = self.sbuilder
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
scb = self.sbuilder = self.find_src_builder()
|
scb = self.sbuilder = self.find_src_builder()
|
||||||
return not scb is None
|
return scb is not None
|
||||||
|
|
||||||
def alter_targets(self):
|
def alter_targets(self):
|
||||||
"""Return any corresponding targets in a build directory.
|
"""Return any corresponding targets in a variant directory.
|
||||||
"""
|
"""
|
||||||
if self.is_derived():
|
if self.is_derived():
|
||||||
return [], None
|
return [], None
|
||||||
return self.fs.build_dir_target_climb(self, self.dir, [self.name])
|
return self.fs.variant_dir_target_climb(self, self.dir, [self.name])
|
||||||
|
|
||||||
def _rmv_existing(self):
|
def _rmv_existing(self):
|
||||||
self.clear_memoized_values()
|
self.clear_memoized_values()
|
||||||
|
@ -2613,8 +2652,8 @@ class File(Base):
|
||||||
# Duplicate from source path if we are set up to do this.
|
# Duplicate from source path if we are set up to do this.
|
||||||
if self.duplicate and not self.is_derived() and not self.linked:
|
if self.duplicate and not self.is_derived() and not self.linked:
|
||||||
src = self.srcnode()
|
src = self.srcnode()
|
||||||
if not src is self:
|
if src is not self:
|
||||||
# At this point, src is meant to be copied in a build directory.
|
# At this point, src is meant to be copied in a variant directory.
|
||||||
src = src.rfile()
|
src = src.rfile()
|
||||||
if src.abspath != self.abspath:
|
if src.abspath != self.abspath:
|
||||||
if src.exists():
|
if src.exists():
|
||||||
|
@ -2623,7 +2662,7 @@ class File(Base):
|
||||||
# not actually occur if the -n option is being used.
|
# not actually occur if the -n option is being used.
|
||||||
else:
|
else:
|
||||||
# The source file does not exist. Make sure no old
|
# The source file does not exist. Make sure no old
|
||||||
# copy remains in the build directory.
|
# copy remains in the variant directory.
|
||||||
if Base.exists(self) or self.islink():
|
if Base.exists(self) or self.islink():
|
||||||
self.fs.unlink(self.path)
|
self.fs.unlink(self.path)
|
||||||
# Return None explicitly because the Base.exists() call
|
# Return None explicitly because the Base.exists() call
|
||||||
|
@ -2638,6 +2677,32 @@ class File(Base):
|
||||||
# SIGNATURE SUBSYSTEM
|
# SIGNATURE SUBSYSTEM
|
||||||
#
|
#
|
||||||
|
|
||||||
|
def get_max_drift_csig(self):
|
||||||
|
"""
|
||||||
|
Returns the content signature currently stored for this node
|
||||||
|
if it's been unmodified longer than the max_drift value, or the
|
||||||
|
max_drift value is 0. Returns None otherwise.
|
||||||
|
"""
|
||||||
|
old = self.get_stored_info()
|
||||||
|
mtime = self.get_timestamp()
|
||||||
|
|
||||||
|
max_drift = self.fs.max_drift
|
||||||
|
if max_drift > 0:
|
||||||
|
if (time.time() - mtime) > max_drift:
|
||||||
|
try:
|
||||||
|
n = old.ninfo
|
||||||
|
if n.timestamp and n.csig and n.timestamp == mtime:
|
||||||
|
return n.csig
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
elif max_drift == 0:
|
||||||
|
try:
|
||||||
|
return old.ninfo.csig
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def get_csig(self):
|
def get_csig(self):
|
||||||
"""
|
"""
|
||||||
Generate a node's content signature, the digested signature
|
Generate a node's content signature, the digested signature
|
||||||
|
@ -2653,8 +2718,14 @@ class File(Base):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
csig = self.get_max_drift_csig()
|
||||||
|
if csig is None:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
if self.get_size() < SCons.Node.FS.File.md5_chunksize:
|
||||||
contents = self.get_contents()
|
contents = self.get_contents()
|
||||||
|
else:
|
||||||
|
csig = self.get_content_hash()
|
||||||
except IOError:
|
except IOError:
|
||||||
# This can happen if there's actually a directory on-disk,
|
# This can happen if there's actually a directory on-disk,
|
||||||
# which can be the case if they've disabled disk checks,
|
# which can be the case if they've disabled disk checks,
|
||||||
|
@ -2662,6 +2733,7 @@ class File(Base):
|
||||||
# create a same-named directory by mistake.
|
# create a same-named directory by mistake.
|
||||||
csig = ''
|
csig = ''
|
||||||
else:
|
else:
|
||||||
|
if not csig:
|
||||||
csig = SCons.Util.MD5signature(contents)
|
csig = SCons.Util.MD5signature(contents)
|
||||||
|
|
||||||
ninfo.csig = csig
|
ninfo.csig = csig
|
||||||
|
@ -2684,7 +2756,7 @@ class File(Base):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def changed_state(self, target, prev_ni):
|
def changed_state(self, target, prev_ni):
|
||||||
return (self.state != SCons.Node.up_to_date)
|
return self.state != SCons.Node.up_to_date
|
||||||
|
|
||||||
def changed_timestamp_then_content(self, target, prev_ni):
|
def changed_timestamp_then_content(self, target, prev_ni):
|
||||||
if not self.changed_timestamp_match(target, prev_ni):
|
if not self.changed_timestamp_match(target, prev_ni):
|
||||||
|
@ -2790,8 +2862,8 @@ class File(Base):
|
||||||
|
|
||||||
cachedir, cachefile = self.get_build_env().get_CacheDir().cachepath(self)
|
cachedir, cachefile = self.get_build_env().get_CacheDir().cachepath(self)
|
||||||
if not self.exists() and cachefile and os.path.exists(cachefile):
|
if not self.exists() and cachefile and os.path.exists(cachefile):
|
||||||
contents = open(cachefile, 'rb').read()
|
self.cachedir_csig = SCons.Util.MD5filesignature(cachefile, \
|
||||||
self.cachedir_csig = SCons.Util.MD5signature(contents)
|
SCons.Node.FS.File.md5_chunksize * 1024)
|
||||||
else:
|
else:
|
||||||
self.cachedir_csig = self.get_csig()
|
self.cachedir_csig = self.get_csig()
|
||||||
return self.cachedir_csig
|
return self.cachedir_csig
|
||||||
|
@ -2806,12 +2878,14 @@ class File(Base):
|
||||||
# targets built by the same action will all have the same
|
# targets built by the same action will all have the same
|
||||||
# build signature, and we have to differentiate them somehow.
|
# build signature, and we have to differentiate them somehow.
|
||||||
children = self.children()
|
children = self.children()
|
||||||
sigs = map(lambda n: n.get_cachedir_csig(), children)
|
|
||||||
executor = self.get_executor()
|
executor = self.get_executor()
|
||||||
|
# sigs = [n.get_cachedir_csig() for n in children]
|
||||||
|
sigs = map(lambda n: n.get_cachedir_csig(), children)
|
||||||
sigs.append(SCons.Util.MD5signature(executor.get_contents()))
|
sigs.append(SCons.Util.MD5signature(executor.get_contents()))
|
||||||
sigs.append(self.path)
|
sigs.append(self.path)
|
||||||
self.cachesig = SCons.Util.MD5collect(sigs)
|
result = self.cachesig = SCons.Util.MD5collect(sigs)
|
||||||
return self.cachesig
|
return result
|
||||||
|
|
||||||
|
|
||||||
default_fs = None
|
default_fs = None
|
||||||
|
|
||||||
|
@ -2842,14 +2916,14 @@ class FileFinder:
|
||||||
It would be more compact to just use this as a nested function
|
It would be more compact to just use this as a nested function
|
||||||
with a default keyword argument (see the commented-out version
|
with a default keyword argument (see the commented-out version
|
||||||
below), but that doesn't work unless you have nested scopes,
|
below), but that doesn't work unless you have nested scopes,
|
||||||
so we define it here just this works work under Python 1.5.2.
|
so we define it here just so this work under Python 1.5.2.
|
||||||
"""
|
"""
|
||||||
if fd is None:
|
if fd is None:
|
||||||
fd = self.default_filedir
|
fd = self.default_filedir
|
||||||
dir, name = os.path.split(fd)
|
dir, name = os.path.split(fd)
|
||||||
drive, d = os.path.splitdrive(dir)
|
drive, d = os.path.splitdrive(dir)
|
||||||
if d in ('/', os.sep):
|
if d in ('/', os.sep):
|
||||||
return p
|
return p.fs.get_root(drive).dir_on_disk(name)
|
||||||
if dir:
|
if dir:
|
||||||
p = self.filedir_lookup(p, dir)
|
p = self.filedir_lookup(p, dir)
|
||||||
if not p:
|
if not p:
|
||||||
|
@ -2859,9 +2933,10 @@ class FileFinder:
|
||||||
node = p.entries[norm_name]
|
node = p.entries[norm_name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return p.dir_on_disk(name)
|
return p.dir_on_disk(name)
|
||||||
# Once we move to Python 2.2 we can do:
|
if isinstance(node, Dir):
|
||||||
#if isinstance(node, (Dir, Entry)):
|
return node
|
||||||
if isinstance(node, Dir) or isinstance(node, Entry):
|
if isinstance(node, Entry):
|
||||||
|
node.must_be_same(Dir)
|
||||||
return node
|
return node
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -2899,14 +2974,11 @@ class FileFinder:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if verbose:
|
if verbose and not callable(verbose):
|
||||||
if not SCons.Util.is_String(verbose):
|
if not SCons.Util.is_String(verbose):
|
||||||
verbose = "find_file"
|
verbose = "find_file"
|
||||||
if not callable(verbose):
|
|
||||||
verbose = ' %s: ' % verbose
|
verbose = ' %s: ' % verbose
|
||||||
verbose = lambda s, v=verbose: sys.stdout.write(v + s)
|
verbose = lambda s, v=verbose: sys.stdout.write(v + s)
|
||||||
else:
|
|
||||||
verbose = lambda x: x
|
|
||||||
|
|
||||||
filedir, filename = os.path.split(filename)
|
filedir, filename = os.path.split(filename)
|
||||||
if filedir:
|
if filedir:
|
||||||
|
@ -2930,8 +3002,11 @@ class FileFinder:
|
||||||
# node = p.entries[norm_name]
|
# node = p.entries[norm_name]
|
||||||
# except KeyError:
|
# except KeyError:
|
||||||
# return p.dir_on_disk(name)
|
# return p.dir_on_disk(name)
|
||||||
# # Once we move to Python 2.2 we can do:
|
# if isinstance(node, Dir):
|
||||||
# #if isinstance(node, (Dir, Entry)):
|
# return node
|
||||||
|
# if isinstance(node, Entry):
|
||||||
|
# node.must_be_same(Dir)
|
||||||
|
# return node
|
||||||
# if isinstance(node, Dir) or isinstance(node, Entry):
|
# if isinstance(node, Dir) or isinstance(node, Entry):
|
||||||
# return node
|
# return node
|
||||||
# return None
|
# return None
|
||||||
|
@ -2942,9 +3017,11 @@ class FileFinder:
|
||||||
|
|
||||||
result = None
|
result = None
|
||||||
for dir in paths:
|
for dir in paths:
|
||||||
|
if verbose:
|
||||||
verbose("looking for '%s' in '%s' ...\n" % (filename, dir))
|
verbose("looking for '%s' in '%s' ...\n" % (filename, dir))
|
||||||
node, d = dir.srcdir_find_file(filename)
|
node, d = dir.srcdir_find_file(filename)
|
||||||
if node:
|
if node:
|
||||||
|
if verbose:
|
||||||
verbose("... FOUND '%s' in '%s'\n" % (filename, d))
|
verbose("... FOUND '%s' in '%s'\n" % (filename, d))
|
||||||
result = node
|
result = node
|
||||||
break
|
break
|
||||||
|
@ -2954,3 +3031,45 @@ class FileFinder:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
find_file = FileFinder().find_file
|
find_file = FileFinder().find_file
|
||||||
|
|
||||||
|
|
||||||
|
def invalidate_node_memos(targets):
|
||||||
|
"""
|
||||||
|
Invalidate the memoized values of all Nodes (files or directories)
|
||||||
|
that are associated with the given entries. Has been added to
|
||||||
|
clear the cache of nodes affected by a direct execution of an
|
||||||
|
action (e.g. Delete/Copy/Chmod). Existing Node caches become
|
||||||
|
inconsistent if the action is run through Execute(). The argument
|
||||||
|
`targets` can be a single Node object or filename, or a sequence
|
||||||
|
of Nodes/filenames.
|
||||||
|
"""
|
||||||
|
from traceback import extract_stack
|
||||||
|
|
||||||
|
# First check if the cache really needs to be flushed. Only
|
||||||
|
# actions run in the SConscript with Execute() seem to be
|
||||||
|
# affected. XXX The way to check if Execute() is in the stacktrace
|
||||||
|
# is a very dirty hack and should be replaced by a more sensible
|
||||||
|
# solution.
|
||||||
|
for f in extract_stack():
|
||||||
|
if f[2] == 'Execute' and f[0][-14:] == 'Environment.py':
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# Dont have to invalidate, so return
|
||||||
|
return
|
||||||
|
|
||||||
|
if not SCons.Util.is_List(targets):
|
||||||
|
targets = [targets]
|
||||||
|
|
||||||
|
for entry in targets:
|
||||||
|
# If the target is a Node object, clear the cache. If it is a
|
||||||
|
# filename, look up potentially existing Node object first.
|
||||||
|
try:
|
||||||
|
entry.clear_memoized_values()
|
||||||
|
except AttributeError:
|
||||||
|
# Not a Node object, try to look up Node by filename. XXX
|
||||||
|
# This creates Node objects even for those filenames which
|
||||||
|
# do not correspond to an existing Node object.
|
||||||
|
node = get_default_fs().Entry(entry)
|
||||||
|
if node:
|
||||||
|
node.clear_memoized_values()
|
||||||
|
|
|
@ -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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
import SCons.Node
|
||||||
|
|
||||||
|
@ -56,9 +56,12 @@ class Value(SCons.Node.Node):
|
||||||
if not built_value is None:
|
if not built_value is None:
|
||||||
self.built_value = built_value
|
self.built_value = built_value
|
||||||
|
|
||||||
def __str__(self):
|
def str_for_display(self):
|
||||||
return repr(self.value)
|
return repr(self.value)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.value)
|
||||||
|
|
||||||
def make_ready(self):
|
def make_ready(self):
|
||||||
self.get_csig()
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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"
|
__revision__ = "src/engine/SCons/Node/__init__.py 3842 2008/12/20 22:59:52 scons"
|
||||||
|
|
||||||
import SCons.compat
|
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
from itertools import chain, izip
|
||||||
import string
|
import string
|
||||||
import UserList
|
import UserList
|
||||||
|
|
||||||
|
@ -75,7 +74,7 @@ executed = 4
|
||||||
failed = 5
|
failed = 5
|
||||||
|
|
||||||
StateString = {
|
StateString = {
|
||||||
0 : "0",
|
0 : "no_state",
|
||||||
1 : "pending",
|
1 : "pending",
|
||||||
2 : "executing",
|
2 : "executing",
|
||||||
3 : "up_to_date",
|
3 : "up_to_date",
|
||||||
|
@ -202,15 +201,16 @@ class Node:
|
||||||
# a class. (Of course, we could always still do that in the
|
# a class. (Of course, we could always still do that in the
|
||||||
# future if we had a good reason to...).
|
# future if we had a good reason to...).
|
||||||
self.sources = [] # source files used to build node
|
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 = [] # explicit dependencies (from Depends)
|
||||||
self.depends_dict = {}
|
self.depends_set = set()
|
||||||
self.ignore = [] # dependencies to ignore
|
self.ignore = [] # dependencies to ignore
|
||||||
self.ignore_dict = {}
|
self.ignore_set = set()
|
||||||
self.prerequisites = SCons.Util.UniqueList()
|
self.prerequisites = SCons.Util.UniqueList()
|
||||||
self.implicit = None # implicit (scanned) dependencies (None means not scanned yet)
|
self.implicit = None # implicit (scanned) dependencies (None means not scanned yet)
|
||||||
self.waiting_parents = {}
|
self.waiting_parents = set()
|
||||||
self.waiting_s_e = {}
|
self.waiting_s_e = set()
|
||||||
self.ref_count = 0
|
self.ref_count = 0
|
||||||
self.wkids = None # Kids yet to walk, when it's an array
|
self.wkids = None # Kids yet to walk, when it's an array
|
||||||
|
|
||||||
|
@ -220,12 +220,11 @@ class Node:
|
||||||
self.noclean = 0
|
self.noclean = 0
|
||||||
self.nocache = 0
|
self.nocache = 0
|
||||||
self.always_build = None
|
self.always_build = None
|
||||||
self.found_includes = {}
|
|
||||||
self.includes = None
|
self.includes = None
|
||||||
self.attributes = self.Attrs() # Generic place to stick information about the Node.
|
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_effect = 0 # true iff this node is a side effect
|
||||||
self.side_effects = [] # the side effects of building this target
|
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()
|
self.clear_memoized_values()
|
||||||
|
|
||||||
|
@ -330,24 +329,29 @@ class Node:
|
||||||
is out-of-date and must be rebuilt, but before actually calling
|
is out-of-date and must be rebuilt, but before actually calling
|
||||||
the method to build the Node.
|
the method to build the Node.
|
||||||
|
|
||||||
This default implemenation checks that all children either exist
|
This default implementation checks that explicit or implicit
|
||||||
or are derived, and initializes the BuildInfo structure that
|
dependencies either exist or are derived, and initializes the
|
||||||
will hold the information about how this node is, uh, built.
|
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
|
Overriding this method allows for for a Node subclass to remove
|
||||||
the underlying file from the file system. Note that subclass
|
the underlying file from the file system. Note that subclass
|
||||||
methods should call this base class method to get the child
|
methods should call this base class method to get the child
|
||||||
check and the BuildInfo structure.
|
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:
|
if not self.implicit is None:
|
||||||
l = l + self.implicit
|
for i in self.implicit:
|
||||||
missing_sources = self.get_executor().get_missing_sources() \
|
if i.missing():
|
||||||
+ filter(lambda c: c.missing(), l)
|
msg = "Implicit dependency `%s' not found, needed by target `%s'."
|
||||||
if missing_sources:
|
raise SCons.Errors.StopError, msg % (i, self)
|
||||||
desc = "Source `%s' not found, needed by target `%s'." % (missing_sources[0], self)
|
|
||||||
raise SCons.Errors.StopError, desc
|
|
||||||
|
|
||||||
self.binfo = self.get_binfo()
|
self.binfo = self.get_binfo()
|
||||||
|
|
||||||
def build(self, **kw):
|
def build(self, **kw):
|
||||||
|
@ -373,9 +377,8 @@ class Node:
|
||||||
|
|
||||||
# Clear the implicit dependency caches of any Nodes
|
# Clear the implicit dependency caches of any Nodes
|
||||||
# waiting for this Node to be built.
|
# waiting for this Node to be built.
|
||||||
for parent in self.waiting_parents.keys():
|
for parent in self.waiting_parents:
|
||||||
parent.implicit = None
|
parent.implicit = None
|
||||||
parent.del_binfo()
|
|
||||||
|
|
||||||
self.clear()
|
self.clear()
|
||||||
|
|
||||||
|
@ -399,7 +402,7 @@ class Node:
|
||||||
#
|
#
|
||||||
|
|
||||||
def add_to_waiting_s_e(self, 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):
|
def add_to_waiting_parents(self, node):
|
||||||
"""
|
"""
|
||||||
|
@ -410,37 +413,26 @@ class Node:
|
||||||
True and False instead...)
|
True and False instead...)
|
||||||
"""
|
"""
|
||||||
wp = self.waiting_parents
|
wp = self.waiting_parents
|
||||||
if wp.has_key(node):
|
if node in wp:
|
||||||
result = 0
|
return 0
|
||||||
else:
|
wp.add(node)
|
||||||
result = 1
|
return 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)
|
|
||||||
|
|
||||||
def postprocess(self):
|
def postprocess(self):
|
||||||
"""Clean up anything we don't need to hang onto after we've
|
"""Clean up anything we don't need to hang onto after we've
|
||||||
been built."""
|
been built."""
|
||||||
self.executor_cleanup()
|
self.executor_cleanup()
|
||||||
self.waiting_parents = {}
|
self.waiting_parents = set()
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
"""Completely clear a Node of all its cached state (so that it
|
"""Completely clear a Node of all its cached state (so that it
|
||||||
can be re-evaluated by interfaces that do continuous integration
|
can be re-evaluated by interfaces that do continuous integration
|
||||||
builds).
|
builds).
|
||||||
"""
|
"""
|
||||||
# Note in case it's important in the future: We also used to clear
|
# The del_binfo() call here isn't necessary for normal execution,
|
||||||
# the build information (the lists of dependencies) here like this:
|
# but is for interactive mode, where we might rebuild the same
|
||||||
#
|
# target and need to start from scratch.
|
||||||
# self.del_binfo()
|
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.
|
|
||||||
self.clear_memoized_values()
|
self.clear_memoized_values()
|
||||||
self.ninfo = self.new_ninfo()
|
self.ninfo = self.new_ninfo()
|
||||||
self.executor_cleanup()
|
self.executor_cleanup()
|
||||||
|
@ -449,7 +441,6 @@ class Node:
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
self.includes = None
|
self.includes = None
|
||||||
self.found_includes = {}
|
|
||||||
|
|
||||||
def clear_memoized_values(self):
|
def clear_memoized_values(self):
|
||||||
self._memo = {}
|
self._memo = {}
|
||||||
|
@ -510,7 +501,7 @@ class Node:
|
||||||
Returns true iff this node is derived (i.e. built).
|
Returns true iff this node is derived (i.e. built).
|
||||||
|
|
||||||
This should return true only for nodes whose path should be in
|
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
|
signatures when they are used as source files to other derived files. For
|
||||||
example: source with source builders are not derived in this sense,
|
example: source with source builders are not derived in this sense,
|
||||||
and hence should not return true.
|
and hence should not return true.
|
||||||
|
@ -597,9 +588,9 @@ class Node:
|
||||||
def add_to_implicit(self, deps):
|
def add_to_implicit(self, deps):
|
||||||
if not hasattr(self, 'implicit') or self.implicit is None:
|
if not hasattr(self, 'implicit') or self.implicit is None:
|
||||||
self.implicit = []
|
self.implicit = []
|
||||||
self.implicit_dict = {}
|
self.implicit_set = set()
|
||||||
self._children_reset()
|
self._children_reset()
|
||||||
self._add_child(self.implicit, self.implicit_dict, deps)
|
self._add_child(self.implicit, self.implicit_set, deps)
|
||||||
|
|
||||||
def scan(self):
|
def scan(self):
|
||||||
"""Scan this node's dependents for implicit dependencies."""
|
"""Scan this node's dependents for implicit dependencies."""
|
||||||
|
@ -609,7 +600,7 @@ class Node:
|
||||||
if not self.implicit is None:
|
if not self.implicit is None:
|
||||||
return
|
return
|
||||||
self.implicit = []
|
self.implicit = []
|
||||||
self.implicit_dict = {}
|
self.implicit_set = set()
|
||||||
self._children_reset()
|
self._children_reset()
|
||||||
if not self.has_builder():
|
if not self.has_builder():
|
||||||
return
|
return
|
||||||
|
@ -638,9 +629,7 @@ class Node:
|
||||||
# one of this node's sources has changed,
|
# one of this node's sources has changed,
|
||||||
# so we must recalculate the implicit deps:
|
# so we must recalculate the implicit deps:
|
||||||
self.implicit = []
|
self.implicit = []
|
||||||
self.implicit_dict = {}
|
self.implicit_set = set()
|
||||||
self._children_reset()
|
|
||||||
self.del_binfo()
|
|
||||||
|
|
||||||
# Have the executor scan the sources.
|
# Have the executor scan the sources.
|
||||||
executor.scan_sources(self.builder.source_scanner)
|
executor.scan_sources(self.builder.source_scanner)
|
||||||
|
@ -713,33 +702,44 @@ class Node:
|
||||||
self.binfo = binfo
|
self.binfo = binfo
|
||||||
|
|
||||||
executor = self.get_executor()
|
executor = self.get_executor()
|
||||||
|
ignore_set = self.ignore_set
|
||||||
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)
|
|
||||||
|
|
||||||
if self.has_builder():
|
if self.has_builder():
|
||||||
binfo.bact = str(executor)
|
binfo.bact = str(executor)
|
||||||
binfo.bactsig = SCons.Util.MD5signature(executor.get_contents())
|
binfo.bactsig = SCons.Util.MD5signature(executor.get_contents())
|
||||||
|
|
||||||
binfo.bsources = sources
|
if self._specific_sources:
|
||||||
binfo.bdepends = depends
|
sources = []
|
||||||
binfo.bimplicit = implicit
|
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
|
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
|
binfo.bimplicitsigs = implicitsigs
|
||||||
|
|
||||||
return binfo
|
return binfo
|
||||||
|
@ -823,7 +823,7 @@ class Node:
|
||||||
def add_dependency(self, depend):
|
def add_dependency(self, depend):
|
||||||
"""Adds dependencies."""
|
"""Adds dependencies."""
|
||||||
try:
|
try:
|
||||||
self._add_child(self.depends, self.depends_dict, depend)
|
self._add_child(self.depends, self.depends_set, depend)
|
||||||
except TypeError, e:
|
except TypeError, e:
|
||||||
e = e.args[0]
|
e = e.args[0]
|
||||||
if SCons.Util.is_List(e):
|
if SCons.Util.is_List(e):
|
||||||
|
@ -840,7 +840,7 @@ class Node:
|
||||||
def add_ignore(self, depend):
|
def add_ignore(self, depend):
|
||||||
"""Adds dependencies to ignore."""
|
"""Adds dependencies to ignore."""
|
||||||
try:
|
try:
|
||||||
self._add_child(self.ignore, self.ignore_dict, depend)
|
self._add_child(self.ignore, self.ignore_set, depend)
|
||||||
except TypeError, e:
|
except TypeError, e:
|
||||||
e = e.args[0]
|
e = e.args[0]
|
||||||
if SCons.Util.is_List(e):
|
if SCons.Util.is_List(e):
|
||||||
|
@ -851,8 +851,10 @@ class Node:
|
||||||
|
|
||||||
def add_source(self, source):
|
def add_source(self, source):
|
||||||
"""Adds sources."""
|
"""Adds sources."""
|
||||||
|
if self._specific_sources:
|
||||||
|
return
|
||||||
try:
|
try:
|
||||||
self._add_child(self.sources, self.sources_dict, source)
|
self._add_child(self.sources, self.sources_set, source)
|
||||||
except TypeError, e:
|
except TypeError, e:
|
||||||
e = e.args[0]
|
e = e.args[0]
|
||||||
if SCons.Util.is_List(e):
|
if SCons.Util.is_List(e):
|
||||||
|
@ -861,9 +863,9 @@ class Node:
|
||||||
s = str(e)
|
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)))
|
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):
|
def _add_child(self, collection, set, child):
|
||||||
"""Adds 'child' to 'collection', first checking 'dict' to see
|
"""Adds 'child' to 'collection', first checking 'set' to see if it's
|
||||||
if it's already present."""
|
already present."""
|
||||||
#if type(child) is not type([]):
|
#if type(child) is not type([]):
|
||||||
# child = [child]
|
# child = [child]
|
||||||
#for c in child:
|
#for c in child:
|
||||||
|
@ -871,13 +873,17 @@ class Node:
|
||||||
# raise TypeError, c
|
# raise TypeError, c
|
||||||
added = None
|
added = None
|
||||||
for c in child:
|
for c in child:
|
||||||
if not dict.has_key(c):
|
if c not in set:
|
||||||
|
set.add(c)
|
||||||
collection.append(c)
|
collection.append(c)
|
||||||
dict[c] = 1
|
|
||||||
added = 1
|
added = 1
|
||||||
if added:
|
if added:
|
||||||
self._children_reset()
|
self._children_reset()
|
||||||
|
|
||||||
|
def set_specific_source(self, source):
|
||||||
|
self.add_source(source)
|
||||||
|
self._specific_sources = True
|
||||||
|
|
||||||
def add_wkid(self, wkid):
|
def add_wkid(self, wkid):
|
||||||
"""Add a node to the list of kids waiting to be evaluated"""
|
"""Add a node to the list of kids waiting to be evaluated"""
|
||||||
if self.wkids != None:
|
if self.wkids != None:
|
||||||
|
@ -889,10 +895,55 @@ class Node:
|
||||||
# build info that it's cached so we can re-calculate it.
|
# build info that it's cached so we can re-calculate it.
|
||||||
self.executor_cleanup()
|
self.executor_cleanup()
|
||||||
|
|
||||||
def do_not_ignore(self, node):
|
memoizer_counters.append(SCons.Memoize.CountValue('_children_get'))
|
||||||
return node not in self.ignore
|
|
||||||
|
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
|
# The return list may contain duplicate Nodes, especially in
|
||||||
# source trees where there are a lot of repeated #includes
|
# source trees where there are a lot of repeated #includes
|
||||||
# of a tangle of .h files. Profiling shows, however, that
|
# of a tangle of .h files. Profiling shows, however, that
|
||||||
|
@ -915,25 +966,6 @@ class Node:
|
||||||
else:
|
else:
|
||||||
return self.sources + self.depends + self.implicit
|
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):
|
def children(self, scan=1):
|
||||||
"""Return a list of the node's direct children, minus those
|
"""Return a list of the node's direct children, minus those
|
||||||
that are ignored by this node."""
|
that are ignored by this node."""
|
||||||
|
@ -1013,9 +1045,10 @@ class Node:
|
||||||
# entries to equal the new dependency list, for the benefit
|
# entries to equal the new dependency list, for the benefit
|
||||||
# of the loop below that updates node information.
|
# of the loop below that updates node information.
|
||||||
then.extend([None] * diff)
|
then.extend([None] * diff)
|
||||||
|
if t: Trace(': old %s new %s' % (len(then), len(children)))
|
||||||
result = True
|
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 child.changed_since_last_build(self, prev_ni):
|
||||||
if t: Trace(': %s changed' % child)
|
if t: Trace(': %s changed' % child)
|
||||||
result = True
|
result = True
|
||||||
|
@ -1071,7 +1104,10 @@ class Node:
|
||||||
env = self.get_build_env()
|
env = self.get_build_env()
|
||||||
for s in self.sources:
|
for s in self.sources:
|
||||||
scanner = self.get_source_scanner(s)
|
scanner = self.get_source_scanner(s)
|
||||||
|
if scanner:
|
||||||
path = self.get_build_scanner_path(scanner)
|
path = self.get_build_scanner_path(scanner)
|
||||||
|
else:
|
||||||
|
path = None
|
||||||
def f(node, env=env, scanner=scanner, path=path):
|
def f(node, env=env, scanner=scanner, path=path):
|
||||||
return node.get_found_includes(env, scanner, path)
|
return node.get_found_includes(env, scanner, path)
|
||||||
return SCons.Util.render_tree(s, f, 1)
|
return SCons.Util.render_tree(s, f, 1)
|
||||||
|
@ -1158,8 +1194,8 @@ class Node:
|
||||||
new_bkids = new.bsources + new.bdepends + new.bimplicit
|
new_bkids = new.bsources + new.bdepends + new.bimplicit
|
||||||
new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs
|
new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs
|
||||||
|
|
||||||
osig = dict(zip(old_bkids, old_bkidsigs))
|
osig = dict(izip(old_bkids, old_bkidsigs))
|
||||||
nsig = dict(zip(new_bkids, new_bkidsigs))
|
nsig = dict(izip(new_bkids, new_bkidsigs))
|
||||||
|
|
||||||
# The sources and dependencies we'll want to report are all stored
|
# The sources and dependencies we'll want to report are all stored
|
||||||
# as relative paths to this target's directory, but we want to
|
# 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
|
# so we only print them after running them through this lambda
|
||||||
# to turn them into the right relative Node and then return
|
# to turn them into the right relative Node and then return
|
||||||
# its string.
|
# 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 = []
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
__doc__ = """SCons.PathList
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ def node_conv(obj):
|
||||||
try:
|
try:
|
||||||
get = obj.get
|
get = obj.get
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
if isinstance(obj, SCons.Node.Node):
|
if isinstance(obj, SCons.Node.Node) or SCons.Util.is_Sequence( obj ):
|
||||||
result = obj
|
result = obj
|
||||||
else:
|
else:
|
||||||
result = str(obj)
|
result = str(obj)
|
||||||
|
@ -132,10 +132,9 @@ class _PathList:
|
||||||
value = env.subst(value, target=target, source=source,
|
value = env.subst(value, target=target, source=source,
|
||||||
conv=node_conv)
|
conv=node_conv)
|
||||||
if SCons.Util.is_Sequence(value):
|
if SCons.Util.is_Sequence(value):
|
||||||
# It came back as a string or tuple, which in this
|
result.extend(value)
|
||||||
# case usually means some variable expanded to an
|
continue
|
||||||
# actually Dir node. Concatenate the values.
|
|
||||||
value = string.join(map(str, value), '')
|
|
||||||
elif type == TYPE_OBJECT:
|
elif type == TYPE_OBJECT:
|
||||||
value = node_conv(value)
|
value = node_conv(value)
|
||||||
if 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 imp
|
||||||
import os
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 os
|
||||||
import string
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
import posix
|
||||||
from SCons.Platform import TempFileMunge
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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):
|
def generate(env):
|
||||||
if not env.has_key('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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
||||||
import os.path
|
import os.path
|
||||||
import popen2
|
|
||||||
import string
|
import string
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import select
|
import select
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ exitvalmap = {
|
||||||
def escape(arg):
|
def escape(arg):
|
||||||
"escape shell special characters"
|
"escape shell special characters"
|
||||||
slash = '\\'
|
slash = '\\'
|
||||||
special = '"$'
|
special = '"$()'
|
||||||
|
|
||||||
arg = string.replace(arg, slash, slash+slash)
|
arg = string.replace(arg, slash, slash+slash)
|
||||||
for c in special:
|
for c in special:
|
||||||
|
@ -92,7 +93,7 @@ def _get_env_command(sh, escape, cmd, args, env):
|
||||||
s = string.join(args)
|
s = string.join(args)
|
||||||
if env:
|
if env:
|
||||||
l = ['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)]
|
[sh, '-c', escape(s)]
|
||||||
s = string.join(l)
|
s = string.join(l)
|
||||||
return s
|
return s
|
||||||
|
@ -109,6 +110,7 @@ def fork_spawn(sh, escape, cmd, args, env):
|
||||||
def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
|
def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
|
||||||
stdout_eof = stderr_eof = 0
|
stdout_eof = stderr_eof = 0
|
||||||
while not (stdout_eof and stderr_eof):
|
while not (stdout_eof and stderr_eof):
|
||||||
|
try:
|
||||||
(i,o,e) = select.select([cmd_stdout, cmd_stderr], [], [])
|
(i,o,e) = select.select([cmd_stdout, cmd_stderr], [], [])
|
||||||
if cmd_stdout in i:
|
if cmd_stdout in i:
|
||||||
str = cmd_stdout.read()
|
str = cmd_stdout.read()
|
||||||
|
@ -124,10 +126,15 @@ def process_cmd_output(cmd_stdout, cmd_stderr, stdout, stderr):
|
||||||
else:
|
else:
|
||||||
#sys.__stderr__.write( "str(stderr) = %s\n" % str )
|
#sys.__stderr__.write( "str(stderr) = %s\n" % str )
|
||||||
stderr.write(str)
|
stderr.write(str)
|
||||||
|
except select.error, (_errno, _strerror):
|
||||||
|
if _errno != errno.EINTR:
|
||||||
|
raise
|
||||||
|
|
||||||
def exec_popen3(l, env, stdout, stderr):
|
def exec_popen3(l, env, stdout, stderr):
|
||||||
proc = popen2.Popen3(string.join(l), 1)
|
proc = subprocess.Popen(string.join(l),
|
||||||
process_cmd_output(proc.fromchild, proc.childerr, stdout, stderr)
|
stdout=stdout,
|
||||||
|
stderr=stderr,
|
||||||
|
shell=True)
|
||||||
stat = proc.wait()
|
stat = proc.wait()
|
||||||
if stat & 0xff:
|
if stat & 0xff:
|
||||||
return stat | 0x80
|
return stat | 0x80
|
||||||
|
@ -235,7 +242,7 @@ def generate(env):
|
||||||
env['LIBSUFFIX'] = '.a'
|
env['LIBSUFFIX'] = '.a'
|
||||||
env['SHLIBPREFIX'] = '$LIBPREFIX'
|
env['SHLIBPREFIX'] = '$LIBPREFIX'
|
||||||
env['SHLIBSUFFIX'] = '.so'
|
env['SHLIBSUFFIX'] = '.so'
|
||||||
env['LIBPREFIXES'] = '$LIBPREFIX'
|
env['LIBPREFIXES'] = [ '$LIBPREFIX' ]
|
||||||
env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ]
|
env['LIBSUFFIXES'] = [ '$LIBSUFFIX', '$SHLIBSUFFIX' ]
|
||||||
env['PSPAWN'] = pspawn
|
env['PSPAWN'] = pspawn
|
||||||
env['SPAWN'] = spawn
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
||||||
import os.path
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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"
|
__revision__ = "src/engine/SCons/SConf.py 3842 2008/12/20 22:59:52 scons"
|
||||||
|
|
||||||
import SCons.compat
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -235,7 +233,9 @@ class SConfBuildTask(SCons.Taskmaster.Task):
|
||||||
raise
|
raise
|
||||||
elif issubclass(exc_type, SCons.Errors.BuildError):
|
elif issubclass(exc_type, SCons.Errors.BuildError):
|
||||||
# we ignore Build Errors (occurs, when a test doesn't pass)
|
# 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:
|
else:
|
||||||
self.display('Caught exception while building "%s":\n' %
|
self.display('Caught exception while building "%s":\n' %
|
||||||
self.targets[0])
|
self.targets[0])
|
||||||
|
@ -381,7 +381,7 @@ class SConfBase:
|
||||||
e.g. custom_tests={'CheckPrivate':MyPrivateTest}, where MyPrivateTest
|
e.g. custom_tests={'CheckPrivate':MyPrivateTest}, where MyPrivateTest
|
||||||
defines a custom test.
|
defines a custom test.
|
||||||
Note also the conf_dir and log_file arguments (you may want to
|
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
|
global SConfFS
|
||||||
if not SConfFS:
|
if not SConfFS:
|
||||||
|
@ -401,14 +401,19 @@ class SConfBase:
|
||||||
|
|
||||||
# add default tests
|
# add default tests
|
||||||
default_tests = {
|
default_tests = {
|
||||||
|
'CheckCC' : CheckCC,
|
||||||
|
'CheckCXX' : CheckCXX,
|
||||||
|
'CheckSHCC' : CheckSHCC,
|
||||||
|
'CheckSHCXX' : CheckSHCXX,
|
||||||
'CheckFunc' : CheckFunc,
|
'CheckFunc' : CheckFunc,
|
||||||
'CheckType' : CheckType,
|
'CheckType' : CheckType,
|
||||||
'CheckTypeSize' : CheckTypeSize,
|
'CheckTypeSize' : CheckTypeSize,
|
||||||
|
'CheckDeclaration' : CheckDeclaration,
|
||||||
'CheckHeader' : CheckHeader,
|
'CheckHeader' : CheckHeader,
|
||||||
'CheckCHeader' : CheckCHeader,
|
'CheckCHeader' : CheckCHeader,
|
||||||
'CheckCXXHeader' : CheckCXXHeader,
|
'CheckCXXHeader' : CheckCXXHeader,
|
||||||
'CheckLib' : CheckLib,
|
'CheckLib' : CheckLib,
|
||||||
'CheckLibWithHeader' : CheckLibWithHeader
|
'CheckLibWithHeader' : CheckLibWithHeader,
|
||||||
}
|
}
|
||||||
self.AddTests(default_tests)
|
self.AddTests(default_tests)
|
||||||
self.AddTests(custom_tests)
|
self.AddTests(custom_tests)
|
||||||
|
@ -425,6 +430,31 @@ class SConfBase:
|
||||||
self._shutdown()
|
self._shutdown()
|
||||||
return self.env
|
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):
|
def BuildNodes(self, nodes):
|
||||||
"""
|
"""
|
||||||
Tries to build the given nodes immediately. Returns 1 on success,
|
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.
|
# TODO: should use self.vardict for $CC, $CPPFLAGS, etc.
|
||||||
return not self.TryBuild(self.env.Object, text, ext)
|
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):
|
def AppendLIBS(self, lib_name_list):
|
||||||
oldLIBS = self.env.get( 'LIBS', [] )
|
oldLIBS = self.env.get( 'LIBS', [] )
|
||||||
self.env.Append(LIBS = lib_name_list)
|
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
|
context.did_show_result = 1
|
||||||
return res
|
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 = '""'):
|
def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'):
|
||||||
# used by CheckHeader and CheckLibWithHeader to produce C - #include
|
# used by CheckHeader and CheckLibWithHeader to produce C - #include
|
||||||
# statements from the specified header (list)
|
# statements from the specified header (list)
|
||||||
|
@ -883,6 +931,22 @@ def CheckHeader(context, header, include_quotes = '<>', language = None):
|
||||||
context.did_show_result = 1
|
context.did_show_result = 1
|
||||||
return not res
|
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.
|
# Bram: Make this function obsolete? CheckHeader() is more generic.
|
||||||
|
|
||||||
def CheckCHeader(context, header, include_quotes = '""'):
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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"
|
__revision__ = "src/engine/SCons/SConsign.py 3842 2008/12/20 22:59:52 scons"
|
||||||
|
|
||||||
import SCons.compat
|
|
||||||
|
|
||||||
import cPickle
|
import cPickle
|
||||||
import os
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 string
|
||||||
|
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
||||||
|
|
||||||
def DScanner():
|
def DScanner():
|
||||||
"""Return a prototype Scanner instance for scanning D source files"""
|
"""Return a prototype Scanner instance for scanning D source files"""
|
||||||
ds = D(name = "DScanner",
|
ds = D()
|
||||||
suffixes = '$DSUFFIXES',
|
|
||||||
path_variable = 'DPATH',
|
|
||||||
regex = 'import\s+([^\;]*)\;')
|
|
||||||
return ds
|
return ds
|
||||||
|
|
||||||
class D(SCons.Scanner.Classic):
|
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):
|
def find_include(self, include, source_dir, path):
|
||||||
# translate dots (package separators) to slashes
|
# translate dots (package separators) to slashes
|
||||||
inc = string.replace(include, '.', '/')
|
inc = string.replace(include, '.', '/')
|
||||||
|
|
||||||
i = SCons.Node.FS.find_file(inc + '.d', (source_dir,) + path)
|
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
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Node.FS
|
||||||
import SCons.Scanner
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 re
|
||||||
import string
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Node.FS
|
||||||
import SCons.Scanner
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
import string
|
||||||
|
|
||||||
|
@ -54,10 +54,8 @@ def scan(node, env, libpath = ()):
|
||||||
return []
|
return []
|
||||||
if SCons.Util.is_String(libs):
|
if SCons.Util.is_String(libs):
|
||||||
libs = string.split(libs)
|
libs = string.split(libs)
|
||||||
elif SCons.Util.is_List(libs):
|
|
||||||
libs = SCons.Util.flatten(libs)
|
|
||||||
else:
|
else:
|
||||||
libs = [libs]
|
libs = SCons.Util.flatten(libs)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
prefix = env['LIBPREFIXES']
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Node.FS
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
||||||
|
import re
|
||||||
|
|
||||||
def CScanner():
|
def RCScan():
|
||||||
"""Return a prototype Scanner instance for scanning source files
|
"""Return a prototype Scanner instance for scanning RC source files"""
|
||||||
that use the C pre-processor"""
|
|
||||||
cs = SCons.Scanner.ClassicCPP("CScanner",
|
res_re= r'^(?:\s*#\s*(?:include)|' \
|
||||||
"$CPPSUFFIXES",
|
'.*?\s+(?:ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)' \
|
||||||
|
'\s*.*?)' \
|
||||||
|
'\s*(<|"| )([^>"\s]+)(?:[>" ])*$'
|
||||||
|
resScanner = SCons.Scanner.ClassicCPP( "ResourceScanner",
|
||||||
|
"$RCSUFFIXES",
|
||||||
"CPPPATH",
|
"CPPPATH",
|
||||||
'^[ \t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")')
|
res_re )
|
||||||
return cs
|
|
||||||
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 re
|
||||||
import string
|
import string
|
||||||
|
@ -67,7 +67,7 @@ class FindPathDirs:
|
||||||
will return all of the *path directories."""
|
will return all of the *path directories."""
|
||||||
def __init__(self, variable):
|
def __init__(self, variable):
|
||||||
self.variable = 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
|
import SCons.PathList
|
||||||
try:
|
try:
|
||||||
path = env[self.variable]
|
path = env[self.variable]
|
||||||
|
@ -346,13 +346,16 @@ class Classic(Current):
|
||||||
def sort_key(self, include):
|
def sort_key(self, include):
|
||||||
return SCons.Node.FS._my_normcase(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=()):
|
def scan(self, node, path=()):
|
||||||
|
|
||||||
# cache the includes list in node so we only scan it once:
|
# cache the includes list in node so we only scan it once:
|
||||||
if node.includes != None:
|
if node.includes != None:
|
||||||
includes = node.includes
|
includes = node.includes
|
||||||
else:
|
else:
|
||||||
includes = self.cre.findall(node.get_contents())
|
includes = self.find_include_names (node)
|
||||||
node.includes = includes
|
node.includes = includes
|
||||||
|
|
||||||
# This is a hand-coded DSU (decorate-sort-undecorate, or
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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"
|
__revision__ = "src/engine/SCons/Script/Main.py 3842 2008/12/20 22:59:52 scons"
|
||||||
|
|
||||||
import SCons.compat
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -68,6 +66,18 @@ import SCons.Taskmaster
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
import SCons.Warnings
|
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):
|
class SConsPrintHelpException(Exception):
|
||||||
|
@ -156,11 +166,16 @@ class BuildTask(SCons.Taskmaster.Task):
|
||||||
self.progress(self.targets[0])
|
self.progress(self.targets[0])
|
||||||
return SCons.Taskmaster.Task.prepare(self)
|
return SCons.Taskmaster.Task.prepare(self)
|
||||||
|
|
||||||
|
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):
|
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:
|
if print_time:
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
global first_command_start
|
global first_command_start
|
||||||
|
@ -174,31 +189,37 @@ class BuildTask(SCons.Taskmaster.Task):
|
||||||
last_command_end = finish_time
|
last_command_end = finish_time
|
||||||
cumulative_command_time = cumulative_command_time+finish_time-start_time
|
cumulative_command_time = cumulative_command_time+finish_time-start_time
|
||||||
sys.stdout.write("Command execution time: %f seconds\n"%(finish_time-start_time))
|
sys.stdout.write("Command execution time: %f seconds\n"%(finish_time-start_time))
|
||||||
break
|
|
||||||
else:
|
|
||||||
if self.top and target.has_builder():
|
|
||||||
display("scons: `%s' is up to date." % str(self.node))
|
|
||||||
|
|
||||||
def do_failed(self, status=2):
|
def do_failed(self, status=2):
|
||||||
_BuildFailures.append(self.exception[1])
|
_BuildFailures.append(self.exception[1])
|
||||||
global exit_status
|
global exit_status
|
||||||
|
global this_build_status
|
||||||
if self.options.ignore_errors:
|
if self.options.ignore_errors:
|
||||||
SCons.Taskmaster.Task.executed(self)
|
SCons.Taskmaster.Task.executed(self)
|
||||||
elif self.options.keep_going:
|
elif self.options.keep_going:
|
||||||
SCons.Taskmaster.Task.fail_continue(self)
|
SCons.Taskmaster.Task.fail_continue(self)
|
||||||
exit_status = status
|
exit_status = status
|
||||||
|
this_build_status = status
|
||||||
else:
|
else:
|
||||||
SCons.Taskmaster.Task.fail_stop(self)
|
SCons.Taskmaster.Task.fail_stop(self)
|
||||||
exit_status = status
|
exit_status = status
|
||||||
|
this_build_status = status
|
||||||
|
|
||||||
def executed(self):
|
def executed(self):
|
||||||
t = self.targets[0]
|
t = self.targets[0]
|
||||||
if self.top and not t.has_builder() and not t.side_effect:
|
if self.top and not t.has_builder() and not t.side_effect:
|
||||||
if not t.exists():
|
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:
|
if not self.options.keep_going:
|
||||||
sys.stderr.write(" Stop.")
|
sys.stderr.write(" Stop.")
|
||||||
sys.stderr.write("\n")
|
sys.stderr.write("\n")
|
||||||
|
try:
|
||||||
|
raise SCons.Errors.BuildError(t, errstr)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
self.exception_set()
|
||||||
self.do_failed()
|
self.do_failed()
|
||||||
else:
|
else:
|
||||||
print "scons: Nothing to be done for `%s'." % t
|
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
|
# Handle the failure of a build task. The primary purpose here
|
||||||
# is to display the various types of Errors and Exceptions
|
# is to display the various types of Errors and Exceptions
|
||||||
# appropriately.
|
# appropriately.
|
||||||
status = 2
|
|
||||||
exc_info = self.exc_info()
|
exc_info = self.exc_info()
|
||||||
try:
|
try:
|
||||||
t, e, tb = exc_info
|
t, e, tb = exc_info
|
||||||
except ValueError:
|
except ValueError:
|
||||||
t, e = exc_info
|
t, e = exc_info
|
||||||
tb = None
|
tb = None
|
||||||
|
|
||||||
if t is None:
|
if t is None:
|
||||||
# The Taskmaster didn't record an exception for this Task;
|
# The Taskmaster didn't record an exception for this Task;
|
||||||
# see if the sys module has one.
|
# 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):
|
# Deprecated string exceptions will have their string stored
|
||||||
if not SCons.Util.is_List(n):
|
# in the first entry of the tuple.
|
||||||
n = [ n ]
|
|
||||||
return string.join(map(str, n), ', ')
|
|
||||||
|
|
||||||
errfmt = "scons: *** [%s] %s\n"
|
|
||||||
|
|
||||||
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
|
|
||||||
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:
|
if e is None:
|
||||||
e = t
|
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)
|
|
||||||
|
|
||||||
if tb and print_stacktrace:
|
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 (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 tb and print_stacktrace:
|
||||||
sys.stderr.write("scons: internal stack trace:\n")
|
sys.stderr.write("scons: internal stack trace:\n")
|
||||||
traceback.print_tb(tb, file=sys.stderr)
|
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()
|
self.exc_clear()
|
||||||
|
|
||||||
|
@ -366,7 +388,9 @@ class QuestionTask(SCons.Taskmaster.Task):
|
||||||
if self.targets[0].get_state() != SCons.Node.up_to_date or \
|
if self.targets[0].get_state() != SCons.Node.up_to_date or \
|
||||||
(self.top and not self.targets[0].exists()):
|
(self.top and not self.targets[0].exists()):
|
||||||
global exit_status
|
global exit_status
|
||||||
|
global this_build_status
|
||||||
exit_status = 1
|
exit_status = 1
|
||||||
|
this_build_status = 1
|
||||||
self.tm.stop()
|
self.tm.stop()
|
||||||
|
|
||||||
def executed(self):
|
def executed(self):
|
||||||
|
@ -392,6 +416,16 @@ class TreePrinter:
|
||||||
SCons.Util.print_tree(t, func, prune=self.prune, showtags=s)
|
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
|
# Global variables
|
||||||
|
|
||||||
print_objects = 0
|
print_objects = 0
|
||||||
|
@ -400,7 +434,8 @@ print_stacktrace = 0
|
||||||
print_time = 0
|
print_time = 0
|
||||||
sconscript_time = 0
|
sconscript_time = 0
|
||||||
cumulative_command_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
|
num_jobs = None
|
||||||
delayed_warnings = []
|
delayed_warnings = []
|
||||||
|
|
||||||
|
@ -566,57 +601,14 @@ def _scons_internal_error():
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
def _setup_warn(arg):
|
def _SConstruct_exists(dirname='', repositories=[], filelist=None):
|
||||||
"""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=[]):
|
|
||||||
"""This function checks that an SConstruct file exists in a directory.
|
"""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
|
If so, it returns the path of the file. By default, it checks the
|
||||||
current directory.
|
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)
|
sfile = os.path.join(dirname, file)
|
||||||
if os.path.isfile(sfile):
|
if os.path.isfile(sfile):
|
||||||
return sfile
|
return sfile
|
||||||
|
@ -730,8 +722,8 @@ def version_string(label, module):
|
||||||
module.__buildsys__)
|
module.__buildsys__)
|
||||||
|
|
||||||
def _main(parser):
|
def _main(parser):
|
||||||
import SCons
|
|
||||||
global exit_status
|
global exit_status
|
||||||
|
global this_build_status
|
||||||
|
|
||||||
options = parser.values
|
options = parser.values
|
||||||
|
|
||||||
|
@ -745,17 +737,22 @@ def _main(parser):
|
||||||
default_warnings = [ SCons.Warnings.CorruptSConsignWarning,
|
default_warnings = [ SCons.Warnings.CorruptSConsignWarning,
|
||||||
SCons.Warnings.DeprecatedWarning,
|
SCons.Warnings.DeprecatedWarning,
|
||||||
SCons.Warnings.DuplicateEnvironmentWarning,
|
SCons.Warnings.DuplicateEnvironmentWarning,
|
||||||
|
SCons.Warnings.FutureReservedVariableWarning,
|
||||||
|
SCons.Warnings.LinkWarning,
|
||||||
SCons.Warnings.MissingSConscriptWarning,
|
SCons.Warnings.MissingSConscriptWarning,
|
||||||
SCons.Warnings.NoMD5ModuleWarning,
|
SCons.Warnings.NoMD5ModuleWarning,
|
||||||
SCons.Warnings.NoMetaclassSupportWarning,
|
SCons.Warnings.NoMetaclassSupportWarning,
|
||||||
SCons.Warnings.NoObjectCountWarning,
|
SCons.Warnings.NoObjectCountWarning,
|
||||||
SCons.Warnings.NoParallelSupportWarning,
|
SCons.Warnings.NoParallelSupportWarning,
|
||||||
SCons.Warnings.MisleadingKeywordsWarning, ]
|
SCons.Warnings.MisleadingKeywordsWarning,
|
||||||
|
SCons.Warnings.ReservedVariableWarning,
|
||||||
|
SCons.Warnings.StackSizeWarning,
|
||||||
|
]
|
||||||
|
|
||||||
for warning in default_warnings:
|
for warning in default_warnings:
|
||||||
SCons.Warnings.enableWarningClass(warning)
|
SCons.Warnings.enableWarningClass(warning)
|
||||||
SCons.Warnings._warningOut = _scons_internal_warning
|
SCons.Warnings._warningOut = _scons_internal_warning
|
||||||
if options.warn:
|
SCons.Warnings.process_warn_strings(options.warn)
|
||||||
_setup_warn(options.warn)
|
|
||||||
|
|
||||||
# Now that we have the warnings configuration set up, we can actually
|
# Now that we have the warnings configuration set up, we can actually
|
||||||
# issue (or suppress) any warnings about warning-worthy things that
|
# issue (or suppress) any warnings about warning-worthy things that
|
||||||
|
@ -788,13 +785,15 @@ def _main(parser):
|
||||||
if options.climb_up:
|
if options.climb_up:
|
||||||
target_top = '.' # directory to prepend to targets
|
target_top = '.' # directory to prepend to targets
|
||||||
script_dir = os.getcwd() # location of script
|
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)
|
script_dir, last_part = os.path.split(script_dir)
|
||||||
if last_part:
|
if last_part:
|
||||||
target_top = os.path.join(last_part, target_top)
|
target_top = os.path.join(last_part, target_top)
|
||||||
else:
|
else:
|
||||||
script_dir = ''
|
script_dir = ''
|
||||||
if script_dir:
|
if script_dir and script_dir != os.getcwd():
|
||||||
display("scons: Entering directory `%s'" % script_dir)
|
display("scons: Entering directory `%s'" % script_dir)
|
||||||
os.chdir(script_dir)
|
os.chdir(script_dir)
|
||||||
|
|
||||||
|
@ -813,7 +812,8 @@ def _main(parser):
|
||||||
if options.file:
|
if options.file:
|
||||||
scripts.extend(options.file)
|
scripts.extend(options.file)
|
||||||
if not scripts:
|
if not scripts:
|
||||||
sfile = _SConstruct_exists(repositories=options.repository)
|
sfile = _SConstruct_exists(repositories=options.repository,
|
||||||
|
filelist=options.file)
|
||||||
if sfile:
|
if sfile:
|
||||||
scripts.append(sfile)
|
scripts.append(sfile)
|
||||||
|
|
||||||
|
@ -835,10 +835,10 @@ def _main(parser):
|
||||||
SCons.Node.implicit_cache = options.implicit_cache
|
SCons.Node.implicit_cache = options.implicit_cache
|
||||||
SCons.Node.implicit_deps_changed = options.implicit_deps_changed
|
SCons.Node.implicit_deps_changed = options.implicit_deps_changed
|
||||||
SCons.Node.implicit_deps_unchanged = options.implicit_deps_unchanged
|
SCons.Node.implicit_deps_unchanged = options.implicit_deps_unchanged
|
||||||
|
|
||||||
if options.no_exec:
|
if options.no_exec:
|
||||||
SCons.SConf.dryrun = 1
|
SCons.SConf.dryrun = 1
|
||||||
SCons.Action.execute_actions = None
|
SCons.Action.execute_actions = None
|
||||||
CleanTask.execute = CleanTask.show
|
|
||||||
if options.question:
|
if options.question:
|
||||||
SCons.SConf.dryrun = 1
|
SCons.SConf.dryrun = 1
|
||||||
if options.clean:
|
if options.clean:
|
||||||
|
@ -850,19 +850,6 @@ def _main(parser):
|
||||||
|
|
||||||
if options.no_progress or options.silent:
|
if options.no_progress or options.silent:
|
||||||
progress_display.set_mode(0)
|
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:
|
if options.site_dir:
|
||||||
_load_site_scons_dir(d, 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_Targets(targets + parser.rargs)
|
||||||
SCons.Script._Add_Arguments(xmit_args)
|
SCons.Script._Add_Arguments(xmit_args)
|
||||||
|
|
||||||
|
# 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)
|
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:')
|
memory_stats.append('before reading SConscript files:')
|
||||||
count_stats.append(('pre-', 'read'))
|
count_stats.append(('pre-', 'read'))
|
||||||
|
@ -902,7 +900,7 @@ def _main(parser):
|
||||||
SCons.Script._SConscript._SConscript(fs, script)
|
SCons.Script._SConscript._SConscript(fs, script)
|
||||||
except SCons.Errors.StopError, e:
|
except SCons.Errors.StopError, e:
|
||||||
# We had problems reading an SConscript file, such as it
|
# 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
|
# reading SConscript files and haven't started building
|
||||||
# things yet, stop regardless of whether they used -i or -k
|
# things yet, stop regardless of whether they used -i or -k
|
||||||
# or anything else.
|
# or anything else.
|
||||||
|
@ -917,6 +915,26 @@ def _main(parser):
|
||||||
memory_stats.append('after reading SConscript files:')
|
memory_stats.append('after reading SConscript files:')
|
||||||
count_stats.append(('post-', 'read'))
|
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:
|
if not options.help:
|
||||||
SCons.SConf.CreateConfigHBuilder(SCons.Defaults.DefaultEnvironment())
|
SCons.SConf.CreateConfigHBuilder(SCons.Defaults.DefaultEnvironment())
|
||||||
|
|
||||||
|
@ -943,7 +961,7 @@ def _main(parser):
|
||||||
|
|
||||||
# Change directory to the top-level SConstruct directory, then tell
|
# Change directory to the top-level SConstruct directory, then tell
|
||||||
# the Node.FS subsystem that we're all done reading the SConscript
|
# 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
|
# directories and the like, so it can go ahead and start memoizing
|
||||||
# the string values of file system nodes.
|
# the string values of file system nodes.
|
||||||
|
|
||||||
|
@ -957,6 +975,49 @@ def _main(parser):
|
||||||
SCons.Node.FS.set_duplicate(options.duplicate)
|
SCons.Node.FS.set_duplicate(options.duplicate)
|
||||||
fs.set_max_drift(options.max_drift)
|
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
|
lookup_top = None
|
||||||
if targets or SCons.Script.BUILD_TARGETS != SCons.Script._build_plus_default:
|
if targets or SCons.Script.BUILD_TARGETS != SCons.Script._build_plus_default:
|
||||||
# They specified targets on the command line or modified
|
# They specified targets on the command line or modified
|
||||||
|
@ -1003,7 +1064,7 @@ def _main(parser):
|
||||||
|
|
||||||
if not targets:
|
if not targets:
|
||||||
sys.stderr.write("scons: *** No targets specified and no Default() targets found. Stop.\n")
|
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):
|
def Entry(x, ltop=lookup_top, ttop=target_top, fs=fs):
|
||||||
if isinstance(x, SCons.Node.Node):
|
if isinstance(x, SCons.Node.Node):
|
||||||
|
@ -1046,7 +1107,7 @@ def _main(parser):
|
||||||
opening_message = "Cleaning targets ..."
|
opening_message = "Cleaning targets ..."
|
||||||
closing_message = "done cleaning targets."
|
closing_message = "done cleaning targets."
|
||||||
if options.keep_going:
|
if options.keep_going:
|
||||||
closing_message = "done cleaning targets (errors occurred during clean)."
|
failure_message = "done cleaning targets (errors occurred during clean)."
|
||||||
else:
|
else:
|
||||||
failure_message = "cleaning terminated because of errors."
|
failure_message = "cleaning terminated because of errors."
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -1091,29 +1152,43 @@ def _main(parser):
|
||||||
msg = "parallel builds are unsupported by this version of Python;\n" + \
|
msg = "parallel builds are unsupported by this version of Python;\n" + \
|
||||||
"\tignoring -j or num_jobs option.\n"
|
"\tignoring -j or num_jobs option.\n"
|
||||||
elif sys.platform == 'win32':
|
elif sys.platform == 'win32':
|
||||||
import SCons.Platform.win32
|
msg = fetch_win32_parallel_msg()
|
||||||
msg = SCons.Platform.win32.parallel_msg
|
|
||||||
if msg:
|
if msg:
|
||||||
SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg)
|
SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg)
|
||||||
|
|
||||||
memory_stats.append('before building targets:')
|
memory_stats.append('before building targets:')
|
||||||
count_stats.append(('pre-', 'build'))
|
count_stats.append(('pre-', 'build'))
|
||||||
|
|
||||||
try:
|
def jobs_postfunc(
|
||||||
progress_display("scons: " + opening_message)
|
jobs=jobs,
|
||||||
jobs.run()
|
options=options,
|
||||||
finally:
|
closing_message=closing_message,
|
||||||
jobs.cleanup()
|
failure_message=failure_message
|
||||||
if exit_status:
|
):
|
||||||
|
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)
|
progress_display("scons: " + failure_message)
|
||||||
else:
|
else:
|
||||||
progress_display("scons: " + closing_message)
|
progress_display("scons: " + closing_message)
|
||||||
if not options.no_exec:
|
if not options.no_exec:
|
||||||
|
if jobs.were_interrupted():
|
||||||
|
progress_display("scons: writing .sconsign file.")
|
||||||
SCons.SConsign.write()
|
SCons.SConsign.write()
|
||||||
|
|
||||||
|
progress_display("scons: " + opening_message)
|
||||||
|
jobs.run(postfunc = jobs_postfunc)
|
||||||
|
|
||||||
memory_stats.append('after building targets:')
|
memory_stats.append('after building targets:')
|
||||||
count_stats.append(('post-', 'build'))
|
count_stats.append(('post-', 'build'))
|
||||||
|
|
||||||
|
return nodes
|
||||||
|
|
||||||
def _exec_main(parser, values):
|
def _exec_main(parser, values):
|
||||||
sconsflags = os.environ.get('SCONSFLAGS', '')
|
sconsflags = os.environ.get('SCONSFLAGS', '')
|
||||||
all_args = string.split(sconsflags) + sys.argv[1:]
|
all_args = string.split(sconsflags) + sys.argv[1:]
|
||||||
|
@ -1124,6 +1199,9 @@ def _exec_main(parser, values):
|
||||||
import pdb
|
import pdb
|
||||||
pdb.Pdb().runcall(_main, parser)
|
pdb.Pdb().runcall(_main, parser)
|
||||||
elif options.profile_file:
|
elif options.profile_file:
|
||||||
|
try:
|
||||||
|
from cProfile import Profile
|
||||||
|
except ImportError, e:
|
||||||
from profile import Profile
|
from profile import Profile
|
||||||
|
|
||||||
# Some versions of Python 2.4 shipped a profiler that had the
|
# Some versions of Python 2.4 shipped a profiler that had the
|
||||||
|
@ -1155,17 +1233,25 @@ def main():
|
||||||
global exit_status
|
global exit_status
|
||||||
global first_command_start
|
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"]
|
parts = ["SCons by Steven Knight et al.:\n"]
|
||||||
try:
|
try:
|
||||||
|
import __main__
|
||||||
parts.append(version_string("script", __main__))
|
parts.append(version_string("script", __main__))
|
||||||
except KeyboardInterrupt:
|
except (ImportError, AttributeError):
|
||||||
raise
|
|
||||||
except:
|
|
||||||
# On Windows there is no scons.py, so there is no
|
# On Windows there is no scons.py, so there is no
|
||||||
# __main__.__version__, hence there is no script version.
|
# __main__.__version__, hence there is no script version.
|
||||||
pass
|
pass
|
||||||
parts.append(version_string("engine", SCons))
|
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, '')
|
version = string.join(parts, '')
|
||||||
|
|
||||||
import SConsOptions
|
import SConsOptions
|
||||||
|
@ -1180,7 +1266,7 @@ def main():
|
||||||
if s:
|
if s:
|
||||||
exit_status = s
|
exit_status = s
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print "Build interrupted."
|
print("scons: Build interrupted.")
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
except SyntaxError, e:
|
except SyntaxError, e:
|
||||||
_scons_syntax_error(e)
|
_scons_syntax_error(e)
|
||||||
|
@ -1191,6 +1277,8 @@ def main():
|
||||||
except SConsPrintHelpException:
|
except SConsPrintHelpException:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit_status = 0
|
exit_status = 0
|
||||||
|
except SCons.Errors.BuildError, e:
|
||||||
|
exit_status = e.exitstatus
|
||||||
except:
|
except:
|
||||||
# An exception here is likely a builtin Python exception Python
|
# An exception here is likely a builtin Python exception Python
|
||||||
# code in an SConscript file. Show them precisely what the
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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"
|
__revision__ = "src/engine/SCons/Script/SConsOptions.py 3842 2008/12/20 22:59:52 scons"
|
||||||
|
|
||||||
import SCons.compat
|
|
||||||
|
|
||||||
import optparse
|
import optparse
|
||||||
|
import re
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
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:
|
try:
|
||||||
from gettext import gettext
|
from gettext import gettext
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -38,6 +44,7 @@ except ImportError:
|
||||||
_ = gettext
|
_ = gettext
|
||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
|
import SCons.Warnings
|
||||||
|
|
||||||
OptionValueError = optparse.OptionValueError
|
OptionValueError = optparse.OptionValueError
|
||||||
SUPPRESS_HELP = optparse.SUPPRESS_HELP
|
SUPPRESS_HELP = optparse.SUPPRESS_HELP
|
||||||
|
@ -119,9 +126,12 @@ class SConsValues(optparse.Values):
|
||||||
'help',
|
'help',
|
||||||
'implicit_cache',
|
'implicit_cache',
|
||||||
'max_drift',
|
'max_drift',
|
||||||
|
'md5_chunksize',
|
||||||
'no_exec',
|
'no_exec',
|
||||||
'num_jobs',
|
'num_jobs',
|
||||||
'random',
|
'random',
|
||||||
|
'stack_size',
|
||||||
|
'warn',
|
||||||
]
|
]
|
||||||
|
|
||||||
def set_option(self, name, value):
|
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
|
# Set this right away so it can affect the rest of the
|
||||||
# file/Node lookups while processing the SConscript files.
|
# file/Node lookups while processing the SConscript files.
|
||||||
SCons.Node.FS.set_diskcheck(value)
|
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
|
self.__SConscript_settings__[name] = value
|
||||||
|
|
||||||
|
@ -369,8 +394,16 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
|
||||||
def format_option(self, option):
|
def format_option(self, option):
|
||||||
"""
|
"""
|
||||||
A copy of the normal optparse.IndentedHelpFormatter.format_option()
|
A copy of the normal optparse.IndentedHelpFormatter.format_option()
|
||||||
method, snarfed so we can set the subsequent_indent on the
|
method. This has been snarfed so we can modify text wrapping to
|
||||||
textwrap.wrap() call below...
|
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 help for each option consists of two parts:
|
||||||
# * the opt strings and metavars
|
# * the opt strings and metavars
|
||||||
|
@ -397,7 +430,11 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
|
||||||
|
|
||||||
opt_width = self.help_position - self.current_indent - 2
|
opt_width = self.help_position - self.current_indent - 2
|
||||||
if len(opts) > opt_width:
|
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
|
indent_first = self.help_position
|
||||||
else: # start help on same line as opts
|
else: # start help on same line as opts
|
||||||
opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts)
|
opts = "%*s%-*s " % (self.current_indent, "", opt_width, opts)
|
||||||
|
@ -415,8 +452,10 @@ class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter):
|
||||||
help_text = expand_default(option)
|
help_text = expand_default(option)
|
||||||
|
|
||||||
# SCons: indent every line of the help text but the first.
|
# SCons: indent every line of the help text but the first.
|
||||||
help_lines = textwrap.wrap(help_text, self.help_width,
|
wrapper = textwrap.TextWrapper(width=self.help_width,
|
||||||
subsequent_indent = ' ')
|
subsequent_indent = ' ')
|
||||||
|
wrapper.wordsep_re = no_hyphen_re
|
||||||
|
help_lines = wrapper.wrap(help_text)
|
||||||
result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
|
result.append("%*s%s\n" % (indent_first, "", help_lines[0]))
|
||||||
for line in help_lines[1:]:
|
for line in help_lines[1:]:
|
||||||
result.append("%*s%s\n" % (self.help_position, "", line))
|
result.append("%*s%s\n" % (self.help_position, "", line))
|
||||||
|
@ -466,6 +505,7 @@ def Parser(version):
|
||||||
usage="usage: scons [OPTION] [TARGET] ...",)
|
usage="usage: scons [OPTION] [TARGET] ...",)
|
||||||
|
|
||||||
op.preserve_unknown_options = True
|
op.preserve_unknown_options = True
|
||||||
|
op.version = version
|
||||||
|
|
||||||
# Add the options to the parser we just created.
|
# Add the options to the parser we just created.
|
||||||
#
|
#
|
||||||
|
@ -489,8 +529,13 @@ def Parser(version):
|
||||||
# options ignored for compatibility
|
# options ignored for compatibility
|
||||||
def opt_ignore(option, opt, value, parser):
|
def opt_ignore(option, opt, value, parser):
|
||||||
sys.stderr.write("Warning: ignoring %s option\n" % opt)
|
sys.stderr.write("Warning: ignoring %s option\n" % opt)
|
||||||
op.add_option("-b", "-m", "-S", "-t",
|
op.add_option("-b", "-d", "-e", "-m", "-S", "-t", "-w",
|
||||||
"--no-keep-going", "--stop", "--touch",
|
"--environment-overrides",
|
||||||
|
"--no-keep-going",
|
||||||
|
"--no-print-directory",
|
||||||
|
"--print-directory",
|
||||||
|
"--stop",
|
||||||
|
"--touch",
|
||||||
action="callback", callback=opt_ignore,
|
action="callback", callback=opt_ignore,
|
||||||
help="Ignored for compatibility.")
|
help="Ignored for compatibility.")
|
||||||
|
|
||||||
|
@ -543,34 +588,30 @@ def Parser(version):
|
||||||
help = opt_config_help,
|
help = opt_config_help,
|
||||||
metavar="MODE")
|
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',
|
op.add_option('-D',
|
||||||
dest="climb_up", default=None,
|
dest="climb_up", default=None,
|
||||||
action="store_const", const=2,
|
action="store_const", const=2,
|
||||||
help="Search up directory tree for SConstruct, "
|
help="Search up directory tree for SConstruct, "
|
||||||
"build all Default() targets.")
|
"build all Default() targets.")
|
||||||
|
|
||||||
debug_options = ["count", "dtree", "explain", "findlibs",
|
|
||||||
"includes", "memoizer", "memory", "objects",
|
|
||||||
"pdb", "presub", "stacktrace", "stree",
|
|
||||||
"time", "tree"]
|
|
||||||
|
|
||||||
deprecated_debug_options = {
|
deprecated_debug_options = {
|
||||||
|
"dtree" : '; please use --tree=derived instead',
|
||||||
"nomemoizer" : ' and has no effect',
|
"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,
|
def opt_debug(option, opt, value, parser,
|
||||||
debug_options=debug_options,
|
debug_options=debug_options,
|
||||||
deprecated_debug_options=deprecated_debug_options):
|
deprecated_debug_options=deprecated_debug_options):
|
||||||
if value in debug_options:
|
if value in debug_options:
|
||||||
parser.values.debug.append(value)
|
parser.values.debug.append(value)
|
||||||
elif value in deprecated_debug_options.keys():
|
if value in deprecated_debug_options.keys():
|
||||||
try:
|
try:
|
||||||
parser.values.delayed_warnings
|
parser.values.delayed_warnings
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
@ -667,6 +708,11 @@ def Parser(version):
|
||||||
action="callback", callback=opt_implicit_deps,
|
action="callback", callback=opt_implicit_deps,
|
||||||
help="Ignore changes in implicit dependencies.")
|
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',
|
op.add_option('-j', '--jobs',
|
||||||
nargs=1, type="int",
|
nargs=1, type="int",
|
||||||
dest="num_jobs", default=1,
|
dest="num_jobs", default=1,
|
||||||
|
@ -686,6 +732,13 @@ def Parser(version):
|
||||||
help="Set maximum system clock drift to N seconds.",
|
help="Set maximum system clock drift to N seconds.",
|
||||||
metavar="N")
|
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',
|
op.add_option('-n', '--no-exec', '--just-print', '--dry-run', '--recon',
|
||||||
dest='no_exec', default=False,
|
dest='no_exec', default=False,
|
||||||
action="store_true",
|
action="store_true",
|
||||||
|
@ -730,6 +783,13 @@ def Parser(version):
|
||||||
help="Use DIR instead of the usual site_scons dir.",
|
help="Use DIR instead of the usual site_scons dir.",
|
||||||
metavar="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',
|
op.add_option('--taskmastertrace',
|
||||||
nargs=1,
|
nargs=1,
|
||||||
dest="taskmastertrace_file", default=None,
|
dest="taskmastertrace_file", default=None,
|
||||||
|
@ -777,17 +837,22 @@ def Parser(version):
|
||||||
help="Search up directory tree for SConstruct, "
|
help="Search up directory tree for SConstruct, "
|
||||||
"build Default() targets from local SConscript.")
|
"build Default() targets from local SConscript.")
|
||||||
|
|
||||||
def opt_version(option, opt, value, parser, version=version):
|
def opt_version(option, opt, value, parser):
|
||||||
sys.stdout.write(version + '\n')
|
sys.stdout.write(parser.version + '\n')
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
op.add_option("-v", "--version",
|
op.add_option("-v", "--version",
|
||||||
action="callback", callback=opt_version,
|
action="callback", callback=opt_version,
|
||||||
help="Print the SCons version number and exit.")
|
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',
|
op.add_option('--warn', '--warning',
|
||||||
nargs=1,
|
nargs=1, type="string",
|
||||||
dest="warn", default=None,
|
dest="warn", default=[],
|
||||||
action="store",
|
action="callback", callback=opt_warn,
|
||||||
help="Enable or disable warnings.",
|
help="Enable or disable warnings.",
|
||||||
metavar="WARNING-SPEC")
|
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
|
# 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.
|
# yet implemented" message and don't show up in the help output.
|
||||||
|
|
||||||
op.add_option('-e', '--environment-overrides',
|
def opt_not_yet(option, opt, value, parser):
|
||||||
dest="environment_overrides",
|
msg = "Warning: the %s option is not yet implemented\n" % opt
|
||||||
action="callback", callback=opt_not_yet,
|
sys.stderr.write(msg)
|
||||||
# help="Environment variables override makefiles."
|
sys.exit(0)
|
||||||
help=SUPPRESS_HELP)
|
|
||||||
|
|
||||||
op.add_option('-l', '--load-average', '--max-load',
|
op.add_option('-l', '--load-average', '--max-load',
|
||||||
nargs=1, type="int",
|
nargs=1, type="int",
|
||||||
dest="load_average", default=0,
|
dest="load_average", default=0,
|
||||||
|
@ -853,16 +919,6 @@ def Parser(version):
|
||||||
dest="no_builtin_rules",
|
dest="no_builtin_rules",
|
||||||
# help="Clear default environments and variables."
|
# help="Clear default environments and variables."
|
||||||
help=SUPPRESS_HELP)
|
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',
|
op.add_option('--write-filenames',
|
||||||
nargs=1, type="string",
|
nargs=1, type="string",
|
||||||
dest="write_filenames",
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
|
@ -39,7 +39,6 @@ import SCons.Errors
|
||||||
import SCons.Node
|
import SCons.Node
|
||||||
import SCons.Node.Alias
|
import SCons.Node.Alias
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Options
|
|
||||||
import SCons.Platform
|
import SCons.Platform
|
||||||
import SCons.SConf
|
import SCons.SConf
|
||||||
import SCons.Script.Main
|
import SCons.Script.Main
|
||||||
|
@ -82,7 +81,10 @@ def get_calling_namespaces():
|
||||||
"""Return the locals and globals for the function that called
|
"""Return the locals and globals for the function that called
|
||||||
into this module in the current call stack."""
|
into this module in the current call stack."""
|
||||||
try: 1/0
|
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
|
# Find the first frame that *isn't* from this file. This means
|
||||||
# that we expect all of the SCons frames that implement an Export()
|
# that we expect all of the SCons frames that implement an Export()
|
||||||
|
@ -141,7 +143,8 @@ call_stack = []
|
||||||
def Return(*vars, **kw):
|
def Return(*vars, **kw):
|
||||||
retval = []
|
retval = []
|
||||||
try:
|
try:
|
||||||
for var in vars:
|
fvars = SCons.Util.flatten(vars)
|
||||||
|
for var in fvars:
|
||||||
for v in string.split(var):
|
for v in string.split(var):
|
||||||
retval.append(call_stack[-1].globals[v])
|
retval.append(call_stack[-1].globals[v])
|
||||||
except KeyError, x:
|
except KeyError, x:
|
||||||
|
@ -276,7 +279,20 @@ def _SConscript(fs, *files, **kw):
|
||||||
fs.chdir(frame.prev_dir, change_os_dir=0)
|
fs.chdir(frame.prev_dir, change_os_dir=0)
|
||||||
rdir = frame.prev_dir.rdir()
|
rdir = frame.prev_dir.rdir()
|
||||||
rdir._create() # Make sure there's a directory there.
|
rdir._create() # Make sure there's a directory there.
|
||||||
|
try:
|
||||||
os.chdir(rdir.get_abspath())
|
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)
|
results.append(frame.retval)
|
||||||
|
|
||||||
|
@ -403,16 +419,16 @@ class SConsEnvironment(SCons.Environment.Base):
|
||||||
if kw.get('exports'):
|
if kw.get('exports'):
|
||||||
exports.extend(self.Split(kw['exports']))
|
exports.extend(self.Split(kw['exports']))
|
||||||
|
|
||||||
build_dir = kw.get('build_dir')
|
variant_dir = kw.get('variant_dir') or kw.get('build_dir')
|
||||||
if build_dir:
|
if variant_dir:
|
||||||
if len(files) != 1:
|
if len(files) != 1:
|
||||||
raise SCons.Errors.UserError, \
|
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)
|
duplicate = kw.get('duplicate', 1)
|
||||||
src_dir = kw.get('src_dir')
|
src_dir = kw.get('src_dir')
|
||||||
if not src_dir:
|
if not src_dir:
|
||||||
src_dir, fname = os.path.split(str(files[0]))
|
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:
|
else:
|
||||||
if not isinstance(src_dir, SCons.Node.Node):
|
if not isinstance(src_dir, SCons.Node.Node):
|
||||||
src_dir = self.fs.Dir(src_dir)
|
src_dir = self.fs.Dir(src_dir)
|
||||||
|
@ -422,11 +438,11 @@ class SConsEnvironment(SCons.Environment.Base):
|
||||||
if fn.is_under(src_dir):
|
if fn.is_under(src_dir):
|
||||||
# Get path relative to the source directory.
|
# Get path relative to the source directory.
|
||||||
fname = fn.get_path(src_dir)
|
fname = fn.get_path(src_dir)
|
||||||
files = [os.path.join(str(build_dir), fname)]
|
files = [os.path.join(str(variant_dir), fname)]
|
||||||
else:
|
else:
|
||||||
files = [fn.abspath]
|
files = [fn.abspath]
|
||||||
kw['src_dir'] = build_dir
|
kw['src_dir'] = variant_dir
|
||||||
self.fs.BuildDir(build_dir, src_dir, duplicate)
|
self.fs.VariantDir(variant_dir, src_dir, duplicate)
|
||||||
|
|
||||||
return (files, exports)
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
import time
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
@ -84,6 +84,7 @@ import SCons.SConf
|
||||||
import SCons.Subst
|
import SCons.Subst
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
import SCons.Variables
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
|
|
||||||
import Main
|
import Main
|
||||||
|
@ -138,22 +139,31 @@ call_stack = _SConscript.call_stack
|
||||||
Action = SCons.Action.Action
|
Action = SCons.Action.Action
|
||||||
AddMethod = SCons.Util.AddMethod
|
AddMethod = SCons.Util.AddMethod
|
||||||
AllowSubstExceptions = SCons.Subst.SetAllowableExceptions
|
AllowSubstExceptions = SCons.Subst.SetAllowableExceptions
|
||||||
BoolOption = SCons.Options.BoolOption
|
|
||||||
Builder = SCons.Builder.Builder
|
Builder = SCons.Builder.Builder
|
||||||
Configure = _SConscript.Configure
|
Configure = _SConscript.Configure
|
||||||
EnumOption = SCons.Options.EnumOption
|
|
||||||
Environment = SCons.Environment.Environment
|
Environment = SCons.Environment.Environment
|
||||||
#OptParser = SCons.SConsOptions.OptParser
|
#OptParser = SCons.SConsOptions.OptParser
|
||||||
FindPathDirs = SCons.Scanner.FindPathDirs
|
FindPathDirs = SCons.Scanner.FindPathDirs
|
||||||
ListOption = SCons.Options.ListOption
|
|
||||||
PackageOption = SCons.Options.PackageOption
|
|
||||||
PathOption = SCons.Options.PathOption
|
|
||||||
Platform = SCons.Platform.Platform
|
Platform = SCons.Platform.Platform
|
||||||
Return = _SConscript.Return
|
Return = _SConscript.Return
|
||||||
Scanner = SCons.Scanner.Base
|
Scanner = SCons.Scanner.Base
|
||||||
Tool = SCons.Tool.Tool
|
Tool = SCons.Tool.Tool
|
||||||
WhereIs = SCons.Util.WhereIs
|
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.
|
# Action factories.
|
||||||
Chmod = SCons.Defaults.Chmod
|
Chmod = SCons.Defaults.Chmod
|
||||||
Copy = SCons.Defaults.Copy
|
Copy = SCons.Defaults.Copy
|
||||||
|
@ -262,6 +272,9 @@ def HelpFunction(text):
|
||||||
sconscript_reading = 0
|
sconscript_reading = 0
|
||||||
|
|
||||||
#
|
#
|
||||||
|
def Variables(files=[], args=ARGUMENTS):
|
||||||
|
return SCons.Variables.Variables(files, args)
|
||||||
|
|
||||||
def Options(files=[], args=ARGUMENTS):
|
def Options(files=[], args=ARGUMENTS):
|
||||||
return SCons.Options.Options(files, args)
|
return SCons.Options.Options(files, args)
|
||||||
|
|
||||||
|
@ -321,6 +334,7 @@ GlobalDefaultEnvironmentFunctions = [
|
||||||
'Tag',
|
'Tag',
|
||||||
'TargetSignatures',
|
'TargetSignatures',
|
||||||
'Value',
|
'Value',
|
||||||
|
'VariantDir',
|
||||||
]
|
]
|
||||||
|
|
||||||
GlobalDefaultBuilders = [
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
__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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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"
|
__revision__ = "src/engine/SCons/Subst.py 3842 2008/12/20 22:59:52 scons"
|
||||||
|
|
||||||
import SCons.compat
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
|
@ -39,11 +37,11 @@ import UserString
|
||||||
|
|
||||||
import SCons.Errors
|
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.
|
# Indexed by the SUBST_* constants below.
|
||||||
_strconv = [SCons.Util.to_String,
|
_strconv = [SCons.Util.to_String_for_subst,
|
||||||
SCons.Util.to_String,
|
SCons.Util.to_String_for_subst,
|
||||||
SCons.Util.to_String_for_signature]
|
SCons.Util.to_String_for_signature]
|
||||||
|
|
||||||
|
|
||||||
|
@ -188,7 +186,7 @@ class NLWrapper:
|
||||||
list = self.list
|
list = self.list
|
||||||
if list is None:
|
if list is None:
|
||||||
list = []
|
list = []
|
||||||
elif not is_List(list) and not is_Tuple(list):
|
elif not is_Sequence(list):
|
||||||
list = [list]
|
list = [list]
|
||||||
# The map(self.func) call is what actually turns
|
# The map(self.func) call is what actually turns
|
||||||
# a list into appropriate proxies.
|
# 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
|
wrapping a NLWrapper. This class handles the different methods used
|
||||||
to access the list, calling the NLWrapper to create proxies on demand.
|
to access the list, calling the NLWrapper to create proxies on demand.
|
||||||
|
|
||||||
Note that we subclass UserList.UserList purely so that the is_List()
|
Note that we subclass UserList.UserList purely so that the
|
||||||
function will identify an object of this class as a list during
|
is_Sequence() function will identify an object of this class as
|
||||||
variable expansion. We're not really using any UserList.UserList
|
a list during variable expansion. We're not really using any
|
||||||
methods in practice.
|
UserList.UserList methods in practice.
|
||||||
"""
|
"""
|
||||||
def __init__(self, nl):
|
def __init__(self, nl):
|
||||||
self.nl = nl
|
self.nl = nl
|
||||||
|
@ -272,7 +270,13 @@ def subst_dict(target, source):
|
||||||
dict = {}
|
dict = {}
|
||||||
|
|
||||||
if target:
|
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['TARGETS'] = Targets_or_Sources(tnl)
|
||||||
dict['TARGET'] = Target_or_Source(tnl)
|
dict['TARGET'] = Target_or_Source(tnl)
|
||||||
else:
|
else:
|
||||||
|
@ -287,7 +291,10 @@ def subst_dict(target, source):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
node = rfile()
|
node = rfile()
|
||||||
|
try:
|
||||||
return node.get_subst_proxy()
|
return node.get_subst_proxy()
|
||||||
|
except AttributeError:
|
||||||
|
return node # probably a String, just return it
|
||||||
snl = NLWrapper(source, get_src_subst_proxy)
|
snl = NLWrapper(source, get_src_subst_proxy)
|
||||||
dict['SOURCES'] = Targets_or_Sources(snl)
|
dict['SOURCES'] = Targets_or_Sources(snl)
|
||||||
dict['SOURCE'] = Target_or_Source(snl)
|
dict['SOURCE'] = Target_or_Source(snl)
|
||||||
|
@ -312,6 +319,25 @@ _remove = re.compile(r'\$\([^\$]*(\$[^\)][^\$]*)*\$\)')
|
||||||
# Indexed by the SUBST_* constants above.
|
# Indexed by the SUBST_* constants above.
|
||||||
_regex_remove = [ _rm, None, _remove ]
|
_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,
|
# Regular expressions for splitting strings and handling substitutions,
|
||||||
# for use by the scons_subst() and scons_subst_list() functions:
|
# 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 ]+(?![^{]*})')
|
_space_sep = re.compile(r'[\t ]+(?![^{]*})')
|
||||||
|
|
||||||
def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None):
|
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
|
This is the work-horse function for substitutions in file names
|
||||||
and the like. The companion scons_subst_list() function (below)
|
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]
|
var = string.split(key, '.')[0]
|
||||||
lv[var] = ''
|
lv[var] = ''
|
||||||
return self.substitute(s, lv)
|
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):
|
def func(l, conv=self.conv, substitute=self.substitute, lvars=lvars):
|
||||||
return conv(substitute(l, lvars))
|
return conv(substitute(l, lvars))
|
||||||
r = map(func, s)
|
return map(func, s)
|
||||||
return string.join(r)
|
|
||||||
elif callable(s):
|
elif callable(s):
|
||||||
try:
|
try:
|
||||||
s = s(target=self.target,
|
s = s(target=self.target,
|
||||||
|
@ -458,6 +484,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
|
||||||
separate tokens.
|
separate tokens.
|
||||||
"""
|
"""
|
||||||
if is_String(args) and not isinstance(args, CmdStringHolder):
|
if is_String(args) and not isinstance(args, CmdStringHolder):
|
||||||
|
args = str(args) # In case it's a UserString.
|
||||||
try:
|
try:
|
||||||
def sub_match(match, conv=self.conv, expand=self.expand, lvars=lvars):
|
def sub_match(match, conv=self.conv, expand=self.expand, lvars=lvars):
|
||||||
return conv(expand(match.group(1), 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 = []
|
result = []
|
||||||
for a in args:
|
for a in args:
|
||||||
result.append(self.conv(self.expand(a, lvars)))
|
result.append(self.conv(self.expand(a, lvars)))
|
||||||
try:
|
|
||||||
result = string.join(result, '')
|
|
||||||
except TypeError:
|
|
||||||
if len(result) == 1:
|
if len(result) == 1:
|
||||||
result = result[0]
|
result = result[0]
|
||||||
|
else:
|
||||||
|
result = string.join(map(str, result), '')
|
||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
return self.expand(args, lvars)
|
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
|
# Compress strings of white space characters into
|
||||||
# a single space.
|
# a single space.
|
||||||
result = string.strip(_space_sep.sub(' ', result))
|
result = string.strip(_space_sep.sub(' ', result))
|
||||||
|
elif is_Sequence(result):
|
||||||
|
remove = _list_remove[mode]
|
||||||
|
if remove:
|
||||||
|
result = remove(result)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -542,7 +572,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
|
||||||
# except KeyError:
|
# except KeyError:
|
||||||
# Subst_List_Strings[strSubst] = 1
|
# Subst_List_Strings[strSubst] = 1
|
||||||
# import SCons.Debug
|
# import SCons.Debug
|
||||||
# SCons.Debug.caller(1)
|
# SCons.Debug.caller_trace(1)
|
||||||
class ListSubber(UserList.UserList):
|
class ListSubber(UserList.UserList):
|
||||||
"""A class to construct the results of a scons_subst_list() call.
|
"""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] = ''
|
lv[var] = ''
|
||||||
self.substitute(s, lv, 0)
|
self.substitute(s, lv, 0)
|
||||||
self.this_word()
|
self.this_word()
|
||||||
elif is_List(s) or is_Tuple(s):
|
elif is_Sequence(s):
|
||||||
for a in s:
|
for a in s:
|
||||||
self.substitute(a, lvars, 1)
|
self.substitute(a, lvars, 1)
|
||||||
self.next_word()
|
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):
|
if is_String(args) and not isinstance(args, CmdStringHolder):
|
||||||
|
args = str(args) # In case it's a UserString.
|
||||||
args = _separate_args.findall(args)
|
args = _separate_args.findall(args)
|
||||||
for a in args:
|
for a in args:
|
||||||
if a[0] in ' \t\n\r\f\v':
|
if a[0] in ' \t\n\r\f\v':
|
||||||
|
@ -827,18 +858,18 @@ def scons_subst_once(strSubst, env, key):
|
||||||
a = match.group(1)
|
a = match.group(1)
|
||||||
if a in matchlist:
|
if a in matchlist:
|
||||||
a = val
|
a = val
|
||||||
if is_List(a) or is_Tuple(a):
|
if is_Sequence(a):
|
||||||
return string.join(map(str, a))
|
return string.join(map(str, a))
|
||||||
else:
|
else:
|
||||||
return str(a)
|
return str(a)
|
||||||
|
|
||||||
if is_List(strSubst) or is_Tuple(strSubst):
|
if is_Sequence(strSubst):
|
||||||
result = []
|
result = []
|
||||||
for arg in strSubst:
|
for arg in strSubst:
|
||||||
if is_String(arg):
|
if is_String(arg):
|
||||||
if arg in matchlist:
|
if arg in matchlist:
|
||||||
arg = val
|
arg = val
|
||||||
if is_List(arg) or is_Tuple(arg):
|
if is_Sequence(arg):
|
||||||
result.extend(arg)
|
result.extend(arg)
|
||||||
else:
|
else:
|
||||||
result.append(arg)
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
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"
|
__revision__ = "src/engine/SCons/Taskmaster.py 3842 2008/12/20 22:59:52 scons"
|
||||||
|
|
||||||
import SCons.compat
|
|
||||||
|
|
||||||
|
from itertools import chain
|
||||||
import operator
|
import operator
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
import SCons.Node
|
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
|
import SCons.Node
|
||||||
|
|
||||||
StateString = SCons.Node.StateString
|
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
|
# A subsystem for recording stats about how different Nodes are handled by
|
||||||
|
@ -134,6 +138,10 @@ class Task:
|
||||||
self.node = node
|
self.node = node
|
||||||
self.exc_clear()
|
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):
|
def display(self, message):
|
||||||
"""
|
"""
|
||||||
Hook to allow the calling interface to display a 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
|
unlink underlying files and make all necessary directories before
|
||||||
the Action is actually called to build the targets.
|
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
|
# Now that it's the appropriate time, give the TaskMaster a
|
||||||
# chance to raise any exceptions it encountered while preparing
|
# chance to raise any exceptions it encountered while preparing
|
||||||
|
@ -165,6 +175,17 @@ class Task:
|
||||||
self.display(self.tm.message)
|
self.display(self.tm.message)
|
||||||
self.tm.message = None
|
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:
|
for t in self.targets:
|
||||||
t.prepare()
|
t.prepare()
|
||||||
for s in t.side_effects:
|
for s in t.side_effects:
|
||||||
|
@ -175,6 +196,17 @@ class Task:
|
||||||
"""
|
"""
|
||||||
return self.node
|
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):
|
def execute(self):
|
||||||
"""
|
"""
|
||||||
Called to execute the task.
|
Called to execute the task.
|
||||||
|
@ -183,6 +215,8 @@ class Task:
|
||||||
so only do thread safe stuff here. Do thread unsafe stuff in
|
so only do thread safe stuff here. Do thread unsafe stuff in
|
||||||
prepare(), executed() or failed().
|
prepare(), executed() or failed().
|
||||||
"""
|
"""
|
||||||
|
T = self.tm.trace
|
||||||
|
if T: T.write(self.trace_message('Task.execute()', self.node))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
everything_was_cached = 1
|
everything_was_cached = 1
|
||||||
|
@ -192,8 +226,6 @@ class Task:
|
||||||
break
|
break
|
||||||
if not everything_was_cached:
|
if not everything_was_cached:
|
||||||
self.targets[0].build()
|
self.targets[0].build()
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
exc_value = sys.exc_info()[1]
|
exc_value = sys.exc_info()[1]
|
||||||
raise SCons.Errors.ExplicitExit(self.targets[0], exc_value.code)
|
raise SCons.Errors.ExplicitExit(self.targets[0], exc_value.code)
|
||||||
|
@ -201,9 +233,11 @@ class Task:
|
||||||
raise
|
raise
|
||||||
except SCons.Errors.BuildError:
|
except SCons.Errors.BuildError:
|
||||||
raise
|
raise
|
||||||
except:
|
except Exception, e:
|
||||||
raise SCons.Errors.TaskmasterException(self.targets[0],
|
buildError = SCons.Errors.convert_to_BuildError(e)
|
||||||
sys.exc_info())
|
buildError.node = self.targets[0]
|
||||||
|
buildError.exc_info = sys.exc_info()
|
||||||
|
raise buildError
|
||||||
|
|
||||||
def executed_without_callbacks(self):
|
def executed_without_callbacks(self):
|
||||||
"""
|
"""
|
||||||
|
@ -211,11 +245,15 @@ class Task:
|
||||||
and the Taskmaster instance doesn't want to call
|
and the Taskmaster instance doesn't want to call
|
||||||
the Node's callback methods.
|
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:
|
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:
|
for side_effect in t.side_effects:
|
||||||
side_effect.set_state(SCons.Node.no_state)
|
side_effect.set_state(NODE_NO_STATE)
|
||||||
t.set_state(SCons.Node.executed)
|
t.set_state(NODE_EXECUTED)
|
||||||
|
|
||||||
def executed_with_callbacks(self):
|
def executed_with_callbacks(self):
|
||||||
"""
|
"""
|
||||||
|
@ -230,11 +268,15 @@ class Task:
|
||||||
post-visit actions that must take place regardless of whether
|
post-visit actions that must take place regardless of whether
|
||||||
or not the target was an actual built target or a source Node.
|
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:
|
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:
|
for side_effect in t.side_effects:
|
||||||
side_effect.set_state(SCons.Node.no_state)
|
side_effect.set_state(NODE_NO_STATE)
|
||||||
t.set_state(SCons.Node.executed)
|
t.set_state(NODE_EXECUTED)
|
||||||
t.built()
|
t.built()
|
||||||
t.visited()
|
t.visited()
|
||||||
|
|
||||||
|
@ -243,15 +285,32 @@ class Task:
|
||||||
def failed(self):
|
def failed(self):
|
||||||
"""
|
"""
|
||||||
Default action when a task fails: stop the build.
|
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()
|
self.fail_stop()
|
||||||
|
|
||||||
def fail_stop(self):
|
def fail_stop(self):
|
||||||
"""
|
"""
|
||||||
Explicit stop-the-build failure.
|
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 = self.tm.trace
|
||||||
t.set_state(SCons.Node.failed)
|
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()
|
self.tm.stop()
|
||||||
|
|
||||||
# We're stopping because of a build failure, but give the
|
# 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
|
This sets failure status on the target nodes and all of
|
||||||
their dependent parent nodes.
|
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 = self.tm.trace
|
||||||
# Set failure state on all of the parents that were dependent
|
if T: T.write(self.trace_message('Task.failed_continue()', self.node))
|
||||||
# on this failed build.
|
|
||||||
def set_state(node): node.set_state(SCons.Node.failed)
|
self.tm.will_not_build(self.targets, lambda n: n.set_state(NODE_FAILED))
|
||||||
t.call_for_all_waiting_parents(set_state)
|
|
||||||
|
|
||||||
def make_ready_all(self):
|
def make_ready_all(self):
|
||||||
"""
|
"""
|
||||||
|
@ -280,11 +342,14 @@ class Task:
|
||||||
This is used when the interface needs every target Node to be
|
This is used when the interface needs every target Node to be
|
||||||
visited--the canonical example being the "scons -c" option.
|
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[:]
|
self.out_of_date = self.targets[:]
|
||||||
for t in 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:
|
for s in t.side_effects:
|
||||||
s.set_state(SCons.Node.executing)
|
s.set_state(NODE_EXECUTING)
|
||||||
|
|
||||||
def make_ready_current(self):
|
def make_ready_current(self):
|
||||||
"""
|
"""
|
||||||
|
@ -293,7 +358,12 @@ class Task:
|
||||||
|
|
||||||
This is the default behavior for building only what's necessary.
|
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 = []
|
self.out_of_date = []
|
||||||
|
needs_executing = False
|
||||||
for t in self.targets:
|
for t in self.targets:
|
||||||
try:
|
try:
|
||||||
t.disambiguate().make_ready()
|
t.disambiguate().make_ready()
|
||||||
|
@ -301,13 +371,24 @@ class Task:
|
||||||
(not t.always_build and t.is_up_to_date())
|
(not t.always_build and t.is_up_to_date())
|
||||||
except EnvironmentError, e:
|
except EnvironmentError, e:
|
||||||
raise SCons.Errors.BuildError(node=t, errstr=e.strerror, filename=e.filename)
|
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)
|
if not is_up_to_date:
|
||||||
else:
|
|
||||||
self.out_of_date.append(t)
|
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:
|
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
|
make_ready = make_ready_current
|
||||||
|
|
||||||
|
@ -321,6 +402,8 @@ class Task:
|
||||||
waiting parent Nodes, or Nodes waiting on a common side effect,
|
waiting parent Nodes, or Nodes waiting on a common side effect,
|
||||||
that can be put back on the candidates list.
|
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
|
# We may have built multiple targets, some of which may have
|
||||||
# common parents waiting for this build. Count up how many
|
# common parents waiting for this build. Count up how many
|
||||||
|
@ -331,24 +414,34 @@ class Task:
|
||||||
|
|
||||||
targets = set(self.targets)
|
targets = set(self.targets)
|
||||||
|
|
||||||
|
pending_children = self.tm.pending_children
|
||||||
parents = {}
|
parents = {}
|
||||||
for t in targets:
|
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
|
parents[p] = parents.get(p, 0) + 1
|
||||||
|
|
||||||
for t in targets:
|
for t in targets:
|
||||||
for s in t.side_effects:
|
for s in t.side_effects:
|
||||||
if s.get_state() == SCons.Node.executing:
|
if s.get_state() == NODE_EXECUTING:
|
||||||
s.set_state(SCons.Node.no_state)
|
s.set_state(NODE_NO_STATE)
|
||||||
for p in s.waiting_parents.keys():
|
for p in s.waiting_parents:
|
||||||
if not parents.has_key(p):
|
parents[p] = parents.get(p, 0) + 1
|
||||||
parents[p] = 1
|
for p in s.waiting_s_e:
|
||||||
for p in s.waiting_s_e.keys():
|
|
||||||
if p.ref_count == 0:
|
if p.ref_count == 0:
|
||||||
self.tm.candidates.append(p)
|
self.tm.candidates.append(p)
|
||||||
|
|
||||||
for p, subtract in parents.items():
|
for p, subtract in parents.items():
|
||||||
p.ref_count = p.ref_count - subtract
|
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:
|
if p.ref_count == 0:
|
||||||
self.tm.candidates.append(p)
|
self.tm.candidates.append(p)
|
||||||
|
|
||||||
|
@ -409,12 +502,15 @@ class Task:
|
||||||
raise exc_type, exc_value, exc_traceback
|
raise exc_type, exc_value, exc_traceback
|
||||||
|
|
||||||
|
|
||||||
def find_cycle(stack):
|
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 stack[0] == stack[-1]:
|
if stack[0] == stack[-1]:
|
||||||
return stack
|
return stack
|
||||||
for n in stack[-1].waiting_parents.keys():
|
if find_cycle(stack, visited):
|
||||||
stack.append(n)
|
|
||||||
if find_cycle(stack):
|
|
||||||
return stack
|
return stack
|
||||||
stack.pop()
|
stack.pop()
|
||||||
return None
|
return None
|
||||||
|
@ -437,6 +533,7 @@ class Taskmaster:
|
||||||
self.message = None
|
self.message = None
|
||||||
self.trace = trace
|
self.trace = trace
|
||||||
self.next_candidate = self.find_next_candidate
|
self.next_candidate = self.find_next_candidate
|
||||||
|
self.pending_children = set()
|
||||||
|
|
||||||
def find_next_candidate(self):
|
def find_next_candidate(self):
|
||||||
"""
|
"""
|
||||||
|
@ -477,9 +574,104 @@ class Taskmaster:
|
||||||
def no_next_candidate(self):
|
def no_next_candidate(self):
|
||||||
"""
|
"""
|
||||||
Stops Taskmaster processing by not returning a next candidate.
|
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
|
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):
|
def _find_next_ready_node(self):
|
||||||
"""
|
"""
|
||||||
Finds the next node that is ready to be built.
|
Finds the next node that is ready to be built.
|
||||||
|
@ -505,15 +697,25 @@ class Taskmaster:
|
||||||
self.ready_exc = None
|
self.ready_exc = None
|
||||||
|
|
||||||
T = self.trace
|
T = self.trace
|
||||||
|
if T: T.write('\n' + self.trace_message('Looking for a node to evaluate'))
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
node = self.next_candidate()
|
node = self.next_candidate()
|
||||||
if node is None:
|
if node is None:
|
||||||
|
if T: T.write(self.trace_message('No candidate anymore.') + '\n')
|
||||||
return None
|
return None
|
||||||
|
|
||||||
node = node.disambiguate()
|
node = node.disambiguate()
|
||||||
state = node.get_state()
|
state = node.get_state()
|
||||||
|
|
||||||
|
# For debugging only:
|
||||||
|
#
|
||||||
|
# try:
|
||||||
|
# self._validate_pending_children()
|
||||||
|
# except:
|
||||||
|
# self.ready_exc = sys.exc_info()
|
||||||
|
# return node
|
||||||
|
|
||||||
if CollectStats:
|
if CollectStats:
|
||||||
if not hasattr(node, 'stats'):
|
if not hasattr(node, 'stats'):
|
||||||
node.stats = Stats()
|
node.stats = Stats()
|
||||||
|
@ -523,119 +725,138 @@ class Taskmaster:
|
||||||
else:
|
else:
|
||||||
S = None
|
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)))
|
||||||
|
|
||||||
|
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:
|
# Skip this node if it has already been evaluated:
|
||||||
if state > SCons.Node.pending:
|
|
||||||
if S: S.already_handled = S.already_handled + 1
|
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
|
continue
|
||||||
|
|
||||||
# Mark this node as being on the execution stack:
|
|
||||||
node.set_state(SCons.Node.pending)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
children = node.children() + node.prerequisites
|
children = node.children()
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
exc_value = sys.exc_info()[1]
|
exc_value = sys.exc_info()[1]
|
||||||
e = SCons.Errors.ExplicitExit(node, exc_value.code)
|
e = SCons.Errors.ExplicitExit(node, exc_value.code)
|
||||||
self.ready_exc = (SCons.Errors.ExplicitExit, e)
|
self.ready_exc = (SCons.Errors.ExplicitExit, e)
|
||||||
if T: T.write(' SystemExit\n')
|
if T: T.write(self.trace_message(' SystemExit'))
|
||||||
return node
|
return node
|
||||||
except KeyboardInterrupt:
|
except Exception, e:
|
||||||
if T: T.write(' KeyboardInterrupt\n')
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
# We had a problem just trying to figure out the
|
# We had a problem just trying to figure out the
|
||||||
# children (like a child couldn't be linked in to a
|
# 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."
|
# raise the exception when the Task is "executed."
|
||||||
self.ready_exc = sys.exc_info()
|
self.ready_exc = sys.exc_info()
|
||||||
if S: S.problem = S.problem + 1
|
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
|
return node
|
||||||
|
|
||||||
if T and children:
|
children_not_visited = []
|
||||||
c = map(str, children)
|
children_pending = set()
|
||||||
c.sort()
|
children_not_ready = []
|
||||||
T.write(' children:\n %s\n ' % c)
|
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 S: S.child_failed = S.child_failed + 1
|
||||||
if T:
|
if T: T.write(self.trace_message('****** %s\n' % self.trace_node(node)))
|
||||||
c = map(str, failed_children)
|
|
||||||
c.sort()
|
|
||||||
T.write(' children failed:\n %s\n' % c)
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Detect dependency cycles:
|
if children_not_ready:
|
||||||
pending_nodes = filter(lambda I: I[1] == SCons.Node.pending, childstate)
|
for child in children_not_ready:
|
||||||
if pending_nodes:
|
# We're waiting on one or more derived targets
|
||||||
for p in pending_nodes:
|
# that have not yet finished building.
|
||||||
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
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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 S: S.not_built = S.not_built + 1
|
||||||
|
|
||||||
|
# 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)))))
|
||||||
|
|
||||||
if T:
|
if T:
|
||||||
c = map(str, n_b_nodes)
|
for pc in children_pending:
|
||||||
c.sort()
|
T.write(self.trace_message(' adding %s to the pending children set\n' %
|
||||||
T.write(' waiting on unfinished children:\n %s\n' % c)
|
self.trace_node(pc)))
|
||||||
|
self.pending_children = self.pending_children | children_pending
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Skip this node if it has side-effects that are
|
# Skip this node if it has side-effects that are
|
||||||
# currently being built:
|
# currently being built:
|
||||||
side_effects = filter(lambda N:
|
wait_side_effects = False
|
||||||
N.get_state() == SCons.Node.executing,
|
for se in node.side_effects:
|
||||||
node.side_effects)
|
if se.get_state() == NODE_EXECUTING:
|
||||||
if side_effects:
|
se.add_to_waiting_s_e(node)
|
||||||
map(lambda n, P=node: n.add_to_waiting_s_e(P), side_effects)
|
wait_side_effects = True
|
||||||
|
|
||||||
|
if wait_side_effects:
|
||||||
if S: S.side_effects = S.side_effects + 1
|
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
|
continue
|
||||||
|
|
||||||
# The default when we've gotten through all of the checks above:
|
# The default when we've gotten through all of the checks above:
|
||||||
# this node is ready to be built.
|
# this node is ready to be built.
|
||||||
if S: S.build = S.build + 1
|
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 node
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -657,11 +878,9 @@ class Taskmaster:
|
||||||
task = self.tasker(self, tlist, node in self.original_top, node)
|
task = self.tasker(self, tlist, node in self.original_top, node)
|
||||||
try:
|
try:
|
||||||
task.make_ready()
|
task.make_ready()
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except:
|
except:
|
||||||
# We had a problem just trying to get this task ready (like
|
# 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
|
# whether this node is current). Arrange to raise the
|
||||||
# exception when the Task is "executed."
|
# exception when the Task is "executed."
|
||||||
self.ready_exc = sys.exc_info()
|
self.ready_exc = sys.exc_info()
|
||||||
|
@ -673,8 +892,94 @@ class Taskmaster:
|
||||||
|
|
||||||
return task
|
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):
|
def stop(self):
|
||||||
"""
|
"""
|
||||||
Stops the current build completely.
|
Stops the current build completely.
|
||||||
"""
|
"""
|
||||||
self.next_candidate = self.no_next_candidate
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
from SCons.Tool.PharLapCommon import addPharLapPaths
|
||||||
import SCons.Util
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Action
|
||||||
import SCons.Builder
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Action
|
||||||
import SCons.Builder
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -49,14 +49,16 @@ if java_parsing:
|
||||||
# double-backslashes;
|
# double-backslashes;
|
||||||
# a single-line comment "//";
|
# a single-line comment "//";
|
||||||
# single or double quotes preceeded by a backslash;
|
# 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 (keyword, class name, specifier);
|
||||||
|
# any alphanumeric token surrounded by angle brackets (generics);
|
||||||
# the multi-line comment begin and end tokens /* and */;
|
# the multi-line comment begin and end tokens /* and */;
|
||||||
# array declarations "[]";
|
# array declarations "[]".
|
||||||
# semi-colons;
|
|
||||||
# periods.
|
|
||||||
_reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.\(\)]|' +
|
_reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"\{\}\;\.\(\)]|' +
|
||||||
r'[A-Za-z_][\w\$\.]*|/\*|\*/|\[\])')
|
r'\d*\.\d*|[A-Za-z_][\w\$\.]*|<[A-Za-z_]\w+>|' +
|
||||||
|
r'/\*|\*/|\[\])')
|
||||||
|
|
||||||
class OuterState:
|
class OuterState:
|
||||||
"""The initial state for parsing a Java file for classes,
|
"""The initial state for parsing a Java file for classes,
|
||||||
|
@ -73,6 +75,7 @@ if java_parsing:
|
||||||
self.stackBrackets = []
|
self.stackBrackets = []
|
||||||
self.brackets = 0
|
self.brackets = 0
|
||||||
self.nextAnon = 1
|
self.nextAnon = 1
|
||||||
|
self.localClasses = []
|
||||||
self.stackAnonClassBrackets = []
|
self.stackAnonClassBrackets = []
|
||||||
self.anonStacksStack = [[0]]
|
self.anonStacksStack = [[0]]
|
||||||
self.package = None
|
self.package = None
|
||||||
|
@ -124,6 +127,7 @@ if java_parsing:
|
||||||
if len(self.stackBrackets) and \
|
if len(self.stackBrackets) and \
|
||||||
self.brackets == self.stackBrackets[-1]:
|
self.brackets == self.stackBrackets[-1]:
|
||||||
self.listOutputs.append(string.join(self.listClasses, '$'))
|
self.listOutputs.append(string.join(self.listClasses, '$'))
|
||||||
|
self.localClasses.pop()
|
||||||
self.listClasses.pop()
|
self.listClasses.pop()
|
||||||
self.anonStacksStack.pop()
|
self.anonStacksStack.pop()
|
||||||
self.stackBrackets.pop()
|
self.stackBrackets.pop()
|
||||||
|
@ -199,6 +203,8 @@ if java_parsing:
|
||||||
return IgnoreState('*/', self)
|
return IgnoreState('*/', self)
|
||||||
elif token == '\n':
|
elif token == '\n':
|
||||||
return self
|
return self
|
||||||
|
elif token[0] == '<' and token[-1] == '>':
|
||||||
|
return self
|
||||||
elif token == '(':
|
elif token == '(':
|
||||||
self.brace_level = self.brace_level + 1
|
self.brace_level = self.brace_level + 1
|
||||||
return self
|
return self
|
||||||
|
@ -236,6 +242,20 @@ if java_parsing:
|
||||||
# the next non-whitespace token should be the name of the class
|
# the next non-whitespace token should be the name of the class
|
||||||
if token == '\n':
|
if token == '\n':
|
||||||
return self
|
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.listClasses.append(token)
|
||||||
self.outer_state.anonStacksStack.append([0])
|
self.outer_state.anonStacksStack.append([0])
|
||||||
return self.outer_state
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
||||||
import os.path
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Action
|
||||||
import SCons.Builder
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Action
|
||||||
import SCons.Builder
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 imp
|
||||||
import sys
|
import sys
|
||||||
|
@ -55,6 +55,7 @@ DefaultToolpath=[]
|
||||||
CScanner = SCons.Scanner.C.CScanner()
|
CScanner = SCons.Scanner.C.CScanner()
|
||||||
DScanner = SCons.Scanner.D.DScanner()
|
DScanner = SCons.Scanner.D.DScanner()
|
||||||
LaTeXScanner = SCons.Scanner.LaTeX.LaTeXScanner()
|
LaTeXScanner = SCons.Scanner.LaTeX.LaTeXScanner()
|
||||||
|
PDFLaTeXScanner = SCons.Scanner.LaTeX.PDFLaTeXScanner()
|
||||||
ProgramScanner = SCons.Scanner.Prog.ProgramScanner()
|
ProgramScanner = SCons.Scanner.Prog.ProgramScanner()
|
||||||
SourceFileScanner = SCons.Scanner.Base({}, name='SourceFileScanner')
|
SourceFileScanner = SCons.Scanner.Base({}, name='SourceFileScanner')
|
||||||
|
|
||||||
|
@ -76,8 +77,13 @@ for suffix in CSuffixes:
|
||||||
for suffix in DSuffixes:
|
for suffix in DSuffixes:
|
||||||
SourceFileScanner.add_scanner(suffix, DScanner)
|
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:
|
for suffix in LaTeXSuffixes:
|
||||||
SourceFileScanner.add_scanner(suffix, LaTeXScanner)
|
SourceFileScanner.add_scanner(suffix, LaTeXScanner)
|
||||||
|
SourceFileScanner.add_scanner(suffix, PDFLaTeXScanner)
|
||||||
|
|
||||||
class Tool:
|
class Tool:
|
||||||
def __init__(self, name, toolpath=[], **kw):
|
def __init__(self, name, toolpath=[], **kw):
|
||||||
|
@ -136,7 +142,7 @@ class Tool:
|
||||||
file.close()
|
file.close()
|
||||||
return module
|
return module
|
||||||
except ImportError, e:
|
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
|
raise SCons.Errors.EnvironmentError, e
|
||||||
try:
|
try:
|
||||||
import zipimport
|
import zipimport
|
||||||
|
@ -163,10 +169,10 @@ class Tool:
|
||||||
kw = self.init_kw
|
kw = self.init_kw
|
||||||
env.Append(TOOLS = [ self.name ])
|
env.Append(TOOLS = [ self.name ])
|
||||||
if hasattr(self, 'options'):
|
if hasattr(self, 'options'):
|
||||||
from SCons.Options import Options
|
import SCons.Variables
|
||||||
if not env.has_key('options'):
|
if not env.has_key('options'):
|
||||||
from SCons.Script import ARGUMENTS
|
from SCons.Script import ARGUMENTS
|
||||||
env['options']=Options(args=ARGUMENTS)
|
env['options']=SCons.Variables.Variables(args=ARGUMENTS)
|
||||||
opts=env['options']
|
opts=env['options']
|
||||||
|
|
||||||
self.options(opts)
|
self.options(opts)
|
||||||
|
@ -422,32 +428,33 @@ def CreateJavaFileBuilder(env):
|
||||||
env['JAVASUFFIX'] = '.java'
|
env['JAVASUFFIX'] = '.java'
|
||||||
return java_file
|
return java_file
|
||||||
|
|
||||||
class ToolInitializer:
|
class ToolInitializerMethod:
|
||||||
"""
|
"""
|
||||||
A class for delayed initialization of Tools modules.
|
This is added to a construction environment in place of a
|
||||||
|
method(s) normally called for a Builder (env.Object, env.StaticObject,
|
||||||
This is intended to be added to a construction environment in
|
etc.). When called, it has its associated ToolInitializer
|
||||||
place of the method(s) normally called for a Builder (env.Object,
|
object search the specified list of tools and apply the first
|
||||||
env.StaticObject, etc.). When called, it searches the specified
|
one that exists to the construction environment. It then calls
|
||||||
list of tools, applies the first one that exists to the construction
|
whatever builder was (presumably) added to the construction
|
||||||
environment, and calls whatever builder was (presumably) added the
|
environment in place of this particular instance.
|
||||||
construction environment in our place.
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, name, tools):
|
def __init__(self, name, initializer):
|
||||||
"""
|
"""
|
||||||
Note: we store the tool name as __name__ so it can be used by
|
Note: we store the tool name as __name__ so it can be used by
|
||||||
the class that attaches this to a construction environment.
|
the class that attaches this to a construction environment.
|
||||||
"""
|
"""
|
||||||
self.__name__ = name
|
self.__name__ = name
|
||||||
if not SCons.Util.is_List(tools):
|
self.initializer = initializer
|
||||||
tools = [tools]
|
|
||||||
self.tools = tools
|
def get_builder(self, env):
|
||||||
def __call__(self, env, *args, **kw):
|
"""
|
||||||
for t in self.tools:
|
Returns the appropriate real Builder for this method name
|
||||||
tool = SCons.Tool.Tool(t)
|
after having the associated ToolInitializer object apply
|
||||||
if tool.exists(env):
|
the appropriate Tool module.
|
||||||
env.Tool(tool)
|
"""
|
||||||
break
|
builder = getattr(env, self.__name__)
|
||||||
|
|
||||||
|
self.initializer.apply_tools(env)
|
||||||
|
|
||||||
builder = getattr(env, self.__name__)
|
builder = getattr(env, self.__name__)
|
||||||
if builder is self:
|
if builder is self:
|
||||||
|
@ -455,21 +462,79 @@ class ToolInitializer:
|
||||||
# for this name was found (or possibly there's a mismatch
|
# for this name was found (or possibly there's a mismatch
|
||||||
# between the name we were called by and the Builder name
|
# between the name we were called by and the Builder name
|
||||||
# added by the Tool module).
|
# added by the Tool module).
|
||||||
#
|
return None
|
||||||
# (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 [], []
|
|
||||||
|
|
||||||
# Let the construction environment remove the added method
|
self.initializer.remove_methods(env)
|
||||||
# so we no longer copy and re-bind this method when the
|
|
||||||
# construction environment gets cloned.
|
return builder
|
||||||
env.RemoveMethod(self)
|
|
||||||
|
def __call__(self, env, *args, **kw):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
builder = self.get_builder(env)
|
||||||
|
if builder is None:
|
||||||
|
return [], []
|
||||||
return apply(builder, args, kw)
|
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):
|
def Initializers(env):
|
||||||
env.AddMethod(ToolInitializer('Install', 'install'))
|
ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs'])
|
||||||
env.AddMethod(ToolInitializer('InstallAs', 'install'))
|
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):
|
def FindTool(tools, env):
|
||||||
for tool in tools:
|
for tool in tools:
|
||||||
|
@ -496,7 +561,7 @@ def tool_list(platform, env):
|
||||||
c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ]
|
c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ]
|
||||||
cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'c++', 'bcc32' ]
|
cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'c++', 'bcc32' ]
|
||||||
assemblers = ['masm', 'nasm', 'gas', '386asm' ]
|
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']
|
ars = ['mslib', 'ar', 'tlib']
|
||||||
elif str(platform) == 'os2':
|
elif str(platform) == 'os2':
|
||||||
"prefer IBM tools on OS/2"
|
"prefer IBM tools on OS/2"
|
||||||
|
@ -520,7 +585,8 @@ def tool_list(platform, env):
|
||||||
c_compilers = ['suncc', 'gcc', 'cc']
|
c_compilers = ['suncc', 'gcc', 'cc']
|
||||||
cxx_compilers = ['sunc++', 'g++', 'c++']
|
cxx_compilers = ['sunc++', 'g++', 'c++']
|
||||||
assemblers = ['as', 'gas']
|
assemblers = ['as', 'gas']
|
||||||
fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran']
|
fortran_compilers = ['sunf95', 'sunf90', 'sunf77', 'f95', 'f90', 'f77',
|
||||||
|
'gfortran', 'g77', 'fortran']
|
||||||
ars = ['sunar']
|
ars = ['sunar']
|
||||||
elif str(platform) == 'hpux':
|
elif str(platform) == 'hpux':
|
||||||
"prefer aCC tools on HP-UX"
|
"prefer aCC tools on HP-UX"
|
||||||
|
@ -544,7 +610,7 @@ def tool_list(platform, env):
|
||||||
c_compilers = ['gcc', 'cc']
|
c_compilers = ['gcc', 'cc']
|
||||||
cxx_compilers = ['g++', 'c++']
|
cxx_compilers = ['g++', 'c++']
|
||||||
assemblers = ['as']
|
assemblers = ['as']
|
||||||
fortran_compilers = ['f95', 'f90', 'g77']
|
fortran_compilers = ['gfortran', 'f95', 'f90', 'g77']
|
||||||
ars = ['ar']
|
ars = ['ar']
|
||||||
else:
|
else:
|
||||||
"prefer GNU tools on all other platforms"
|
"prefer GNU tools on all other platforms"
|
||||||
|
@ -552,7 +618,7 @@ def tool_list(platform, env):
|
||||||
c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc']
|
c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc']
|
||||||
cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++']
|
cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++']
|
||||||
assemblers = ['gas', 'nasm', 'masm']
|
assemblers = ['gas', 'nasm', 'masm']
|
||||||
fortran_compilers = ['f95', 'f90', 'g77', 'ifort', 'ifl', 'fortran']
|
fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77']
|
||||||
ars = ['ar', 'mslib']
|
ars = ['ar', 'mslib']
|
||||||
|
|
||||||
c_compiler = FindTool(c_compilers, env) or c_compilers[0]
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
||||||
import os.path
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 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):
|
def generate(env):
|
||||||
"""Add Builders and construction variables for applelink to an
|
"""Add Builders and construction variables for applelink to an
|
||||||
Environment."""
|
Environment."""
|
||||||
gnulink.generate(env)
|
link.generate(env)
|
||||||
|
|
||||||
env['FRAMEWORKPATHPREFIX'] = '-F'
|
env['FRAMEWORKPATHPREFIX'] = '-F'
|
||||||
env['_FRAMEWORKPATH'] = '${_concat(FRAMEWORKPATHPREFIX, FRAMEWORKPATH, "", __env__)}'
|
env['_FRAMEWORKPATH'] = '${_concat(FRAMEWORKPATHPREFIX, FRAMEWORKPATH, "", __env__)}'
|
||||||
env['_FRAMEWORKS'] = '${_concat("-framework ", FRAMEWORKS, "", __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['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
|
# override the default for loadable modules, which are different
|
||||||
# on OS X than dynamic shared libs. echoing what XCode does for
|
# on OS X than dynamic shared libs. echoing what XCode does for
|
||||||
|
@ -60,5 +62,4 @@ def generate(env):
|
||||||
|
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
import sys
|
return env['PLATFORM'] == 'darwin'
|
||||||
return sys.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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Defaults
|
||||||
import SCons.Tool
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Defaults
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
|
@ -40,7 +40,7 @@ import SCons.Util
|
||||||
assemblers = ['as']
|
assemblers = ['as']
|
||||||
|
|
||||||
ASSuffixes = ['.s', '.asm', '.ASM']
|
ASSuffixes = ['.s', '.asm', '.ASM']
|
||||||
ASPPSuffixes = ['.spp', '.SPP']
|
ASPPSuffixes = ['.spp', '.SPP', '.sx']
|
||||||
if SCons.Util.case_sensitive_suffixes('.s', '.S'):
|
if SCons.Util.case_sensitive_suffixes('.s', '.S'):
|
||||||
ASPPSuffixes.extend(['.S'])
|
ASPPSuffixes.extend(['.S'])
|
||||||
else:
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
||||||
import os.path
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
import os.path
|
||||||
|
|
||||||
|
@ -73,11 +73,11 @@ def generate(env):
|
||||||
SCons.Tool.cc.add_common_cc_variables(env)
|
SCons.Tool.cc.add_common_cc_variables(env)
|
||||||
|
|
||||||
env['CXX'] = 'c++'
|
env['CXX'] = 'c++'
|
||||||
env['CXXFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
|
env['CXXFLAGS'] = SCons.Util.CLVar('')
|
||||||
env['CXXCOM'] = '$CXX -o $TARGET -c $CXXFLAGS $_CCCOMCOM $SOURCES'
|
env['CXXCOM'] = '$CXX -o $TARGET -c $CXXFLAGS $CCFLAGS $_CCCOMCOM $SOURCES'
|
||||||
env['SHCXX'] = '$CXX'
|
env['SHCXX'] = '$CXX'
|
||||||
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS')
|
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['CPPDEFPREFIX'] = '-D'
|
||||||
env['CPPDEFSUFFIX'] = ''
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Tool
|
||||||
import SCons.Defaults
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
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.
|
blah.lib from the directory where SConstruct resides.
|
||||||
|
|
||||||
Compiler variables:
|
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.
|
DPATH - List of paths to search for import modules.
|
||||||
DVERSIONS - List of version tags to enable when compiling.
|
DVERSIONS - List of version tags to enable when compiling.
|
||||||
DDEBUG - List of debug tags to enable when compiling.
|
DDEBUG - List of debug tags to enable when compiling.
|
||||||
|
|
||||||
Linker related variables:
|
Linker related variables:
|
||||||
LIBS - List of library files to link in.
|
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.
|
DLINKFLAGS - List of linker flags.
|
||||||
|
|
||||||
Lib tool variables:
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 os
|
||||||
import string
|
import string
|
||||||
|
@ -93,7 +94,8 @@ def generate(env):
|
||||||
static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter)
|
static_obj.add_emitter('.d', SCons.Defaults.StaticObjectEmitter)
|
||||||
shared_obj.add_emitter('.d', SCons.Defaults.SharedObjectEmitter)
|
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['DCOM'] = '$DC $_DINCFLAGS $_DVERFLAGS $_DDEBUGFLAGS $_DFLAGS -c -of$TARGET $SOURCES'
|
||||||
env['_DINCFLAGS'] = '$( ${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
env['_DINCFLAGS'] = '$( ${_concat(DINCPREFIX, DPATH, DINCSUFFIX, __env__, RDirs, TARGET, SOURCE)} $)'
|
||||||
env['_DVERFLAGS'] = '$( ${_concat(DVERPREFIX, DVERSIONS, DVERSUFFIX, __env__)} $)'
|
env['_DVERFLAGS'] = '$( ${_concat(DVERPREFIX, DVERSIONS, DVERSUFFIX, __env__)} $)'
|
||||||
|
@ -105,11 +107,12 @@ def generate(env):
|
||||||
env['DVERSIONS'] = []
|
env['DVERSIONS'] = []
|
||||||
env['DDEBUG'] = []
|
env['DDEBUG'] = []
|
||||||
|
|
||||||
|
if dc:
|
||||||
# Add the path to the standard library.
|
# Add the path to the standard library.
|
||||||
# This is merely for the convenience of the dependency scanner.
|
# This is merely for the convenience of the dependency scanner.
|
||||||
dmd_path = env.WhereIs('dmd')
|
dmd_path = env.WhereIs(dc)
|
||||||
if dmd_path:
|
if dmd_path:
|
||||||
x = string.rindex(dmd_path, 'dmd')
|
x = string.rindex(dmd_path, dc)
|
||||||
phobosDir = dmd_path[:x] + '/../src/phobos'
|
phobosDir = dmd_path[:x] + '/../src/phobos'
|
||||||
if os.path.isdir(phobosDir):
|
if os.path.isdir(phobosDir):
|
||||||
env.Append(DPATH = [phobosDir])
|
env.Append(DPATH = [phobosDir])
|
||||||
|
@ -191,14 +194,17 @@ def generate(env):
|
||||||
env['SMART_LINKCOM'] = smart_link[linkcom]
|
env['SMART_LINKCOM'] = smart_link[linkcom]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
def _smartLink(source, target, env, for_signature,
|
def _smartLink(source, target, env, for_signature,
|
||||||
defaultLinker=linkcom):
|
defaultLinker=linkcom, dc=dc):
|
||||||
if isD(source):
|
if isD(source):
|
||||||
try:
|
try:
|
||||||
libs = env['LIBS']
|
libs = env['LIBS']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
libs = []
|
libs = []
|
||||||
if 'phobos' not in libs:
|
if 'phobos' not in libs:
|
||||||
|
if dc is 'dmd':
|
||||||
env.Append(LIBS = ['phobos'])
|
env.Append(LIBS = ['phobos'])
|
||||||
|
elif dc is 'gdmd':
|
||||||
|
env.Append(LIBS = ['gphobos'])
|
||||||
if 'pthread' not in libs:
|
if 'pthread' not in libs:
|
||||||
env.Append(LIBS = ['pthread'])
|
env.Append(LIBS = ['pthread'])
|
||||||
if 'm' not in libs:
|
if 'm' not in libs:
|
||||||
|
@ -209,4 +215,4 @@ def generate(env):
|
||||||
env['LINKCOM'] = '$SMART_LINKCOM '
|
env['LINKCOM'] = '$SMART_LINKCOM '
|
||||||
|
|
||||||
def exists(env):
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Builder
|
||||||
import SCons.Tool
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Action
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Tool.pdf
|
import SCons.Tool.pdf
|
||||||
|
import SCons.Tool.tex
|
||||||
import SCons.Util
|
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
|
PDFAction = None
|
||||||
|
DVIPDFAction = None
|
||||||
|
|
||||||
def PDFEmitter(target, source, env):
|
def PDFEmitter(target, source, env):
|
||||||
"""Strips any .aux or .log files from the input source list.
|
"""Strips any .aux or .log files from the input source list.
|
||||||
|
@ -57,11 +97,15 @@ def generate(env):
|
||||||
if PDFAction is None:
|
if PDFAction is None:
|
||||||
PDFAction = SCons.Action.Action('$DVIPDFCOM', '$DVIPDFCOMSTR')
|
PDFAction = SCons.Action.Action('$DVIPDFCOM', '$DVIPDFCOMSTR')
|
||||||
|
|
||||||
|
global DVIPDFAction
|
||||||
|
if DVIPDFAction is None:
|
||||||
|
DVIPDFAction = SCons.Action.Action(DviPdfFunction, strfunction = DviPdfStrFunction)
|
||||||
|
|
||||||
import pdf
|
import pdf
|
||||||
pdf.generate(env)
|
pdf.generate(env)
|
||||||
|
|
||||||
bld = env['BUILDERS']['PDF']
|
bld = env['BUILDERS']['PDF']
|
||||||
bld.add_action('.dvi', PDFAction)
|
bld.add_action('.dvi', DVIPDFAction)
|
||||||
bld.add_emitter('.dvi', PDFEmitter)
|
bld.add_emitter('.dvi', PDFEmitter)
|
||||||
|
|
||||||
env['DVIPDF'] = 'dvipdf'
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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.Action
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
|
import SCons.Tool.dvipdf
|
||||||
import SCons.Util
|
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
|
PSAction = None
|
||||||
|
DVIPSAction = None
|
||||||
PSBuilder = None
|
PSBuilder = None
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
|
@ -46,19 +61,24 @@ def generate(env):
|
||||||
if PSAction is None:
|
if PSAction is None:
|
||||||
PSAction = SCons.Action.Action('$PSCOM', '$PSCOMSTR')
|
PSAction = SCons.Action.Action('$PSCOM', '$PSCOMSTR')
|
||||||
|
|
||||||
|
global DVIPSAction
|
||||||
|
if DVIPSAction is None:
|
||||||
|
DVIPSAction = SCons.Action.Action(DviPsFunction, strfunction = DviPsStrFunction)
|
||||||
|
|
||||||
global PSBuilder
|
global PSBuilder
|
||||||
if PSBuilder is None:
|
if PSBuilder is None:
|
||||||
PSBuilder = SCons.Builder.Builder(action = PSAction,
|
PSBuilder = SCons.Builder.Builder(action = PSAction,
|
||||||
prefix = '$PSPREFIX',
|
prefix = '$PSPREFIX',
|
||||||
suffix = '$PSSUFFIX',
|
suffix = '$PSSUFFIX',
|
||||||
src_suffix = '.dvi',
|
src_suffix = '.dvi',
|
||||||
src_builder = 'DVI')
|
src_builder = 'DVI',
|
||||||
|
single_source=True)
|
||||||
|
|
||||||
env['BUILDERS']['PostScript'] = PSBuilder
|
env['BUILDERS']['PostScript'] = PSBuilder
|
||||||
|
|
||||||
env['DVIPS'] = 'dvips'
|
env['DVIPS'] = 'dvips'
|
||||||
env['DVIPSFLAGS'] = SCons.Util.CLVar('')
|
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.
|
# 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['PSCOM'] = 'cd ${TARGET.dir} && $DVIPS $DVIPSFLAGS -o ${TARGET.file} ${SOURCE.file}'
|
||||||
env['PSPREFIX'] = ''
|
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.
|
There normally shouldn't be any need to import this module directly.
|
||||||
It will usually be imported through the generic SCons.Tool.Tool()
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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):
|
def generate(env):
|
||||||
"""Add Builders and construction variables for g77 to an Environment."""
|
add_all_to_env(env)
|
||||||
f77.generate(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):
|
def exists(env):
|
||||||
return env.Detect(compilers)
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
import SCons
|
||||||
from SCons.Tool.install import copyFunc
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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 os.path
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
|
|
||||||
import SCons.Defaults
|
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
@ -53,35 +53,32 @@ def generate(env):
|
||||||
env['CXX'] = env.Detect(compilers)
|
env['CXX'] = env.Detect(compilers)
|
||||||
|
|
||||||
# platform specific settings
|
# platform specific settings
|
||||||
if env['PLATFORM'] == 'cygwin':
|
if env['PLATFORM'] == 'aix':
|
||||||
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')
|
|
||||||
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -mminimal-toc')
|
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -mminimal-toc')
|
||||||
env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
|
env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
|
||||||
env['SHOBJSUFFIX'] = '$OBJSUFFIX'
|
env['SHOBJSUFFIX'] = '$OBJSUFFIX'
|
||||||
elif env['PLATFORM'] == 'hpux':
|
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'
|
env['SHOBJSUFFIX'] = '.pic.o'
|
||||||
elif env['PLATFORM'] == 'sunos':
|
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'
|
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
|
# determine compiler version
|
||||||
if env['CXX']:
|
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)
|
match = re.search(r'[0-9]+(\.[0-9]+)+', line)
|
||||||
if match:
|
if match:
|
||||||
env['CXXVERSION'] = match.group(0)
|
env['CXXVERSION'] = match.group(0)
|
||||||
|
|
||||||
|
|
||||||
def exists(env):
|
def exists(env):
|
||||||
return env.Detect(compilers)
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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(), [])
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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"
|
__revision__ = "src/engine/SCons/Tool/gcc.py 3842 2008/12/20 22:59:52 scons"
|
||||||
|
|
||||||
import SCons.Util
|
|
||||||
|
|
||||||
import cc
|
import cc
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
import SCons.Util
|
||||||
|
|
||||||
compilers = ['gcc', 'cc']
|
compilers = ['gcc', 'cc']
|
||||||
|
|
||||||
|
@ -52,7 +53,19 @@ def generate(env):
|
||||||
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC')
|
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC')
|
||||||
# determine compiler version
|
# determine compiler version
|
||||||
if env['CC']:
|
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)
|
match = re.search(r'[0-9]+(\.[0-9]+)+', line)
|
||||||
if match:
|
if match:
|
||||||
env['CCVERSION'] = match.group(0)
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# 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.
|
# 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
|
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