support SCons 3 (initial attempt)
This commit is contained in:
parent
3cb74f0871
commit
5732df452c
221 changed files with 4908 additions and 3867 deletions
58
SConstruct
58
SConstruct
|
@ -137,7 +137,7 @@ env = Environment(ENV=os.environ)
|
|||
init_environment(env)
|
||||
|
||||
def fix_path(path):
|
||||
return os.path.abspath(path)
|
||||
return str(os.path.abspath(path))
|
||||
|
||||
def color_print(color,text,newline=True):
|
||||
# 1 - red
|
||||
|
@ -146,15 +146,15 @@ def color_print(color,text,newline=True):
|
|||
# 4 - blue
|
||||
text = "\033[9%sm%s\033[0m" % (color,text)
|
||||
if not newline:
|
||||
print text,
|
||||
print(text, end=" ")
|
||||
else:
|
||||
print text
|
||||
print (text)
|
||||
|
||||
def regular_print(color,text,newline=True):
|
||||
if not newline:
|
||||
print text,
|
||||
print (text, end = " ")
|
||||
else:
|
||||
print text
|
||||
print (text)
|
||||
|
||||
def call(cmd, silent=False):
|
||||
stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
|
||||
|
@ -511,7 +511,7 @@ elif HELP_REQUESTED:
|
|||
# https://github.com/mapnik/mapnik/issues/2112
|
||||
if not os.path.exists(SCONS_LOCAL_LOG) and not os.path.exists(SCONS_CONFIGURE_CACHE) \
|
||||
and ('-c' in command_line_args or '--clean' in command_line_args):
|
||||
print 'all good: nothing to clean, but you might want to run "make distclean"'
|
||||
print ('all good: nothing to clean, but you might want to run "make distclean"')
|
||||
Exit(0)
|
||||
|
||||
# initially populate environment with defaults and any possible custom arguments
|
||||
|
@ -622,9 +622,9 @@ def parse_config(context, config, checks='--libs --cflags'):
|
|||
else:
|
||||
env.ParseConfig(cmd)
|
||||
parsed = True
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
ret = False
|
||||
print ' (xml2-config not found!)'
|
||||
print (' (xml2-config not found!)')
|
||||
if not parsed:
|
||||
if config in ('GDAL_CONFIG'):
|
||||
# optional deps...
|
||||
|
@ -658,9 +658,9 @@ def get_pkg_lib(context, config, lib):
|
|||
else:
|
||||
# osx 1.8 install gives '-framework GDAL'
|
||||
libname = 'gdal'
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
ret = False
|
||||
print ' unable to determine library name:'# %s' % str(e)
|
||||
print (' unable to determine library name:# {}'.format(str(e)))
|
||||
return None
|
||||
context.Result( libname )
|
||||
return libname
|
||||
|
@ -808,7 +808,7 @@ int main()
|
|||
return ret
|
||||
|
||||
def CheckIcuData(context, silent=False):
|
||||
|
||||
|
||||
if not silent:
|
||||
context.Message('Checking for ICU data directory...')
|
||||
ret = context.TryRun("""
|
||||
|
@ -835,7 +835,7 @@ int main() {
|
|||
return ret[1].strip()
|
||||
|
||||
def CheckGdalData(context, silent=False):
|
||||
|
||||
|
||||
if not silent:
|
||||
context.Message('Checking for GDAL data directory...')
|
||||
ret = context.TryRun("""
|
||||
|
@ -858,7 +858,7 @@ int main() {
|
|||
return ret[1].strip()
|
||||
|
||||
def CheckProjData(context, silent=False):
|
||||
|
||||
|
||||
if not silent:
|
||||
context.Message('Checking for PROJ_LIB directory...')
|
||||
ret = context.TryRun("""
|
||||
|
@ -1236,7 +1236,7 @@ if not preconfigured:
|
|||
if os.path.exists(conf):
|
||||
opts.files.append(conf)
|
||||
color_print(4,"SCons CONFIG found: '%s', variables will be inherited..." % conf)
|
||||
optfile = file(conf)
|
||||
optfile = open(conf, 'r')
|
||||
#print optfile.read().replace("\n", " ").replace("'","").replace(" = ","=")
|
||||
optfile.close()
|
||||
|
||||
|
@ -1407,7 +1407,7 @@ if not preconfigured:
|
|||
temp_env.ParseConfig('%s --libs' % env['FREETYPE_CONFIG'])
|
||||
if 'bz2' in temp_env['LIBS']:
|
||||
env['EXTRA_FREETYPE_LIBS'].append('bz2')
|
||||
except OSError,e:
|
||||
except OSError as e:
|
||||
pass
|
||||
|
||||
# libxml2 should be optional but is currently not
|
||||
|
@ -1481,7 +1481,7 @@ if not preconfigured:
|
|||
|
||||
# if requested, sort LIBPATH and CPPPATH before running CheckLibWithHeader tests
|
||||
if env['PRIORITIZE_LINKING']:
|
||||
conf.prioritize_paths(silent=True)
|
||||
pass#conf.prioritize_paths(silent=True)
|
||||
|
||||
# test for C++14 support, which is required
|
||||
if not env['HOST'] and not conf.supports_cxx14():
|
||||
|
@ -1539,7 +1539,7 @@ if not preconfigured:
|
|||
|
||||
# if requested, sort LIBPATH and CPPPATH before running CheckLibWithHeader tests
|
||||
if env['PRIORITIZE_LINKING']:
|
||||
conf.prioritize_paths(silent=True)
|
||||
pass#conf.prioritize_paths(silent=True)
|
||||
|
||||
if not env['HOST']:
|
||||
# if the user is not setting custom boost configuration
|
||||
|
@ -1708,7 +1708,7 @@ if not preconfigured:
|
|||
if not lib in env['LIBS']:
|
||||
env["SQLITE_LINKFLAGS"].append(lib)
|
||||
env.Append(LIBS=lib)
|
||||
except OSError,e:
|
||||
except OSError as e:
|
||||
for lib in ["sqlite3","dl","pthread"]:
|
||||
if not lib in env['LIBS']:
|
||||
env["SQLITE_LINKFLAGS"].append("lib")
|
||||
|
@ -1793,7 +1793,7 @@ if not preconfigured:
|
|||
env['HAS_CAIRO'] = False
|
||||
env['SKIPPED_DEPS'].append('cairo')
|
||||
else:
|
||||
print 'Checking for cairo lib and include paths... ',
|
||||
print ('Checking for cairo lib and include paths... ', end=" ")
|
||||
cmd = 'pkg-config --libs --cflags cairo'
|
||||
if env['RUNTIME_LINK'] == 'static':
|
||||
cmd += ' --static'
|
||||
|
@ -1810,8 +1810,8 @@ if not preconfigured:
|
|||
if not inc in env['CPPPATH']:
|
||||
env["CAIRO_CPPPATHS"].append(inc)
|
||||
env['HAS_CAIRO'] = True
|
||||
print 'yes'
|
||||
except OSError,e:
|
||||
print ('yes')
|
||||
except OSError as e:
|
||||
color_print(1,'no')
|
||||
env['SKIPPED_DEPS'].append('cairo')
|
||||
color_print(1,'pkg-config reported: %s' % e)
|
||||
|
@ -1961,35 +1961,35 @@ if not preconfigured:
|
|||
|
||||
# if requested, sort LIBPATH and CPPPATH one last time before saving...
|
||||
if env['PRIORITIZE_LINKING']:
|
||||
conf.prioritize_paths(silent=True)
|
||||
pass#conf.prioritize_paths(silent=True)
|
||||
|
||||
# finish config stage and pickle results
|
||||
env = conf.Finish()
|
||||
env_cache = open(SCONS_CONFIGURE_CACHE, 'w')
|
||||
env_cache = open(SCONS_CONFIGURE_CACHE, 'wb')
|
||||
pickle_dict = {}
|
||||
for i in pickle_store:
|
||||
pickle_dict[i] = env.get(i)
|
||||
pickle.dump(pickle_dict,env_cache)
|
||||
pickle.dump(pickle_dict, env_cache)
|
||||
env_cache.close()
|
||||
# fix up permissions on configure outputs
|
||||
# this is hackish but avoids potential problems
|
||||
# with a non-root configure following a root install
|
||||
# that also triggered a re-configure
|
||||
try:
|
||||
os.chmod(SCONS_CONFIGURE_CACHE,0666)
|
||||
os.chmod(SCONS_CONFIGURE_CACHE,0o666)
|
||||
except: pass
|
||||
try:
|
||||
os.chmod(SCONS_LOCAL_CONFIG,0666)
|
||||
os.chmod(SCONS_LOCAL_CONFIG,0o666)
|
||||
except: pass
|
||||
try:
|
||||
os.chmod('.sconsign.dblite',0666)
|
||||
os.chmod('.sconsign.dblite',0o666)
|
||||
except: pass
|
||||
try:
|
||||
os.chmod(SCONS_LOCAL_LOG,0666)
|
||||
os.chmod(SCONS_LOCAL_LOG,0o666)
|
||||
except: pass
|
||||
try:
|
||||
for item in glob('%s/*' % SCONF_TEMP_DIR):
|
||||
os.chmod(item,0666)
|
||||
os.chmod(item,0o666)
|
||||
except: pass
|
||||
|
||||
if 'configure' in command_line_args:
|
||||
|
|
|
@ -43,5 +43,5 @@ ini = ini_template % locals()
|
|||
open('viewer.ini','w').write(ini)
|
||||
|
||||
try:
|
||||
os.chmod('viewer.ini',0666)
|
||||
os.chmod('viewer.ini',0o666)
|
||||
except: pass
|
||||
|
|
|
@ -29,7 +29,7 @@ if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
|||
can_build = True
|
||||
|
||||
if not can_build:
|
||||
print 'WARNING: skipping building the optional CSV datasource plugin which requires boost >= 1.56'
|
||||
print ('WARNING: skipping building the optional CSV datasource plugin which requires boost >= 1.56')
|
||||
else:
|
||||
Import ('plugin_base')
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
|||
can_build = True
|
||||
|
||||
if not can_build:
|
||||
print 'WARNING: skipping building the optional geojson datasource plugin which requires boost >= 1.56'
|
||||
print ('WARNING: skipping building the optional geojson datasource plugin which requires boost >= 1.56')
|
||||
else:
|
||||
|
||||
Import ('plugin_base')
|
||||
|
|
|
@ -43,7 +43,7 @@ if env['RUNTIME_LINK'] == 'static':
|
|||
cmd = 'pkg-config libpq --libs --static'
|
||||
try:
|
||||
plugin_env.ParseConfig(cmd)
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
plugin_env.Append(LIBS='pq')
|
||||
else:
|
||||
plugin_env.Append(LIBS='pq')
|
||||
|
|
|
@ -42,7 +42,7 @@ if env['RUNTIME_LINK'] == 'static':
|
|||
cmd = 'pkg-config libpq --libs --static'
|
||||
try:
|
||||
plugin_env.ParseConfig(cmd)
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
plugin_env.Append(LIBS='pq')
|
||||
else:
|
||||
plugin_env.Append(LIBS='pq')
|
||||
|
|
|
@ -29,7 +29,7 @@ if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
|||
can_build = True
|
||||
|
||||
if not can_build:
|
||||
print 'WARNING: skipping building the optional topojson datasource plugin which requires boost >= 1.56'
|
||||
print ('WARNING: skipping building the optional topojson datasource plugin which requires boost >= 1.56')
|
||||
else:
|
||||
Import ('plugin_base')
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
This copyright and license do not apply to any other software
|
||||
with which this software may have been included.
|
||||
|
||||
Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
|
||||
SCons - a software construction tool
|
||||
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 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/Sig.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Sig module hierarchy
|
||||
|
||||
This is no longer used, but code out there (such as the NSIS module on
|
||||
the SCons wiki) may try to import SCons.Sig. If so, we generate a warning
|
||||
that points them to the line that caused the import, and don't die.
|
||||
|
||||
If someone actually tried to use the sub-modules or functions within
|
||||
the package (for example, SCons.Sig.MD5.signature()), then they'll still
|
||||
get an AttributeError, but at least they'll know where to start looking.
|
||||
"""
|
||||
|
||||
import SCons.Util
|
||||
import SCons.Warnings
|
||||
|
||||
msg = 'The SCons.Sig module no longer exists.\n' \
|
||||
' Remove the following "import SCons.Sig" line to eliminate this warning:'
|
||||
|
||||
SCons.Warnings.warn(SCons.Warnings.DeprecatedSigModuleWarning, msg)
|
||||
|
||||
default_calc = None
|
||||
default_module = None
|
||||
|
||||
class MD5Null(SCons.Util.Null):
|
||||
def __repr__(self):
|
||||
return "MD5Null()"
|
||||
|
||||
class TimeStampNull(SCons.Util.Null):
|
||||
def __repr__(self):
|
||||
return "TimeStampNull()"
|
||||
|
||||
MD5 = MD5Null()
|
||||
TimeStamp = TimeStampNull()
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -1,66 +0,0 @@
|
|||
"""SCons.Tool.BitKeeper.py
|
||||
|
||||
Tool-specific initialization for the BitKeeper source code control
|
||||
system.
|
||||
|
||||
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 - 2016 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/BitKeeper.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
||||
import SCons.Util
|
||||
|
||||
def generate(env):
|
||||
"""Add a Builder factory function and construction variables for
|
||||
BitKeeper to an Environment."""
|
||||
|
||||
def BitKeeperFactory(env=env):
|
||||
""" """
|
||||
import SCons.Warnings as W
|
||||
W.warn(W.DeprecatedSourceCodeWarning, """The BitKeeper() factory is deprecated and there is no replacement.""")
|
||||
act = SCons.Action.Action("$BITKEEPERCOM", "$BITKEEPERCOMSTR")
|
||||
return SCons.Builder.Builder(action = act, env = env)
|
||||
|
||||
env.BitKeeper = BitKeeperFactory
|
||||
|
||||
env['BITKEEPER'] = 'bk'
|
||||
env['BITKEEPERGET'] = '$BITKEEPER get'
|
||||
env['BITKEEPERGETFLAGS'] = SCons.Util.CLVar('')
|
||||
env['BITKEEPERCOM'] = '$BITKEEPERGET $BITKEEPERGETFLAGS $TARGET'
|
||||
|
||||
def exists(env):
|
||||
return env.Detect('bk')
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -1,72 +0,0 @@
|
|||
"""SCons.Tool.CVS.py
|
||||
|
||||
Tool-specific initialization for CVS.
|
||||
|
||||
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 - 2016 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/CVS.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
||||
import SCons.Util
|
||||
|
||||
def generate(env):
|
||||
"""Add a Builder factory function and construction variables for
|
||||
CVS to an Environment."""
|
||||
|
||||
def CVSFactory(repos, module='', env=env):
|
||||
""" """
|
||||
import SCons.Warnings as W
|
||||
W.warn(W.DeprecatedSourceCodeWarning, """The CVS() factory is deprecated and there is no replacement.""")
|
||||
# fail if repos is not an absolute path name?
|
||||
if module != '':
|
||||
# Don't use os.path.join() because the name we fetch might
|
||||
# be across a network and must use POSIX slashes as separators.
|
||||
module = module + '/'
|
||||
env['CVSCOM'] = '$CVS $CVSFLAGS co $CVSCOFLAGS -d ${TARGET.dir} $CVSMODULE${TARGET.posix}'
|
||||
act = SCons.Action.Action('$CVSCOM', '$CVSCOMSTR')
|
||||
return SCons.Builder.Builder(action = act,
|
||||
env = env,
|
||||
CVSREPOSITORY = repos,
|
||||
CVSMODULE = module)
|
||||
|
||||
env.CVS = CVSFactory
|
||||
|
||||
env['CVS'] = 'cvs'
|
||||
env['CVSFLAGS'] = SCons.Util.CLVar('-d $CVSREPOSITORY')
|
||||
env['CVSCOFLAGS'] = SCons.Util.CLVar('')
|
||||
env['CVSCOM'] = '$CVS $CVSFLAGS co $CVSCOFLAGS ${TARGET.posix}'
|
||||
|
||||
def exists(env):
|
||||
return env.Detect('cvs')
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -1,413 +0,0 @@
|
|||
"""SCons.Tool.GettextCommon module
|
||||
|
||||
Used by several tools of `gettext` toolset.
|
||||
"""
|
||||
|
||||
# Copyright (c) 2001 - 2016 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/GettextCommon.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
|
||||
import SCons.Warnings
|
||||
import re
|
||||
|
||||
#############################################################################
|
||||
class XgettextToolWarning(SCons.Warnings.Warning): pass
|
||||
class XgettextNotFound(XgettextToolWarning): pass
|
||||
class MsginitToolWarning(SCons.Warnings.Warning): pass
|
||||
class MsginitNotFound(MsginitToolWarning): pass
|
||||
class MsgmergeToolWarning(SCons.Warnings.Warning): pass
|
||||
class MsgmergeNotFound(MsgmergeToolWarning): pass
|
||||
class MsgfmtToolWarning(SCons.Warnings.Warning): pass
|
||||
class MsgfmtNotFound(MsgfmtToolWarning): pass
|
||||
#############################################################################
|
||||
SCons.Warnings.enableWarningClass(XgettextToolWarning)
|
||||
SCons.Warnings.enableWarningClass(XgettextNotFound)
|
||||
SCons.Warnings.enableWarningClass(MsginitToolWarning)
|
||||
SCons.Warnings.enableWarningClass(MsginitNotFound)
|
||||
SCons.Warnings.enableWarningClass(MsgmergeToolWarning)
|
||||
SCons.Warnings.enableWarningClass(MsgmergeNotFound)
|
||||
SCons.Warnings.enableWarningClass(MsgfmtToolWarning)
|
||||
SCons.Warnings.enableWarningClass(MsgfmtNotFound)
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
class _POTargetFactory(object):
|
||||
""" A factory of `PO` target files.
|
||||
|
||||
Factory defaults differ from these of `SCons.Node.FS.FS`. We set `precious`
|
||||
(this is required by builders and actions gettext) and `noclean` flags by
|
||||
default for all produced nodes.
|
||||
"""
|
||||
def __init__( self, env, nodefault = True, alias = None, precious = True
|
||||
, noclean = True ):
|
||||
""" Object constructor.
|
||||
|
||||
**Arguments**
|
||||
|
||||
- *env* (`SCons.Environment.Environment`)
|
||||
- *nodefault* (`boolean`) - if `True`, produced nodes will be ignored
|
||||
from default target `'.'`
|
||||
- *alias* (`string`) - if provided, produced nodes will be automatically
|
||||
added to this alias, and alias will be set as `AlwaysBuild`
|
||||
- *precious* (`boolean`) - if `True`, the produced nodes will be set as
|
||||
`Precious`.
|
||||
- *noclen* (`boolean`) - if `True`, the produced nodes will be excluded
|
||||
from `Clean`.
|
||||
"""
|
||||
self.env = env
|
||||
self.alias = alias
|
||||
self.precious = precious
|
||||
self.noclean = noclean
|
||||
self.nodefault = nodefault
|
||||
|
||||
def _create_node(self, name, factory, directory = None, create = 1):
|
||||
""" Create node, and set it up to factory settings. """
|
||||
import SCons.Util
|
||||
node = factory(name, directory, create)
|
||||
node.set_noclean(self.noclean)
|
||||
node.set_precious(self.precious)
|
||||
if self.nodefault:
|
||||
self.env.Ignore('.', node)
|
||||
if self.alias:
|
||||
self.env.AlwaysBuild(self.env.Alias(self.alias, node))
|
||||
return node
|
||||
|
||||
def Entry(self, name, directory = None, create = 1):
|
||||
""" Create `SCons.Node.FS.Entry` """
|
||||
return self._create_node(name, self.env.fs.Entry, directory, create)
|
||||
|
||||
def File(self, name, directory = None, create = 1):
|
||||
""" Create `SCons.Node.FS.File` """
|
||||
return self._create_node(name, self.env.fs.File, directory, create)
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
_re_comment = re.compile(r'(#[^\n\r]+)$', re.M)
|
||||
_re_lang = re.compile(r'([a-zA-Z0-9_]+)', re.M)
|
||||
#############################################################################
|
||||
def _read_linguas_from_files(env, linguas_files = None):
|
||||
""" Parse `LINGUAS` file and return list of extracted languages """
|
||||
import SCons.Util
|
||||
import SCons.Environment
|
||||
global _re_comment
|
||||
global _re_lang
|
||||
if not SCons.Util.is_List(linguas_files) \
|
||||
and not SCons.Util.is_String(linguas_files) \
|
||||
and not isinstance(linguas_files, SCons.Node.FS.Base) \
|
||||
and linguas_files:
|
||||
# If, linguas_files==True or such, then read 'LINGUAS' file.
|
||||
linguas_files = [ 'LINGUAS' ]
|
||||
if linguas_files is None:
|
||||
return []
|
||||
fnodes = env.arg2nodes(linguas_files)
|
||||
linguas = []
|
||||
for fnode in fnodes:
|
||||
contents = _re_comment.sub("", fnode.get_text_contents())
|
||||
ls = [ l for l in _re_lang.findall(contents) if l ]
|
||||
linguas.extend(ls)
|
||||
return linguas
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
from SCons.Builder import BuilderBase
|
||||
#############################################################################
|
||||
class _POFileBuilder(BuilderBase):
|
||||
""" `PO` file builder.
|
||||
|
||||
This is multi-target single-source builder. In typical situation the source
|
||||
is single `POT` file, e.g. `messages.pot`, and there are multiple `PO`
|
||||
targets to be updated from this `POT`. We must run
|
||||
`SCons.Builder.BuilderBase._execute()` separatelly for each target to track
|
||||
dependencies separatelly for each target file.
|
||||
|
||||
**NOTE**: if we call `SCons.Builder.BuilderBase._execute(.., target, ...)`
|
||||
with target being list of all targets, all targets would be rebuilt each time
|
||||
one of the targets from this list is missing. This would happen, for example,
|
||||
when new language `ll` enters `LINGUAS_FILE` (at this moment there is no
|
||||
`ll.po` file yet). To avoid this, we override
|
||||
`SCons.Builder.BuilerBase._execute()` and call it separatelly for each
|
||||
target. Here we also append to the target list the languages read from
|
||||
`LINGUAS_FILE`.
|
||||
"""
|
||||
#
|
||||
#* The argument for overriding _execute(): We must use environment with
|
||||
# builder overrides applied (see BuilderBase.__init__(). Here it comes for
|
||||
# free.
|
||||
#* The argument against using 'emitter': The emitter is called too late
|
||||
# by BuilderBase._execute(). If user calls, for example:
|
||||
#
|
||||
# env.POUpdate(LINGUAS_FILE = 'LINGUAS')
|
||||
#
|
||||
# the builder throws error, because it is called with target=None,
|
||||
# source=None and is trying to "generate" sources or target list first.
|
||||
# If user calls
|
||||
#
|
||||
# env.POUpdate(['foo', 'baz'], LINGUAS_FILE = 'LINGUAS')
|
||||
#
|
||||
# the env.BuilderWrapper() calls our builder with target=None,
|
||||
# source=['foo', 'baz']. The BuilderBase._execute() then splits execution
|
||||
# and execute iterativelly (recursion) self._execute(None, source[i]).
|
||||
# After that it calls emitter (which is quite too late). The emitter is
|
||||
# also called in each iteration, what makes things yet worse.
|
||||
def __init__(self, env, **kw):
|
||||
if not 'suffix' in kw:
|
||||
kw['suffix'] = '$POSUFFIX'
|
||||
if not 'src_suffix' in kw:
|
||||
kw['src_suffix'] = '$POTSUFFIX'
|
||||
if not 'src_builder' in kw:
|
||||
kw['src_builder'] = '_POTUpdateBuilder'
|
||||
if not 'single_source' in kw:
|
||||
kw['single_source'] = True
|
||||
alias = None
|
||||
if 'target_alias' in kw:
|
||||
alias = kw['target_alias']
|
||||
del kw['target_alias']
|
||||
if not 'target_factory' in kw:
|
||||
kw['target_factory'] = _POTargetFactory(env, alias=alias).File
|
||||
BuilderBase.__init__(self, **kw)
|
||||
|
||||
def _execute(self, env, target, source, *args, **kw):
|
||||
""" Execute builder's actions.
|
||||
|
||||
Here we append to `target` the languages read from `$LINGUAS_FILE` and
|
||||
apply `SCons.Builder.BuilderBase._execute()` separatelly to each target.
|
||||
The arguments and return value are same as for
|
||||
`SCons.Builder.BuilderBase._execute()`.
|
||||
"""
|
||||
import SCons.Util
|
||||
import SCons.Node
|
||||
linguas_files = None
|
||||
if env.has_key('LINGUAS_FILE') and env['LINGUAS_FILE']:
|
||||
linguas_files = env['LINGUAS_FILE']
|
||||
# This prevents endless recursion loop (we'll be invoked once for
|
||||
# each target appended here, we must not extend the list again).
|
||||
env['LINGUAS_FILE'] = None
|
||||
linguas = _read_linguas_from_files(env,linguas_files)
|
||||
if SCons.Util.is_List(target):
|
||||
target.extend(linguas)
|
||||
elif target is not None:
|
||||
target = [target] + linguas
|
||||
else:
|
||||
target = linguas
|
||||
if not target:
|
||||
# Let the SCons.BuilderBase to handle this patologic situation
|
||||
return BuilderBase._execute( self, env, target, source, *args, **kw)
|
||||
# The rest is ours
|
||||
if not SCons.Util.is_List(target):
|
||||
target = [ target ]
|
||||
result = []
|
||||
for tgt in target:
|
||||
r = BuilderBase._execute( self, env, [tgt], source, *args, **kw)
|
||||
result.extend(r)
|
||||
if linguas_files is not None:
|
||||
env['LINGUAS_FILE'] = linguas_files
|
||||
return SCons.Node.NodeList(result)
|
||||
#############################################################################
|
||||
|
||||
import SCons.Environment
|
||||
#############################################################################
|
||||
def _translate(env, target=None, source=SCons.Environment._null, *args, **kw):
|
||||
""" Function for `Translate()` pseudo-builder """
|
||||
if target is None: target = []
|
||||
pot = env.POTUpdate(None, source, *args, **kw)
|
||||
po = env.POUpdate(target, pot, *args, **kw)
|
||||
return po
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
class RPaths(object):
|
||||
""" Callable object, which returns pathnames relative to SCons current
|
||||
working directory.
|
||||
|
||||
It seems like `SCons.Node.FS.Base.get_path()` returns absolute paths
|
||||
for nodes that are outside of current working directory (`env.fs.getcwd()`).
|
||||
Here, we often have `SConscript`, `POT` and `PO` files within `po/`
|
||||
directory and source files (e.g. `*.c`) outside of it. When generating `POT`
|
||||
template file, references to source files are written to `POT` template, so
|
||||
a translator may later quickly jump to appropriate source file and line from
|
||||
its `PO` editor (e.g. `poedit`). Relative paths in `PO` file are usually
|
||||
interpreted by `PO` editor as paths relative to the place, where `PO` file
|
||||
lives. The absolute paths would make resultant `POT` file nonportable, as
|
||||
the references would be correct only on the machine, where `POT` file was
|
||||
recently re-created. For such reason, we need a function, which always
|
||||
returns relative paths. This is the purpose of `RPaths` callable object.
|
||||
|
||||
The `__call__` method returns paths relative to current working directory, but
|
||||
we assume, that *xgettext(1)* is run from the directory, where target file is
|
||||
going to be created.
|
||||
|
||||
Note, that this may not work for files distributed over several hosts or
|
||||
across different drives on windows. We assume here, that single local
|
||||
filesystem holds both source files and target `POT` templates.
|
||||
|
||||
Intended use of `RPaths` - in `xgettext.py`::
|
||||
|
||||
def generate(env):
|
||||
from GettextCommon import RPaths
|
||||
...
|
||||
sources = '$( ${_concat( "", SOURCES, "", __env__, XgettextRPaths, TARGET, SOURCES)} $)'
|
||||
env.Append(
|
||||
...
|
||||
XGETTEXTCOM = 'XGETTEXT ... ' + sources,
|
||||
...
|
||||
XgettextRPaths = RPaths(env)
|
||||
)
|
||||
"""
|
||||
# NOTE: This callable object returns pathnames of dirs/files relative to
|
||||
# current working directory. The pathname remains relative also for entries
|
||||
# that are outside of current working directory (node, that
|
||||
# SCons.Node.FS.File and siblings return absolute path in such case). For
|
||||
# simplicity we compute path relative to current working directory, this
|
||||
# seems be enough for our purposes (don't need TARGET variable and
|
||||
# SCons.Defaults.Variable_Caller stuff).
|
||||
|
||||
def __init__(self, env):
|
||||
""" Initialize `RPaths` callable object.
|
||||
|
||||
**Arguments**:
|
||||
|
||||
- *env* - a `SCons.Environment.Environment` object, defines *current
|
||||
working dir*.
|
||||
"""
|
||||
self.env = env
|
||||
|
||||
# FIXME: I'm not sure, how it should be implemented (what the *args are in
|
||||
# general, what is **kw).
|
||||
def __call__(self, nodes, *args, **kw):
|
||||
""" Return nodes' paths (strings) relative to current working directory.
|
||||
|
||||
**Arguments**:
|
||||
|
||||
- *nodes* ([`SCons.Node.FS.Base`]) - list of nodes.
|
||||
- *args* - currently unused.
|
||||
- *kw* - currently unused.
|
||||
|
||||
**Returns**:
|
||||
|
||||
- Tuple of strings, which represent paths relative to current working
|
||||
directory (for given environment).
|
||||
"""
|
||||
import os
|
||||
import SCons.Node.FS
|
||||
rpaths = ()
|
||||
cwd = self.env.fs.getcwd().get_abspath()
|
||||
for node in nodes:
|
||||
rpath = None
|
||||
if isinstance(node, SCons.Node.FS.Base):
|
||||
rpath = os.path.relpath(node.get_abspath(), cwd)
|
||||
# FIXME: Other types possible here?
|
||||
if rpath is not None:
|
||||
rpaths += (rpath,)
|
||||
return rpaths
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _init_po_files(target, source, env):
|
||||
""" Action function for `POInit` builder. """
|
||||
nop = lambda target, source, env : 0
|
||||
if env.has_key('POAUTOINIT'):
|
||||
autoinit = env['POAUTOINIT']
|
||||
else:
|
||||
autoinit = False
|
||||
# Well, if everything outside works well, this loop should do single
|
||||
# iteration. Otherwise we are rebuilding all the targets even, if just
|
||||
# one has changed (but is this our fault?).
|
||||
for tgt in target:
|
||||
if not tgt.exists():
|
||||
if autoinit:
|
||||
action = SCons.Action.Action('$MSGINITCOM', '$MSGINITCOMSTR')
|
||||
else:
|
||||
msg = 'File ' + repr(str(tgt)) + ' does not exist. ' \
|
||||
+ 'If you are a translator, you can create it through: \n' \
|
||||
+ '$MSGINITCOM'
|
||||
action = SCons.Action.Action(nop, msg)
|
||||
status = action([tgt], source, env)
|
||||
if status: return status
|
||||
return 0
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _detect_xgettext(env):
|
||||
""" Detects *xgettext(1)* binary """
|
||||
if env.has_key('XGETTEXT'):
|
||||
return env['XGETTEXT']
|
||||
xgettext = env.Detect('xgettext');
|
||||
if xgettext:
|
||||
return xgettext
|
||||
raise SCons.Errors.StopError(XgettextNotFound,"Could not detect xgettext")
|
||||
return None
|
||||
#############################################################################
|
||||
def _xgettext_exists(env):
|
||||
return _detect_xgettext(env)
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _detect_msginit(env):
|
||||
""" Detects *msginit(1)* program. """
|
||||
if env.has_key('MSGINIT'):
|
||||
return env['MSGINIT']
|
||||
msginit = env.Detect('msginit');
|
||||
if msginit:
|
||||
return msginit
|
||||
raise SCons.Errors.StopError(MsginitNotFound, "Could not detect msginit")
|
||||
return None
|
||||
#############################################################################
|
||||
def _msginit_exists(env):
|
||||
return _detect_msginit(env)
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _detect_msgmerge(env):
|
||||
""" Detects *msgmerge(1)* program. """
|
||||
if env.has_key('MSGMERGE'):
|
||||
return env['MSGMERGE']
|
||||
msgmerge = env.Detect('msgmerge');
|
||||
if msgmerge:
|
||||
return msgmerge
|
||||
raise SCons.Errors.StopError(MsgmergeNotFound, "Could not detect msgmerge")
|
||||
return None
|
||||
#############################################################################
|
||||
def _msgmerge_exists(env):
|
||||
return _detect_msgmerge(env)
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _detect_msgfmt(env):
|
||||
""" Detects *msgmfmt(1)* program. """
|
||||
if env.has_key('MSGFMT'):
|
||||
return env['MSGFMT']
|
||||
msgfmt = env.Detect('msgfmt');
|
||||
if msgfmt:
|
||||
return msgfmt
|
||||
raise SCons.Errors.StopError(MsgfmtNotFound, "Could not detect msgfmt")
|
||||
return None
|
||||
#############################################################################
|
||||
def _msgfmt_exists(env):
|
||||
return _detect_msgfmt(env)
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def tool_list(platform, env):
|
||||
""" List tools that shall be generated by top-level `gettext` tool """
|
||||
return [ 'xgettext', 'msginit', 'msgmerge', 'msgfmt' ]
|
||||
#############################################################################
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
"""SCons.Tool.Perforce.py
|
||||
|
||||
Tool-specific initialization for Perforce Source Code Management system.
|
||||
|
||||
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 - 2016 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/Perforce.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
|
||||
import os
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
||||
import SCons.Node.FS
|
||||
import SCons.Util
|
||||
|
||||
|
||||
# Variables that we want to import from the base OS environment.
|
||||
_import_env = [ 'P4PORT', 'P4CLIENT', 'P4USER', 'USER', 'USERNAME', 'P4PASSWD',
|
||||
'P4CHARSET', 'P4LANGUAGE', 'SystemRoot' ]
|
||||
|
||||
PerforceAction = SCons.Action.Action('$P4COM', '$P4COMSTR')
|
||||
|
||||
def generate(env):
|
||||
"""Add a Builder factory function and construction variables for
|
||||
Perforce to an Environment."""
|
||||
|
||||
def PerforceFactory(env=env):
|
||||
""" """
|
||||
import SCons.Warnings as W
|
||||
W.warn(W.DeprecatedSourceCodeWarning, """The Perforce() factory is deprecated and there is no replacement.""")
|
||||
return SCons.Builder.Builder(action = PerforceAction, env = env)
|
||||
|
||||
env.Perforce = PerforceFactory
|
||||
|
||||
env['P4'] = 'p4'
|
||||
env['P4FLAGS'] = SCons.Util.CLVar('')
|
||||
env['P4COM'] = '$P4 $P4FLAGS sync $TARGET'
|
||||
try:
|
||||
environ = env['ENV']
|
||||
except KeyError:
|
||||
environ = {}
|
||||
env['ENV'] = environ
|
||||
|
||||
# Perforce seems to use the PWD environment variable rather than
|
||||
# calling getcwd() for itself, which is odd. If no PWD variable
|
||||
# is present, p4 WILL call getcwd, but this seems to cause problems
|
||||
# with good ol' Windows's tilde-mangling for long file names.
|
||||
environ['PWD'] = env.Dir('#').get_abspath()
|
||||
|
||||
for var in _import_env:
|
||||
v = os.environ.get(var)
|
||||
if v:
|
||||
environ[var] = v
|
||||
|
||||
if SCons.Util.can_read_reg:
|
||||
# If we can read the registry, add the path to Perforce to our environment.
|
||||
try:
|
||||
k=SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE,
|
||||
'Software\\Perforce\\environment')
|
||||
val, tok = SCons.Util.RegQueryValueEx(k, 'P4INSTROOT')
|
||||
SCons.Util.AddPathIfNotExists(environ, 'PATH', val)
|
||||
except SCons.Util.RegError:
|
||||
# Can't detect where Perforce is, hope the user has it set in the
|
||||
# PATH.
|
||||
pass
|
||||
|
||||
def exists(env):
|
||||
return env.Detect('p4')
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -1,63 +0,0 @@
|
|||
"""SCons.Tool.SCCS.py
|
||||
|
||||
Tool-specific initialization for SCCS.
|
||||
|
||||
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 - 2016 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/SCCS.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
||||
import SCons.Util
|
||||
|
||||
def generate(env):
|
||||
"""Add a Builder factory function and construction variables for
|
||||
SCCS to an Environment."""
|
||||
|
||||
def SCCSFactory(env=env):
|
||||
""" """
|
||||
import SCons.Warnings as W
|
||||
W.warn(W.DeprecatedSourceCodeWarning, """The SCCS() factory is deprecated and there is no replacement.""")
|
||||
act = SCons.Action.Action('$SCCSCOM', '$SCCSCOMSTR')
|
||||
return SCons.Builder.Builder(action = act, env = env)
|
||||
|
||||
env.SCCS = SCCSFactory
|
||||
|
||||
env['SCCS'] = 'sccs'
|
||||
env['SCCSFLAGS'] = SCons.Util.CLVar('')
|
||||
env['SCCSGETFLAGS'] = SCons.Util.CLVar('')
|
||||
env['SCCSCOM'] = '$SCCS $SCCSFLAGS get $SCCSGETFLAGS $TARGET'
|
||||
|
||||
def exists(env):
|
||||
return env.Detect('sccs')
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -1,70 +0,0 @@
|
|||
"""SCons.Tool.Subversion.py
|
||||
|
||||
Tool-specific initialization for Subversion.
|
||||
|
||||
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 - 2016 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/Subversion.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
|
||||
import os.path
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
||||
import SCons.Util
|
||||
|
||||
def generate(env):
|
||||
"""Add a Builder factory function and construction variables for
|
||||
Subversion to an Environment."""
|
||||
|
||||
def SubversionFactory(repos, module='', env=env):
|
||||
""" """
|
||||
# fail if repos is not an absolute path name?
|
||||
import SCons.Warnings as W
|
||||
W.warn(W.DeprecatedSourceCodeWarning, """The Subversion() factory is deprecated and there is no replacement.""")
|
||||
if module != '':
|
||||
module = os.path.join(module, '')
|
||||
act = SCons.Action.Action('$SVNCOM', '$SVNCOMSTR')
|
||||
return SCons.Builder.Builder(action = act,
|
||||
env = env,
|
||||
SVNREPOSITORY = repos,
|
||||
SVNMODULE = module)
|
||||
|
||||
env.Subversion = SubversionFactory
|
||||
|
||||
env['SVN'] = 'svn'
|
||||
env['SVNFLAGS'] = SCons.Util.CLVar('')
|
||||
env['SVNCOM'] = '$SVN $SVNFLAGS cat $SVNREPOSITORY/$SVNMODULE$TARGET > $TARGET'
|
||||
|
||||
def exists(env):
|
||||
return env.Detect('svn')
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -1,116 +0,0 @@
|
|||
"""SCons.Tool.jar
|
||||
|
||||
Tool-specific initialization for jar.
|
||||
|
||||
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 - 2016 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/jar.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
|
||||
import SCons.Subst
|
||||
import SCons.Util
|
||||
|
||||
def jarSources(target, source, env, for_signature):
|
||||
"""Only include sources that are not a manifest file."""
|
||||
try:
|
||||
env['JARCHDIR']
|
||||
except KeyError:
|
||||
jarchdir_set = False
|
||||
else:
|
||||
jarchdir_set = True
|
||||
jarchdir = env.subst('$JARCHDIR', target=target, source=source)
|
||||
if jarchdir:
|
||||
jarchdir = env.fs.Dir(jarchdir)
|
||||
result = []
|
||||
for src in source:
|
||||
contents = src.get_text_contents()
|
||||
if contents[:16] != "Manifest-Version":
|
||||
if jarchdir_set:
|
||||
_chdir = jarchdir
|
||||
else:
|
||||
try:
|
||||
_chdir = src.attributes.java_classdir
|
||||
except AttributeError:
|
||||
_chdir = None
|
||||
if _chdir:
|
||||
# If we are changing the dir with -C, then sources should
|
||||
# be relative to that directory.
|
||||
src = SCons.Subst.Literal(src.get_path(_chdir))
|
||||
result.append('-C')
|
||||
result.append(_chdir)
|
||||
result.append(src)
|
||||
return result
|
||||
|
||||
def jarManifest(target, source, env, for_signature):
|
||||
"""Look in sources for a manifest file, if any."""
|
||||
for src in source:
|
||||
contents = src.get_text_contents()
|
||||
if contents[:16] == "Manifest-Version":
|
||||
return src
|
||||
return ''
|
||||
|
||||
def jarFlags(target, source, env, for_signature):
|
||||
"""If we have a manifest, make sure that the 'm'
|
||||
flag is specified."""
|
||||
jarflags = env.subst('$JARFLAGS', target=target, source=source)
|
||||
for src in source:
|
||||
contents = src.get_text_contents()
|
||||
if contents[:16] == "Manifest-Version":
|
||||
if not 'm' in jarflags:
|
||||
return jarflags + 'm'
|
||||
break
|
||||
return jarflags
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for jar to an Environment."""
|
||||
SCons.Tool.CreateJarBuilder(env)
|
||||
|
||||
env['JAR'] = 'jar'
|
||||
env['JARFLAGS'] = SCons.Util.CLVar('cf')
|
||||
env['_JARFLAGS'] = jarFlags
|
||||
env['_JARMANIFEST'] = jarManifest
|
||||
env['_JARSOURCES'] = jarSources
|
||||
env['_JARCOM'] = '$JAR $_JARFLAGS $TARGET $_JARMANIFEST $_JARSOURCES'
|
||||
env['JARCOM'] = "${TEMPFILE('$_JARCOM','$JARCOMSTR')}"
|
||||
env['JARSUFFIX'] = '.jar'
|
||||
|
||||
def exists(env):
|
||||
# As reported by Jan Nijtmans in issue #2730, the simple
|
||||
# return env.Detect('jar')
|
||||
# doesn't always work during initialization. For now, we
|
||||
# stop trying to detect an executable (analogous to the
|
||||
# javac Builder).
|
||||
# TODO: Come up with a proper detect() routine...and enable it.
|
||||
return 1
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -1,339 +0,0 @@
|
|||
""" xgettext tool
|
||||
|
||||
Tool specific initialization of `xgettext` tool.
|
||||
"""
|
||||
|
||||
# Copyright (c) 2001 - 2016 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/xgettext.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
|
||||
#############################################################################
|
||||
class _CmdRunner(object):
|
||||
""" Callabe object, which runs shell command storing its stdout and stderr to
|
||||
variables. It also provides `strfunction()` method, which shall be used by
|
||||
scons Action objects to print command string. """
|
||||
|
||||
def __init__( self, command, commandstr = None):
|
||||
self.out = None
|
||||
self.err = None
|
||||
self.status = None
|
||||
self.command = command
|
||||
self.commandstr = commandstr
|
||||
|
||||
def __call__(self, target, source, env):
|
||||
import SCons.Action
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
kw = {
|
||||
'stdin' : 'devnull',
|
||||
'stdout' : subprocess.PIPE,
|
||||
'stderr' : subprocess.PIPE,
|
||||
'universal_newlines' : True,
|
||||
'shell' : True
|
||||
}
|
||||
command = env.subst(self.command, target = target, source = source)
|
||||
proc = SCons.Action._subproc(env, command, **kw)
|
||||
self.out, self.err = proc.communicate()
|
||||
self.status = proc.wait()
|
||||
if self.err: sys.stderr.write(unicode(self.err))
|
||||
return self.status
|
||||
|
||||
def strfunction(self, target, source, env):
|
||||
import os
|
||||
comstr = self.commandstr
|
||||
if env.subst(comstr, target = target, source = source) == "":
|
||||
comstr = self.command
|
||||
s = env.subst(comstr, target = target, source = source)
|
||||
return s
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _update_pot_file(target, source, env):
|
||||
""" Action function for `POTUpdate` builder """
|
||||
import re
|
||||
import os
|
||||
import SCons.Action
|
||||
nop = lambda target, source, env : 0
|
||||
|
||||
# Save scons cwd and os cwd (NOTE: they may be different. After the job, we
|
||||
# revert each one to its original state).
|
||||
save_cwd = env.fs.getcwd()
|
||||
save_os_cwd = os.getcwd()
|
||||
chdir = target[0].dir
|
||||
chdir_str = repr(chdir.get_abspath())
|
||||
# Print chdir message (employ SCons.Action.Action for that. It knows better
|
||||
# than me how to to this correctly).
|
||||
env.Execute(SCons.Action.Action(nop, "Entering " + chdir_str))
|
||||
# Go to target's directory and do our job
|
||||
env.fs.chdir(chdir, 1) # Go into target's directory
|
||||
try:
|
||||
cmd = _CmdRunner('$XGETTEXTCOM', '$XGETTEXTCOMSTR')
|
||||
action = SCons.Action.Action(cmd, strfunction=cmd.strfunction)
|
||||
status = action([ target[0] ], source, env)
|
||||
except:
|
||||
# Something went wrong.
|
||||
env.Execute(SCons.Action.Action(nop, "Leaving " + chdir_str))
|
||||
# Revert working dirs to previous state and re-throw exception.
|
||||
env.fs.chdir(save_cwd, 0)
|
||||
os.chdir(save_os_cwd)
|
||||
raise
|
||||
# Print chdir message.
|
||||
env.Execute(SCons.Action.Action(nop, "Leaving " + chdir_str))
|
||||
# Revert working dirs to previous state.
|
||||
env.fs.chdir(save_cwd, 0)
|
||||
os.chdir(save_os_cwd)
|
||||
# If the command was not successfull, return error code.
|
||||
if status: return status
|
||||
|
||||
new_content = cmd.out
|
||||
|
||||
if not new_content:
|
||||
# When xgettext finds no internationalized messages, no *.pot is created
|
||||
# (because we don't want to bother translators with empty POT files).
|
||||
needs_update = False
|
||||
explain = "no internationalized messages encountered"
|
||||
else:
|
||||
if target[0].exists():
|
||||
# If the file already exists, it's left unaltered unless its messages
|
||||
# are outdated (w.r.t. to these recovered by xgettext from sources).
|
||||
old_content = target[0].get_text_contents()
|
||||
re_cdate = re.compile(r'^"POT-Creation-Date: .*"$[\r\n]?', re.M)
|
||||
old_content_nocdate = re.sub(re_cdate,"",old_content)
|
||||
new_content_nocdate = re.sub(re_cdate,"",new_content)
|
||||
if(old_content_nocdate == new_content_nocdate):
|
||||
# Messages are up-to-date
|
||||
needs_update = False
|
||||
explain = "messages in file found to be up-to-date"
|
||||
else:
|
||||
# Messages are outdated
|
||||
needs_update = True
|
||||
explain = "messages in file were outdated"
|
||||
else:
|
||||
# No POT file found, create new one
|
||||
needs_update = True
|
||||
explain = "new file"
|
||||
if needs_update:
|
||||
# Print message employing SCons.Action.Action for that.
|
||||
msg = "Writing " + repr(str(target[0])) + " (" + explain + ")"
|
||||
env.Execute(SCons.Action.Action(nop, msg))
|
||||
f = open(str(target[0]),"w")
|
||||
f.write(new_content)
|
||||
f.close()
|
||||
return 0
|
||||
else:
|
||||
# Print message employing SCons.Action.Action for that.
|
||||
msg = "Not writing " + repr(str(target[0])) + " (" + explain + ")"
|
||||
env.Execute(SCons.Action.Action(nop, msg))
|
||||
return 0
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
from SCons.Builder import BuilderBase
|
||||
#############################################################################
|
||||
class _POTBuilder(BuilderBase):
|
||||
def _execute(self, env, target, source, *args):
|
||||
if not target:
|
||||
if env.has_key('POTDOMAIN') and env['POTDOMAIN']:
|
||||
domain = env['POTDOMAIN']
|
||||
else:
|
||||
domain = 'messages'
|
||||
target = [ domain ]
|
||||
return BuilderBase._execute(self, env, target, source, *args)
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _scan_xgettext_from_files(target, source, env, files = None, path = None):
|
||||
""" Parses `POTFILES.in`-like file and returns list of extracted file names.
|
||||
"""
|
||||
import re
|
||||
import SCons.Util
|
||||
import SCons.Node.FS
|
||||
|
||||
if files is None:
|
||||
return 0
|
||||
if not SCons.Util.is_List(files):
|
||||
files = [ files ]
|
||||
|
||||
if path is None:
|
||||
if env.has_key('XGETTEXTPATH'):
|
||||
path = env['XGETTEXTPATH']
|
||||
else:
|
||||
path = []
|
||||
if not SCons.Util.is_List(path):
|
||||
path = [ path ]
|
||||
|
||||
path = SCons.Util.flatten(path)
|
||||
|
||||
dirs = ()
|
||||
for p in path:
|
||||
if not isinstance(p, SCons.Node.FS.Base):
|
||||
if SCons.Util.is_String(p):
|
||||
p = env.subst(p, source = source, target = target)
|
||||
p = env.arg2nodes(p, env.fs.Dir)
|
||||
dirs += tuple(p)
|
||||
# cwd is the default search path (when no path is defined by user)
|
||||
if not dirs:
|
||||
dirs = (env.fs.getcwd(),)
|
||||
|
||||
# Parse 'POTFILE.in' files.
|
||||
re_comment = re.compile(r'^#[^\n\r]*$\r?\n?', re.M)
|
||||
re_emptyln = re.compile(r'^[ \t\r]*$\r?\n?', re.M)
|
||||
re_trailws = re.compile(r'[ \t\r]+$')
|
||||
for f in files:
|
||||
# Find files in search path $XGETTEXTPATH
|
||||
if isinstance(f, SCons.Node.FS.Base) and f.rexists():
|
||||
contents = f.get_text_contents()
|
||||
contents = re_comment.sub("", contents)
|
||||
contents = re_emptyln.sub("", contents)
|
||||
contents = re_trailws.sub("", contents)
|
||||
depnames = contents.splitlines()
|
||||
for depname in depnames:
|
||||
depfile = SCons.Node.FS.find_file(depname, dirs)
|
||||
if not depfile:
|
||||
depfile = env.arg2nodes(depname, dirs[0].File)
|
||||
env.Depends(target, depfile)
|
||||
return 0
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _pot_update_emitter(target, source, env):
|
||||
""" Emitter function for `POTUpdate` builder """
|
||||
from SCons.Tool.GettextCommon import _POTargetFactory
|
||||
import SCons.Util
|
||||
import SCons.Node.FS
|
||||
|
||||
if env.has_key('XGETTEXTFROM'):
|
||||
xfrom = env['XGETTEXTFROM']
|
||||
else:
|
||||
return target, source
|
||||
if not SCons.Util.is_List(xfrom):
|
||||
xfrom = [ xfrom ]
|
||||
|
||||
xfrom = SCons.Util.flatten(xfrom)
|
||||
|
||||
# Prepare list of 'POTFILE.in' files.
|
||||
files = []
|
||||
for xf in xfrom:
|
||||
if not isinstance(xf, SCons.Node.FS.Base):
|
||||
if SCons.Util.is_String(xf):
|
||||
# Interpolate variables in strings
|
||||
xf = env.subst(xf, source = source, target = target)
|
||||
xf = env.arg2nodes(xf)
|
||||
files.extend(xf)
|
||||
if files:
|
||||
env.Depends(target, files)
|
||||
_scan_xgettext_from_files(target, source, env, files)
|
||||
return target, source
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
from SCons.Environment import _null
|
||||
#############################################################################
|
||||
def _POTUpdateBuilderWrapper(env, target=None, source=_null, **kw):
|
||||
return env._POTUpdateBuilder(target, source, **kw)
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _POTUpdateBuilder(env, **kw):
|
||||
""" Creates `POTUpdate` builder object """
|
||||
import SCons.Action
|
||||
from SCons.Tool.GettextCommon import _POTargetFactory
|
||||
kw['action'] = SCons.Action.Action(_update_pot_file, None)
|
||||
kw['suffix'] = '$POTSUFFIX'
|
||||
kw['target_factory'] = _POTargetFactory(env, alias='$POTUPDATE_ALIAS').File
|
||||
kw['emitter'] = _pot_update_emitter
|
||||
return _POTBuilder(**kw)
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def generate(env,**kw):
|
||||
""" Generate `xgettext` tool """
|
||||
import SCons.Util
|
||||
from SCons.Tool.GettextCommon import RPaths, _detect_xgettext
|
||||
|
||||
try:
|
||||
env['XGETTEXT'] = _detect_xgettext(env)
|
||||
except:
|
||||
env['XGETTEXT'] = 'xgettext'
|
||||
# NOTE: sources="$SOURCES" would work as well. However, we use following
|
||||
# construction to convert absolute paths provided by scons onto paths
|
||||
# relative to current working dir. Note, that scons expands $SOURCE(S) to
|
||||
# absolute paths for sources $SOURCE(s) outside of current subtree (e.g. in
|
||||
# "../"). With source=$SOURCE these absolute paths would be written to the
|
||||
# resultant *.pot file (and its derived *.po files) as references to lines in
|
||||
# source code (e.g. referring lines in *.c files). Such references would be
|
||||
# correct (e.g. in poedit) only on machine on which *.pot was generated and
|
||||
# would be of no use on other hosts (having a copy of source code located
|
||||
# in different place in filesystem).
|
||||
sources = '$( ${_concat( "", SOURCES, "", __env__, XgettextRPaths, TARGET' \
|
||||
+ ', SOURCES)} $)'
|
||||
|
||||
# NOTE: the output from $XGETTEXTCOM command must go to stdout, not to a file.
|
||||
# This is required by the POTUpdate builder's action.
|
||||
xgettextcom = '$XGETTEXT $XGETTEXTFLAGS $_XGETTEXTPATHFLAGS' \
|
||||
+ ' $_XGETTEXTFROMFLAGS -o - ' + sources
|
||||
|
||||
xgettextpathflags = '$( ${_concat( XGETTEXTPATHPREFIX, XGETTEXTPATH' \
|
||||
+ ', XGETTEXTPATHSUFFIX, __env__, RDirs, TARGET, SOURCES)} $)'
|
||||
xgettextfromflags = '$( ${_concat( XGETTEXTFROMPREFIX, XGETTEXTFROM' \
|
||||
+ ', XGETTEXTFROMSUFFIX, __env__, target=TARGET, source=SOURCES)} $)'
|
||||
|
||||
env.SetDefault(
|
||||
_XGETTEXTDOMAIN = '${TARGET.filebase}',
|
||||
XGETTEXTFLAGS = [ ],
|
||||
XGETTEXTCOM = xgettextcom,
|
||||
XGETTEXTCOMSTR = '',
|
||||
XGETTEXTPATH = [ ],
|
||||
XGETTEXTPATHPREFIX = '-D',
|
||||
XGETTEXTPATHSUFFIX = '',
|
||||
XGETTEXTFROM = None,
|
||||
XGETTEXTFROMPREFIX = '-f',
|
||||
XGETTEXTFROMSUFFIX = '',
|
||||
_XGETTEXTPATHFLAGS = xgettextpathflags,
|
||||
_XGETTEXTFROMFLAGS = xgettextfromflags,
|
||||
POTSUFFIX = ['.pot'],
|
||||
POTUPDATE_ALIAS = 'pot-update',
|
||||
XgettextRPaths = RPaths(env)
|
||||
)
|
||||
env.Append( BUILDERS = {
|
||||
'_POTUpdateBuilder' : _POTUpdateBuilder(env)
|
||||
} )
|
||||
env.AddMethod(_POTUpdateBuilderWrapper, 'POTUpdate')
|
||||
env.AlwaysBuild(env.Alias('$POTUPDATE_ALIAS'))
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def exists(env):
|
||||
""" Check, whether the tool exists """
|
||||
from SCons.Tool.GettextCommon import _xgettext_exists
|
||||
try:
|
||||
return _xgettext_exists(env)
|
||||
except:
|
||||
return False
|
||||
#############################################################################
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -1,107 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2015 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.
|
||||
#
|
||||
|
||||
# Portions of the following are derived from the compat.py file in
|
||||
# Twisted, under the following copyright:
|
||||
#
|
||||
# Copyright (c) 2001-2004 Twisted Matrix Laboratories
|
||||
|
||||
__doc__ = """
|
||||
Compatibility idioms for builtins names
|
||||
|
||||
This module adds names to the builtins module for things that we want
|
||||
to use in SCons but which don't show up until later Python versions than
|
||||
the earliest ones we support.
|
||||
|
||||
This module checks for the following builtins names:
|
||||
|
||||
all()
|
||||
any()
|
||||
memoryview()
|
||||
|
||||
Implementations of functions are *NOT* guaranteed to be fully compliant
|
||||
with these functions in later versions of Python. We are only concerned
|
||||
with adding functionality that we actually use in SCons, so be wary
|
||||
if you lift this code for other uses. (That said, making these more
|
||||
nearly the same as later, official versions is still a desirable goal,
|
||||
we just don't need to be obsessive about it.)
|
||||
|
||||
If you're looking at this with pydoc and various names don't show up in
|
||||
the FUNCTIONS or DATA output, that means those names are already built in
|
||||
to this version of Python and we don't need to add them from this module.
|
||||
"""
|
||||
|
||||
__revision__ = "src/engine/SCons/compat/_scons_builtins.py rel_2.4.1:3480:df381b06597b 2015/11/21 07:35:35 bdbaddog"
|
||||
|
||||
import builtins
|
||||
|
||||
try:
|
||||
all
|
||||
except NameError:
|
||||
# Pre-2.5 Python has no all() function.
|
||||
def all(iterable):
|
||||
"""
|
||||
Returns True if all elements of the iterable are true.
|
||||
"""
|
||||
for element in iterable:
|
||||
if not element:
|
||||
return False
|
||||
return True
|
||||
builtins.all = all
|
||||
all = all
|
||||
|
||||
try:
|
||||
any
|
||||
except NameError:
|
||||
# Pre-2.5 Python has no any() function.
|
||||
def any(iterable):
|
||||
"""
|
||||
Returns True if any element of the iterable is true.
|
||||
"""
|
||||
for element in iterable:
|
||||
if element:
|
||||
return True
|
||||
return False
|
||||
builtins.any = any
|
||||
any = any
|
||||
|
||||
try:
|
||||
memoryview
|
||||
except NameError:
|
||||
# Pre-2.7 doesn't have the memoryview() built-in.
|
||||
class memoryview(object):
|
||||
def __init__(self, obj):
|
||||
# wrapping buffer in () keeps the fixer from changing it
|
||||
self.obj = (buffer)(obj)
|
||||
def __getitem__(self, indx):
|
||||
if isinstance(indx, slice):
|
||||
return self.obj[indx.start:indx.stop]
|
||||
else:
|
||||
return self.obj[indx]
|
||||
builtins.memoryview = memoryview
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -1,76 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2015 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.
|
||||
#
|
||||
|
||||
__doc__ = """
|
||||
hashlib backwards-compatibility module for older (pre-2.5) Python versions
|
||||
|
||||
This does not not NOT (repeat, *NOT*) provide complete hashlib
|
||||
functionality. It only wraps the portions of MD5 functionality used
|
||||
by SCons, in an interface that looks like hashlib (or enough for our
|
||||
purposes, anyway). In fact, this module will raise an ImportError if
|
||||
the underlying md5 module isn't available.
|
||||
"""
|
||||
|
||||
__revision__ = "src/engine/SCons/compat/_scons_hashlib.py rel_2.4.1:3480:df381b06597b 2015/11/21 07:35:35 bdbaddog"
|
||||
|
||||
import md5
|
||||
from string import hexdigits
|
||||
|
||||
class md5obj(object):
|
||||
|
||||
md5_module = md5
|
||||
|
||||
def __init__(self, name, string=''):
|
||||
if not name in ('MD5', 'md5'):
|
||||
raise ValueError("unsupported hash type")
|
||||
self.name = 'md5'
|
||||
self.m = self.md5_module.md5()
|
||||
|
||||
def __repr__(self):
|
||||
return '<%s HASH object @ %#x>' % (self.name, id(self))
|
||||
|
||||
def copy(self):
|
||||
import copy
|
||||
result = copy.copy(self)
|
||||
result.m = self.m.copy()
|
||||
return result
|
||||
|
||||
def digest(self):
|
||||
return self.m.digest()
|
||||
|
||||
def update(self, arg):
|
||||
return self.m.update(arg)
|
||||
|
||||
def hexdigest(self):
|
||||
return self.m.hexdigest()
|
||||
|
||||
new = md5obj
|
||||
|
||||
def md5(string=''):
|
||||
return md5obj('md5', string)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -1,256 +0,0 @@
|
|||
# dblite.py module contributed by Ralf W. Grosse-Kunstleve.
|
||||
# Extended for Unicode by Steven Knight.
|
||||
|
||||
import SCons.compat
|
||||
|
||||
import os
|
||||
# compat layer imports "cPickle" for us if it's available.
|
||||
import pickle
|
||||
import shutil
|
||||
import time
|
||||
|
||||
keep_all_files = 00000
|
||||
ignore_corrupt_dbfiles = 0
|
||||
|
||||
def corruption_warning(filename):
|
||||
print "Warning: Discarding corrupt database:", filename
|
||||
|
||||
try: unicode
|
||||
except NameError:
|
||||
def is_string(s):
|
||||
return isinstance(s, str)
|
||||
else:
|
||||
def is_string(s):
|
||||
return type(s) in (str, unicode)
|
||||
|
||||
try:
|
||||
unicode('a')
|
||||
except NameError:
|
||||
def unicode(s): return s
|
||||
|
||||
dblite_suffix = '.dblite'
|
||||
tmp_suffix = '.tmp'
|
||||
|
||||
class dblite(object):
|
||||
|
||||
# Squirrel away references to the functions in various modules
|
||||
# that we'll use when our __del__() method calls our sync() method
|
||||
# during shutdown. We might get destroyed when Python is in the midst
|
||||
# of tearing down the different modules we import in an essentially
|
||||
# arbitrary order, and some of the various modules's global attributes
|
||||
# may already be wiped out from under us.
|
||||
#
|
||||
# See the discussion at:
|
||||
# http://mail.python.org/pipermail/python-bugs-list/2003-March/016877.html
|
||||
|
||||
_open = open
|
||||
_pickle_dump = staticmethod(pickle.dump)
|
||||
_os_chmod = os.chmod
|
||||
try:
|
||||
_os_chown = os.chown
|
||||
except AttributeError:
|
||||
_os_chown = None
|
||||
_os_rename = os.rename
|
||||
_os_unlink = os.unlink
|
||||
_shutil_copyfile = shutil.copyfile
|
||||
_time_time = time.time
|
||||
|
||||
def __init__(self, file_base_name, flag, mode):
|
||||
assert flag in (None, "r", "w", "c", "n")
|
||||
if (flag is None): flag = "r"
|
||||
base, ext = os.path.splitext(file_base_name)
|
||||
if ext == dblite_suffix:
|
||||
# There's already a suffix on the file name, don't add one.
|
||||
self._file_name = file_base_name
|
||||
self._tmp_name = base + tmp_suffix
|
||||
else:
|
||||
self._file_name = file_base_name + dblite_suffix
|
||||
self._tmp_name = file_base_name + tmp_suffix
|
||||
self._flag = flag
|
||||
self._mode = mode
|
||||
self._dict = {}
|
||||
self._needs_sync = 00000
|
||||
if self._os_chown is not None and (os.geteuid()==0 or os.getuid()==0):
|
||||
# running as root; chown back to current owner/group when done
|
||||
try:
|
||||
statinfo = os.stat(self._file_name)
|
||||
self._chown_to = statinfo.st_uid
|
||||
self._chgrp_to = statinfo.st_gid
|
||||
except OSError, e:
|
||||
# db file doesn't exist yet.
|
||||
# Check os.environ for SUDO_UID, use if set
|
||||
self._chown_to = int(os.environ.get('SUDO_UID', -1))
|
||||
self._chgrp_to = int(os.environ.get('SUDO_GID', -1))
|
||||
else:
|
||||
self._chown_to = -1 # don't chown
|
||||
self._chgrp_to = -1 # don't chgrp
|
||||
if (self._flag == "n"):
|
||||
self._open(self._file_name, "wb", self._mode)
|
||||
else:
|
||||
try:
|
||||
f = self._open(self._file_name, "rb")
|
||||
except IOError, e:
|
||||
if (self._flag != "c"):
|
||||
raise e
|
||||
self._open(self._file_name, "wb", self._mode)
|
||||
else:
|
||||
p = f.read()
|
||||
if (len(p) > 0):
|
||||
try:
|
||||
self._dict = pickle.loads(p)
|
||||
except (pickle.UnpicklingError, EOFError, KeyError):
|
||||
# Note how we catch KeyErrors too here, which might happen
|
||||
# when we don't have cPickle available (default pickle
|
||||
# throws it).
|
||||
if (ignore_corrupt_dbfiles == 0): raise
|
||||
if (ignore_corrupt_dbfiles == 1):
|
||||
corruption_warning(self._file_name)
|
||||
|
||||
def close(self):
|
||||
if (self._needs_sync):
|
||||
self.sync()
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
|
||||
def sync(self):
|
||||
self._check_writable()
|
||||
f = self._open(self._tmp_name, "wb", self._mode)
|
||||
self._pickle_dump(self._dict, f, 1)
|
||||
f.close()
|
||||
# Windows doesn't allow renaming if the file exists, so unlink
|
||||
# it first, chmod'ing it to make sure we can do so. On UNIX, we
|
||||
# may not be able to chmod the file if it's owned by someone else
|
||||
# (e.g. from a previous run as root). We should still be able to
|
||||
# unlink() the file if the directory's writable, though, so ignore
|
||||
# any OSError exception thrown by the chmod() call.
|
||||
try: self._os_chmod(self._file_name, 0777)
|
||||
except OSError: pass
|
||||
self._os_unlink(self._file_name)
|
||||
self._os_rename(self._tmp_name, self._file_name)
|
||||
if self._os_chown is not None and self._chown_to > 0: # don't chown to root or -1
|
||||
try:
|
||||
self._os_chown(self._file_name, self._chown_to, self._chgrp_to)
|
||||
except OSError:
|
||||
pass
|
||||
self._needs_sync = 00000
|
||||
if (keep_all_files):
|
||||
self._shutil_copyfile(
|
||||
self._file_name,
|
||||
self._file_name + "_" + str(int(self._time_time())))
|
||||
|
||||
def _check_writable(self):
|
||||
if (self._flag == "r"):
|
||||
raise IOError("Read-only database: %s" % self._file_name)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._dict[key]
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self._check_writable()
|
||||
if (not is_string(key)):
|
||||
raise TypeError("key `%s' must be a string but is %s" % (key, type(key)))
|
||||
if (not is_string(value)):
|
||||
raise TypeError("value `%s' must be a string but is %s" % (value, type(value)))
|
||||
self._dict[key] = value
|
||||
self._needs_sync = 0001
|
||||
|
||||
def keys(self):
|
||||
return list(self._dict.keys())
|
||||
|
||||
def has_key(self, key):
|
||||
return key in self._dict
|
||||
|
||||
def __contains__(self, key):
|
||||
return key in self._dict
|
||||
|
||||
def iterkeys(self):
|
||||
# Wrapping name in () prevents fixer from "fixing" this
|
||||
return (self._dict.iterkeys)()
|
||||
|
||||
__iter__ = iterkeys
|
||||
|
||||
def __len__(self):
|
||||
return len(self._dict)
|
||||
|
||||
def open(file, flag=None, mode=0666):
|
||||
return dblite(file, flag, mode)
|
||||
|
||||
def _exercise():
|
||||
db = open("tmp", "n")
|
||||
assert len(db) == 0
|
||||
db["foo"] = "bar"
|
||||
assert db["foo"] == "bar"
|
||||
db[unicode("ufoo")] = unicode("ubar")
|
||||
assert db[unicode("ufoo")] == unicode("ubar")
|
||||
db.sync()
|
||||
db = open("tmp", "c")
|
||||
assert len(db) == 2, len(db)
|
||||
assert db["foo"] == "bar"
|
||||
db["bar"] = "foo"
|
||||
assert db["bar"] == "foo"
|
||||
db[unicode("ubar")] = unicode("ufoo")
|
||||
assert db[unicode("ubar")] == unicode("ufoo")
|
||||
db.sync()
|
||||
db = open("tmp", "r")
|
||||
assert len(db) == 4, len(db)
|
||||
assert db["foo"] == "bar"
|
||||
assert db["bar"] == "foo"
|
||||
assert db[unicode("ufoo")] == unicode("ubar")
|
||||
assert db[unicode("ubar")] == unicode("ufoo")
|
||||
try:
|
||||
db.sync()
|
||||
except IOError, e:
|
||||
assert str(e) == "Read-only database: tmp.dblite"
|
||||
else:
|
||||
raise RuntimeError("IOError expected.")
|
||||
db = open("tmp", "w")
|
||||
assert len(db) == 4
|
||||
db["ping"] = "pong"
|
||||
db.sync()
|
||||
try:
|
||||
db[(1,2)] = "tuple"
|
||||
except TypeError, e:
|
||||
assert str(e) == "key `(1, 2)' must be a string but is <type 'tuple'>", str(e)
|
||||
else:
|
||||
raise RuntimeError("TypeError exception expected")
|
||||
try:
|
||||
db["list"] = [1,2]
|
||||
except TypeError, e:
|
||||
assert str(e) == "value `[1, 2]' must be a string but is <type 'list'>", str(e)
|
||||
else:
|
||||
raise RuntimeError("TypeError exception expected")
|
||||
db = open("tmp", "r")
|
||||
assert len(db) == 5
|
||||
db = open("tmp", "n")
|
||||
assert len(db) == 0
|
||||
dblite._open("tmp.dblite", "w")
|
||||
db = open("tmp", "r")
|
||||
dblite._open("tmp.dblite", "w").write("x")
|
||||
try:
|
||||
db = open("tmp", "r")
|
||||
except pickle.UnpicklingError:
|
||||
pass
|
||||
else:
|
||||
raise RuntimeError("pickle exception expected.")
|
||||
global ignore_corrupt_dbfiles
|
||||
ignore_corrupt_dbfiles = 2
|
||||
db = open("tmp", "r")
|
||||
assert len(db) == 0
|
||||
os.unlink("tmp.dblite")
|
||||
try:
|
||||
db = open("tmp", "w")
|
||||
except IOError, e:
|
||||
assert str(e) == "[Errno 2] No such file or directory: 'tmp.dblite'", str(e)
|
||||
else:
|
||||
raise RuntimeError("IOError expected.")
|
||||
print "OK"
|
||||
|
||||
if (__name__ == "__main__"):
|
||||
_exercise()
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -60,6 +60,7 @@ this module:
|
|||
get_presig()
|
||||
Fetches the "contents" of a subclass for signature calculation.
|
||||
The varlist is added to this to produce the Action's contents.
|
||||
TODO(?): Change this to always return ascii/bytes and not unicode (or py3 strings)
|
||||
|
||||
strfunction()
|
||||
Returns a substituted string representation of the Action.
|
||||
|
@ -76,7 +77,7 @@ way for wrapping up the functions.
|
|||
|
||||
"""
|
||||
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -97,15 +98,15 @@ way for wrapping up the functions.
|
|||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
__revision__ = "src/engine/SCons/Action.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Action.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import dis
|
||||
import os
|
||||
# compat layer imports "cPickle" for us if it's available.
|
||||
import pickle
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
import itertools
|
||||
import inspect
|
||||
|
||||
import SCons.Debug
|
||||
from SCons.Debug import logInstanceCreation
|
||||
|
@ -124,37 +125,25 @@ print_actions = 1
|
|||
execute_actions = 1
|
||||
print_actions_presub = 0
|
||||
|
||||
# Use pickle protocol 1 when pickling functions for signature
|
||||
# otherwise python3 and python2 will yield different pickles
|
||||
# for the same object.
|
||||
# This is due to default being 1 for python 2.7, and 3 for 3.x
|
||||
# TODO: We can roll this forward to 2 (if it has value), but not
|
||||
# before a deprecation cycle as the sconsigns will change
|
||||
ACTION_SIGNATURE_PICKLE_PROTOCOL = 1
|
||||
|
||||
|
||||
def rfile(n):
|
||||
try:
|
||||
return n.rfile()
|
||||
except AttributeError:
|
||||
return n
|
||||
|
||||
|
||||
def default_exitstatfunc(s):
|
||||
return s
|
||||
|
||||
try:
|
||||
SET_LINENO = dis.SET_LINENO
|
||||
HAVE_ARGUMENT = dis.HAVE_ARGUMENT
|
||||
except AttributeError:
|
||||
remove_set_lineno_codes = lambda x: x
|
||||
else:
|
||||
def remove_set_lineno_codes(code):
|
||||
result = []
|
||||
n = len(code)
|
||||
i = 0
|
||||
while i < n:
|
||||
c = code[i]
|
||||
op = ord(c)
|
||||
if op >= HAVE_ARGUMENT:
|
||||
if op != SET_LINENO:
|
||||
result.append(code[i:i+3])
|
||||
i = i+3
|
||||
else:
|
||||
result.append(c)
|
||||
i = i+1
|
||||
return ''.join(result)
|
||||
|
||||
strip_quotes = re.compile('^[\'"](.*)[\'"]$')
|
||||
|
||||
|
||||
|
@ -163,12 +152,12 @@ def _callable_contents(obj):
|
|||
"""
|
||||
try:
|
||||
# Test if obj is a method.
|
||||
return _function_contents(obj.im_func)
|
||||
return _function_contents(obj.__func__)
|
||||
|
||||
except AttributeError:
|
||||
try:
|
||||
# Test if obj is a callable object.
|
||||
return _function_contents(obj.__call__.im_func)
|
||||
return _function_contents(obj.__call__.__func__)
|
||||
|
||||
except AttributeError:
|
||||
try:
|
||||
|
@ -176,8 +165,8 @@ def _callable_contents(obj):
|
|||
return _code_contents(obj)
|
||||
|
||||
except AttributeError:
|
||||
# Test if obj is a function object.
|
||||
return _function_contents(obj)
|
||||
# Test if obj is a function object.
|
||||
return _function_contents(obj)
|
||||
|
||||
|
||||
def _object_contents(obj):
|
||||
|
@ -188,12 +177,12 @@ def _object_contents(obj):
|
|||
"""
|
||||
try:
|
||||
# Test if obj is a method.
|
||||
return _function_contents(obj.im_func)
|
||||
return _function_contents(obj.__func__)
|
||||
|
||||
except AttributeError:
|
||||
try:
|
||||
# Test if obj is a callable object.
|
||||
return _function_contents(obj.__call__.im_func)
|
||||
return _function_contents(obj.__call__.__func__)
|
||||
|
||||
except AttributeError:
|
||||
try:
|
||||
|
@ -205,20 +194,23 @@ def _object_contents(obj):
|
|||
# Test if obj is a function object.
|
||||
return _function_contents(obj)
|
||||
|
||||
except AttributeError:
|
||||
# Should be a pickable Python object.
|
||||
except AttributeError as ae:
|
||||
# Should be a pickle-able Python object.
|
||||
try:
|
||||
return pickle.dumps(obj)
|
||||
except (pickle.PicklingError, TypeError):
|
||||
return _object_instance_content(obj)
|
||||
# pickling an Action instance or object doesn't yield a stable
|
||||
# content as instance property may be dumped in different orders
|
||||
# return pickle.dumps(obj, ACTION_SIGNATURE_PICKLE_PROTOCOL)
|
||||
except (pickle.PicklingError, TypeError, AttributeError) as ex:
|
||||
# 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)
|
||||
return bytearray(repr(obj), 'utf-8')
|
||||
|
||||
|
||||
def _code_contents(code):
|
||||
def _code_contents(code, docstring=None):
|
||||
"""Return the signature contents of a code object.
|
||||
|
||||
By providing direct access to the code object of the
|
||||
|
@ -228,61 +220,173 @@ def _code_contents(code):
|
|||
number indications in the compiled byte code. Boo!
|
||||
So we remove the line number byte codes to prevent
|
||||
recompilations from moving a Python function.
|
||||
|
||||
See:
|
||||
- https://docs.python.org/2/library/inspect.html
|
||||
- http://python-reference.readthedocs.io/en/latest/docs/code/index.html
|
||||
|
||||
For info on what each co\_ variable provides
|
||||
|
||||
The signature is as follows (should be byte/chars):
|
||||
co_argcount, len(co_varnames), len(co_cellvars), len(co_freevars),
|
||||
( comma separated signature for each object in co_consts ),
|
||||
( comma separated signature for each object in co_names ),
|
||||
( The bytecode with line number bytecodes removed from co_code )
|
||||
|
||||
co_argcount - Returns the number of positional arguments (including arguments with default values).
|
||||
co_varnames - Returns a tuple containing the names of the local variables (starting with the argument names).
|
||||
co_cellvars - Returns a tuple containing the names of local variables that are referenced by nested functions.
|
||||
co_freevars - Returns a tuple containing the names of free variables. (?)
|
||||
co_consts - Returns a tuple containing the literals used by the bytecode.
|
||||
co_names - Returns a tuple containing the names used by the bytecode.
|
||||
co_code - Returns a string representing the sequence of bytecode instructions.
|
||||
|
||||
"""
|
||||
|
||||
contents = []
|
||||
# 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)))
|
||||
contents.append(",%s,%s" % (len(code.co_cellvars), len(code.co_freevars)))
|
||||
contents = bytearray("{}, {}".format(code.co_argcount, len(code.co_varnames)), 'utf-8')
|
||||
|
||||
contents.extend(b", ")
|
||||
contents.extend(bytearray(str(len(code.co_cellvars)), 'utf-8'))
|
||||
contents.extend(b", ")
|
||||
contents.extend(bytearray(str(len(code.co_freevars)), 'utf-8'))
|
||||
|
||||
# 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(',(' + ','.join(map(_object_contents,code.co_consts[1:])) + ')')
|
||||
|
||||
z = [_object_contents(cc) for cc in code.co_consts[1:]]
|
||||
contents.extend(b',(')
|
||||
contents.extend(bytearray(',', 'utf-8').join(z))
|
||||
contents.extend(b')')
|
||||
|
||||
# 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(',(' + ','.join(map(_object_contents,code.co_names)) + ')')
|
||||
|
||||
z= [bytearray(_object_contents(cc)) for cc in code.co_names]
|
||||
contents.extend(b',(')
|
||||
contents.extend(bytearray(',','utf-8').join(z))
|
||||
contents.extend(b')')
|
||||
|
||||
# The code contents depends on its actual code!!!
|
||||
contents.append(',(' + str(remove_set_lineno_codes(code.co_code)) + ')')
|
||||
contents.extend(b',(')
|
||||
contents.extend(code.co_code)
|
||||
contents.extend(b')')
|
||||
|
||||
return ''.join(contents)
|
||||
return contents
|
||||
|
||||
|
||||
def _function_contents(func):
|
||||
"""Return the signature contents of a function."""
|
||||
"""
|
||||
The signature is as follows (should be byte/chars):
|
||||
< _code_contents (see above) from func.__code__ >
|
||||
,( comma separated _object_contents for function argument defaults)
|
||||
,( comma separated _object_contents for any closure contents )
|
||||
|
||||
contents = [_code_contents(func.func_code)]
|
||||
|
||||
See also: https://docs.python.org/3/reference/datamodel.html
|
||||
- func.__code__ - The code object representing the compiled function body.
|
||||
- func.__defaults__ - A tuple containing default argument values for those arguments that have defaults, or None if no arguments have a default value
|
||||
- func.__closure__ - None or a tuple of cells that contain bindings for the function's free variables.
|
||||
|
||||
:Returns:
|
||||
Signature contents of a function. (in bytes)
|
||||
"""
|
||||
|
||||
contents = [_code_contents(func.__code__, func.__doc__)]
|
||||
|
||||
# The function contents depends on the value of defaults arguments
|
||||
if func.func_defaults:
|
||||
contents.append(',(' + ','.join(map(_object_contents,func.func_defaults)) + ')')
|
||||
if func.__defaults__:
|
||||
|
||||
function_defaults_contents = [_object_contents(cc) for cc in func.__defaults__]
|
||||
|
||||
defaults = bytearray(b',(')
|
||||
defaults.extend(bytearray(b',').join(function_defaults_contents))
|
||||
defaults.extend(b')')
|
||||
|
||||
contents.append(defaults)
|
||||
else:
|
||||
contents.append(',()')
|
||||
contents.append(b',()')
|
||||
|
||||
# The function contents depends on the closure captured cell values.
|
||||
closure = func.func_closure or []
|
||||
closure = func.__closure__ or []
|
||||
|
||||
#xxx = [_object_contents(x.cell_contents) for x in closure]
|
||||
try:
|
||||
xxx = [_object_contents(x.cell_contents) for x in closure]
|
||||
closure_contents = [_object_contents(x.cell_contents) for x in closure]
|
||||
except AttributeError:
|
||||
xxx = []
|
||||
contents.append(',(' + ','.join(xxx) + ')')
|
||||
closure_contents = []
|
||||
|
||||
return ''.join(contents)
|
||||
contents.append(b',(')
|
||||
contents.append(bytearray(b',').join(closure_contents))
|
||||
contents.append(b')')
|
||||
|
||||
retval = bytearray(b'').join(contents)
|
||||
return retval
|
||||
|
||||
|
||||
def _object_instance_content(obj):
|
||||
"""
|
||||
Returns consistant content for a action class or an instance thereof
|
||||
|
||||
:Parameters:
|
||||
- `obj` Should be either and action class or an instance thereof
|
||||
|
||||
:Returns:
|
||||
bytearray or bytes representing the obj suitable for generating a signature from.
|
||||
"""
|
||||
retval = bytearray()
|
||||
|
||||
if obj is None:
|
||||
return b'N.'
|
||||
|
||||
if isinstance(obj, SCons.Util.BaseStringTypes):
|
||||
return SCons.Util.to_bytes(obj)
|
||||
|
||||
inst_class = obj.__class__
|
||||
inst_class_name = bytearray(obj.__class__.__name__,'utf-8')
|
||||
inst_class_module = bytearray(obj.__class__.__module__,'utf-8')
|
||||
inst_class_hierarchy = bytearray(repr(inspect.getclasstree([obj.__class__,])),'utf-8')
|
||||
# print("ICH:%s : %s"%(inst_class_hierarchy, repr(obj)))
|
||||
|
||||
properties = [(p, getattr(obj, p, "None")) for p in dir(obj) if not (p[:2] == '__' or inspect.ismethod(getattr(obj, p)) or inspect.isbuiltin(getattr(obj,p))) ]
|
||||
properties.sort()
|
||||
properties_str = ','.join(["%s=%s"%(p[0],p[1]) for p in properties])
|
||||
properties_bytes = bytearray(properties_str,'utf-8')
|
||||
|
||||
methods = [p for p in dir(obj) if inspect.ismethod(getattr(obj, p))]
|
||||
methods.sort()
|
||||
|
||||
method_contents = []
|
||||
for m in methods:
|
||||
# print("Method:%s"%m)
|
||||
v = _function_contents(getattr(obj, m))
|
||||
# print("[%s->]V:%s [%s]"%(m,v,type(v)))
|
||||
method_contents.append(v)
|
||||
|
||||
retval = bytearray(b'{')
|
||||
retval.extend(inst_class_name)
|
||||
retval.extend(b":")
|
||||
retval.extend(inst_class_module)
|
||||
retval.extend(b'}[[')
|
||||
retval.extend(inst_class_hierarchy)
|
||||
retval.extend(b']]{{')
|
||||
retval.extend(bytearray(b",").join(method_contents))
|
||||
retval.extend(b"}}{{{")
|
||||
retval.extend(properties_bytes)
|
||||
retval.extend(b'}}}')
|
||||
return retval
|
||||
|
||||
# print("class :%s"%inst_class)
|
||||
# print("class_name :%s"%inst_class_name)
|
||||
# print("class_module :%s"%inst_class_module)
|
||||
# print("Class hier :\n%s"%pp.pformat(inst_class_hierarchy))
|
||||
# print("Inst Properties:\n%s"%pp.pformat(properties))
|
||||
# print("Inst Methods :\n%s"%pp.pformat(methods))
|
||||
|
||||
def _actionAppend(act1, act2):
|
||||
# This function knows how to slap two actions together.
|
||||
|
@ -305,6 +409,7 @@ def _actionAppend(act1, act2):
|
|||
else:
|
||||
return ListAction([ a1, a2 ])
|
||||
|
||||
|
||||
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.
|
||||
|
@ -332,6 +437,7 @@ def _do_create_keywords(args, kw):
|
|||
raise SCons.Errors.UserError(
|
||||
'Cannot have both strfunction and cmdstr args to Action()')
|
||||
|
||||
|
||||
def _do_create_action(act, kw):
|
||||
"""This is the actual "implementation" for the
|
||||
Action factory method, below. This handles the
|
||||
|
@ -362,7 +468,7 @@ def _do_create_action(act, kw):
|
|||
# The list of string commands may include a LazyAction, so we
|
||||
# reprocess them via _do_create_list_action.
|
||||
return _do_create_list_action(commands, kw)
|
||||
|
||||
|
||||
if is_List(act):
|
||||
return CommandAction(act, **kw)
|
||||
|
||||
|
@ -384,6 +490,7 @@ def _do_create_action(act, kw):
|
|||
# Else fail silently (???)
|
||||
return None
|
||||
|
||||
|
||||
def _do_create_list_action(act, kw):
|
||||
"""A factory for list actions. Convert the input list into Actions
|
||||
and then wrap them in a ListAction."""
|
||||
|
@ -398,6 +505,7 @@ def _do_create_list_action(act, kw):
|
|||
else:
|
||||
return ListAction(acts)
|
||||
|
||||
|
||||
def Action(act, *args, **kw):
|
||||
"""A factory for action objects."""
|
||||
# Really simple: the _do_create_* routines do the heavy lifting.
|
||||
|
@ -406,13 +514,14 @@ def Action(act, *args, **kw):
|
|||
return _do_create_list_action(act, kw)
|
||||
return _do_create_action(act, kw)
|
||||
|
||||
|
||||
class ActionBase(object):
|
||||
"""Base class for all types of action objects that can be held by
|
||||
other objects (Builders, Executors, etc.) This provides the
|
||||
common methods for manipulating and combining those actions."""
|
||||
|
||||
def __cmp__(self, other):
|
||||
return cmp(self.__dict__, other)
|
||||
def __eq__(self, other):
|
||||
return self.__dict__ == other
|
||||
|
||||
def no_batch_key(self, env, target, source):
|
||||
return None
|
||||
|
@ -423,7 +532,18 @@ class ActionBase(object):
|
|||
return str(self)
|
||||
|
||||
def get_contents(self, target, source, env):
|
||||
result = [ self.get_presig(target, source, env) ]
|
||||
result = self.get_presig(target, source, env)
|
||||
|
||||
if not isinstance(result,(bytes, bytearray)):
|
||||
result = bytearray("",'utf-8').join([ SCons.Util.to_bytes(r) for r in result ])
|
||||
else:
|
||||
# Make a copy and put in bytearray, without this the contents returned by get_presig
|
||||
# can be changed by the logic below, appending with each call and causing very
|
||||
# hard to track down issues...
|
||||
result = bytearray(result)
|
||||
|
||||
# At this point everything should be a bytearray
|
||||
|
||||
# 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.
|
||||
|
@ -431,8 +551,18 @@ class ActionBase(object):
|
|||
if is_String(vl): vl = (vl,)
|
||||
for v in vl:
|
||||
# do the subst this way to ignore $(...$) parts:
|
||||
result.append(env.subst_target_source('${'+v+'}', SCons.Subst.SUBST_SIG, target, source))
|
||||
return ''.join(result)
|
||||
if isinstance(result, bytearray):
|
||||
result.extend(SCons.Util.to_bytes(env.subst_target_source('${'+v+'}', SCons.Subst.SUBST_SIG, target, source)))
|
||||
else:
|
||||
raise Exception("WE SHOULD NEVER GET HERE result should be bytearray not:%s"%type(result))
|
||||
# result.append(SCons.Util.to_bytes(env.subst_target_source('${'+v+'}', SCons.Subst.SUBST_SIG, target, source)))
|
||||
|
||||
|
||||
if isinstance(result, (bytes,bytearray)):
|
||||
return result
|
||||
else:
|
||||
raise Exception("WE SHOULD NEVER GET HERE - #2 result should be bytearray not:%s" % type(result))
|
||||
# return b''.join(result)
|
||||
|
||||
def __add__(self, other):
|
||||
return _actionAppend(self, other)
|
||||
|
@ -462,6 +592,7 @@ class ActionBase(object):
|
|||
"""
|
||||
return self.targets
|
||||
|
||||
|
||||
class _ActionAction(ActionBase):
|
||||
"""Base class for actions that create output objects."""
|
||||
def __init__(self, cmdstr=_null, strfunction=_null, varlist=(),
|
||||
|
@ -495,16 +626,18 @@ class _ActionAction(ActionBase):
|
|||
SCons.Util.AddMethod(self, batch_key, 'batch_key')
|
||||
|
||||
def print_cmd_line(self, s, target, source, env):
|
||||
# In python 3, and in some of our tests, sys.stdout is
|
||||
# a String io object, and it takes unicode strings only
|
||||
# In other cases it's a regular Python 2.x file object
|
||||
# which takes strings (bytes), and if you pass those a
|
||||
# unicode object they try to decode with 'ascii' codec
|
||||
# which fails if the cmd line has any hi-bit-set chars.
|
||||
# This code assumes s is a regular string, but should
|
||||
# work if it's unicode too.
|
||||
"""
|
||||
In python 3, and in some of our tests, sys.stdout is
|
||||
a String io object, and it takes unicode strings only
|
||||
In other cases it's a regular Python 2.x file object
|
||||
which takes strings (bytes), and if you pass those a
|
||||
unicode object they try to decode with 'ascii' codec
|
||||
which fails if the cmd line has any hi-bit-set chars.
|
||||
This code assumes s is a regular string, but should
|
||||
work if it's unicode too.
|
||||
"""
|
||||
try:
|
||||
sys.stdout.write(unicode(s + "\n"))
|
||||
sys.stdout.write(s + u"\n")
|
||||
except UnicodeDecodeError:
|
||||
sys.stdout.write(s + "\n")
|
||||
|
||||
|
@ -601,13 +734,17 @@ def _string_from_cmd_list(cmd_list):
|
|||
cl.append(arg)
|
||||
return ' '.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):
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
global default_ENV
|
||||
try:
|
||||
return env['ENV']
|
||||
|
@ -622,12 +759,15 @@ def get_default_ENV(env):
|
|||
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(scons_env, cmd, error = 'ignore', **kw):
|
||||
"""Do common setup for a subprocess.Popen() call"""
|
||||
"""Do common setup for a subprocess.Popen() call
|
||||
|
||||
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.
|
||||
"""
|
||||
# allow std{in,out,err} to be "'devnull'"
|
||||
io = kw.get('stdin')
|
||||
if is_String(io) and io == 'devnull':
|
||||
|
@ -664,12 +804,12 @@ def _subproc(scons_env, cmd, error = 'ignore', **kw):
|
|||
|
||||
try:
|
||||
return subprocess.Popen(cmd, **kw)
|
||||
except EnvironmentError, e:
|
||||
except EnvironmentError as e:
|
||||
if error == 'raise': raise
|
||||
# return a dummy Popen instance that only returns error
|
||||
class dummyPopen(object):
|
||||
def __init__(self, e): self.exception = e
|
||||
def communicate(self,input=None): return ('','')
|
||||
def communicate(self, input=None): return ('', '')
|
||||
def wait(self): return -self.exception.errno
|
||||
stdin = None
|
||||
class f(object):
|
||||
|
@ -679,6 +819,7 @@ def _subproc(scons_env, cmd, error = 'ignore', **kw):
|
|||
stdout = stderr = f()
|
||||
return dummyPopen(e)
|
||||
|
||||
|
||||
class CommandAction(_ActionAction):
|
||||
"""Class for command-execution actions."""
|
||||
def __init__(self, cmd, **kw):
|
||||
|
@ -695,7 +836,7 @@ class CommandAction(_ActionAction):
|
|||
|
||||
_ActionAction.__init__(self, **kw)
|
||||
if is_List(cmd):
|
||||
if list(filter(is_List, cmd)):
|
||||
if [c for c in cmd if is_List(c)]:
|
||||
raise TypeError("CommandAction should be given only " \
|
||||
"a single command")
|
||||
self.cmd_list = cmd
|
||||
|
@ -845,6 +986,7 @@ class CommandAction(_ActionAction):
|
|||
res.append(env.fs.File(d))
|
||||
return res
|
||||
|
||||
|
||||
class CommandGeneratorAction(ActionBase):
|
||||
"""Class for command-generator actions."""
|
||||
def __init__(self, generator, kw):
|
||||
|
@ -916,25 +1058,25 @@ class CommandGeneratorAction(ActionBase):
|
|||
return self._generate(None, None, env, 1, executor).get_targets(env, executor)
|
||||
|
||||
|
||||
|
||||
# A LazyAction is a kind of hybrid generator and command action for
|
||||
# strings of the form "$VAR". These strings normally expand to other
|
||||
# strings (think "$CCCOM" to "$CC -c -o $TARGET $SOURCE"), but we also
|
||||
# want to be able to replace them with functions in the construction
|
||||
# environment. Consequently, we want lazy evaluation and creation of
|
||||
# an Action in the case of the function, but that's overkill in the more
|
||||
# normal case of expansion to other strings.
|
||||
#
|
||||
# So we do this with a subclass that's both a generator *and*
|
||||
# a command action. The overridden methods all do a quick check
|
||||
# of the construction variable, and if it's a string we just call
|
||||
# the corresponding CommandAction method to do the heavy lifting.
|
||||
# If not, then we call the same-named CommandGeneratorAction method.
|
||||
# The CommandGeneratorAction methods work by using the overridden
|
||||
# _generate() method, that is, our own way of handling "generation" of
|
||||
# an action based on what's in the construction variable.
|
||||
|
||||
class LazyAction(CommandGeneratorAction, CommandAction):
|
||||
"""
|
||||
A LazyAction is a kind of hybrid generator and command action for
|
||||
strings of the form "$VAR". These strings normally expand to other
|
||||
strings (think "$CCCOM" to "$CC -c -o $TARGET $SOURCE"), but we also
|
||||
want to be able to replace them with functions in the construction
|
||||
environment. Consequently, we want lazy evaluation and creation of
|
||||
an Action in the case of the function, but that's overkill in the more
|
||||
normal case of expansion to other strings.
|
||||
|
||||
So we do this with a subclass that's both a generator *and*
|
||||
a command action. The overridden methods all do a quick check
|
||||
of the construction variable, and if it's a string we just call
|
||||
the corresponding CommandAction method to do the heavy lifting.
|
||||
If not, then we call the same-named CommandGeneratorAction method.
|
||||
The CommandGeneratorAction methods work by using the overridden
|
||||
_generate() method, that is, our own way of handling "generation" of
|
||||
an action based on what's in the construction variable.
|
||||
"""
|
||||
|
||||
def __init__(self, var, kw):
|
||||
if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.LazyAction')
|
||||
|
@ -1013,6 +1155,7 @@ class FunctionAction(_ActionAction):
|
|||
c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
||||
if c:
|
||||
return c
|
||||
|
||||
def array(a):
|
||||
def quote(s):
|
||||
try:
|
||||
|
@ -1052,11 +1195,11 @@ class FunctionAction(_ActionAction):
|
|||
rsources = list(map(rfile, source))
|
||||
try:
|
||||
result = self.execfunction(target=target, source=rsources, env=env)
|
||||
except KeyboardInterrupt, e:
|
||||
except KeyboardInterrupt as e:
|
||||
raise
|
||||
except SystemExit, e:
|
||||
except SystemExit as e:
|
||||
raise
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
result = e
|
||||
exc_info = sys.exc_info()
|
||||
|
||||
|
@ -1086,7 +1229,6 @@ class FunctionAction(_ActionAction):
|
|||
# more information about this issue.
|
||||
del exc_info
|
||||
|
||||
|
||||
def get_presig(self, target, source, env):
|
||||
"""Return the signature contents of this callable action."""
|
||||
try:
|
||||
|
@ -1126,7 +1268,7 @@ class ListAction(ActionBase):
|
|||
|
||||
Simple concatenation of the signatures of the elements.
|
||||
"""
|
||||
return "".join([x.get_contents(target, source, env) for x in self.list])
|
||||
return b"".join([bytes(x.get_contents(target, source, env)) for x in self.list])
|
||||
|
||||
def __call__(self, target, source, env, exitstatfunc=_null, presub=_null,
|
||||
show=_null, execute=_null, chdir=_null, executor=None):
|
||||
|
@ -1153,6 +1295,7 @@ class ListAction(ActionBase):
|
|||
result[var] = True
|
||||
return list(result.keys())
|
||||
|
||||
|
||||
class ActionCaller(object):
|
||||
"""A class for delaying calling an Action function with specific
|
||||
(positional and keyword) arguments until the Action is actually
|
||||
|
@ -1171,16 +1314,16 @@ class ActionCaller(object):
|
|||
actfunc = self.parent.actfunc
|
||||
try:
|
||||
# "self.actfunc" is a function.
|
||||
contents = str(actfunc.func_code.co_code)
|
||||
contents = actfunc.__code__.co_code
|
||||
except AttributeError:
|
||||
# "self.actfunc" is a callable object.
|
||||
try:
|
||||
contents = str(actfunc.__call__.im_func.func_code.co_code)
|
||||
contents = actfunc.__call__.__func__.__code__.co_code
|
||||
except AttributeError:
|
||||
# No __call__() method, so it might be a builtin
|
||||
# or something like that. Do the best we can.
|
||||
contents = str(actfunc)
|
||||
contents = remove_set_lineno_codes(contents)
|
||||
contents = repr(actfunc)
|
||||
|
||||
return contents
|
||||
|
||||
def subst(self, s, target, source, env):
|
||||
|
@ -1206,7 +1349,7 @@ class ActionCaller(object):
|
|||
|
||||
def subst_kw(self, target, source, env):
|
||||
kw = {}
|
||||
for key in self.kw.keys():
|
||||
for key in list(self.kw.keys()):
|
||||
kw[key] = self.subst(self.kw[key], target, source, env)
|
||||
return kw
|
||||
|
||||
|
@ -1223,6 +1366,7 @@ class ActionCaller(object):
|
|||
def __str__(self):
|
||||
return self.parent.strfunc(*self.args, **self.kw)
|
||||
|
||||
|
||||
class ActionFactory(object):
|
||||
"""A factory class that will wrap up an arbitrary function
|
||||
as an SCons-executable Action object.
|
|
@ -1,4 +1,5 @@
|
|||
"""SCons.Builder
|
||||
"""
|
||||
SCons.Builder
|
||||
|
||||
Builder object subsystem.
|
||||
|
||||
|
@ -31,7 +32,7 @@ There is also a proxy that looks like a Builder:
|
|||
Builders and their proxies have the following public interface methods
|
||||
used by other modules:
|
||||
|
||||
__call__()
|
||||
- __call__()
|
||||
THE public interface. Calling a Builder object (with the
|
||||
use of internal helper methods) sets up the target and source
|
||||
dependencies, appropriate mapping to a specific action, and the
|
||||
|
@ -39,12 +40,12 @@ used by other modules:
|
|||
variable. This also takes care of warning about possible mistakes
|
||||
in keyword arguments.
|
||||
|
||||
add_emitter()
|
||||
- add_emitter()
|
||||
Adds an emitter for a specific file suffix, used by some Tool
|
||||
modules to specify that (for example) a yacc invocation on a .y
|
||||
can create a .h *and* a .c file.
|
||||
|
||||
add_action()
|
||||
- add_action()
|
||||
Adds an action for a specific file suffix, heavily used by
|
||||
Tool modules to add their specific action(s) for turning
|
||||
a source file into an object file to the global static
|
||||
|
@ -52,23 +53,23 @@ used by other modules:
|
|||
|
||||
There are the following methods for internal use within this module:
|
||||
|
||||
_execute()
|
||||
- _execute()
|
||||
The internal method that handles the heavily lifting when a
|
||||
Builder is called. This is used so that the __call__() methods
|
||||
can set up warning about possible mistakes in keyword-argument
|
||||
overrides, and *then* execute all of the steps necessary so that
|
||||
the warnings only occur once.
|
||||
|
||||
get_name()
|
||||
- get_name()
|
||||
Returns the Builder's name within a specific Environment,
|
||||
primarily used to try to return helpful information in error
|
||||
messages.
|
||||
|
||||
adjust_suffix()
|
||||
get_prefix()
|
||||
get_suffix()
|
||||
get_src_suffix()
|
||||
set_src_suffix()
|
||||
- adjust_suffix()
|
||||
- get_prefix()
|
||||
- get_suffix()
|
||||
- get_src_suffix()
|
||||
- set_src_suffix()
|
||||
Miscellaneous stuff for handling the prefix and suffix
|
||||
manipulation we use in turning source file names into target
|
||||
file names.
|
||||
|
@ -76,7 +77,7 @@ There are the following methods for internal use within this module:
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -97,7 +98,7 @@ There are the following methods for internal use within this module:
|
|||
# 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/Builder.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Builder.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import collections
|
||||
|
||||
|
@ -166,7 +167,7 @@ class DictCmdGenerator(SCons.Util.Selector):
|
|||
|
||||
try:
|
||||
ret = SCons.Util.Selector.__call__(self, env, source, ext)
|
||||
except KeyError, e:
|
||||
except KeyError as e:
|
||||
raise UserError("Ambiguous suffixes after environment substitution: %s == %s == %s" % (e.args[0], e.args[1], e.args[2]))
|
||||
if ret is None:
|
||||
raise UserError("While building `%s' from `%s': Don't know how to build from a source file with suffix `%s'. Expected a suffix in this list: %s." % \
|
||||
|
@ -229,7 +230,7 @@ class OverrideWarner(collections.UserDict):
|
|||
def warn(self):
|
||||
if self.already_warned:
|
||||
return
|
||||
for k in self.keys():
|
||||
for k in list(self.keys()):
|
||||
if k in misleading_keywords:
|
||||
alt = misleading_keywords[k]
|
||||
msg = "Did you mean to use `%s' instead of `%s'?" % (alt, k)
|
||||
|
@ -290,7 +291,14 @@ def _node_errors(builder, env, tlist, slist):
|
|||
if t.side_effect:
|
||||
raise UserError("Multiple ways to build the same target were specified for: %s" % t)
|
||||
if t.has_explicit_builder():
|
||||
if not t.env is None and not t.env is env:
|
||||
# Check for errors when the environments are different
|
||||
# No error if environments are the same Environment instance
|
||||
if (not t.env is None and not t.env is env and
|
||||
# Check OverrideEnvironment case - no error if wrapped Environments
|
||||
# are the same instance, and overrides lists match
|
||||
not (getattr(t.env, '__subject', 0) is getattr(env, '__subject', 1) and
|
||||
getattr(t.env, 'overrides', 0) == getattr(env, 'overrides', 1) and
|
||||
not builder.multi)):
|
||||
action = t.builder.action
|
||||
t_contents = t.builder.action.get_contents(tlist, slist, t.env)
|
||||
contents = builder.action.get_contents(tlist, slist, env)
|
||||
|
@ -299,7 +307,10 @@ def _node_errors(builder, env, tlist, slist):
|
|||
msg = "Two different environments were specified for target %s,\n\tbut they appear to have the same action: %s" % (t, action.genstring(tlist, slist, t.env))
|
||||
SCons.Warnings.warn(SCons.Warnings.DuplicateEnvironmentWarning, msg)
|
||||
else:
|
||||
msg = "Two environments with different actions were specified for the same target: %s\n(action 1: %s)\n(action 2: %s)" % (t,t_contents,contents)
|
||||
try:
|
||||
msg = "Two environments with different actions were specified for the same target: %s\n(action 1: %s)\n(action 2: %s)" % (t,t_contents.decode('utf-8'),contents.decode('utf-8'))
|
||||
except UnicodeDecodeError as e:
|
||||
msg = "Two environments with different actions were specified for the same target: %s"%t
|
||||
raise UserError(msg)
|
||||
if builder.multi:
|
||||
if t.builder != builder:
|
||||
|
@ -344,8 +355,11 @@ class EmitterProxy(object):
|
|||
return (target, source)
|
||||
|
||||
|
||||
def __cmp__(self, other):
|
||||
return cmp(self.var, other.var)
|
||||
def __eq__(self, other):
|
||||
return self.var == other.var
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.var < other.var
|
||||
|
||||
class BuilderBase(object):
|
||||
"""Base class for Builders, objects that create output
|
||||
|
@ -423,6 +437,9 @@ class BuilderBase(object):
|
|||
def __nonzero__(self):
|
||||
raise InternalError("Do not test for the Node.builder attribute directly; use Node.has_builder() instead")
|
||||
|
||||
def __bool__(self):
|
||||
return self.__nonzero__()
|
||||
|
||||
def get_name(self, env):
|
||||
"""Attempts to get the name of the Builder.
|
||||
|
||||
|
@ -440,8 +457,8 @@ class BuilderBase(object):
|
|||
except AttributeError:
|
||||
return str(self.__class__)
|
||||
|
||||
def __cmp__(self, other):
|
||||
return cmp(self.__dict__, other.__dict__)
|
||||
def __eq__(self, other):
|
||||
return self.__dict__ == other.__dict__
|
||||
|
||||
def splitext(self, path, env=None):
|
||||
if not env:
|
||||
|
@ -604,6 +621,8 @@ class BuilderBase(object):
|
|||
else:
|
||||
ekw = self.executor_kw.copy()
|
||||
ekw['chdir'] = chdir
|
||||
if 'chdir' in ekw and SCons.Util.is_String(ekw['chdir']):
|
||||
ekw['chdir'] = env.subst(ekw['chdir'])
|
||||
if kw:
|
||||
if 'srcdir' in kw:
|
||||
def prependDirIfRelative(f, srcdir=kw['srcdir']):
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/CacheDir.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/CacheDir.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """
|
||||
CacheDir support
|
|
@ -101,7 +101,6 @@ Autoconf-like configuration support; low level implementation of tests.
|
|||
#
|
||||
|
||||
import re
|
||||
from types import IntType
|
||||
|
||||
#
|
||||
# PUBLIC VARIABLES
|
||||
|
@ -707,11 +706,12 @@ def CheckProg(context, prog_name):
|
|||
def _YesNoResult(context, ret, key, text, comment = None):
|
||||
"""
|
||||
Handle the result of a test with a "yes" or "no" result.
|
||||
"ret" is the return value: empty if OK, error message when not.
|
||||
"key" is the name of the symbol to be defined (HAVE_foo).
|
||||
"text" is the source code of the program used for testing.
|
||||
"comment" is the C comment to add above the line defining the symbol (the
|
||||
comment is automatically put inside a /* */). If None, no comment is added.
|
||||
|
||||
:Parameters:
|
||||
- `ret` is the return value: empty if OK, error message when not.
|
||||
- `key` is the name of the symbol to be defined (HAVE_foo).
|
||||
- `text` is the source code of the program used for testing.
|
||||
- `comment` is the C comment to add above the line defining the symbol (the comment is automatically put inside a /\* \*/). If None, no comment is added.
|
||||
"""
|
||||
if key:
|
||||
_Have(context, key, not ret, comment)
|
||||
|
@ -725,18 +725,20 @@ def _YesNoResult(context, ret, key, text, comment = None):
|
|||
def _Have(context, key, have, comment = None):
|
||||
"""
|
||||
Store result of a test in context.havedict and context.headerfilename.
|
||||
"key" is a "HAVE_abc" name. It is turned into all CAPITALS and non-
|
||||
alphanumerics are replaced by an underscore.
|
||||
|
||||
:Parameters:
|
||||
- `key` - is a "HAVE_abc" name. It is turned into all CAPITALS and non-alphanumerics are replaced by an underscore.
|
||||
- `have` - value as it should appear in the header file, include quotes when desired and escape special characters!
|
||||
- `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.
|
||||
|
||||
|
||||
The value of "have" can be:
|
||||
1 - Feature is defined, add "#define key".
|
||||
0 - Feature is not defined, add "/* #undef key */".
|
||||
Adding "undef" is what autoconf does. Not useful for the
|
||||
compiler, but it shows that the test was done.
|
||||
number - Feature is defined to this number "#define key have".
|
||||
Doesn't work for 0 or 1, use a string then.
|
||||
string - Feature is defined to this string "#define key have".
|
||||
Give "have" as is should appear in the header file, include quotes
|
||||
when desired and escape special characters!
|
||||
- 1 - Feature is defined, add "#define key".
|
||||
- 0 - Feature is not defined, add "/\* #undef key \*/". Adding "undef" is what autoconf does. Not useful for the compiler, but it shows that the test was done.
|
||||
- number - Feature is defined to this number "#define key have". Doesn't work for 0 or 1, use a string then.
|
||||
- string - Feature is defined to this string "#define key have".
|
||||
|
||||
|
||||
"""
|
||||
key_up = key.upper()
|
||||
key_up = re.sub('[^A-Z0-9_]', '_', key_up)
|
||||
|
@ -745,7 +747,7 @@ def _Have(context, key, have, comment = None):
|
|||
line = "#define %s 1\n" % key_up
|
||||
elif have == 0:
|
||||
line = "/* #undef %s */\n" % key_up
|
||||
elif isinstance(have, IntType):
|
||||
elif isinstance(have, int):
|
||||
line = "#define %s %d\n" % (key_up, have)
|
||||
else:
|
||||
line = "#define %s %s\n" % (key_up, str(have))
|
||||
|
@ -787,10 +789,11 @@ def _lang2suffix(lang):
|
|||
When "lang" is empty or None C is assumed.
|
||||
Returns a tuple (lang, suffix, None) when it works.
|
||||
For an unrecognized language returns (None, None, msg).
|
||||
|
||||
Where:
|
||||
lang = the unified language name
|
||||
suffix = the suffix, including the leading dot
|
||||
msg = an error message
|
||||
- lang = the unified language name
|
||||
- suffix = the suffix, including the leading dot
|
||||
- msg = an error message
|
||||
"""
|
||||
if not lang or lang in ["C", "c"]:
|
||||
return ("C", ".c", None)
|
|
@ -9,7 +9,7 @@ caller_trace()
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ caller_trace()
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Debug.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Debug.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
@ -97,7 +97,8 @@ def dumpLoggedInstances(classes, file=sys.stdout):
|
|||
if sys.platform[:5] == "linux":
|
||||
# Linux doesn't actually support memory usage stats from getrusage().
|
||||
def memory():
|
||||
mstr = open('/proc/self/stat').read()
|
||||
with open('/proc/self/stat') as f:
|
||||
mstr = f.read()
|
||||
mstr = mstr.split()[22]
|
||||
return int(mstr)
|
||||
elif sys.platform[:6] == 'darwin':
|
||||
|
@ -233,6 +234,7 @@ def Trace(msg, file=None, mode='w', tstamp=None):
|
|||
PreviousTime = now
|
||||
fp.write(msg)
|
||||
fp.flush()
|
||||
fp.close()
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
|
@ -10,7 +10,7 @@ from distutils.msvccompiler.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -33,7 +33,7 @@ from distutils.msvccompiler.
|
|||
#
|
||||
from __future__ import division
|
||||
|
||||
__revision__ = "src/engine/SCons/Defaults.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Defaults.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
|
||||
import os
|
||||
|
@ -261,9 +261,13 @@ def copy_func(dest, src, symlinks=True):
|
|||
else:
|
||||
return copy_func(dest, os.path.realpath(src))
|
||||
elif os.path.isfile(src):
|
||||
return shutil.copy2(src, dest)
|
||||
shutil.copy2(src, dest)
|
||||
return 0
|
||||
else:
|
||||
return shutil.copytree(src, dest, symlinks)
|
||||
shutil.copytree(src, dest, symlinks)
|
||||
# copytree returns None in python2 and destination string in python3
|
||||
# A error is raised in both cases, so we can just return 0 for success
|
||||
return 0
|
||||
|
||||
Copy = ActionFactory(
|
||||
copy_func,
|
||||
|
@ -298,7 +302,7 @@ def mkdir_func(dest):
|
|||
for entry in dest:
|
||||
try:
|
||||
os.makedirs(str(entry))
|
||||
except os.error, e:
|
||||
except os.error as e:
|
||||
p = str(entry)
|
||||
if (e.args[0] == errno.EEXIST or
|
||||
(sys.platform=='win32' and e.args[0]==183)) \
|
||||
|
@ -458,7 +462,7 @@ def processDefines(defs):
|
|||
else:
|
||||
l.append(str(d[0]))
|
||||
elif SCons.Util.is_Dict(d):
|
||||
for macro,value in d.iteritems():
|
||||
for macro,value in d.items():
|
||||
if value is not None:
|
||||
l.append(str(macro) + '=' + str(value))
|
||||
else:
|
||||
|
@ -484,6 +488,7 @@ def processDefines(defs):
|
|||
l = [str(defs)]
|
||||
return l
|
||||
|
||||
|
||||
def _defines(prefix, defs, suffix, env, c=_concat_ixes):
|
||||
"""A wrapper around _concat_ixes that turns a list or string
|
||||
into a list of C preprocessor command-line definitions.
|
||||
|
@ -491,6 +496,7 @@ def _defines(prefix, defs, suffix, env, c=_concat_ixes):
|
|||
|
||||
return c(prefix, env.subst_path(processDefines(defs)), suffix, env)
|
||||
|
||||
|
||||
class NullCmdGenerator(object):
|
||||
"""This is a callable class that can be used in place of other
|
||||
command generators if you don't want them to do anything.
|
||||
|
@ -509,6 +515,7 @@ class NullCmdGenerator(object):
|
|||
def __call__(self, target, source, env, for_signature=None):
|
||||
return self.cmd
|
||||
|
||||
|
||||
class Variable_Method_Caller(object):
|
||||
"""A class for finding a construction variable on the stack and
|
||||
calling one of its methods.
|
||||
|
@ -540,10 +547,10 @@ class Variable_Method_Caller(object):
|
|||
frame = frame.f_back
|
||||
return None
|
||||
|
||||
# if env[version_var] id defined, returns env[flags_var], otherwise returns None
|
||||
# if $version_var is not empty, returns env[flags_var], otherwise returns None
|
||||
def __libversionflags(env, version_var, flags_var):
|
||||
try:
|
||||
if env[version_var]:
|
||||
if env.subst('$'+version_var):
|
||||
return env[flags_var]
|
||||
except KeyError:
|
||||
pass
|
|
@ -10,7 +10,7 @@ Environment
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ Environment
|
|||
# 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/Environment.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Environment.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
|
||||
import copy
|
||||
|
@ -128,7 +128,7 @@ future_reserved_construction_var_names = [
|
|||
|
||||
def copy_non_reserved_keywords(dict):
|
||||
result = semi_deepcopy(dict)
|
||||
for k in result.keys():
|
||||
for k in list(result.keys()):
|
||||
if k in reserved_construction_var_names:
|
||||
msg = "Ignoring attempt to set reserved variable `$%s'"
|
||||
SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % k)
|
||||
|
@ -147,7 +147,7 @@ def _set_future_reserved(env, key, value):
|
|||
def _set_BUILDERS(env, key, value):
|
||||
try:
|
||||
bd = env._dict[key]
|
||||
for k in bd.keys():
|
||||
for k in list(bd.keys()):
|
||||
del bd[k]
|
||||
except KeyError:
|
||||
bd = BuilderDict(kwbd, env)
|
||||
|
@ -167,7 +167,7 @@ def _set_SCANNERS(env, key, value):
|
|||
|
||||
def _delete_duplicates(l, keep_last):
|
||||
"""Delete duplicates from a sequence, keeping the first or last."""
|
||||
seen={}
|
||||
seen=set()
|
||||
result=[]
|
||||
if keep_last: # reverse in & out, then keep first
|
||||
l.reverse()
|
||||
|
@ -175,7 +175,7 @@ def _delete_duplicates(l, keep_last):
|
|||
try:
|
||||
if i not in seen:
|
||||
result.append(i)
|
||||
seen[i]=1
|
||||
seen.add(i)
|
||||
except TypeError:
|
||||
# probably unhashable. Just keep it.
|
||||
result.append(i)
|
||||
|
@ -342,7 +342,7 @@ def is_valid_construction_var(varstr):
|
|||
class SubstitutionEnvironment(object):
|
||||
"""Base class for different flavors of construction environments.
|
||||
|
||||
This class contains a minimal set of methods that handle contruction
|
||||
This class contains a minimal set of methods that handle construction
|
||||
variable expansion and conversion of strings to Nodes, which may or
|
||||
may not be actually useful as a stand-alone class. Which methods
|
||||
ended up in this class is pretty arbitrary right now. They're
|
||||
|
@ -396,8 +396,8 @@ class SubstitutionEnvironment(object):
|
|||
# gotten better than dict.has_key() in Python 2.5.)
|
||||
self._special_set_keys = list(self._special_set.keys())
|
||||
|
||||
def __cmp__(self, other):
|
||||
return cmp(self._dict, other._dict)
|
||||
def __eq__(self, other):
|
||||
return self._dict == other._dict
|
||||
|
||||
def __delitem__(self, key):
|
||||
special = self._special_del.get(key)
|
||||
|
@ -589,7 +589,7 @@ class SubstitutionEnvironment(object):
|
|||
out,err = p.communicate()
|
||||
status = p.wait()
|
||||
if err:
|
||||
sys.stderr.write(unicode(err))
|
||||
sys.stderr.write(u"" + err)
|
||||
if status:
|
||||
raise OSError("'%s' exited %d" % (command, status))
|
||||
return out
|
||||
|
@ -1185,7 +1185,7 @@ class Base(SubstitutionEnvironment):
|
|||
if SCons.Util.is_List(val):
|
||||
if key == 'CPPDEFINES':
|
||||
tmp = []
|
||||
for (k, v) in orig.iteritems():
|
||||
for (k, v) in orig.items():
|
||||
if v is not None:
|
||||
tmp.append((k, v))
|
||||
else:
|
||||
|
@ -1273,7 +1273,7 @@ class Base(SubstitutionEnvironment):
|
|||
# Construct a list of (key, value) tuples.
|
||||
if SCons.Util.is_Dict(dk):
|
||||
tmp = []
|
||||
for (k, v) in dk.iteritems():
|
||||
for (k, v) in dk.items():
|
||||
if v is not None:
|
||||
tmp.append((k, v))
|
||||
else:
|
||||
|
@ -1321,7 +1321,7 @@ class Base(SubstitutionEnvironment):
|
|||
# Construct a list of (key, value) tuples.
|
||||
if SCons.Util.is_Dict(val):
|
||||
tmp = []
|
||||
for (k, v) in val.iteritems():
|
||||
for (k, v) in val.items():
|
||||
if v is not None:
|
||||
tmp.append((k, v))
|
||||
else:
|
||||
|
@ -1330,7 +1330,7 @@ class Base(SubstitutionEnvironment):
|
|||
elif SCons.Util.is_String(val):
|
||||
val = [(val,)]
|
||||
if delete_existing:
|
||||
dk = filter(lambda x, val=val: x not in val, dk)
|
||||
dk = list(filter(lambda x, val=val: x not in val, dk))
|
||||
self._dict[key] = dk + val
|
||||
else:
|
||||
dk = [x for x in dk if x not in val]
|
||||
|
@ -1339,7 +1339,7 @@ class Base(SubstitutionEnvironment):
|
|||
# By elimination, val is not a list. Since dk is a
|
||||
# list, wrap val in a list first.
|
||||
if delete_existing:
|
||||
dk = filter(lambda x, val=val: x not in val, dk)
|
||||
dk = list(filter(lambda x, val=val: x not in val, dk))
|
||||
self._dict[key] = dk + [val]
|
||||
else:
|
||||
if not val in dk:
|
||||
|
@ -1350,7 +1350,7 @@ class Base(SubstitutionEnvironment):
|
|||
dk = [dk]
|
||||
elif SCons.Util.is_Dict(dk):
|
||||
tmp = []
|
||||
for (k, v) in dk.iteritems():
|
||||
for (k, v) in dk.items():
|
||||
if v is not None:
|
||||
tmp.append((k, v))
|
||||
else:
|
||||
|
@ -1363,7 +1363,7 @@ class Base(SubstitutionEnvironment):
|
|||
val = [val]
|
||||
elif SCons.Util.is_Dict(val):
|
||||
tmp = []
|
||||
for i,j in val.iteritems():
|
||||
for i,j in val.items():
|
||||
if j is not None:
|
||||
tmp.append((i,j))
|
||||
else:
|
||||
|
@ -1771,7 +1771,7 @@ class Base(SubstitutionEnvironment):
|
|||
return os.path.join(dir, new_prefix+name+new_suffix)
|
||||
|
||||
def SetDefault(self, **kw):
|
||||
for k in kw.keys():
|
||||
for k in list(kw.keys()):
|
||||
if k in self._dict:
|
||||
del kw[k]
|
||||
self.Replace(**kw)
|
||||
|
@ -1833,7 +1833,7 @@ class Base(SubstitutionEnvironment):
|
|||
uniq = {}
|
||||
for executor in [n.get_executor() for n in nodes]:
|
||||
uniq[executor] = 1
|
||||
for executor in uniq.keys():
|
||||
for executor in list(uniq.keys()):
|
||||
executor.add_pre_action(action)
|
||||
return nodes
|
||||
|
||||
|
@ -1843,7 +1843,7 @@ class Base(SubstitutionEnvironment):
|
|||
uniq = {}
|
||||
for executor in [n.get_executor() for n in nodes]:
|
||||
uniq[executor] = 1
|
||||
for executor in uniq.keys():
|
||||
for executor in list(uniq.keys()):
|
||||
executor.add_post_action(action)
|
||||
return nodes
|
||||
|
||||
|
@ -1983,6 +1983,15 @@ class Base(SubstitutionEnvironment):
|
|||
return result
|
||||
return self.fs.Dir(s, *args, **kw)
|
||||
|
||||
def PyPackageDir(self, modulename):
|
||||
s = self.subst(modulename)
|
||||
if SCons.Util.is_Sequence(s):
|
||||
result=[]
|
||||
for e in s:
|
||||
result.append(self.fs.PyPackageDir(e))
|
||||
return result
|
||||
return self.fs.PyPackageDir(s)
|
||||
|
||||
def NoClean(self, *targets):
|
||||
"""Tags a target so that it will not be cleaned by -c"""
|
||||
tlist = []
|
||||
|
@ -2180,13 +2189,16 @@ class Base(SubstitutionEnvironment):
|
|||
"""This function converts a string or list into a list of strings
|
||||
or Nodes. This makes things easier for users by allowing files to
|
||||
be specified as a white-space separated list to be split.
|
||||
|
||||
The input rules are:
|
||||
- A single string containing names separated by spaces. These will be
|
||||
split apart at the spaces.
|
||||
- A single Node instance
|
||||
- A list containing either strings or Node instances. Any strings
|
||||
in the list are not split at spaces.
|
||||
|
||||
In all cases, the function returns a list of Nodes and strings."""
|
||||
|
||||
if SCons.Util.is_List(arg):
|
||||
return list(map(self.subst, arg))
|
||||
elif SCons.Util.is_String(arg):
|
||||
|
@ -2246,7 +2258,7 @@ class Base(SubstitutionEnvironment):
|
|||
while (node != node.srcnode()):
|
||||
node = node.srcnode()
|
||||
return node
|
||||
sources = map( final_source, sources );
|
||||
sources = list(map( final_source, sources ));
|
||||
# remove duplicates
|
||||
return list(set(sources))
|
||||
|
||||
|
@ -2368,19 +2380,21 @@ class OverrideEnvironment(Base):
|
|||
|
||||
Environment = Base
|
||||
|
||||
# An entry point for returning a proxy subclass instance that overrides
|
||||
# the subst*() methods so they don't actually perform construction
|
||||
# variable substitution. This is specifically intended to be the shim
|
||||
# layer in between global function calls (which don't want construction
|
||||
# variable substitution) and the DefaultEnvironment() (which would
|
||||
# substitute variables if left to its own devices)."""
|
||||
#
|
||||
# We have to wrap this in a function that allows us to delay definition of
|
||||
# the class until it's necessary, so that when it subclasses Environment
|
||||
# it will pick up whatever Environment subclass the wrapper interface
|
||||
# might have assigned to SCons.Environment.Environment.
|
||||
|
||||
def NoSubstitutionProxy(subject):
|
||||
"""
|
||||
An entry point for returning a proxy subclass instance that overrides
|
||||
the subst*() methods so they don't actually perform construction
|
||||
variable substitution. This is specifically intended to be the shim
|
||||
layer in between global function calls (which don't want construction
|
||||
variable substitution) and the DefaultEnvironment() (which would
|
||||
substitute variables if left to its own devices).
|
||||
|
||||
We have to wrap this in a function that allows us to delay definition of
|
||||
the class until it's necessary, so that when it subclasses Environment
|
||||
it will pick up whatever Environment subclass the wrapper interface
|
||||
might have assigned to SCons.Environment.Environment.
|
||||
"""
|
||||
class _NoSubstitutionProxy(Environment):
|
||||
def __init__(self, subject):
|
||||
self.__dict__['__subject'] = subject
|
||||
|
@ -2389,7 +2403,7 @@ def NoSubstitutionProxy(subject):
|
|||
def __setattr__(self, name, value):
|
||||
return setattr(self.__dict__['__subject'], name, value)
|
||||
def executor_to_lvars(self, kwdict):
|
||||
if kwdict.has_key('executor'):
|
||||
if 'executor' in kwdict:
|
||||
kwdict['lvars'] = kwdict['executor'].get_lvars()
|
||||
del kwdict['executor']
|
||||
else:
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -28,72 +28,74 @@ and user errors in SCons.
|
|||
|
||||
"""
|
||||
|
||||
__revision__ = "src/engine/SCons/Errors.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Errors.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import shutil
|
||||
import SCons.Util
|
||||
|
||||
import exceptions
|
||||
|
||||
class BuildError(Exception):
|
||||
""" Errors occuring while building.
|
||||
""" Errors occurring while building.
|
||||
|
||||
BuildError have the following attributes:
|
||||
=========================================
|
||||
|
||||
Information about the cause of the build error:
|
||||
-----------------------------------------------
|
||||
Information about the cause of the build error:
|
||||
-----------------------------------------------
|
||||
|
||||
errstr : a description of the error message
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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.
|
||||
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:
|
||||
---------------------------------------------------------
|
||||
Information about the cause of the location of the error:
|
||||
---------------------------------------------------------
|
||||
|
||||
node : the error occurred 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)
|
||||
node : the error occured while building this target node(s)
|
||||
|
||||
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)
|
||||
"""
|
||||
executor : the executor that caused the build to fail (might
|
||||
be None if the build failures is not due to the
|
||||
executor failing)
|
||||
|
||||
def __init__(self,
|
||||
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
|
||||
|
||||
# py3: errstr should be string and not bytes.
|
||||
|
||||
self.errstr = SCons.Util.to_str(errstr)
|
||||
self.status = status
|
||||
self.exitstatus = exitstatus
|
||||
self.filename = filename
|
||||
|
@ -104,7 +106,7 @@ class BuildError(Exception):
|
|||
self.action = action
|
||||
self.command = command
|
||||
|
||||
Exception.__init__(self, node, errstr, status, exitstatus, filename,
|
||||
Exception.__init__(self, node, errstr, status, exitstatus, filename,
|
||||
executor, action, command, exc_info)
|
||||
|
||||
def __str__(self):
|
||||
|
@ -139,13 +141,17 @@ 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.
|
||||
:Parameters:
|
||||
- `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
|
||||
|
@ -163,14 +169,32 @@ def convert_to_BuildError(status, exc_info=None):
|
|||
status=2,
|
||||
exitstatus=2,
|
||||
exc_info=exc_info)
|
||||
elif isinstance(status, exceptions.EnvironmentError):
|
||||
elif isinstance(status, shutil.SameFileError):
|
||||
# PY3 has a exception for when copying file to itself
|
||||
# It's object provides info differently than below
|
||||
try:
|
||||
filename = status.filename
|
||||
except AttributeError:
|
||||
filename = None
|
||||
|
||||
buildError = BuildError(
|
||||
errstr=status.args[0],
|
||||
status=status.errno,
|
||||
exitstatus=2,
|
||||
filename=filename,
|
||||
exc_info=exc_info)
|
||||
|
||||
elif isinstance(status, (EnvironmentError, OSError, IOError)):
|
||||
# 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
|
||||
try:
|
||||
filename = status.filename
|
||||
except AttributeError:
|
||||
filename = None
|
||||
|
||||
buildError = BuildError(
|
||||
errstr=status.strerror,
|
||||
status=status.errno,
|
||||
|
@ -195,7 +219,7 @@ def convert_to_BuildError(status, exc_info=None):
|
|||
exitstatus=2)
|
||||
|
||||
#import sys
|
||||
#sys.stderr.write("convert_to_BuildError: status %s => (errstr %s, status %s)"%(status,buildError.errstr, buildError.status))
|
||||
#sys.stderr.write("convert_to_BuildError: status %s => (errstr %s, status %s)\n"%(status,buildError.errstr, buildError.status))
|
||||
return buildError
|
||||
|
||||
# Local Variables:
|
|
@ -6,7 +6,7 @@ Nodes.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -26,8 +26,9 @@ Nodes.
|
|||
# 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.
|
||||
from __future__ import print_function
|
||||
|
||||
__revision__ = "src/engine/SCons/Executor.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Executor.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import collections
|
||||
|
||||
|
@ -35,7 +36,7 @@ import SCons.Debug
|
|||
from SCons.Debug import logInstanceCreation
|
||||
import SCons.Errors
|
||||
import SCons.Memoize
|
||||
|
||||
from SCons.compat import with_metaclass, NoSlotsPyPy
|
||||
|
||||
class Batch(object):
|
||||
"""Remembers exact association between targets
|
||||
|
@ -154,7 +155,7 @@ _execute_str_map = {0 : execute_null_str,
|
|||
1 : execute_actions_str}
|
||||
|
||||
|
||||
class Executor(object):
|
||||
class Executor(object, with_metaclass(NoSlotsPyPy)):
|
||||
"""A class for controlling instances of executing an action.
|
||||
|
||||
This largely exists to hold a single association of an action,
|
||||
|
@ -455,10 +456,16 @@ class Executor(object):
|
|||
except KeyError:
|
||||
pass
|
||||
env = self.get_build_env()
|
||||
result = "".join([action.get_contents(self.get_all_targets(),
|
||||
self.get_all_sources(),
|
||||
env)
|
||||
for action in self.get_action_list()])
|
||||
|
||||
action_list = self.get_action_list()
|
||||
all_targets = self.get_all_targets()
|
||||
all_sources = self.get_all_sources()
|
||||
|
||||
result = bytearray("",'utf-8').join([action.get_contents(all_targets,
|
||||
all_sources,
|
||||
env)
|
||||
for action in action_list])
|
||||
|
||||
self._memo['get_contents'] = result
|
||||
return result
|
||||
|
||||
|
@ -580,7 +587,7 @@ def get_NullEnvironment():
|
|||
nullenv = NullEnvironment()
|
||||
return nullenv
|
||||
|
||||
class Null(object):
|
||||
class Null(object, with_metaclass(NoSlotsPyPy)):
|
||||
"""A null Executor, with a null build Environment, that does
|
||||
nothing when the rest of the methods call it.
|
||||
|
|
@ -7,7 +7,7 @@ stop, and wait on jobs.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -29,7 +29,7 @@ stop, and wait on jobs.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Job.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Job.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.compat
|
||||
|
||||
|
@ -278,14 +278,14 @@ else:
|
|||
|
||||
try:
|
||||
prev_size = threading.stack_size(stack_size*1024)
|
||||
except AttributeError, e:
|
||||
except AttributeError as 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:
|
||||
except ValueError as e:
|
||||
msg = "Setting stack size failed:\n " + str(e)
|
||||
SCons.Warnings.warn(SCons.Warnings.StackSizeWarning, msg)
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -20,8 +20,9 @@
|
|||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
from __future__ import print_function
|
||||
|
||||
__revision__ = "src/engine/SCons/Memoize.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Memoize.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """Memoizer
|
||||
|
||||
|
@ -33,7 +34,7 @@ values in a consistent way. In particular, it requires that the class uses a
|
|||
dictionary named "_memo" to store the cached values.
|
||||
|
||||
Here is an example of wrapping a method that returns a computed value,
|
||||
with no input parameters:
|
||||
with no input parameters::
|
||||
|
||||
@SCons.Memoize.CountMethodCall
|
||||
def foo(self):
|
||||
|
@ -50,7 +51,7 @@ with no input parameters:
|
|||
return result
|
||||
|
||||
Here is an example of wrapping a method that will return different values
|
||||
based on one or more input arguments:
|
||||
based on one or more input arguments::
|
||||
|
||||
def _bar_key(self, argument): # Memoization
|
||||
return argument # Memoization
|
||||
|
@ -123,13 +124,12 @@ class Counter(object):
|
|||
def key(self):
|
||||
return self.cls_name+'.'+self.method_name
|
||||
def display(self):
|
||||
fmt = " %7d hits %7d misses %s()"
|
||||
print fmt % (self.hit, self.miss, self.key())
|
||||
def __cmp__(self, other):
|
||||
print(" {:7d} hits {:7d} misses {}()".format(self.hit, self.miss, self.key()))
|
||||
def __eq__(self, other):
|
||||
try:
|
||||
return cmp(self.key(), other.key())
|
||||
return self.key() == other.key()
|
||||
except AttributeError:
|
||||
return 0
|
||||
return True
|
||||
|
||||
class CountValue(Counter):
|
||||
"""
|
||||
|
@ -185,7 +185,7 @@ def Dump(title=None):
|
|||
collected so far.
|
||||
"""
|
||||
if title:
|
||||
print title
|
||||
print(title)
|
||||
for counter in sorted(CounterList):
|
||||
CounterList[counter].display()
|
||||
|
|
@ -8,7 +8,7 @@ This creates a hash of global Aliases (dummy targets).
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ This creates a hash of global Aliases (dummy targets).
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Node/Alias.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Node/Alias.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import collections
|
||||
|
|
@ -11,7 +11,7 @@ that can be used by scripts or modules looking for the canonical default.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,8 +31,9 @@ that can be used by scripts or modules looking for the canonical default.
|
|||
# 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.
|
||||
from __future__ import print_function
|
||||
|
||||
__revision__ = "src/engine/SCons/Node/FS.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Node/FS.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import fnmatch
|
||||
import os
|
||||
|
@ -122,7 +123,7 @@ def save_strings(val):
|
|||
# tells us whether or not os.path.splitdrive() actually does anything
|
||||
# on this system, and therefore whether we need to bother calling it
|
||||
# when looking up path names in various methods below.
|
||||
#
|
||||
#
|
||||
|
||||
do_splitdrive = None
|
||||
_my_splitdrive =None
|
||||
|
@ -157,7 +158,7 @@ def initialize_do_splitdrive():
|
|||
global OS_SEP
|
||||
global UNC_PREFIX
|
||||
global os_sep_is_slash
|
||||
|
||||
|
||||
OS_SEP = os.sep
|
||||
UNC_PREFIX = OS_SEP + OS_SEP
|
||||
os_sep_is_slash = OS_SEP == '/'
|
||||
|
@ -178,7 +179,7 @@ needs_normpath_check = re.compile(
|
|||
# b) The path starts with '..'. E.g. '../' or '../moredirs'
|
||||
# but we not match '..abc/'.
|
||||
# c) The path ends with '..'. E.g. '/..' or 'dirs/..'
|
||||
# d) The path contains a '..' in the middle.
|
||||
# d) The path contains a '..' in the middle.
|
||||
# E.g. dirs/../moredirs
|
||||
|
||||
(.*/)?\.\.(?:/|$) |
|
||||
|
@ -200,7 +201,7 @@ needs_normpath_check = re.compile(
|
|||
|
||||
\./|.*/\.(?:/|$)
|
||||
|
||||
''',
|
||||
''',
|
||||
re.VERBOSE
|
||||
)
|
||||
needs_normpath_match = needs_normpath_check.match
|
||||
|
@ -219,7 +220,12 @@ needs_normpath_match = needs_normpath_check.match
|
|||
# there should be *no* changes to the external file system(s)...
|
||||
#
|
||||
|
||||
if hasattr(os, 'link'):
|
||||
# For Now disable hard & softlinks for win32
|
||||
# PY3 supports them, but the rest of SCons is not ready for this
|
||||
# in some cases user permissions may be required.
|
||||
# TODO: See if theres a reasonable way to enable using links on win32/64
|
||||
|
||||
if hasattr(os, 'link') and sys.platform != 'win32':
|
||||
def _hardlink_func(fs, src, dst):
|
||||
# If the source is a symlink, we can't just hard-link to it
|
||||
# because a relative symlink may point somewhere completely
|
||||
|
@ -235,7 +241,7 @@ if hasattr(os, 'link'):
|
|||
else:
|
||||
_hardlink_func = None
|
||||
|
||||
if hasattr(os, 'symlink'):
|
||||
if hasattr(os, 'symlink') and sys.platform != 'win32':
|
||||
def _softlink_func(fs, src, dst):
|
||||
fs.symlink(src, dst)
|
||||
else:
|
||||
|
@ -350,33 +356,6 @@ class _Null(object):
|
|||
|
||||
_null = _Null()
|
||||
|
||||
DefaultSCCSBuilder = None
|
||||
DefaultRCSBuilder = None
|
||||
|
||||
def get_DefaultSCCSBuilder():
|
||||
global DefaultSCCSBuilder
|
||||
if DefaultSCCSBuilder is None:
|
||||
import SCons.Builder
|
||||
# "env" will get filled in by Executor.get_build_env()
|
||||
# calling SCons.Defaults.DefaultEnvironment() when necessary.
|
||||
act = SCons.Action.Action('$SCCSCOM', '$SCCSCOMSTR')
|
||||
DefaultSCCSBuilder = SCons.Builder.Builder(action = act,
|
||||
env = None,
|
||||
name = "DefaultSCCSBuilder")
|
||||
return DefaultSCCSBuilder
|
||||
|
||||
def get_DefaultRCSBuilder():
|
||||
global DefaultRCSBuilder
|
||||
if DefaultRCSBuilder is None:
|
||||
import SCons.Builder
|
||||
# "env" will get filled in by Executor.get_build_env()
|
||||
# calling SCons.Defaults.DefaultEnvironment() when necessary.
|
||||
act = SCons.Action.Action('$RCS_COCOM', '$RCS_COCOMSTR')
|
||||
DefaultRCSBuilder = SCons.Builder.Builder(action = act,
|
||||
env = None,
|
||||
name = "DefaultRCSBuilder")
|
||||
return DefaultRCSBuilder
|
||||
|
||||
# Cygwin's os.path.normcase pretends it's on a case-sensitive filesystem.
|
||||
_is_cygwin = sys.platform == "cygwin"
|
||||
if os.path.normcase("TeSt") == os.path.normpath("TeSt") and not _is_cygwin:
|
||||
|
@ -421,46 +400,12 @@ def do_diskcheck_match(node, predicate, errorfmt):
|
|||
def ignore_diskcheck_match(node, predicate, errorfmt):
|
||||
pass
|
||||
|
||||
def do_diskcheck_rcs(node, name):
|
||||
try:
|
||||
rcs_dir = node.rcs_dir
|
||||
except AttributeError:
|
||||
if node.entry_exists_on_disk('RCS'):
|
||||
rcs_dir = node.Dir('RCS')
|
||||
else:
|
||||
rcs_dir = None
|
||||
node.rcs_dir = rcs_dir
|
||||
if rcs_dir:
|
||||
return rcs_dir.entry_exists_on_disk(name+',v')
|
||||
return None
|
||||
|
||||
def ignore_diskcheck_rcs(node, name):
|
||||
return None
|
||||
|
||||
def do_diskcheck_sccs(node, name):
|
||||
try:
|
||||
sccs_dir = node.sccs_dir
|
||||
except AttributeError:
|
||||
if node.entry_exists_on_disk('SCCS'):
|
||||
sccs_dir = node.Dir('SCCS')
|
||||
else:
|
||||
sccs_dir = None
|
||||
node.sccs_dir = sccs_dir
|
||||
if sccs_dir:
|
||||
return sccs_dir.entry_exists_on_disk('s.'+name)
|
||||
return None
|
||||
|
||||
def ignore_diskcheck_sccs(node, name):
|
||||
return None
|
||||
|
||||
diskcheck_match = DiskChecker('match', do_diskcheck_match, ignore_diskcheck_match)
|
||||
diskcheck_rcs = DiskChecker('rcs', do_diskcheck_rcs, ignore_diskcheck_rcs)
|
||||
diskcheck_sccs = DiskChecker('sccs', do_diskcheck_sccs, ignore_diskcheck_sccs)
|
||||
|
||||
diskcheckers = [
|
||||
diskcheck_match,
|
||||
diskcheck_rcs,
|
||||
diskcheck_sccs,
|
||||
]
|
||||
|
||||
def set_diskcheck(list):
|
||||
|
@ -476,6 +421,11 @@ class EntryProxy(SCons.Util.Proxy):
|
|||
|
||||
__str__ = SCons.Util.Delegate('__str__')
|
||||
|
||||
# In PY3 if a class defines __eq__, then it must explicitly provide
|
||||
# __hash__. Since SCons.Util.Proxy provides __eq__ we need the following
|
||||
# see: https://docs.python.org/3.1/reference/datamodel.html#object.__hash__
|
||||
__hash__ = SCons.Util.Delegate('__hash__')
|
||||
|
||||
def __get_abspath(self):
|
||||
entry = self.get()
|
||||
return SCons.Subst.SpecialAttrWrapper(entry.get_abspath(),
|
||||
|
@ -564,7 +514,7 @@ class EntryProxy(SCons.Util.Proxy):
|
|||
except KeyError:
|
||||
try:
|
||||
attr = SCons.Util.Proxy.__getattr__(self, name)
|
||||
except AttributeError, e:
|
||||
except AttributeError as e:
|
||||
# Raise our own AttributeError subclass with an
|
||||
# overridden __str__() method that identifies the
|
||||
# name of the entry that caused the exception.
|
||||
|
@ -573,6 +523,7 @@ class EntryProxy(SCons.Util.Proxy):
|
|||
else:
|
||||
return attr_function(self)
|
||||
|
||||
|
||||
class Base(SCons.Node.Node):
|
||||
"""A generic class for file system entries. This class is for
|
||||
when we don't know yet whether the entry being looked up is a file
|
||||
|
@ -608,14 +559,13 @@ class Base(SCons.Node.Node):
|
|||
our relative and absolute paths, identify our parent
|
||||
directory, and indicate that this node should use
|
||||
signatures."""
|
||||
|
||||
if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.Base')
|
||||
SCons.Node.Node.__init__(self)
|
||||
|
||||
# Filenames and paths are probably reused and are intern'ed to
|
||||
# save some memory.
|
||||
|
||||
#: Filename with extension as it was specified when the object was
|
||||
#: created; to obtain filesystem path, use Python str() function
|
||||
# Filenames and paths are probably reused and are intern'ed to save some memory.
|
||||
# Filename with extension as it was specified when the object was
|
||||
# created; to obtain filesystem path, use Python str() function
|
||||
self.name = SCons.Util.silent_intern(name)
|
||||
self.fs = fs #: Reference to parent Node.FS object
|
||||
|
||||
|
@ -670,14 +620,14 @@ class Base(SCons.Node.Node):
|
|||
single variables lazily when required, in order to save memory.
|
||||
The redirection to the getters lets older Tools and
|
||||
SConstruct continue to work without any additional changes,
|
||||
fully transparent to the user.
|
||||
fully transparent to the user.
|
||||
Note, that __getattr__ is only called as fallback when the
|
||||
requested attribute can't be found, so there should be no
|
||||
speed performance penalty involved for standard builds.
|
||||
"""
|
||||
if attr in node_bwcomp:
|
||||
return node_bwcomp[attr](self)
|
||||
|
||||
|
||||
raise AttributeError("%r object has no attribute %r" %
|
||||
(self.__class__, attr))
|
||||
|
||||
|
@ -689,13 +639,17 @@ class Base(SCons.Node.Node):
|
|||
return self._save_str()
|
||||
return self._get_str()
|
||||
|
||||
def __lt__(self, other):
|
||||
""" less than operator used by sorting on py3"""
|
||||
return str(self) < str(other)
|
||||
|
||||
@SCons.Memoize.CountMethodCall
|
||||
def _save_str(self):
|
||||
try:
|
||||
return self._memo['_save_str']
|
||||
except KeyError:
|
||||
pass
|
||||
result = sys.intern(self._get_str())
|
||||
result = SCons.Util.silent_intern(self._get_str())
|
||||
self._memo['_save_str'] = result
|
||||
return result
|
||||
|
||||
|
@ -799,7 +753,7 @@ class Base(SCons.Node.Node):
|
|||
path_elems = self.get_path_elements()
|
||||
pathname = ''
|
||||
try: i = path_elems.index(dir)
|
||||
except ValueError:
|
||||
except ValueError:
|
||||
for p in path_elems[:-1]:
|
||||
pathname += p.dirname
|
||||
else:
|
||||
|
@ -840,13 +794,13 @@ class Base(SCons.Node.Node):
|
|||
return self.name
|
||||
else:
|
||||
return self.dir.entry_path(self.name)
|
||||
|
||||
|
||||
def get_tpath(self):
|
||||
if self.dir._tpath == '.':
|
||||
return self.name
|
||||
else:
|
||||
return self.dir.entry_tpath(self.name)
|
||||
|
||||
|
||||
def get_path_elements(self):
|
||||
return self.dir._path_elements + [self]
|
||||
|
||||
|
@ -939,7 +893,7 @@ class Base(SCons.Node.Node):
|
|||
|
||||
def _glob1(self, pattern, ondisk=True, source=False, strings=False):
|
||||
return []
|
||||
|
||||
|
||||
# Dict that provides a simple backward compatibility
|
||||
# layer for the Node attributes 'abspath', 'labspath',
|
||||
# 'path', 'tpath' and 'path_elements'.
|
||||
|
@ -971,15 +925,13 @@ class Entry(Base):
|
|||
'root',
|
||||
'dirname',
|
||||
'on_disk_entries',
|
||||
'sccs_dir',
|
||||
'rcs_dir',
|
||||
'released_target_info',
|
||||
'contentsig']
|
||||
|
||||
def __init__(self, name, directory, fs):
|
||||
Base.__init__(self, name, directory, fs)
|
||||
self._func_exists = 3
|
||||
self._func_get_contents = 1
|
||||
self._func_get_contents = 1
|
||||
|
||||
def diskcheck_match(self):
|
||||
pass
|
||||
|
@ -1198,7 +1150,7 @@ class FS(LocalFS):
|
|||
|
||||
DirNodeInfo.fs = self
|
||||
FileNodeInfo.fs = self
|
||||
|
||||
|
||||
def set_SConstruct_dir(self, dir):
|
||||
self.SConstruct_dir = dir
|
||||
|
||||
|
@ -1210,9 +1162,9 @@ class FS(LocalFS):
|
|||
|
||||
def getcwd(self):
|
||||
if hasattr(self, "_cwd"):
|
||||
return self._cwd
|
||||
return self._cwd
|
||||
else:
|
||||
return "<no cwd>"
|
||||
return "<no cwd>"
|
||||
|
||||
def chdir(self, dir, change_os_dir=0):
|
||||
"""Change the current working directory for lookups.
|
||||
|
@ -1310,7 +1262,7 @@ class FS(LocalFS):
|
|||
p = p.strip('/')
|
||||
|
||||
needs_normpath = needs_normpath_match(p)
|
||||
|
||||
|
||||
# The path is relative to the top-level SCons directory.
|
||||
if p in ('', '.'):
|
||||
p = directory.get_labspath()
|
||||
|
@ -1437,6 +1389,35 @@ class FS(LocalFS):
|
|||
if not isinstance(d, SCons.Node.Node):
|
||||
d = self.Dir(d)
|
||||
self.Top.addRepository(d)
|
||||
|
||||
def PyPackageDir(self, modulename):
|
||||
"""Locate the directory of a given python module name
|
||||
|
||||
For example scons might resolve to
|
||||
Windows: C:\Python27\Lib\site-packages\scons-2.5.1
|
||||
Linux: /usr/lib/scons
|
||||
|
||||
This can be useful when we want to determine a toolpath based on a python module name"""
|
||||
|
||||
dirpath = ''
|
||||
if sys.version_info[0] < 3 or (sys.version_info[0] == 3 and sys.version_info[1] in (0,1,2,3,4)):
|
||||
# Python2 Code
|
||||
import imp
|
||||
splitname = modulename.split('.')
|
||||
srchpths = sys.path
|
||||
for item in splitname:
|
||||
file, path, desc = imp.find_module(item, srchpths)
|
||||
if file is not None:
|
||||
path = os.path.dirname(path)
|
||||
srchpths = [path]
|
||||
dirpath = path
|
||||
else:
|
||||
# Python3 Code
|
||||
import importlib.util
|
||||
modspec = importlib.util.find_spec(modulename)
|
||||
dirpath = os.path.dirname(modspec.origin)
|
||||
return self._lookup(dirpath, None, Dir, True)
|
||||
|
||||
|
||||
def variant_dir_target_climb(self, orig, dir, tail):
|
||||
"""Create targets in corresponding variant directories
|
||||
|
@ -1469,7 +1450,7 @@ class FS(LocalFS):
|
|||
"""
|
||||
Globs
|
||||
|
||||
This is mainly a shim layer
|
||||
This is mainly a shim layer
|
||||
"""
|
||||
if cwd is None:
|
||||
cwd = self.getcwd()
|
||||
|
@ -1518,8 +1499,6 @@ class Dir(Base):
|
|||
'root',
|
||||
'dirname',
|
||||
'on_disk_entries',
|
||||
'sccs_dir',
|
||||
'rcs_dir',
|
||||
'released_target_info',
|
||||
'contentsig']
|
||||
|
||||
|
@ -1555,7 +1534,7 @@ class Dir(Base):
|
|||
self._func_sconsign = 1
|
||||
self._func_exists = 2
|
||||
self._func_get_contents = 2
|
||||
|
||||
|
||||
self._abspath = SCons.Util.silent_intern(self.dir.entry_abspath(self.name))
|
||||
self._labspath = SCons.Util.silent_intern(self.dir.entry_labspath(self.name))
|
||||
if self.dir._path == '.':
|
||||
|
@ -1594,7 +1573,7 @@ class Dir(Base):
|
|||
# Prepend MkdirBuilder action to existing action list
|
||||
l = self.get_executor().action_list
|
||||
a = get_MkdirBuilder().action
|
||||
l.insert(0, a)
|
||||
l.insert(0, a)
|
||||
self.get_executor().set_action_list(l)
|
||||
|
||||
def diskcheck_match(self):
|
||||
|
@ -1606,7 +1585,7 @@ class Dir(Base):
|
|||
This clears any cached information that is invalidated by changing
|
||||
the repository."""
|
||||
|
||||
for node in self.entries.values():
|
||||
for node in list(self.entries.values()):
|
||||
if node != self.dir:
|
||||
if node != self and isinstance(node, Dir):
|
||||
node.__clearRepositoryCache(duplicate)
|
||||
|
@ -1742,7 +1721,7 @@ class Dir(Base):
|
|||
|
||||
path_elems = ['..'] * (len(self._path_elements) - i) \
|
||||
+ [n.name for n in other._path_elements[i:]]
|
||||
|
||||
|
||||
result = OS_SEP.join(path_elems)
|
||||
|
||||
memo_dict[other] = result
|
||||
|
@ -1913,10 +1892,10 @@ class Dir(Base):
|
|||
|
||||
def get_internal_path(self):
|
||||
return self._path
|
||||
|
||||
|
||||
def get_tpath(self):
|
||||
return self._tpath
|
||||
|
||||
|
||||
def get_path_elements(self):
|
||||
return self._path_elements
|
||||
|
||||
|
@ -1936,7 +1915,7 @@ class Dir(Base):
|
|||
""" Searches through the file/dir entries of the current
|
||||
directory, and returns True if a physical entry with the given
|
||||
name could be found.
|
||||
|
||||
|
||||
@see rentry_exists_on_disk
|
||||
"""
|
||||
try:
|
||||
|
@ -1970,10 +1949,10 @@ class Dir(Base):
|
|||
The local directory (self) gets searched first, so
|
||||
repositories take a lower precedence regarding the
|
||||
searching order.
|
||||
|
||||
|
||||
@see entry_exists_on_disk
|
||||
"""
|
||||
|
||||
|
||||
rentry_exists = self.entry_exists_on_disk(name)
|
||||
if not rentry_exists:
|
||||
# Search through the repository folders
|
||||
|
@ -2085,9 +2064,7 @@ class Dir(Base):
|
|||
return node
|
||||
|
||||
def file_on_disk(self, name):
|
||||
if self.entry_exists_on_disk(name) or \
|
||||
diskcheck_rcs(self, name) or \
|
||||
diskcheck_sccs(self, name):
|
||||
if self.entry_exists_on_disk(name):
|
||||
try: return self.File(name)
|
||||
except TypeError: pass
|
||||
node = self.srcdir_duplicate(name)
|
||||
|
@ -2178,7 +2155,7 @@ class Dir(Base):
|
|||
for x in excludeList:
|
||||
r = self.glob(x, ondisk, source, strings)
|
||||
excludes.extend(r)
|
||||
result = filter(lambda x: not any(fnmatch.fnmatch(str(x), str(e)) for e in SCons.Util.flatten(excludes)), result)
|
||||
result = [x for x in result if not any(fnmatch.fnmatch(str(x), str(e)) for e in SCons.Util.flatten(excludes))]
|
||||
return sorted(result, key=lambda a: str(a))
|
||||
|
||||
def _glob1(self, pattern, ondisk=True, source=False, strings=False):
|
||||
|
@ -2256,9 +2233,9 @@ class RootDir(Dir):
|
|||
add a separator when creating the path names of entries within
|
||||
this directory.
|
||||
"""
|
||||
|
||||
|
||||
__slots__ = ['_lookupDict']
|
||||
|
||||
|
||||
def __init__(self, drive, fs):
|
||||
if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.RootDir')
|
||||
SCons.Node.Node.__init__(self)
|
||||
|
@ -2266,7 +2243,7 @@ class RootDir(Dir):
|
|||
# Handle all the types of drives:
|
||||
if drive == '':
|
||||
# No drive, regular UNIX root or Windows default drive.
|
||||
name = OS_SEP
|
||||
name = OS_SEP
|
||||
dirname = OS_SEP
|
||||
elif drive == '//':
|
||||
# UNC path
|
||||
|
@ -2277,8 +2254,8 @@ class RootDir(Dir):
|
|||
name = drive
|
||||
dirname = drive + OS_SEP
|
||||
|
||||
#: Filename with extension as it was specified when the object was
|
||||
#: created; to obtain filesystem path, use Python str() function
|
||||
# Filename with extension as it was specified when the object was
|
||||
# created; to obtain filesystem path, use Python str() function
|
||||
self.name = SCons.Util.silent_intern(name)
|
||||
self.fs = fs #: Reference to parent Node.FS object
|
||||
|
||||
|
@ -2336,7 +2313,7 @@ class RootDir(Dir):
|
|||
self._func_sconsign = 1
|
||||
self._func_exists = 2
|
||||
self._func_get_contents = 2
|
||||
|
||||
|
||||
# Don't just reset the executor, replace its action list,
|
||||
# because it might have some pre-or post-actions that need to
|
||||
# be preserved.
|
||||
|
@ -2352,9 +2329,9 @@ class RootDir(Dir):
|
|||
# Prepend MkdirBuilder action to existing action list
|
||||
l = self.get_executor().action_list
|
||||
a = get_MkdirBuilder().action
|
||||
l.insert(0, a)
|
||||
l.insert(0, a)
|
||||
self.get_executor().set_action_list(l)
|
||||
|
||||
|
||||
|
||||
def must_be_same(self, klass):
|
||||
if klass is Dir:
|
||||
|
@ -2433,6 +2410,7 @@ class RootDir(Dir):
|
|||
def src_builder(self):
|
||||
return _null
|
||||
|
||||
|
||||
class FileNodeInfo(SCons.Node.NodeInfoBase):
|
||||
__slots__ = ('csig', 'timestamp', 'size')
|
||||
current_version_id = 2
|
||||
|
@ -2484,6 +2462,7 @@ class FileNodeInfo(SCons.Node.NodeInfoBase):
|
|||
if key not in ('__weakref__',):
|
||||
setattr(self, key, value)
|
||||
|
||||
|
||||
class FileBuildInfo(SCons.Node.BuildInfoBase):
|
||||
__slots__ = ()
|
||||
current_version_id = 2
|
||||
|
@ -2514,6 +2493,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
|
|||
pass
|
||||
else:
|
||||
setattr(self, attr, list(map(node_to_str, val)))
|
||||
|
||||
def convert_from_sconsign(self, dir, name):
|
||||
"""
|
||||
Converts a newly-read FileBuildInfo object for in-SCons use
|
||||
|
@ -2522,6 +2502,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
|
|||
perform--but we're leaving this method here to make that clear.
|
||||
"""
|
||||
pass
|
||||
|
||||
def prepare_dependencies(self):
|
||||
"""
|
||||
Prepares a FileBuildInfo object for explaining what changed
|
||||
|
@ -2550,6 +2531,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
|
|||
s = ni.str_to_node(s)
|
||||
nodes.append(s)
|
||||
setattr(self, nattr, nodes)
|
||||
|
||||
def format(self, names=0):
|
||||
result = []
|
||||
bkids = self.bsources + self.bdepends + self.bimplicit
|
||||
|
@ -2562,6 +2544,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
|
|||
result.append('%s [%s]' % (self.bactsig, self.bact))
|
||||
return '\n'.join(result)
|
||||
|
||||
|
||||
class File(Base):
|
||||
"""A class for files in a file system.
|
||||
"""
|
||||
|
@ -2578,8 +2561,6 @@ class File(Base):
|
|||
'root',
|
||||
'dirname',
|
||||
'on_disk_entries',
|
||||
'sccs_dir',
|
||||
'rcs_dir',
|
||||
'released_target_info',
|
||||
'contentsig']
|
||||
|
||||
|
@ -2628,11 +2609,11 @@ class File(Base):
|
|||
self.store_info = 1
|
||||
self._func_exists = 4
|
||||
self._func_get_contents = 3
|
||||
|
||||
|
||||
# Initialize this Node's decider function to decide_source() because
|
||||
# every file is a source file until it has a Builder attached...
|
||||
self.changed_since_last_build = 4
|
||||
|
||||
|
||||
# If there was already a Builder set on this entry, then
|
||||
# we need to make sure we call the target-decider function,
|
||||
# not the source-decider. Reaching in and doing this by hand
|
||||
|
@ -2652,10 +2633,12 @@ class File(Base):
|
|||
def get_contents(self):
|
||||
return SCons.Node._get_contents_map[self._func_get_contents](self)
|
||||
|
||||
# This attempts to figure out what the encoding of the text is
|
||||
# based upon the BOM bytes, and then decodes the contents so that
|
||||
# it's a valid python string.
|
||||
def get_text_contents(self):
|
||||
"""
|
||||
This attempts to figure out what the encoding of the text is
|
||||
based upon the BOM bytes, and then decodes the contents so that
|
||||
it's a valid python string.
|
||||
"""
|
||||
contents = self.get_contents()
|
||||
# The behavior of various decode() methods and functions
|
||||
# w.r.t. the initial BOM bytes is different for different
|
||||
|
@ -2663,13 +2646,20 @@ class File(Base):
|
|||
# them, but has a 'utf-8-sig' which does; 'utf-16' seems to
|
||||
# strip them; etc.) Just sidestep all the complication by
|
||||
# explicitly stripping the BOM before we decode().
|
||||
if contents.startswith(codecs.BOM_UTF8):
|
||||
if contents[:len(codecs.BOM_UTF8)] == codecs.BOM_UTF8:
|
||||
return contents[len(codecs.BOM_UTF8):].decode('utf-8')
|
||||
if contents.startswith(codecs.BOM_UTF16_LE):
|
||||
if contents[:len(codecs.BOM_UTF16_LE)] == codecs.BOM_UTF16_LE:
|
||||
return contents[len(codecs.BOM_UTF16_LE):].decode('utf-16-le')
|
||||
if contents.startswith(codecs.BOM_UTF16_BE):
|
||||
if contents[:len(codecs.BOM_UTF16_BE)] == codecs.BOM_UTF16_BE:
|
||||
return contents[len(codecs.BOM_UTF16_BE):].decode('utf-16-be')
|
||||
return contents
|
||||
try:
|
||||
return contents.decode('utf-8')
|
||||
except UnicodeDecodeError as e:
|
||||
try:
|
||||
return contents.decode('latin-1')
|
||||
except UnicodeDecodeError as e:
|
||||
return contents.decode('utf-8', error='backslashreplace')
|
||||
|
||||
|
||||
def get_content_hash(self):
|
||||
"""
|
||||
|
@ -2681,12 +2671,12 @@ class File(Base):
|
|||
try:
|
||||
cs = SCons.Util.MD5filesignature(fname,
|
||||
chunksize=SCons.Node.FS.File.md5_chunksize*1024)
|
||||
except EnvironmentError, e:
|
||||
except EnvironmentError as e:
|
||||
if not e.filename:
|
||||
e.filename = fname
|
||||
raise
|
||||
return cs
|
||||
|
||||
|
||||
@SCons.Memoize.CountMethodCall
|
||||
def get_size(self):
|
||||
try:
|
||||
|
@ -2960,30 +2950,30 @@ class File(Base):
|
|||
def release_target_info(self):
|
||||
"""Called just after this node has been marked
|
||||
up-to-date or was built completely.
|
||||
|
||||
|
||||
This is where we try to release as many target node infos
|
||||
as possible for clean builds and update runs, in order
|
||||
to minimize the overall memory consumption.
|
||||
|
||||
|
||||
We'd like to remove a lot more attributes like self.sources
|
||||
and self.sources_set, but they might get used
|
||||
in a next build step. For example, during configuration
|
||||
the source files for a built *.o file are used to figure out
|
||||
the source files for a built E{*}.o file are used to figure out
|
||||
which linker to use for the resulting Program (gcc vs. g++)!
|
||||
That's why we check for the 'keep_targetinfo' attribute,
|
||||
config Nodes and the Interactive mode just don't allow
|
||||
an early release of most variables.
|
||||
an early release of most variables.
|
||||
|
||||
In the same manner, we can't simply remove the self.attributes
|
||||
here. The smart linking relies on the shared flag, and some
|
||||
parts of the java Tool use it to transport information
|
||||
about nodes...
|
||||
|
||||
|
||||
@see: built() and Node.release_target_info()
|
||||
"""
|
||||
if (self.released_target_info or SCons.Node.interactive):
|
||||
return
|
||||
|
||||
|
||||
if not hasattr(self.attributes, 'keep_targetinfo'):
|
||||
# Cache some required values, before releasing
|
||||
# stuff like env, executor and builder...
|
||||
|
@ -3014,12 +3004,7 @@ class File(Base):
|
|||
return None
|
||||
scb = self.dir.src_builder()
|
||||
if scb is _null:
|
||||
if diskcheck_sccs(self.dir, self.name):
|
||||
scb = get_DefaultSCCSBuilder()
|
||||
elif diskcheck_rcs(self.dir, self.name):
|
||||
scb = get_DefaultRCSBuilder()
|
||||
else:
|
||||
scb = None
|
||||
scb = None
|
||||
if scb is not None:
|
||||
try:
|
||||
b = self.builder
|
||||
|
@ -3056,7 +3041,7 @@ class File(Base):
|
|||
def _rmv_existing(self):
|
||||
self.clear_memoized_values()
|
||||
if SCons.Node.print_duplicate:
|
||||
print "dup: removing existing target %s"%self
|
||||
print("dup: removing existing target {}".format(self))
|
||||
e = Unlink(self, [], None)
|
||||
if isinstance(e, SCons.Errors.BuildError):
|
||||
raise e
|
||||
|
@ -3080,9 +3065,8 @@ class File(Base):
|
|||
else:
|
||||
try:
|
||||
self._createDir()
|
||||
except SCons.Errors.StopError, drive:
|
||||
desc = "No drive `%s' for target `%s'." % (drive, self)
|
||||
raise SCons.Errors.StopError(desc)
|
||||
except SCons.Errors.StopError as drive:
|
||||
raise SCons.Errors.StopError("No drive `{}' for target `{}'.".format(drive, self))
|
||||
|
||||
#
|
||||
#
|
||||
|
@ -3098,12 +3082,11 @@ class File(Base):
|
|||
def do_duplicate(self, src):
|
||||
self._createDir()
|
||||
if SCons.Node.print_duplicate:
|
||||
print "dup: relinking variant '%s' from '%s'"%(self, src)
|
||||
print("dup: relinking variant '{}' from '{}'".format(self, src))
|
||||
Unlink(self, None, None)
|
||||
e = Link(self, src, None)
|
||||
if isinstance(e, SCons.Errors.BuildError):
|
||||
desc = "Cannot duplicate `%s' in `%s': %s." % (src.get_internal_path(), self.dir._path, e.errstr)
|
||||
raise SCons.Errors.StopError(desc)
|
||||
raise SCons.Errors.StopError("Cannot duplicate `{}' in `{}': {}.".format(src.get_internal_path(), self.dir._path, e.errstr))
|
||||
self.linked = 1
|
||||
# The Link() action may or may not have actually
|
||||
# created the file, depending on whether the -n
|
||||
|
@ -3117,7 +3100,6 @@ class File(Base):
|
|||
return self._memo['exists']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
result = SCons.Node._exists_map[self._func_exists](self)
|
||||
self._memo['exists'] = result
|
||||
return result
|
||||
|
@ -3199,37 +3181,37 @@ class File(Base):
|
|||
|
||||
def built(self):
|
||||
"""Called just after this File node is successfully built.
|
||||
|
||||
|
||||
Just like for 'release_target_info' we try to release
|
||||
some more target node attributes in order to minimize the
|
||||
overall memory consumption.
|
||||
|
||||
|
||||
@see: release_target_info
|
||||
"""
|
||||
|
||||
SCons.Node.Node.built(self)
|
||||
|
||||
if (not SCons.Node.interactive and
|
||||
if (not SCons.Node.interactive and
|
||||
not hasattr(self.attributes, 'keep_targetinfo')):
|
||||
# Ensure that the build infos get computed and cached...
|
||||
# Ensure that the build infos get computed and cached...
|
||||
SCons.Node.store_info_map[self.store_info](self)
|
||||
# ... then release some more variables.
|
||||
self._specific_sources = False
|
||||
self._labspath = None
|
||||
self._save_str()
|
||||
self.cwd = None
|
||||
|
||||
|
||||
self.scanner_paths = None
|
||||
|
||||
def changed(self, node=None, allowcache=False):
|
||||
"""
|
||||
Returns if the node is up-to-date with respect to the BuildInfo
|
||||
stored last time it was built.
|
||||
|
||||
stored last time it was built.
|
||||
|
||||
For File nodes this is basically a wrapper around Node.changed(),
|
||||
but we allow the return value to get cached after the reference
|
||||
to the Executor got released in release_target_info().
|
||||
|
||||
|
||||
@see: Node.changed()
|
||||
"""
|
||||
if node is None:
|
||||
|
@ -3237,7 +3219,7 @@ class File(Base):
|
|||
return self._memo['changed']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
has_changed = SCons.Node.Node.changed(self, node)
|
||||
if allowcache:
|
||||
self._memo['changed'] = has_changed
|
||||
|
@ -3290,7 +3272,7 @@ class File(Base):
|
|||
# ...and they'd like a local copy.
|
||||
e = LocalCopy(self, r, None)
|
||||
if isinstance(e, SCons.Errors.BuildError):
|
||||
raise
|
||||
raise
|
||||
SCons.Node.store_info_map[self.store_info](self)
|
||||
if T: Trace(' 1\n')
|
||||
return 1
|
||||
|
@ -3372,12 +3354,12 @@ class File(Base):
|
|||
It computes and returns the signature for this
|
||||
node's contents.
|
||||
"""
|
||||
|
||||
|
||||
try:
|
||||
return self.contentsig
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
executor = self.get_executor()
|
||||
|
||||
result = self.contentsig = SCons.Util.MD5signature(executor.get_contents())
|
||||
|
@ -3397,7 +3379,7 @@ class File(Base):
|
|||
return self.cachesig
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
# Collect signatures for all children
|
||||
children = self.children()
|
||||
sigs = [n.get_cachedir_csig() for n in children]
|
||||
|
@ -3461,24 +3443,19 @@ class FileFinder(object):
|
|||
|
||||
def _find_file_key(self, filename, paths, verbose=None):
|
||||
return (filename, paths)
|
||||
|
||||
|
||||
@SCons.Memoize.CountDictCall(_find_file_key)
|
||||
def find_file(self, filename, paths, verbose=None):
|
||||
"""
|
||||
find_file(str, [Dir()]) -> [nodes]
|
||||
Find a node corresponding to either a derived file or a file that exists already.
|
||||
|
||||
filename - a filename to find
|
||||
paths - a list of directory path *nodes* to search in. Can be
|
||||
represented as a list, a tuple, or a callable that is
|
||||
called with no arguments and returns the list or tuple.
|
||||
Only the first file found is returned, and none is returned if no file is found.
|
||||
|
||||
returns - the node created from the found file.
|
||||
filename: A filename to find
|
||||
paths: A list of directory path *nodes* to search in. Can be represented as a list, a tuple, or a callable that is called with no arguments and returns the list or tuple.
|
||||
|
||||
Find a node corresponding to either a derived file or a file
|
||||
that exists already.
|
||||
returns The node created from the found file.
|
||||
|
||||
Only the first file found is returned, and none is returned
|
||||
if no file is found.
|
||||
"""
|
||||
memo_key = self._find_file_key(filename, paths)
|
||||
try:
|
||||
|
@ -3547,7 +3524,7 @@ def invalidate_node_memos(targets):
|
|||
|
||||
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.
|
||||
|
@ -3559,7 +3536,7 @@ def invalidate_node_memos(targets):
|
|||
# do not correspond to an existing Node object.
|
||||
node = get_default_fs().Entry(entry)
|
||||
if node:
|
||||
node.clear_memoized_values()
|
||||
node.clear_memoized_values()
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
|
@ -5,7 +5,7 @@ Python nodes.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ Python nodes.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Node/Python.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Node/Python.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.Node
|
||||
|
||||
|
@ -58,7 +58,7 @@ class ValueNodeInfo(SCons.Node.NodeInfoBase):
|
|||
del state['__weakref__']
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
return state
|
||||
|
||||
def __setstate__(self, state):
|
||||
|
@ -77,7 +77,7 @@ class ValueBuildInfo(SCons.Node.BuildInfoBase):
|
|||
current_version_id = 2
|
||||
|
||||
class Value(SCons.Node.Node):
|
||||
"""A class for Python variables, typically passed on the command line
|
||||
"""A class for Python variables, typically passed on the command line
|
||||
or generated by a script, but not from a file or some other source.
|
||||
"""
|
||||
|
||||
|
@ -108,7 +108,7 @@ class Value(SCons.Node.Node):
|
|||
is_up_to_date = SCons.Node.Node.children_are_up_to_date
|
||||
|
||||
def is_under(self, dir):
|
||||
# Make Value nodes get built regardless of
|
||||
# Make Value nodes get built regardless of
|
||||
# what directory scons was run from. Value nodes
|
||||
# are outside the filesystem:
|
||||
return 1
|
||||
|
@ -133,10 +133,17 @@ class Value(SCons.Node.Node):
|
|||
###TODO: something reasonable about universal newlines
|
||||
contents = str(self.value)
|
||||
for kid in self.children(None):
|
||||
contents = contents + kid.get_contents()
|
||||
contents = contents + kid.get_contents().decode()
|
||||
return contents
|
||||
|
||||
get_contents = get_text_contents ###TODO should return 'bytes' value
|
||||
def get_contents(self):
|
||||
text_contents = self.get_text_contents()
|
||||
try:
|
||||
return text_contents.encode()
|
||||
except UnicodeDecodeError:
|
||||
# Already encoded as python2 str are bytes
|
||||
return text_contents
|
||||
|
||||
|
||||
def changed_since_last_build(self, target, prev_ni):
|
||||
cur_csig = self.get_csig()
|
|
@ -19,8 +19,10 @@ be able to depend on any other type of "thing."
|
|||
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -41,7 +43,7 @@ be able to depend on any other type of "thing."
|
|||
# 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/Node/__init__.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Node/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import collections
|
||||
import copy
|
||||
|
@ -55,6 +57,8 @@ import SCons.Util
|
|||
|
||||
from SCons.Debug import Trace
|
||||
|
||||
from SCons.compat import with_metaclass, NoSlotsPyPy
|
||||
|
||||
print_duplicate = 0
|
||||
|
||||
def classname(obj):
|
||||
|
@ -151,7 +155,7 @@ def exists_file(node):
|
|||
# The source file does not exist. Make sure no old
|
||||
# copy remains in the variant directory.
|
||||
if print_duplicate:
|
||||
print "dup: no src for %s, unlinking old variant copy"%self
|
||||
print("dup: no src for %s, unlinking old variant copy"%self)
|
||||
if exists_base(node) or node.islink():
|
||||
node.fs.unlink(node.get_internal_path())
|
||||
# Return None explicitly because the Base.exists() call
|
||||
|
@ -205,13 +209,14 @@ def get_contents_dir(node):
|
|||
contents.append('%s %s\n' % (n.get_csig(), n.name))
|
||||
return ''.join(contents)
|
||||
|
||||
def get_contents_file(node):
|
||||
def get_contents_file(node):
|
||||
if not node.rexists():
|
||||
return ''
|
||||
return b''
|
||||
fname = node.rfile().get_abspath()
|
||||
try:
|
||||
contents = open(fname, "rb").read()
|
||||
except EnvironmentError, e:
|
||||
with open(fname, "rb") as fp:
|
||||
contents = fp.read()
|
||||
except EnvironmentError as e:
|
||||
if not e.filename:
|
||||
e.filename = fname
|
||||
raise
|
||||
|
@ -345,6 +350,7 @@ class NodeInfoBase(object):
|
|||
"""
|
||||
__slots__ = ('__weakref__',)
|
||||
current_version_id = 2
|
||||
|
||||
def update(self, node):
|
||||
try:
|
||||
field_list = self.field_list
|
||||
|
@ -361,8 +367,10 @@ class NodeInfoBase(object):
|
|||
pass
|
||||
else:
|
||||
setattr(self, f, func())
|
||||
|
||||
def convert(self, node, val):
|
||||
pass
|
||||
|
||||
def merge(self, other):
|
||||
"""
|
||||
Merge the fields of another object into this object. Already existing
|
||||
|
@ -377,7 +385,7 @@ class NodeInfoBase(object):
|
|||
try:
|
||||
field_list = self.field_list
|
||||
except AttributeError:
|
||||
field_list = getattr(self, '__dict__', {}).keys()
|
||||
field_list = list(getattr(self, '__dict__', {}).keys())
|
||||
for obj in type(self).mro():
|
||||
for slot in getattr(obj, '__slots__', ()):
|
||||
if slot not in ('__weakref__', '__dict__'):
|
||||
|
@ -407,21 +415,21 @@ class NodeInfoBase(object):
|
|||
for name in getattr(obj,'__slots__',()):
|
||||
if hasattr(self, name):
|
||||
state[name] = getattr(self, name)
|
||||
|
||||
|
||||
state['_version_id'] = self.current_version_id
|
||||
try:
|
||||
del state['__weakref__']
|
||||
except KeyError:
|
||||
pass
|
||||
return state
|
||||
|
||||
|
||||
def __setstate__(self, state):
|
||||
"""
|
||||
Restore the attributes from a pickled state. The version is discarded.
|
||||
"""
|
||||
# TODO check or discard version
|
||||
del state['_version_id']
|
||||
|
||||
|
||||
for key, value in state.items():
|
||||
if key not in ('__weakref__',):
|
||||
setattr(self, key, value)
|
||||
|
@ -440,6 +448,7 @@ class BuildInfoBase(object):
|
|||
__slots__ = ("bsourcesigs", "bdependsigs", "bimplicitsigs", "bactsig",
|
||||
"bsources", "bdepends", "bact", "bimplicit", "__weakref__")
|
||||
current_version_id = 2
|
||||
|
||||
def __init__(self):
|
||||
# Create an object attribute from the class attribute so it ends up
|
||||
# in the pickled data in the .sconsign file.
|
||||
|
@ -447,6 +456,7 @@ class BuildInfoBase(object):
|
|||
self.bdependsigs = []
|
||||
self.bimplicitsigs = []
|
||||
self.bactsig = None
|
||||
|
||||
def merge(self, other):
|
||||
"""
|
||||
Merge the fields of another object into this object. Already existing
|
||||
|
@ -456,7 +466,7 @@ class BuildInfoBase(object):
|
|||
"""
|
||||
state = other.__getstate__()
|
||||
self.__setstate__(state)
|
||||
|
||||
|
||||
def __getstate__(self):
|
||||
"""
|
||||
Return all fields that shall be pickled. Walk the slots in the class
|
||||
|
@ -487,7 +497,8 @@ class BuildInfoBase(object):
|
|||
if key not in ('__weakref__',):
|
||||
setattr(self, key, value)
|
||||
|
||||
class Node(object):
|
||||
|
||||
class Node(object, with_metaclass(NoSlotsPyPy)):
|
||||
"""The base Node class, for entities that we know how to
|
||||
build, or use to build other Nodes.
|
||||
"""
|
||||
|
@ -536,7 +547,7 @@ class Node(object):
|
|||
|
||||
class Attrs(object):
|
||||
__slots__ = ('shared', '__dict__')
|
||||
|
||||
|
||||
|
||||
def __init__(self):
|
||||
if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.Node')
|
||||
|
@ -588,7 +599,7 @@ class Node(object):
|
|||
self._func_rexists = 1
|
||||
self._func_get_contents = 0
|
||||
self._func_target_from_source = 0
|
||||
|
||||
|
||||
self.clear_memoized_values()
|
||||
|
||||
# Let the interface in which the build engine is embedded
|
||||
|
@ -737,7 +748,7 @@ class Node(object):
|
|||
"""
|
||||
try:
|
||||
self.get_executor()(self, **kw)
|
||||
except SCons.Errors.BuildError, e:
|
||||
except SCons.Errors.BuildError as e:
|
||||
e.node = self
|
||||
raise
|
||||
|
||||
|
@ -776,16 +787,16 @@ class Node(object):
|
|||
def release_target_info(self):
|
||||
"""Called just after this node has been marked
|
||||
up-to-date or was built completely.
|
||||
|
||||
|
||||
This is where we try to release as many target node infos
|
||||
as possible for clean builds and update runs, in order
|
||||
to minimize the overall memory consumption.
|
||||
|
||||
|
||||
By purging attributes that aren't needed any longer after
|
||||
a Node (=File) got built, we don't have to care that much how
|
||||
many KBytes a Node actually requires...as long as we free
|
||||
the memory shortly afterwards.
|
||||
|
||||
|
||||
@see: built() and File.release_target_info()
|
||||
"""
|
||||
pass
|
||||
|
@ -924,9 +935,9 @@ class Node(object):
|
|||
scanner's recursive flag says that we should.
|
||||
"""
|
||||
nodes = [self]
|
||||
seen = {}
|
||||
seen[self] = 1
|
||||
seen = set(nodes)
|
||||
dependencies = []
|
||||
path_memo = {}
|
||||
|
||||
root_node_scanner = self._get_scanner(env, initial_scanner, None, kw)
|
||||
|
||||
|
@ -934,38 +945,40 @@ class Node(object):
|
|||
node = nodes.pop(0)
|
||||
|
||||
scanner = node._get_scanner(env, initial_scanner, root_node_scanner, kw)
|
||||
|
||||
if not scanner:
|
||||
continue
|
||||
|
||||
path = path_func(scanner)
|
||||
try:
|
||||
path = path_memo[scanner]
|
||||
except KeyError:
|
||||
path = path_func(scanner)
|
||||
path_memo[scanner] = path
|
||||
|
||||
included_deps = [x for x in node.get_found_includes(env, scanner, path) if x not in seen]
|
||||
if included_deps:
|
||||
dependencies.extend(included_deps)
|
||||
for dep in included_deps:
|
||||
seen[dep] = 1
|
||||
seen.update(included_deps)
|
||||
nodes.extend(scanner.recurse_nodes(included_deps))
|
||||
|
||||
return dependencies
|
||||
|
||||
def _get_scanner(self, env, initial_scanner, root_node_scanner, kw):
|
||||
if not initial_scanner:
|
||||
if initial_scanner:
|
||||
# handle explicit scanner case
|
||||
scanner = initial_scanner.select(self)
|
||||
else:
|
||||
# handle implicit scanner case
|
||||
scanner = self.get_env_scanner(env, kw)
|
||||
if scanner:
|
||||
scanner = scanner.select(self)
|
||||
else:
|
||||
# handle explicit scanner case
|
||||
scanner = initial_scanner.select(self)
|
||||
|
||||
|
||||
if not scanner:
|
||||
# no scanner could be found for the given node's scanner key;
|
||||
# thus, make an attempt at using a default.
|
||||
scanner = root_node_scanner
|
||||
|
||||
|
||||
return scanner
|
||||
|
||||
|
||||
def get_env_scanner(self, env, kw={}):
|
||||
return env.get_scanner(self.scanner_key())
|
||||
|
||||
|
@ -1123,38 +1136,22 @@ class Node(object):
|
|||
binfo.bactsig = SCons.Util.MD5signature(executor.get_contents())
|
||||
|
||||
if self._specific_sources:
|
||||
sources = []
|
||||
for s in self.sources:
|
||||
if s not in ignore_set:
|
||||
sources.append(s)
|
||||
sources = [ s for s in self.sources if not s in ignore_set]
|
||||
|
||||
else:
|
||||
sources = executor.get_unignored_sources(self, 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.bsources = [s for s in sources if s not in seen and not seen.add(s)]
|
||||
binfo.bsourcesigs = [s.get_ninfo() for s in binfo.bsources]
|
||||
|
||||
depends = self.depends
|
||||
dependsigs = []
|
||||
for d in depends:
|
||||
if d not in ignore_set:
|
||||
dependsigs.append(d.get_ninfo())
|
||||
binfo.bdepends = depends
|
||||
binfo.bdependsigs = dependsigs
|
||||
|
||||
implicit = self.implicit or []
|
||||
implicitsigs = []
|
||||
for i in implicit:
|
||||
if i not in ignore_set:
|
||||
implicitsigs.append(i.get_ninfo())
|
||||
binfo.bimplicit = implicit
|
||||
binfo.bimplicitsigs = implicitsigs
|
||||
binfo.bdepends = self.depends
|
||||
binfo.bdependsigs = [d.get_ninfo() for d in self.depends if d not in ignore_set]
|
||||
|
||||
binfo.bimplicit = self.implicit or []
|
||||
binfo.bimplicitsigs = [i.get_ninfo() for i in binfo.bimplicit if i not in ignore_set]
|
||||
|
||||
|
||||
return binfo
|
||||
|
||||
|
@ -1237,7 +1234,7 @@ class Node(object):
|
|||
"""Adds dependencies."""
|
||||
try:
|
||||
self._add_child(self.depends, self.depends_set, depend)
|
||||
except TypeError, e:
|
||||
except TypeError as e:
|
||||
e = e.args[0]
|
||||
if SCons.Util.is_List(e):
|
||||
s = list(map(str, e))
|
||||
|
@ -1256,7 +1253,7 @@ class Node(object):
|
|||
"""Adds dependencies to ignore."""
|
||||
try:
|
||||
self._add_child(self.ignore, self.ignore_set, depend)
|
||||
except TypeError, e:
|
||||
except TypeError as e:
|
||||
e = e.args[0]
|
||||
if SCons.Util.is_List(e):
|
||||
s = list(map(str, e))
|
||||
|
@ -1270,7 +1267,7 @@ class Node(object):
|
|||
return
|
||||
try:
|
||||
self._add_child(self.sources, self.sources_set, source)
|
||||
except TypeError, e:
|
||||
except TypeError as e:
|
||||
e = e.args[0]
|
||||
if SCons.Util.is_List(e):
|
||||
s = list(map(str, e))
|
||||
|
@ -1330,7 +1327,7 @@ class Node(object):
|
|||
# dictionary patterns I found all ended up using "not in"
|
||||
# internally anyway...)
|
||||
if self.ignore_set:
|
||||
iter = chain.from_iterable(filter(None, [self.sources, self.depends, self.implicit]))
|
||||
iter = chain.from_iterable([_f for _f in [self.sources, self.depends, self.implicit] if _f])
|
||||
|
||||
children = []
|
||||
for i in iter:
|
||||
|
@ -1364,7 +1361,7 @@ class Node(object):
|
|||
# using dictionary keys, lose the order, and the only ordered
|
||||
# dictionary patterns I found all ended up using "not in"
|
||||
# internally anyway...)
|
||||
return list(chain.from_iterable(filter(None, [self.sources, self.depends, self.implicit])))
|
||||
return list(chain.from_iterable([_f for _f in [self.sources, self.depends, self.implicit] if _f]))
|
||||
|
||||
def children(self, scan=1):
|
||||
"""Return a list of the node's direct children, minus those
|
||||
|
@ -1388,7 +1385,7 @@ class Node(object):
|
|||
|
||||
def Decider(self, function):
|
||||
foundkey = None
|
||||
for k, v in _decider_map.iteritems():
|
||||
for k, v in _decider_map.items():
|
||||
if v == function:
|
||||
foundkey = k
|
||||
break
|
||||
|
@ -1422,14 +1419,14 @@ class Node(object):
|
|||
any difference, but we now rely on checking every dependency
|
||||
to make sure that any necessary Node information (for example,
|
||||
the content signature of an #included .h file) is updated.
|
||||
|
||||
|
||||
The allowcache option was added for supporting the early
|
||||
release of the executor/builder structures, right after
|
||||
a File target was built. When set to true, the return
|
||||
value of this changed method gets cached for File nodes.
|
||||
Like this, the executor isn't needed any longer for subsequent
|
||||
calls to changed().
|
||||
|
||||
|
||||
@see: FS.File.changed(), FS.File.release_target_info()
|
||||
"""
|
||||
t = 0
|
||||
|
@ -1601,8 +1598,8 @@ class Node(object):
|
|||
new_bkids = new.bsources + new.bdepends + new.bimplicit
|
||||
new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs
|
||||
|
||||
osig = dict(zip(old_bkids, old_bkidsigs))
|
||||
nsig = dict(zip(new_bkids, new_bkidsigs))
|
||||
osig = dict(list(zip(old_bkids, old_bkidsigs)))
|
||||
nsig = dict(list(zip(new_bkids, new_bkidsigs)))
|
||||
|
||||
# The sources and dependencies we'll want to report are all stored
|
||||
# as relative paths to this target's directory, but we want to
|
||||
|
@ -1643,6 +1640,9 @@ class Node(object):
|
|||
if old.bact == new.bact:
|
||||
lines.append("the contents of the build action changed\n" +
|
||||
fmt_with_title('action: ', new.bact))
|
||||
|
||||
# lines.append("the contents of the build action changed [%s] [%s]\n"%(old.bactsig,new.bactsig) +
|
||||
# fmt_with_title('action: ', new.bact))
|
||||
else:
|
||||
lines.append("the build action changed:\n" +
|
||||
fmt_with_title('old: ', old.bact) +
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Options/BoolOption.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Options/BoolOption.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Options module hierarchy
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Options/EnumOption.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Options/EnumOption.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Options module hierarchy
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Options/ListOption.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Options/ListOption.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Options module hierarchy
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Options/PackageOption.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Options/PackageOption.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Options module hierarchy
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Options/PathOption.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Options/PathOption.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Options module hierarchy
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Options/__init__.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Options/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """Place-holder for the old SCons.Options module hierarchy
|
||||
|
||||
|
@ -33,11 +33,11 @@ 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
|
||||
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
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/PathList.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/PathList.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """SCons.PathList
|
||||
|
||||
|
@ -104,11 +104,11 @@ class _PathList(object):
|
|||
pl = []
|
||||
for p in pathlist:
|
||||
try:
|
||||
index = p.find('$')
|
||||
found = '$' in p
|
||||
except (AttributeError, TypeError):
|
||||
type = TYPE_OBJECT
|
||||
else:
|
||||
if index == -1:
|
||||
if not found:
|
||||
type = TYPE_STRING_NO_SUBST
|
||||
else:
|
||||
type = TYPE_STRING_SUBST
|
|
@ -20,8 +20,8 @@ their own platform definition.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
#
|
||||
# Copyright (c) 2001 - 2017 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
|
||||
|
@ -41,8 +41,9 @@ their own platform definition.
|
|||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
from __future__ import print_function
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/__init__.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Platform/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.compat
|
||||
|
||||
|
@ -55,6 +56,7 @@ import SCons.Errors
|
|||
import SCons.Subst
|
||||
import SCons.Tool
|
||||
|
||||
|
||||
def platform_default():
|
||||
"""Return the platform string for our execution environment.
|
||||
|
||||
|
@ -130,7 +132,7 @@ class PlatformSpec(object):
|
|||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class TempFileMunge(object):
|
||||
"""A callable class. You can set an Environment variable to this,
|
||||
then call it with a string argument, then it will perform temporary
|
||||
|
@ -183,9 +185,9 @@ class TempFileMunge(object):
|
|||
node = target[0] if SCons.Util.is_List(target) else target
|
||||
cmdlist = getattr(node.attributes, 'tempfile_cmdlist', None) \
|
||||
if node is not None else None
|
||||
if cmdlist is not None :
|
||||
if cmdlist is not None :
|
||||
return cmdlist
|
||||
|
||||
|
||||
# We do a normpath because mktemp() has what appears to be
|
||||
# a bug in Windows that will use a forward slash as a path
|
||||
# delimiter. Windows's link mistakes that for a command line
|
||||
|
@ -215,7 +217,7 @@ class TempFileMunge(object):
|
|||
prefix = '@'
|
||||
|
||||
args = list(map(SCons.Subst.quote_spaces, cmd[1:]))
|
||||
os.write(fd, " ".join(args) + "\n")
|
||||
os.write(fd, bytearray(" ".join(args) + "\n",'utf-8'))
|
||||
os.close(fd)
|
||||
# XXX Using the SCons.Action.print_actions value directly
|
||||
# like this is bogus, but expedient. This class should
|
||||
|
@ -233,14 +235,14 @@ class TempFileMunge(object):
|
|||
# purity get in the way of just being helpful, so we'll
|
||||
# reach into SCons.Action directly.
|
||||
if SCons.Action.print_actions:
|
||||
cmdstr = env.subst(self.cmdstr, SCons.Subst.SUBST_RAW, target,
|
||||
cmdstr = env.subst(self.cmdstr, SCons.Subst.SUBST_RAW, target,
|
||||
source) if self.cmdstr is not None else ''
|
||||
# Print our message only if XXXCOMSTR returns an empty string
|
||||
if len(cmdstr) == 0 :
|
||||
print("Using tempfile "+native_tmp+" for command line:\n"+
|
||||
str(cmd[0]) + " " + " ".join(args))
|
||||
|
||||
# Store the temporary file command list into the target Node.attributes
|
||||
|
||||
# Store the temporary file command list into the target Node.attributes
|
||||
# to avoid creating two temporary files one for print and one for execute.
|
||||
cmdlist = [ cmd[0], prefix + native_tmp + '\n' + rm, native_tmp ]
|
||||
if node is not None:
|
||||
|
@ -249,7 +251,8 @@ class TempFileMunge(object):
|
|||
except AttributeError:
|
||||
pass
|
||||
return cmdlist
|
||||
|
||||
|
||||
|
||||
def Platform(name = platform_default()):
|
||||
"""Select a canned Platform specification.
|
||||
"""
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,12 +30,12 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/aix.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Platform/aix.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import posix
|
||||
from . import posix
|
||||
|
||||
import SCons.Util
|
||||
import SCons.Action
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,9 +30,9 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/cygwin.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Platform/cygwin.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import posix
|
||||
from . import posix
|
||||
from SCons.Platform import TempFileMunge
|
||||
|
||||
def generate(env):
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,9 +30,9 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/darwin.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Platform/darwin.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import posix
|
||||
from . import posix
|
||||
import os
|
||||
|
||||
def generate(env):
|
||||
|
@ -63,6 +63,10 @@ def generate(env):
|
|||
env.AppendENVPath('PATHOSX', line.strip('\n'))
|
||||
f.close()
|
||||
|
||||
# Not sure why this wasn't the case all along?
|
||||
if env['ENV'].get('PATHOSX', False) and os.environ.get('SCONS_USE_MAC_PATHS', False):
|
||||
env.AppendENVPath('PATH',env['ENV']['PATHOSX'])
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,9 +30,9 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/hpux.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Platform/hpux.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import posix
|
||||
from . import posix
|
||||
|
||||
def generate(env):
|
||||
posix.generate(env)
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,9 +30,9 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/irix.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Platform/irix.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import posix
|
||||
from . import posix
|
||||
|
||||
def generate(env):
|
||||
posix.generate(env)
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,8 +30,8 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/os2.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
import win32
|
||||
__revision__ = "src/engine/SCons/Platform/os2.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
from . import win32
|
||||
|
||||
def generate(env):
|
||||
if 'ENV' not in env:
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/posix.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Platform/posix.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import errno
|
||||
import os
|
||||
|
@ -56,7 +56,7 @@ def escape(arg):
|
|||
for c in special:
|
||||
arg = arg.replace(c, slash+c)
|
||||
|
||||
# print "ESCAPE RESULT: %s"%arg
|
||||
# print("ESCAPE RESULT: %s" % arg)
|
||||
return '"' + arg + '"'
|
||||
|
||||
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,9 +30,9 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/sunos.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Platform/sunos.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import posix
|
||||
from . import posix
|
||||
|
||||
def generate(env):
|
||||
posix.generate(env)
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Platform/win32.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Platform/win32.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
@ -60,15 +60,8 @@ except AttributeError:
|
|||
else:
|
||||
parallel_msg = None
|
||||
|
||||
_builtin_file = file
|
||||
_builtin_open = open
|
||||
|
||||
class _scons_file(_builtin_file):
|
||||
def __init__(self, *args, **kw):
|
||||
_builtin_file.__init__(self, *args, **kw)
|
||||
win32api.SetHandleInformation(msvcrt.get_osfhandle(self.fileno()),
|
||||
win32con.HANDLE_FLAG_INHERIT, 0)
|
||||
|
||||
def _scons_open(*args, **kw):
|
||||
fp = _builtin_open(*args, **kw)
|
||||
win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()),
|
||||
|
@ -76,13 +69,64 @@ else:
|
|||
0)
|
||||
return fp
|
||||
|
||||
file = _scons_file
|
||||
open = _scons_open
|
||||
|
||||
if sys.version_info.major == 2:
|
||||
_builtin_file = file
|
||||
class _scons_file(_builtin_file):
|
||||
def __init__(self, *args, **kw):
|
||||
_builtin_file.__init__(self, *args, **kw)
|
||||
win32api.SetHandleInformation(msvcrt.get_osfhandle(self.fileno()),
|
||||
win32con.HANDLE_FLAG_INHERIT, 0)
|
||||
file = _scons_file
|
||||
else:
|
||||
import io
|
||||
for io_class in ['BufferedReader', 'BufferedWriter', 'BufferedRWPair',
|
||||
'BufferedRandom', 'TextIOWrapper']:
|
||||
_builtin_file = getattr(io, io_class)
|
||||
class _scons_file(_builtin_file):
|
||||
def __init__(self, *args, **kw):
|
||||
_builtin_file.__init__(self, *args, **kw)
|
||||
win32api.SetHandleInformation(msvcrt.get_osfhandle(self.fileno()),
|
||||
win32con.HANDLE_FLAG_INHERIT, 0)
|
||||
setattr(io, io_class, _scons_file)
|
||||
|
||||
|
||||
|
||||
if False:
|
||||
# Now swap out shutil.filecopy and filecopy2 for win32 api native CopyFile
|
||||
try:
|
||||
from ctypes import windll
|
||||
import shutil
|
||||
|
||||
CopyFile = windll.kernel32.CopyFileA
|
||||
SetFileTime = windll.kernel32.SetFileTime
|
||||
|
||||
_shutil_copy = shutil.copy
|
||||
_shutil_copy2 = shutil.copy2
|
||||
|
||||
shutil.copy2 = CopyFile
|
||||
|
||||
def win_api_copyfile(src,dst):
|
||||
CopyFile(src,dst)
|
||||
os.utime(dst)
|
||||
|
||||
shutil.copy = win_api_copyfile
|
||||
|
||||
except AttributeError:
|
||||
parallel_msg = \
|
||||
"Couldn't override shutil.copy or shutil.copy2 falling back to shutil defaults"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
import threading
|
||||
spawn_lock = threading.Lock()
|
||||
|
||||
|
||||
# This locked version of spawnve works around a Windows
|
||||
# MSVCRT bug, because its spawnve is not thread-safe.
|
||||
# Without this, python can randomly crash while using -jN.
|
||||
|
@ -111,11 +155,12 @@ except ImportError:
|
|||
# simulating a non-existent package.
|
||||
def spawnve(mode, file, args, env):
|
||||
return os.spawnve(mode, file, args, env)
|
||||
|
||||
|
||||
# The upshot of all this is that, if you are using Python 1.5.2,
|
||||
# you had better have cmd or command.com in your PATH when you run
|
||||
# scons.
|
||||
|
||||
|
||||
def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
||||
# There is no direct way to do that in python. What we do
|
||||
# here should work for most cases:
|
||||
|
@ -136,8 +181,7 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
|||
stderrRedirected = 0
|
||||
for arg in args:
|
||||
# are there more possibilities to redirect stdout ?
|
||||
if (arg.find( ">", 0, 1 ) != -1 or
|
||||
arg.find( "1>", 0, 2 ) != -1):
|
||||
if arg.find( ">", 0, 1 ) != -1 or arg.find( "1>", 0, 2 ) != -1:
|
||||
stdoutRedirected = 1
|
||||
# are there more possibilities to redirect stderr ?
|
||||
if arg.find( "2>", 0, 2 ) != -1:
|
||||
|
@ -153,7 +197,7 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
|||
try:
|
||||
args = [sh, '/C', escape(' '.join(args)) ]
|
||||
ret = spawnve(os.P_WAIT, sh, args, env)
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
# catch any error
|
||||
try:
|
||||
ret = exitvalmap[e[0]]
|
||||
|
@ -178,13 +222,14 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
|||
pass
|
||||
return ret
|
||||
|
||||
|
||||
def exec_spawn(l, env):
|
||||
try:
|
||||
result = spawnve(os.P_WAIT, l[0], l, env)
|
||||
except OSError, e:
|
||||
except (OSError, EnvironmentError) as e:
|
||||
try:
|
||||
result = exitvalmap[e[0]]
|
||||
sys.stderr.write("scons: %s: %s\n" % (l[0], e[1]))
|
||||
result = exitvalmap[e.errno]
|
||||
sys.stderr.write("scons: %s: %s\n" % (l[0], e.strerror))
|
||||
except KeyError:
|
||||
result = 127
|
||||
if len(l) > 2:
|
||||
|
@ -194,9 +239,10 @@ def exec_spawn(l, env):
|
|||
command = l[0]
|
||||
else:
|
||||
command = l[0]
|
||||
sys.stderr.write("scons: unknown OSError exception code %d - '%s': %s\n" % (e[0], command, e[1]))
|
||||
sys.stderr.write("scons: unknown OSError exception code %d - '%s': %s\n" % (e.errno, command, e.strerror))
|
||||
return result
|
||||
|
||||
|
||||
def spawn(sh, escape, cmd, args, env):
|
||||
if not sh:
|
||||
sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n")
|
||||
|
@ -216,6 +262,7 @@ def escape(x):
|
|||
# Get the windows system directory name
|
||||
_system_root = None
|
||||
|
||||
|
||||
def get_system_root():
|
||||
global _system_root
|
||||
if _system_root is not None:
|
||||
|
@ -240,11 +287,21 @@ def get_system_root():
|
|||
raise
|
||||
except:
|
||||
pass
|
||||
|
||||
# Ensure system root is a string and not unicode
|
||||
# (This only matters for py27 were unicode in env passed to POpen fails)
|
||||
val = str(val)
|
||||
_system_root = val
|
||||
return val
|
||||
|
||||
# Get the location of the program files directory
|
||||
|
||||
def get_program_files_dir():
|
||||
"""
|
||||
Get the location of the program files directory
|
||||
Returns
|
||||
-------
|
||||
|
||||
"""
|
||||
# Now see if we can look in the registry...
|
||||
val = ''
|
||||
if SCons.Util.can_read_reg:
|
||||
|
@ -261,14 +318,13 @@ def get_program_files_dir():
|
|||
# A reasonable default if we can't read the registry
|
||||
# (Actually, it's pretty reasonable even if we can :-)
|
||||
val = os.path.join(os.path.dirname(get_system_root()),"Program Files")
|
||||
|
||||
|
||||
return val
|
||||
|
||||
|
||||
|
||||
# Determine which windows CPU were running on.
|
||||
class ArchDefinition(object):
|
||||
"""
|
||||
Determine which windows CPU were running on.
|
||||
A class for defining architecture-specific settings and logic.
|
||||
"""
|
||||
def __init__(self, arch, synonyms=[]):
|
||||
|
@ -298,6 +354,7 @@ for a in SupportedArchitectureList:
|
|||
for s in a.synonyms:
|
||||
SupportedArchitectureMap[s] = a
|
||||
|
||||
|
||||
def get_architecture(arch=None):
|
||||
"""Returns the definition for the specified architecture string.
|
||||
|
||||
|
@ -311,6 +368,7 @@ def get_architecture(arch=None):
|
|||
arch = os.environ.get('PROCESSOR_ARCHITECTURE')
|
||||
return SupportedArchitectureMap.get(arch, ArchDefinition('', ['']))
|
||||
|
||||
|
||||
def generate(env):
|
||||
# Attempt to find cmd.exe (for WinNT/2k/XP) or
|
||||
# command.com for Win9x
|
||||
|
@ -346,7 +404,7 @@ def generate(env):
|
|||
os.path.join(systemroot,'System32')
|
||||
tmp_pathext = '.com;.exe;.bat;.cmd'
|
||||
if 'PATHEXT' in os.environ:
|
||||
tmp_pathext = os.environ['PATHEXT']
|
||||
tmp_pathext = os.environ['PATHEXT']
|
||||
cmd_interp = SCons.Util.WhereIs('cmd', tmp_path, tmp_pathext)
|
||||
if not cmd_interp:
|
||||
cmd_interp = SCons.Util.WhereIs('command', tmp_path, tmp_pathext)
|
||||
|
@ -356,7 +414,6 @@ def generate(env):
|
|||
if not cmd_interp:
|
||||
cmd_interp = env.Detect('command')
|
||||
|
||||
|
||||
if 'ENV' not in env:
|
||||
env['ENV'] = {}
|
||||
|
||||
|
@ -368,7 +425,7 @@ def generate(env):
|
|||
# for SystemDrive because it's related.
|
||||
#
|
||||
# Weigh the impact carefully before adding other variables to this list.
|
||||
import_env = [ 'SystemDrive', 'SystemRoot', 'TEMP', 'TMP' ]
|
||||
import_env = ['SystemDrive', 'SystemRoot', 'TEMP', 'TMP' ]
|
||||
for var in import_env:
|
||||
v = os.environ.get(var)
|
||||
if v:
|
||||
|
@ -401,10 +458,10 @@ def generate(env):
|
|||
env['TEMPFILEPREFIX'] = '@'
|
||||
env['MAXLINELENGTH'] = 2048
|
||||
env['ESCAPE'] = escape
|
||||
|
||||
|
||||
env['HOST_OS'] = 'win32'
|
||||
env['HOST_ARCH'] = get_architecture().arch
|
||||
|
||||
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
|
@ -12,7 +12,7 @@ libraries are installed, if some command line options are supported etc.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -33,8 +33,9 @@ libraries are installed, if some command line options are supported etc.
|
|||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
from __future__ import print_function
|
||||
|
||||
__revision__ = "src/engine/SCons/SConf.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/SConf.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.compat
|
||||
|
||||
|
@ -109,7 +110,7 @@ def _createConfigH(target, source, env):
|
|||
#define %(DEFNAME)s_SEEN
|
||||
|
||||
""" % {'DEFNAME' : defname})
|
||||
t.write(source[0].get_contents())
|
||||
t.write(source[0].get_contents().decode())
|
||||
t.write("""
|
||||
#endif /* %(DEFNAME)s_SEEN */
|
||||
""" % {'DEFNAME' : defname})
|
||||
|
@ -131,10 +132,10 @@ def CreateConfigHBuilder(env):
|
|||
_stringConfigH)
|
||||
sconfigHBld = SCons.Builder.Builder(action=action)
|
||||
env.Append( BUILDERS={'SConfigHBuilder':sconfigHBld} )
|
||||
for k in _ac_config_hs.keys():
|
||||
for k in list(_ac_config_hs.keys()):
|
||||
env.SConfigHBuilder(k, env.Value(_ac_config_hs[k]))
|
||||
|
||||
|
||||
|
||||
class SConfWarning(SCons.Warnings.Warning):
|
||||
pass
|
||||
SCons.Warnings.enableWarningClass(SConfWarning)
|
||||
|
@ -163,11 +164,11 @@ class ConfigureCacheError(SConfError):
|
|||
# define actions for building text files
|
||||
def _createSource( target, source, env ):
|
||||
fd = open(str(target[0]), "w")
|
||||
fd.write(source[0].get_contents())
|
||||
fd.write(source[0].get_contents().decode())
|
||||
fd.close()
|
||||
def _stringSource( target, source, env ):
|
||||
return (str(target[0]) + ' <-\n |' +
|
||||
source[0].get_contents().replace( '\n', "\n |" ) )
|
||||
source[0].get_contents().decode().replace( '\n', "\n |" ) )
|
||||
|
||||
class SConfBuildInfo(SCons.Node.FS.FileBuildInfo):
|
||||
"""
|
||||
|
@ -176,7 +177,7 @@ class SConfBuildInfo(SCons.Node.FS.FileBuildInfo):
|
|||
contains messages of the original build phase.
|
||||
"""
|
||||
__slots__ = ('result', 'string')
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.result = None # -> 0/None -> no error, != 0 error
|
||||
self.string = None # the stdout / stderr output when building the target
|
||||
|
@ -217,7 +218,7 @@ class Streamer(object):
|
|||
if self.orig:
|
||||
self.orig.flush()
|
||||
self.s.flush()
|
||||
|
||||
|
||||
|
||||
class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
|
||||
"""
|
||||
|
@ -311,7 +312,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
|
|||
binfo = self.targets[0].get_stored_info().binfo
|
||||
self.display_cached_string(binfo)
|
||||
raise SCons.Errors.BuildError # will be 'caught' in self.failed
|
||||
elif is_up_to_date:
|
||||
elif is_up_to_date:
|
||||
self.display("\"%s\" is up to date." % str(self.targets[0]))
|
||||
binfo = self.targets[0].get_stored_info().binfo
|
||||
self.display_cached_string(binfo)
|
||||
|
@ -332,7 +333,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
|
|||
env_decider=env.decide_source):
|
||||
env_decider(dependency, target, prev_ni)
|
||||
return True
|
||||
if env.decide_source.func_code is not force_build.func_code:
|
||||
if env.decide_source.__code__ is not force_build.__code__:
|
||||
env.Decider(force_build)
|
||||
env['PSTDOUT'] = env['PSTDERR'] = s
|
||||
try:
|
||||
|
@ -346,7 +347,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
|
|||
except SystemExit:
|
||||
exc_value = sys.exc_info()[1]
|
||||
raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code)
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
for t in self.targets:
|
||||
binfo = SConfBuildInfo()
|
||||
binfo.merge(t.get_binfo())
|
||||
|
@ -396,7 +397,7 @@ class SConfBase(object):
|
|||
"""
|
||||
|
||||
def __init__(self, env, custom_tests = {}, conf_dir='$CONFIGUREDIR',
|
||||
log_file='$CONFIGURELOG', config_h = None, _depth = 0):
|
||||
log_file='$CONFIGURELOG', config_h = None, _depth = 0):
|
||||
"""Constructor. Pass additional tests in the custom_tests-dictionary,
|
||||
e.g. custom_tests={'CheckPrivate':MyPrivateTest}, where MyPrivateTest
|
||||
defines a custom test.
|
||||
|
@ -457,10 +458,10 @@ class SConfBase(object):
|
|||
|
||||
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."""
|
||||
|
||||
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 will be added automatically).
|
||||
"""
|
||||
lines = []
|
||||
if comment:
|
||||
comment_str = "/* %s */" % comment
|
||||
|
@ -608,7 +609,7 @@ class SConfBase(object):
|
|||
ok = self.TryBuild(self.env.SConfActionBuilder, text, extension)
|
||||
del self.env['BUILDERS']['SConfActionBuilder']
|
||||
if ok:
|
||||
outputStr = self.lastTarget.get_contents()
|
||||
outputStr = self.lastTarget.get_contents().decode()
|
||||
return (1, outputStr)
|
||||
return (0, "")
|
||||
|
||||
|
@ -642,7 +643,7 @@ class SConfBase(object):
|
|||
node = self.env.Command(output, prog, [ [ pname, ">", "${TARGET}"] ])
|
||||
ok = self.BuildNodes(node)
|
||||
if ok:
|
||||
outputStr = output.get_contents()
|
||||
outputStr = SCons.Util.to_str(output.get_contents())
|
||||
return( 1, outputStr)
|
||||
return (0, "")
|
||||
|
||||
|
@ -670,7 +671,7 @@ class SConfBase(object):
|
|||
"""Adds all the tests given in the tests dictionary to this SConf
|
||||
instance
|
||||
"""
|
||||
for name in tests.keys():
|
||||
for name in list(tests.keys()):
|
||||
self.AddTest(name, tests[name])
|
||||
|
||||
def _createDir( self, node ):
|
||||
|
@ -689,7 +690,7 @@ class SConfBase(object):
|
|||
global _ac_config_logs
|
||||
global sconf_global
|
||||
global SConfFS
|
||||
|
||||
|
||||
self.lastEnvFs = self.env.fs
|
||||
self.env.fs = SConfFS
|
||||
self._createDir(self.confdir)
|
||||
|
@ -716,7 +717,7 @@ class SConfBase(object):
|
|||
self.logstream.write('file %s,line %d:\n\tConfigure(confdir = %s)\n' %
|
||||
(tb[0], tb[1], str(self.confdir)) )
|
||||
SConfFS.chdir(old_fs_dir)
|
||||
else:
|
||||
else:
|
||||
self.logstream = None
|
||||
# we use a special builder to create source files from TEXT
|
||||
action = SCons.Action.Action(_createSource,
|
||||
|
@ -913,14 +914,14 @@ def CheckType(context, type_name, includes = "", language = None):
|
|||
|
||||
def CheckTypeSize(context, type_name, includes = "", language = None, expect = None):
|
||||
res = SCons.Conftest.CheckTypeSize(context, type_name,
|
||||
header = includes, language = language,
|
||||
header = includes, language = language,
|
||||
expect = expect)
|
||||
context.did_show_result = 1
|
||||
return res
|
||||
|
||||
def CheckDeclaration(context, declaration, includes = "", language = None):
|
||||
res = SCons.Conftest.CheckDeclaration(context, declaration,
|
||||
includes = includes,
|
||||
includes = includes,
|
||||
language = language)
|
||||
context.did_show_result = 1
|
||||
return not res
|
||||
|
@ -1004,7 +1005,7 @@ def CheckLib(context, library = None, symbol = "main",
|
|||
|
||||
if not SCons.Util.is_List(library):
|
||||
library = [library]
|
||||
|
||||
|
||||
# ToDo: accept path for the library
|
||||
res = SCons.Conftest.CheckLib(context, library, symbol, header = header,
|
||||
language = language, autoadd = autoadd)
|
|
@ -5,7 +5,7 @@ Writing and reading information to the .sconsign file or files.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,17 +27,21 @@ Writing and reading information to the .sconsign file or files.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/SConsign.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
from __future__ import print_function
|
||||
|
||||
__revision__ = "src/engine/SCons/SConsign.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.compat
|
||||
|
||||
import os
|
||||
# compat layer imports "cPickle" for us if it's available.
|
||||
import pickle
|
||||
|
||||
import SCons.dblite
|
||||
import SCons.Warnings
|
||||
|
||||
from SCons.compat import PICKLE_PROTOCOL
|
||||
|
||||
|
||||
def corrupt_dblite_warning(filename):
|
||||
SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning,
|
||||
"Ignoring corrupt .sconsign file: %s"%filename)
|
||||
|
@ -45,7 +49,7 @@ def corrupt_dblite_warning(filename):
|
|||
SCons.dblite.ignore_corrupt_dbfiles = 1
|
||||
SCons.dblite.corruption_warning = corrupt_dblite_warning
|
||||
|
||||
#XXX Get rid of the global array so this becomes re-entrant.
|
||||
# XXX Get rid of the global array so this becomes re-entrant.
|
||||
sig_files = []
|
||||
|
||||
# Info for the database SConsign implementation (now the default):
|
||||
|
@ -59,6 +63,7 @@ DB_Module = SCons.dblite
|
|||
DB_Name = ".sconsign"
|
||||
DB_sync_list = []
|
||||
|
||||
|
||||
def Get_DataBase(dir):
|
||||
global DataBase, DB_Module, DB_Name
|
||||
top = dir.fs.Top
|
||||
|
@ -84,9 +89,10 @@ def Get_DataBase(dir):
|
|||
DB_sync_list.append(db)
|
||||
return db, "c"
|
||||
except TypeError:
|
||||
print "DataBase =", DataBase
|
||||
print("DataBase =", DataBase)
|
||||
raise
|
||||
|
||||
|
||||
def Reset():
|
||||
"""Reset global state. Used by unit tests that end up using
|
||||
SConsign multiple times to get a clean slate for each test."""
|
||||
|
@ -96,6 +102,7 @@ def Reset():
|
|||
|
||||
normcase = os.path.normcase
|
||||
|
||||
|
||||
def write():
|
||||
global sig_files
|
||||
for sig_file in sig_files:
|
||||
|
@ -114,6 +121,7 @@ def write():
|
|||
else:
|
||||
closemethod()
|
||||
|
||||
|
||||
class SConsignEntry(object):
|
||||
"""
|
||||
Wrapper class for the generic entry in a .sconsign file.
|
||||
|
@ -124,16 +132,16 @@ class SConsignEntry(object):
|
|||
"""
|
||||
__slots__ = ("binfo", "ninfo", "__weakref__")
|
||||
current_version_id = 2
|
||||
|
||||
|
||||
def __init__(self):
|
||||
# Create an object attribute from the class attribute so it ends up
|
||||
# in the pickled data in the .sconsign file.
|
||||
#_version_id = self.current_version_id
|
||||
pass
|
||||
|
||||
|
||||
def convert_to_sconsign(self):
|
||||
self.binfo.convert_to_sconsign()
|
||||
|
||||
|
||||
def convert_from_sconsign(self, dir, name):
|
||||
self.binfo.convert_from_sconsign(dir, name)
|
||||
|
||||
|
@ -155,7 +163,8 @@ class SConsignEntry(object):
|
|||
for key, value in state.items():
|
||||
if key not in ('_version_id','__weakref__'):
|
||||
setattr(self, key, value)
|
||||
|
||||
|
||||
|
||||
class Base(object):
|
||||
"""
|
||||
This is the controlling class for the signatures for the collection of
|
||||
|
@ -210,6 +219,7 @@ class Base(object):
|
|||
self.entries[key] = entry
|
||||
self.to_be_merged = {}
|
||||
|
||||
|
||||
class DB(Base):
|
||||
"""
|
||||
A Base subclass that reads and writes signature information
|
||||
|
@ -239,7 +249,7 @@ class DB(Base):
|
|||
raise TypeError
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning,
|
||||
"Ignoring corrupt sconsign entry : %s (%s)\n"%(self.dir.get_tpath(), e))
|
||||
for key, entry in self.entries.items():
|
||||
|
@ -271,7 +281,7 @@ class DB(Base):
|
|||
path = normcase(self.dir.get_internal_path())
|
||||
for key, entry in self.entries.items():
|
||||
entry.convert_to_sconsign()
|
||||
db[path] = pickle.dumps(self.entries, 1)
|
||||
db[path] = pickle.dumps(self.entries, PICKLE_PROTOCOL)
|
||||
|
||||
if sync:
|
||||
try:
|
||||
|
@ -282,6 +292,7 @@ class DB(Base):
|
|||
else:
|
||||
syncmethod()
|
||||
|
||||
|
||||
class Dir(Base):
|
||||
def __init__(self, fp=None, dir=None):
|
||||
"""
|
||||
|
@ -301,6 +312,7 @@ class Dir(Base):
|
|||
for key, entry in self.entries.items():
|
||||
entry.convert_from_sconsign(dir, key)
|
||||
|
||||
|
||||
class DirFile(Dir):
|
||||
"""
|
||||
Encapsulates reading and writing a per-directory .sconsign file.
|
||||
|
@ -359,12 +371,12 @@ class DirFile(Dir):
|
|||
return
|
||||
for key, entry in self.entries.items():
|
||||
entry.convert_to_sconsign()
|
||||
pickle.dump(self.entries, file, 1)
|
||||
pickle.dump(self.entries, file, PICKLE_PROTOCOL)
|
||||
file.close()
|
||||
if fname != self.sconsign:
|
||||
try:
|
||||
mode = os.stat(self.sconsign)[0]
|
||||
os.chmod(self.sconsign, 0666)
|
||||
os.chmod(self.sconsign, 0o666)
|
||||
os.unlink(self.sconsign)
|
||||
except (IOError, OSError):
|
||||
# Try to carry on in the face of either OSError
|
||||
|
@ -391,6 +403,7 @@ class DirFile(Dir):
|
|||
|
||||
ForDirectory = DB
|
||||
|
||||
|
||||
def File(name, dbm_module=None):
|
||||
"""
|
||||
Arrange for all signatures to be stored in a global .sconsign.db*
|
|
@ -5,7 +5,7 @@ This module implements the dependency scanner for C/C++ code.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ This module implements the dependency scanner for C/C++ code.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/C.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Scanner/C.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.Node.FS
|
||||
import SCons.Scanner
|
||||
|
@ -58,12 +58,11 @@ class SConsCPPScanner(SCons.cpp.PreProcessor):
|
|||
return result
|
||||
def read_file(self, file):
|
||||
try:
|
||||
fp = open(str(file.rfile()))
|
||||
except EnvironmentError, e:
|
||||
with open(str(file.rfile())) as fp:
|
||||
return fp.read()
|
||||
except EnvironmentError as e:
|
||||
self.missing.append((file, self.current_file))
|
||||
return ''
|
||||
else:
|
||||
return fp.read()
|
||||
|
||||
def dictify_CPPDEFINES(env):
|
||||
cppdefines = env.get('CPPDEFINES', {})
|
|
@ -8,7 +8,7 @@ Coded by Andy Friesen
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,9 +30,7 @@ Coded by Andy Friesen
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/D.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
|
||||
import re
|
||||
__revision__ = "src/engine/SCons/Scanner/D.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.Scanner
|
||||
|
||||
|
@ -43,13 +41,13 @@ def DScanner():
|
|||
|
||||
class D(SCons.Scanner.Classic):
|
||||
def __init__ (self):
|
||||
SCons.Scanner.Classic.__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)
|
||||
regex = '(?:import\s+)([\w\s=,.]+)(?:\s*:[\s\w,=]+)?(?:;)'
|
||||
)
|
||||
|
||||
def find_include(self, include, source_dir, path):
|
||||
# translate dots (package separators) to slashes
|
||||
|
@ -62,8 +60,10 @@ class D(SCons.Scanner.Classic):
|
|||
|
||||
def find_include_names(self, node):
|
||||
includes = []
|
||||
for i in self.cre.findall(node.get_text_contents()):
|
||||
includes = includes + self.cre2.findall(i)
|
||||
for iii in self.cre.findall(node.get_text_contents()):
|
||||
for jjj in iii.split(','):
|
||||
kkk = jjj.split('=')[-1]
|
||||
includes.append(kkk.strip())
|
||||
return includes
|
||||
|
||||
# Local Variables:
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -20,14 +20,14 @@
|
|||
# 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/Dir.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Scanner/Dir.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.Node.FS
|
||||
import SCons.Scanner
|
||||
|
||||
def only_dirs(nodes):
|
||||
is_Dir = lambda n: isinstance(n.disambiguate(), SCons.Node.FS.Dir)
|
||||
return list(filter(is_Dir, nodes))
|
||||
return [node for node in nodes if is_Dir(node)]
|
||||
|
||||
def DirScanner(**kw):
|
||||
"""Return a prototype Scanner instance for scanning
|
|
@ -5,7 +5,7 @@ This module implements the dependency scanner for Fortran code.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -26,7 +26,7 @@ This module implements the dependency scanner for Fortran code.
|
|||
# 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/Fortran.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Scanner/Fortran.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import re
|
||||
|
|
@ -6,7 +6,7 @@ Definition Language) files.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -28,7 +28,7 @@ Definition Language) files.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/IDL.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Scanner/IDL.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.Node.FS
|
||||
import SCons.Scanner
|
|
@ -5,7 +5,7 @@ This module implements the dependency scanner for LaTeX code.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ This module implements the dependency scanner for LaTeX code.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/LaTeX.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Scanner/LaTeX.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import os.path
|
||||
import re
|
||||
|
@ -37,7 +37,9 @@ import SCons.Util
|
|||
|
||||
# list of graphics file extensions for TeX and LaTeX
|
||||
TexGraphics = ['.eps', '.ps']
|
||||
LatexGraphics = ['.pdf', '.png', '.jpg', '.gif', '.tif']
|
||||
#LatexGraphics = ['.pdf', '.png', '.jpg', '.gif', '.tif']
|
||||
LatexGraphics = [ '.png', '.jpg', '.gif', '.tif']
|
||||
|
||||
|
||||
# Used as a return value of modify_env_var if the variable is not set.
|
||||
class _Null(object):
|
||||
|
@ -76,8 +78,10 @@ def modify_env_var(env, var, abspath):
|
|||
return save
|
||||
|
||||
class FindENVPathDirs(object):
|
||||
"""A class to bind a specific *PATH variable name to a function that
|
||||
will return all of the *path directories."""
|
||||
"""
|
||||
A class to bind a specific E{*}PATH variable name to a function that
|
||||
will return all of the E{*}path directories.
|
||||
"""
|
||||
def __init__(self, variable):
|
||||
self.variable = variable
|
||||
def __call__(self, env, dir=None, target=None, source=None, argument=None):
|
||||
|
@ -94,7 +98,8 @@ class FindENVPathDirs(object):
|
|||
|
||||
|
||||
def LaTeXScanner():
|
||||
"""Return a prototype Scanner instance for scanning LaTeX source files
|
||||
"""
|
||||
Return a prototype Scanner instance for scanning LaTeX source files
|
||||
when built with latex.
|
||||
"""
|
||||
ds = LaTeX(name = "LaTeXScanner",
|
||||
|
@ -105,7 +110,8 @@ def LaTeXScanner():
|
|||
return ds
|
||||
|
||||
def PDFLaTeXScanner():
|
||||
"""Return a prototype Scanner instance for scanning LaTeX source files
|
||||
"""
|
||||
Return a prototype Scanner instance for scanning LaTeX source files
|
||||
when built with pdflatex.
|
||||
"""
|
||||
ds = LaTeX(name = "PDFLaTeXScanner",
|
||||
|
@ -116,7 +122,8 @@ def PDFLaTeXScanner():
|
|||
return ds
|
||||
|
||||
class LaTeX(SCons.Scanner.Base):
|
||||
"""Class for scanning LaTeX files for included files.
|
||||
"""
|
||||
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
|
||||
|
@ -133,10 +140,12 @@ class LaTeX(SCons.Scanner.Base):
|
|||
|
||||
The actual subset and search order may be altered by
|
||||
DeclareGraphicsExtensions command. This complication is ignored.
|
||||
The default order corresponds to experimentation with teTeX
|
||||
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'].
|
||||
|
@ -148,8 +157,7 @@ class LaTeX(SCons.Scanner.Base):
|
|||
env['TEXINPUTS'] for "lstinputlisting" keyword
|
||||
env['BIBINPUTS'] for "bibliography" keyword
|
||||
env['BSTINPUTS'] for "bibliographystyle" keyword
|
||||
env['INDEXSTYLE'] for "makeindex" keyword, no scanning support needed
|
||||
just allows user to set it if needed.
|
||||
env['INDEXSTYLE'] for "makeindex" keyword, no scanning support needed just allows user to set it if needed.
|
||||
|
||||
FIXME: also look for the class or style in document[class|style]{}
|
||||
FIXME: also look for the argument of bibliographystyle{}
|
||||
|
@ -166,6 +174,9 @@ class LaTeX(SCons.Scanner.Base):
|
|||
'usepackage': 'TEXINPUTS',
|
||||
'lstinputlisting': 'TEXINPUTS'}
|
||||
env_variables = SCons.Util.unique(list(keyword_paths.values()))
|
||||
two_arg_commands = ['import', 'subimport',
|
||||
'includefrom', 'subincludefrom',
|
||||
'inputfrom', 'subinputfrom']
|
||||
|
||||
def __init__(self, name, suffixes, graphics_extensions, *args, **kw):
|
||||
|
||||
|
@ -175,8 +186,29 @@ class LaTeX(SCons.Scanner.Base):
|
|||
# line followed by one or more newline characters (i.e. blank
|
||||
# lines), interfering with a match on the next line.
|
||||
# add option for whitespace before the '[options]' or the '{filename}'
|
||||
regex = r'^[^%\n]*\\(include|includegraphics(?:\s*\[[^\]]+\])?|lstinputlisting(?:\[[^\]]+\])?|input|bibliography|addbibresource|addglobalbib|addsectionbib|usepackage)\s*{([^}]*)}'
|
||||
self.cre = re.compile(regex, re.M)
|
||||
regex = r'''
|
||||
^[^%\n]*
|
||||
\\(
|
||||
include
|
||||
| includegraphics(?:\s*\[[^\]]+\])?
|
||||
| lstinputlisting(?:\[[^\]]+\])?
|
||||
| input
|
||||
| import
|
||||
| subimport
|
||||
| includefrom
|
||||
| subincludefrom
|
||||
| inputfrom
|
||||
| subinputfrom
|
||||
| bibliography
|
||||
| addbibresource
|
||||
| addglobalbib
|
||||
| addsectionbib
|
||||
| usepackage
|
||||
)
|
||||
\s*{([^}]*)} # first arg
|
||||
(?: \s*{([^}]*)} )? # maybe another arg
|
||||
'''
|
||||
self.cre = re.compile(regex, re.M | re.X)
|
||||
self.comment_re = re.compile(r'^((?:(?:\\%)|[^%\n])*)(.*)$', re.M)
|
||||
|
||||
self.graphics_extensions = graphics_extensions
|
||||
|
@ -236,23 +268,26 @@ class LaTeX(SCons.Scanner.Base):
|
|||
|
||||
SCons.Scanner.Base.__init__(self, *args, **kw)
|
||||
|
||||
def _latex_names(self, include):
|
||||
filename = include[1]
|
||||
if include[0] == 'input':
|
||||
def _latex_names(self, include_type, filename):
|
||||
if include_type == 'input':
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
return [filename + '.tex']
|
||||
if (include[0] == 'include'):
|
||||
return [filename + '.tex']
|
||||
if include[0] == 'bibliography':
|
||||
if include_type in ('include', 'import', 'subimport',
|
||||
'includefrom', 'subincludefrom',
|
||||
'inputfrom', 'subinputfrom'):
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
return [filename + '.tex']
|
||||
if include_type == 'bibliography':
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
return [filename + '.bib']
|
||||
if include[0] == 'usepackage':
|
||||
if include_type == 'usepackage':
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
return [filename + '.sty']
|
||||
if include[0] == 'includegraphics':
|
||||
if include_type == 'includegraphics':
|
||||
base, ext = os.path.splitext( filename )
|
||||
if ext == "":
|
||||
#return [filename+e for e in self.graphics_extensions + TexGraphics]
|
||||
|
@ -267,21 +302,26 @@ class LaTeX(SCons.Scanner.Base):
|
|||
return SCons.Node.FS._my_normcase(str(include))
|
||||
|
||||
def find_include(self, include, source_dir, path):
|
||||
inc_type, inc_subdir, inc_filename = include
|
||||
try:
|
||||
sub_path = path[include[0]]
|
||||
sub_paths = path[inc_type]
|
||||
except (IndexError, KeyError):
|
||||
sub_path = ()
|
||||
try_names = self._latex_names(include)
|
||||
sub_paths = ((), ())
|
||||
try_names = self._latex_names(inc_type, inc_filename)
|
||||
|
||||
# There are three search paths to try:
|
||||
# 1. current directory "source_dir"
|
||||
# 2. env[var]
|
||||
# 3. env['ENV'][var]
|
||||
search_paths = [(source_dir,)] + list(sub_paths)
|
||||
|
||||
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
|
||||
for search_path in search_paths:
|
||||
paths = tuple([d.Dir(inc_subdir) for d in search_path])
|
||||
i = SCons.Node.FS.find_file(n, paths)
|
||||
if i:
|
||||
return i, include
|
||||
return None, include
|
||||
|
||||
def canonical_text(self, text):
|
||||
"""Standardize an input TeX-file contents.
|
||||
|
@ -300,7 +340,7 @@ class LaTeX(SCons.Scanner.Base):
|
|||
line_continues_a_comment = len(comment) > 0
|
||||
return '\n'.join(out).rstrip()+'\n'
|
||||
|
||||
def scan(self, node):
|
||||
def scan(self, node, subdir='.'):
|
||||
# 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.
|
||||
|
@ -326,9 +366,14 @@ class LaTeX(SCons.Scanner.Base):
|
|||
split_includes = []
|
||||
for include in includes:
|
||||
inc_type = noopt_cre.sub('', include[0])
|
||||
inc_list = include[1].split(',')
|
||||
inc_subdir = subdir
|
||||
if inc_type in self.two_arg_commands:
|
||||
inc_subdir = os.path.join(subdir, include[1])
|
||||
inc_list = include[2].split(',')
|
||||
else:
|
||||
inc_list = include[1].split(',')
|
||||
for j in range(len(inc_list)):
|
||||
split_includes.append( (inc_type, inc_list[j]) )
|
||||
split_includes.append( (inc_type, inc_subdir, inc_list[j]) )
|
||||
#
|
||||
includes = split_includes
|
||||
node.includes = includes
|
||||
|
@ -359,11 +404,13 @@ class LaTeX(SCons.Scanner.Base):
|
|||
while queue:
|
||||
|
||||
include = queue.pop()
|
||||
inc_type, inc_subdir, inc_filename = include
|
||||
|
||||
try:
|
||||
if seen[include[1]] == 1:
|
||||
if seen[inc_filename] == 1:
|
||||
continue
|
||||
except KeyError:
|
||||
seen[include[1]] = 1
|
||||
seen[inc_filename] = 1
|
||||
|
||||
#
|
||||
# Handle multiple filenames in include[1]
|
||||
|
@ -372,14 +419,14 @@ class LaTeX(SCons.Scanner.Base):
|
|||
if n is None:
|
||||
# Do not bother with 'usepackage' warnings, as they most
|
||||
# likely refer to system-level files
|
||||
if include[0] != 'usepackage':
|
||||
if inc_type != '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))
|
||||
# recurse down
|
||||
queue.extend( self.scan(n) )
|
||||
# recurse down
|
||||
queue.extend( self.scan(n, inc_subdir) )
|
||||
|
||||
return [pair[1] for pair in sorted(nodes)]
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/Prog.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Scanner/Prog.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.Node
|
||||
import SCons.Node.FS
|
|
@ -6,7 +6,7 @@ Definition Language) files.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -28,23 +28,34 @@ Definition Language) files.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/RC.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Scanner/RC.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import re
|
||||
|
||||
import SCons.Node.FS
|
||||
import SCons.Scanner
|
||||
import re
|
||||
|
||||
|
||||
def no_tlb(nodes):
|
||||
"""
|
||||
Filter out .tlb files as they are binary and shouldn't be scanned
|
||||
"""
|
||||
# print("Nodes:%s"%[str(n) for n in nodes])
|
||||
return [n for n in nodes if str(n)[-4:] != '.tlb']
|
||||
|
||||
|
||||
def RCScan():
|
||||
"""Return a prototype Scanner instance for scanning RC source files"""
|
||||
|
||||
|
||||
res_re= r'^(?:\s*#\s*(?:include)|' \
|
||||
'.*?\s+(?:ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)' \
|
||||
'\s*.*?)' \
|
||||
'\s*(<|"| )([^>"\s]+)(?:[>"\s])*$'
|
||||
resScanner = SCons.Scanner.ClassicCPP( "ResourceScanner",
|
||||
"$RCSUFFIXES",
|
||||
"CPPPATH",
|
||||
res_re )
|
||||
resScanner = SCons.Scanner.ClassicCPP("ResourceScanner",
|
||||
"$RCSUFFIXES",
|
||||
"CPPPATH",
|
||||
res_re,
|
||||
recursive=no_tlb)
|
||||
|
||||
return resScanner
|
||||
|
|
@ -5,7 +5,7 @@ This module implements the dependency scanner for SWIG code.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ This module implements the dependency scanner for SWIG code.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/SWIG.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Scanner/SWIG.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.Scanner
|
||||
|
|
@ -5,7 +5,7 @@ The Scanner package for the SCons software construction utility.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ The Scanner package for the SCons software construction utility.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Scanner/__init__.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Scanner/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import re
|
||||
|
||||
|
@ -62,8 +62,10 @@ def Scanner(function, *args, **kw):
|
|||
|
||||
|
||||
class FindPathDirs(object):
|
||||
"""A class to bind a specific *PATH variable name to a function that
|
||||
will return all of the *path directories."""
|
||||
"""
|
||||
A class to bind a specific E{*}PATH variable name to a function that
|
||||
will return all of the E{*}path directories.
|
||||
"""
|
||||
def __init__(self, variable):
|
||||
self.variable = variable
|
||||
def __call__(self, env, dir=None, target=None, source=None, argument=None):
|
||||
|
@ -188,12 +190,12 @@ class Base(object):
|
|||
def path(self, env, dir=None, target=None, source=None):
|
||||
if not self.path_function:
|
||||
return ()
|
||||
if not self.argument is _null:
|
||||
if self.argument is not _null:
|
||||
return self.path_function(env, dir, target, source, self.argument)
|
||||
else:
|
||||
return self.path_function(env, dir, target, source)
|
||||
|
||||
def __call__(self, node, env, path = ()):
|
||||
def __call__(self, node, env, path=()):
|
||||
"""
|
||||
This method scans a single object. 'node' is the node
|
||||
that will be passed to the scanner function, and 'env' is the
|
||||
|
@ -206,27 +208,27 @@ class Base(object):
|
|||
self = self.select(node)
|
||||
|
||||
if not self.argument is _null:
|
||||
list = self.function(node, env, path, self.argument)
|
||||
node_list = self.function(node, env, path, self.argument)
|
||||
else:
|
||||
list = self.function(node, env, path)
|
||||
node_list = self.function(node, env, path)
|
||||
|
||||
kw = {}
|
||||
if hasattr(node, 'dir'):
|
||||
kw['directory'] = node.dir
|
||||
node_factory = env.get_factory(self.node_factory)
|
||||
nodes = []
|
||||
for l in list:
|
||||
for l in node_list:
|
||||
if self.node_class and not isinstance(l, self.node_class):
|
||||
l = node_factory(l, **kw)
|
||||
nodes.append(l)
|
||||
return nodes
|
||||
|
||||
def __cmp__(self, other):
|
||||
def __eq__(self, other):
|
||||
try:
|
||||
return cmp(self.__dict__, other.__dict__)
|
||||
return self.__dict__ == other.__dict__
|
||||
except AttributeError:
|
||||
# other probably doesn't have a __dict__
|
||||
return cmp(self.__dict__, other)
|
||||
return self.__dict__ == other
|
||||
|
||||
def __hash__(self):
|
||||
return id(self)
|
||||
|
@ -259,7 +261,7 @@ class Base(object):
|
|||
def _recurse_no_nodes(self, nodes):
|
||||
return []
|
||||
|
||||
recurse_nodes = _recurse_no_nodes
|
||||
# recurse_nodes = _recurse_no_nodes
|
||||
|
||||
def add_scanner(self, skey, scanner):
|
||||
self.function[skey] = scanner
|
||||
|
@ -283,7 +285,7 @@ class Selector(Base):
|
|||
self.dict = dict
|
||||
self.skeys = list(dict.keys())
|
||||
|
||||
def __call__(self, node, env, path = ()):
|
||||
def __call__(self, node, env, path=()):
|
||||
return self.select(node)(node, env, path)
|
||||
|
||||
def select(self, node):
|
||||
|
@ -326,7 +328,7 @@ class Classic(Current):
|
|||
|
||||
self.cre = re.compile(regex, re.M)
|
||||
|
||||
def _scan(node, env, path=(), self=self):
|
||||
def _scan(node, _, path=(), self=self):
|
||||
node = node.rfile()
|
||||
if not node.exists():
|
||||
return []
|
||||
|
@ -334,7 +336,12 @@ class Classic(Current):
|
|||
|
||||
kw['function'] = _scan
|
||||
kw['path_function'] = FindPathDirs(path_variable)
|
||||
kw['recursive'] = 1
|
||||
|
||||
# Allow recursive to propagate if child class specifies.
|
||||
# In this case resource scanner needs to specify a filter on which files
|
||||
# get recursively processed. Previously was hardcoded to 1 instead of
|
||||
# defaulted to 1.
|
||||
kw['recursive'] = kw.get('recursive', 1)
|
||||
kw['skeys'] = suffixes
|
||||
kw['name'] = name
|
||||
|
||||
|
@ -356,7 +363,7 @@ class Classic(Current):
|
|||
if node.includes is not None:
|
||||
includes = node.includes
|
||||
else:
|
||||
includes = self.find_include_names (node)
|
||||
includes = self.find_include_names(node)
|
||||
# Intern the names of the include files. Saves some memory
|
||||
# if the same header is included many times.
|
||||
node.includes = list(map(SCons.Util.silent_intern, includes))
|
||||
|
@ -393,6 +400,7 @@ class ClassicCPP(Classic):
|
|||
the contained filename in group 1.
|
||||
"""
|
||||
def find_include(self, include, source_dir, path):
|
||||
include = list(map(SCons.Util.to_str, include))
|
||||
if include[0] == '"':
|
||||
paths = (source_dir,) + tuple(path)
|
||||
else:
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -19,8 +19,9 @@
|
|||
# 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.
|
||||
from __future__ import print_function
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/Interactive.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Script/Interactive.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """
|
||||
SCons interactive mode
|
||||
|
@ -98,17 +99,14 @@ except ImportError:
|
|||
|
||||
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.
|
||||
"""
|
||||
|
||||
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',
|
||||
|
@ -129,12 +127,12 @@ class SConsInteractiveCmd(cmd.Cmd):
|
|||
self.shell_variable = 'SHELL'
|
||||
|
||||
def default(self, argv):
|
||||
print "*** Unknown command: %s" % argv[0]
|
||||
print("*** Unknown command: %s" % argv[0])
|
||||
|
||||
def onecmd(self, line):
|
||||
line = line.strip()
|
||||
if not line:
|
||||
print self.lastcmd
|
||||
print(self.lastcmd)
|
||||
return self.emptyline()
|
||||
self.lastcmd = line
|
||||
if line[0] == '!':
|
||||
|
@ -221,7 +219,7 @@ class SConsInteractiveCmd(cmd.Cmd):
|
|||
def get_unseen_children(node, parent, seen_nodes=seen_nodes):
|
||||
def is_unseen(node, seen_nodes=seen_nodes):
|
||||
return node not in seen_nodes
|
||||
return list(filter(is_unseen, node.children(scan=1)))
|
||||
return [child for child in node.children(scan=1) if is_unseen(child)]
|
||||
|
||||
def add_to_seen_nodes(node, parent, seen_nodes=seen_nodes):
|
||||
seen_nodes[node] = 1
|
||||
|
@ -249,7 +247,7 @@ class SConsInteractiveCmd(cmd.Cmd):
|
|||
while n:
|
||||
n = walker.get_next()
|
||||
|
||||
for node in seen_nodes.keys():
|
||||
for node in list(seen_nodes.keys()):
|
||||
# Call node.clear() to clear most of the state
|
||||
node.clear()
|
||||
# node.clear() doesn't reset node.state, so call
|
||||
|
@ -274,7 +272,7 @@ class SConsInteractiveCmd(cmd.Cmd):
|
|||
return self.do_build(['build', '--clean'] + argv[1:])
|
||||
|
||||
def do_EOF(self, argv):
|
||||
print
|
||||
print()
|
||||
self.do_exit(argv)
|
||||
|
||||
def _do_one_help(self, arg):
|
||||
|
@ -351,7 +349,7 @@ class SConsInteractiveCmd(cmd.Cmd):
|
|||
# Doing the right thing with an argument list currently
|
||||
# requires different shell= values on Windows and Linux.
|
||||
p = subprocess.Popen(argv, shell=(sys.platform=='win32'))
|
||||
except EnvironmentError, e:
|
||||
except EnvironmentError as e:
|
||||
sys.stderr.write('scons: %s: %s\n' % (argv[0], e.strerror))
|
||||
else:
|
||||
p.wait()
|
|
@ -10,10 +10,14 @@ some other module. If it's specific to the "scons" script invocation,
|
|||
it goes here.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
unsupported_python_version = (2, 6, 0)
|
||||
deprecated_python_version = (2, 7, 0)
|
||||
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -34,7 +38,8 @@ deprecated_python_version = (2, 7, 0)
|
|||
# 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/Main.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Script/Main.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
|
||||
import SCons.compat
|
||||
|
||||
|
@ -42,6 +47,7 @@ import os
|
|||
import sys
|
||||
import time
|
||||
import traceback
|
||||
import sysconfig
|
||||
|
||||
import SCons.CacheDir
|
||||
import SCons.Debug
|
||||
|
@ -60,6 +66,7 @@ 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
|
||||
|
@ -70,6 +77,7 @@ def fetch_win32_parallel_msg():
|
|||
import SCons.Platform.win32
|
||||
return SCons.Platform.win32.parallel_msg
|
||||
|
||||
|
||||
def revert_io():
|
||||
# This call is added to revert stderr and stdout to the original
|
||||
# ones just in case some build rule or something else in the system
|
||||
|
@ -86,6 +94,7 @@ progress_display = SCons.Util.DisplayEngine()
|
|||
first_command_start = None
|
||||
last_command_end = None
|
||||
|
||||
|
||||
class Progressor(object):
|
||||
prev = ''
|
||||
count = 0
|
||||
|
@ -149,9 +158,11 @@ def Progress(*args, **kw):
|
|||
|
||||
_BuildFailures = []
|
||||
|
||||
|
||||
def GetBuildFailures():
|
||||
return _BuildFailures
|
||||
|
||||
|
||||
class BuildTask(SCons.Taskmaster.OutOfDateTask):
|
||||
"""An SCons build task."""
|
||||
progress = ProgressObject
|
||||
|
@ -220,7 +231,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask):
|
|||
self.exception_set()
|
||||
self.do_failed()
|
||||
else:
|
||||
print "scons: Nothing to be done for `%s'." % t
|
||||
print("scons: Nothing to be done for `%s'." % t)
|
||||
SCons.Taskmaster.OutOfDateTask.executed(self)
|
||||
else:
|
||||
SCons.Taskmaster.OutOfDateTask.executed(self)
|
||||
|
@ -289,8 +300,8 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask):
|
|||
if self.options.debug_includes:
|
||||
tree = t.render_include_tree()
|
||||
if tree:
|
||||
print
|
||||
print tree
|
||||
print()
|
||||
print(tree)
|
||||
SCons.Taskmaster.OutOfDateTask.postprocess(self)
|
||||
|
||||
def make_ready(self):
|
||||
|
@ -301,6 +312,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask):
|
|||
if explanation:
|
||||
sys.stdout.write("scons: " + explanation)
|
||||
|
||||
|
||||
class CleanTask(SCons.Taskmaster.AlwaysTask):
|
||||
"""An SCons clean task."""
|
||||
def fs_delete(self, path, pathstr, remove=True):
|
||||
|
@ -325,10 +337,10 @@ class CleanTask(SCons.Taskmaster.AlwaysTask):
|
|||
else:
|
||||
errstr = "Path '%s' exists but isn't a file or directory."
|
||||
raise SCons.Errors.UserError(errstr % (pathstr))
|
||||
except SCons.Errors.UserError, e:
|
||||
print e
|
||||
except (IOError, OSError), e:
|
||||
print "scons: Could not remove '%s':" % pathstr, e.strerror
|
||||
except SCons.Errors.UserError as e:
|
||||
print(e)
|
||||
except (IOError, OSError) as e:
|
||||
print("scons: Could not remove '%s':" % pathstr, e.strerror)
|
||||
|
||||
def _get_files_to_clean(self):
|
||||
result = []
|
||||
|
@ -354,13 +366,13 @@ class CleanTask(SCons.Taskmaster.AlwaysTask):
|
|||
for t in self._get_files_to_clean():
|
||||
try:
|
||||
removed = t.remove()
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
# An OSError may indicate something like a permissions
|
||||
# issue, an IOError would indicate something like
|
||||
# the file not existing. In either case, print a
|
||||
# message and keep going to try to remove as many
|
||||
# targets as possible.
|
||||
print "scons: Could not remove '%s':" % str(t), e.strerror
|
||||
print("scons: Could not remove '{0}'".format(str(t)), e.strerror)
|
||||
else:
|
||||
if removed:
|
||||
display("Removed " + str(t))
|
||||
|
@ -564,7 +576,7 @@ def find_deepest_user_frame(tb):
|
|||
|
||||
def _scons_user_error(e):
|
||||
"""Handle user errors. Print out a message and a description of the
|
||||
error, along with the line number and routine where it occurred.
|
||||
error, along with the line number and routine where it occured.
|
||||
The file and line number will be the deepest stack frame that is
|
||||
not part of SCons itself.
|
||||
"""
|
||||
|
@ -579,7 +591,7 @@ def _scons_user_error(e):
|
|||
|
||||
def _scons_user_warning(e):
|
||||
"""Handle user warnings. Print out a message and a description of
|
||||
the warning, along with the line number and routine where it occurred.
|
||||
the warning, along with the line number and routine where it occured.
|
||||
The file and line number will be the deepest stack frame that is
|
||||
not part of SCons itself.
|
||||
"""
|
||||
|
@ -600,7 +612,7 @@ def _scons_internal_error():
|
|||
"""Handle all errors but user errors. Print out a message telling
|
||||
the user what to do in this case and print a normal trace.
|
||||
"""
|
||||
print 'internal error'
|
||||
print('internal error')
|
||||
traceback.print_exc()
|
||||
sys.exit(2)
|
||||
|
||||
|
@ -714,7 +726,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None):
|
|||
# the error checking makes it longer.
|
||||
try:
|
||||
m = sys.modules['SCons.Script']
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
fmt = 'cannot import site_init.py: missing SCons.Script module %s'
|
||||
raise SCons.Errors.InternalError(fmt % repr(e))
|
||||
try:
|
||||
|
@ -722,15 +734,15 @@ def _load_site_scons_dir(topdir, site_dir_name=None):
|
|||
modname = os.path.basename(pathname)[:-len(sfx)]
|
||||
site_m = {"__file__": pathname, "__name__": modname, "__doc__": None}
|
||||
re_special = re.compile("__[^_]+__")
|
||||
for k in m.__dict__.keys():
|
||||
for k in list(m.__dict__.keys()):
|
||||
if not re_special.match(k):
|
||||
site_m[k] = m.__dict__[k]
|
||||
|
||||
# This is the magic.
|
||||
exec fp in site_m
|
||||
exec(compile(fp.read(), fp.name, 'exec'), site_m)
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
fmt = '*** Error loading site_init file %s:\n'
|
||||
sys.stderr.write(fmt % repr(site_init_file))
|
||||
raise
|
||||
|
@ -740,7 +752,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None):
|
|||
m.__dict__[k] = site_m[k]
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except ImportError, e:
|
||||
except ImportError as e:
|
||||
fmt = '*** cannot import site init file %s:\n'
|
||||
sys.stderr.write(fmt % repr(site_init_file))
|
||||
raise
|
||||
|
@ -792,7 +804,7 @@ def _load_all_site_scons_dirs(topdir, verbose=None):
|
|||
dirs=sysdirs + [topdir]
|
||||
for d in dirs:
|
||||
if verbose: # this is used by unit tests.
|
||||
print "Loading site dir ", d
|
||||
print("Loading site dir ", d)
|
||||
_load_site_scons_dir(d)
|
||||
|
||||
def test_load_all_site_scons_dirs(d):
|
||||
|
@ -992,7 +1004,7 @@ def _main(parser):
|
|||
try:
|
||||
for script in scripts:
|
||||
SCons.Script._SConscript._SConscript(fs, script)
|
||||
except SCons.Errors.StopError, e:
|
||||
except SCons.Errors.StopError as e:
|
||||
# We had problems reading an SConscript file, such as it
|
||||
# couldn't be copied in to the VariantDir. Since we're just
|
||||
# reading SConscript files and haven't started building
|
||||
|
@ -1053,8 +1065,8 @@ def _main(parser):
|
|||
# SConscript files. Give them the options usage.
|
||||
raise SConsPrintHelpException
|
||||
else:
|
||||
print help_text
|
||||
print "Use scons -H for help about command-line options."
|
||||
print(help_text)
|
||||
print("Use scons -H for help about command-line options.")
|
||||
exit_status = 0
|
||||
return
|
||||
|
||||
|
@ -1091,7 +1103,7 @@ def _main(parser):
|
|||
nodes = _build_targets(fs, options, targets, target_top)
|
||||
if not nodes:
|
||||
revert_io()
|
||||
print 'Found nothing to build'
|
||||
print('Found nothing to build')
|
||||
exit_status = 2
|
||||
|
||||
def _build_targets(fs, options, targets, target_top):
|
||||
|
@ -1157,7 +1169,7 @@ def _build_targets(fs, options, targets, target_top):
|
|||
# or not a file, so go ahead and keep it as a default
|
||||
# target and let the engine sort it out:
|
||||
return 1
|
||||
d = list(filter(check_dir, SCons.Script.DEFAULT_TARGETS))
|
||||
d = [tgt for tgt in SCons.Script.DEFAULT_TARGETS if check_dir(tgt)]
|
||||
SCons.Script.DEFAULT_TARGETS[:] = d
|
||||
target_top = None
|
||||
lookup_top = None
|
||||
|
@ -1231,7 +1243,7 @@ def _build_targets(fs, options, targets, target_top):
|
|||
if options.taskmastertrace_file == '-':
|
||||
tmtrace = sys.stdout
|
||||
elif options.taskmastertrace_file:
|
||||
tmtrace = open(options.taskmastertrace_file, 'wb')
|
||||
tmtrace = open(options.taskmastertrace_file, 'w')
|
||||
else:
|
||||
tmtrace = None
|
||||
taskmaster = SCons.Taskmaster.Taskmaster(nodes, task_class, order, tmtrace)
|
||||
|
@ -1240,16 +1252,19 @@ def _build_targets(fs, options, targets, target_top):
|
|||
# various print_* settings, tree_printer list, etc.
|
||||
BuildTask.options = options
|
||||
|
||||
|
||||
python_has_threads = sysconfig.get_config_var('WITH_THREAD')
|
||||
# to check if python configured with threads.
|
||||
global num_jobs
|
||||
num_jobs = options.num_jobs
|
||||
jobs = SCons.Job.Jobs(num_jobs, taskmaster)
|
||||
if num_jobs > 1:
|
||||
msg = None
|
||||
if jobs.num_jobs == 1:
|
||||
if sys.platform == 'win32':
|
||||
msg = fetch_win32_parallel_msg()
|
||||
elif jobs.num_jobs == 1 or not python_has_threads:
|
||||
msg = "parallel builds are unsupported by this version of Python;\n" + \
|
||||
"\tignoring -j or num_jobs option.\n"
|
||||
elif sys.platform == 'win32':
|
||||
msg = fetch_win32_parallel_msg()
|
||||
if msg:
|
||||
SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg)
|
||||
|
||||
|
@ -1332,10 +1347,10 @@ def main():
|
|||
pass
|
||||
parts.append(version_string("engine", SCons))
|
||||
parts.append(path_string("engine", SCons))
|
||||
parts.append("Copyright (c) 2001 - 2016 The SCons Foundation")
|
||||
parts.append("Copyright (c) 2001 - 2017 The SCons Foundation")
|
||||
version = ''.join(parts)
|
||||
|
||||
import SConsOptions
|
||||
from . import SConsOptions
|
||||
parser = SConsOptions.Parser(version)
|
||||
values = SConsOptions.SConsValues(parser.get_default_values())
|
||||
|
||||
|
@ -1346,23 +1361,23 @@ def main():
|
|||
_exec_main(parser, values)
|
||||
finally:
|
||||
revert_io()
|
||||
except SystemExit, s:
|
||||
except SystemExit as s:
|
||||
if s:
|
||||
exit_status = s
|
||||
except KeyboardInterrupt:
|
||||
print("scons: Build interrupted.")
|
||||
sys.exit(2)
|
||||
except SyntaxError, e:
|
||||
except SyntaxError as e:
|
||||
_scons_syntax_error(e)
|
||||
except SCons.Errors.InternalError:
|
||||
_scons_internal_error()
|
||||
except SCons.Errors.UserError, e:
|
||||
except SCons.Errors.UserError as e:
|
||||
_scons_user_error(e)
|
||||
except SConsPrintHelpException:
|
||||
parser.print_help()
|
||||
exit_status = 0
|
||||
except SCons.Errors.BuildError, e:
|
||||
print e
|
||||
except SCons.Errors.BuildError as e:
|
||||
print(e)
|
||||
exit_status = e.exitstatus
|
||||
except:
|
||||
# An exception here is likely a builtin Python exception Python
|
||||
|
@ -1398,10 +1413,10 @@ def main():
|
|||
else:
|
||||
ct = last_command_end - first_command_start
|
||||
scons_time = total_time - sconscript_time - ct
|
||||
print "Total build time: %f seconds"%total_time
|
||||
print "Total SConscript file execution time: %f seconds"%sconscript_time
|
||||
print "Total SCons execution time: %f seconds"%scons_time
|
||||
print "Total command execution time: %f seconds"%ct
|
||||
print("Total build time: %f seconds"%total_time)
|
||||
print("Total SConscript file execution time: %f seconds"%sconscript_time)
|
||||
print("Total SCons execution time: %f seconds"%scons_time)
|
||||
print("Total command execution time: %f seconds"%ct)
|
||||
|
||||
sys.exit(exit_status)
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/SConsOptions.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Script/SConsOptions.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import optparse
|
||||
import re
|
||||
|
@ -63,6 +63,7 @@ def diskcheck_convert(value):
|
|||
raise ValueError(v)
|
||||
return result
|
||||
|
||||
|
||||
class SConsValues(optparse.Values):
|
||||
"""
|
||||
Holder class for uniform access to SCons options, regardless
|
||||
|
@ -112,7 +113,18 @@ class SConsValues(optparse.Values):
|
|||
try:
|
||||
return self.__dict__['__SConscript_settings__'][attr]
|
||||
except KeyError:
|
||||
return getattr(self.__dict__['__defaults__'], attr)
|
||||
try:
|
||||
return getattr(self.__dict__['__defaults__'], attr)
|
||||
except KeyError:
|
||||
# Added because with py3 this is a new class,
|
||||
# not a classic class, and due to the way
|
||||
# In that case it will create an object without
|
||||
# __defaults__, and then query for __setstate__
|
||||
# which will throw an exception of KeyError
|
||||
# deepcopy() is expecting AttributeError if __setstate__
|
||||
# is not available.
|
||||
raise AttributeError(attr)
|
||||
|
||||
|
||||
settable = [
|
||||
'clean',
|
||||
|
@ -127,6 +139,7 @@ class SConsValues(optparse.Values):
|
|||
'random',
|
||||
'stack_size',
|
||||
'warn',
|
||||
'silent'
|
||||
]
|
||||
|
||||
def set_option(self, name, value):
|
||||
|
@ -161,7 +174,7 @@ class SConsValues(optparse.Values):
|
|||
elif name == 'diskcheck':
|
||||
try:
|
||||
value = diskcheck_convert(value)
|
||||
except ValueError, v:
|
||||
except ValueError as v:
|
||||
raise SCons.Errors.UserError("Not a valid diskcheck value: %s"%v)
|
||||
if 'diskcheck' not in self.__dict__:
|
||||
# No --diskcheck= option was specified on the command line.
|
||||
|
@ -186,6 +199,7 @@ class SConsValues(optparse.Values):
|
|||
|
||||
self.__SConscript_settings__[name] = value
|
||||
|
||||
|
||||
class SConsOption(optparse.Option):
|
||||
def convert_value(self, opt, value):
|
||||
if value is not None:
|
||||
|
@ -638,7 +652,7 @@ def Parser(version):
|
|||
for value in value__.split(','):
|
||||
if value in debug_options:
|
||||
parser.values.debug.append(value)
|
||||
elif value in deprecated_debug_options.keys():
|
||||
elif value in list(deprecated_debug_options.keys()):
|
||||
parser.values.debug.append(value)
|
||||
try:
|
||||
parser.values.delayed_warnings
|
||||
|
@ -663,7 +677,7 @@ def Parser(version):
|
|||
def opt_diskcheck(option, opt, value, parser):
|
||||
try:
|
||||
diskcheck_value = diskcheck_convert(value)
|
||||
except ValueError, e:
|
||||
except ValueError as e:
|
||||
raise OptionValueError("`%s' is not a valid diskcheck type" % e)
|
||||
setattr(parser.values, option.dest, diskcheck_value)
|
||||
|
||||
|
@ -830,7 +844,7 @@ def Parser(version):
|
|||
tree_options = ["all", "derived", "prune", "status"]
|
||||
|
||||
def opt_tree(option, opt, value, parser, tree_options=tree_options):
|
||||
import Main
|
||||
from . import Main
|
||||
tp = Main.TreePrinter()
|
||||
for o in value.split(','):
|
||||
if o == 'all':
|
|
@ -6,7 +6,7 @@ files.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -26,9 +26,8 @@ files.
|
|||
# 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.
|
||||
from __future__ import division
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/SConscript.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Script/SConscript.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons
|
||||
import SCons.Action
|
||||
|
@ -45,12 +44,15 @@ import SCons.Script.Main
|
|||
import SCons.Tool
|
||||
import SCons.Util
|
||||
|
||||
from . import Main
|
||||
|
||||
import collections
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
import traceback
|
||||
import time
|
||||
|
||||
class SConscriptReturn(Exception):
|
||||
pass
|
||||
|
@ -69,7 +71,7 @@ def get_calling_namespaces():
|
|||
"""Return the locals and globals for the function that called
|
||||
into this module in the current call stack."""
|
||||
try: 1//0
|
||||
except ZeroDivisionError:
|
||||
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
|
||||
|
@ -103,7 +105,7 @@ def compute_exports(exports):
|
|||
retval[export] = loc[export]
|
||||
except KeyError:
|
||||
retval[export] = glob[export]
|
||||
except KeyError, x:
|
||||
except KeyError as x:
|
||||
raise SCons.Errors.UserError("Export of non-existent variable '%s'"%x)
|
||||
|
||||
return retval
|
||||
|
@ -135,7 +137,7 @@ def Return(*vars, **kw):
|
|||
for var in fvars:
|
||||
for v in var.split():
|
||||
retval.append(call_stack[-1].globals[v])
|
||||
except KeyError, x:
|
||||
except KeyError as x:
|
||||
raise SCons.Errors.UserError("Return of non-existent variable '%s'"%x)
|
||||
|
||||
if len(retval) == 1:
|
||||
|
@ -164,7 +166,7 @@ def _SConscript(fs, *files, **kw):
|
|||
try:
|
||||
SCons.Script.sconscript_reading = SCons.Script.sconscript_reading + 1
|
||||
if fn == "-":
|
||||
exec sys.stdin in call_stack[-1].globals
|
||||
exec(sys.stdin.read(), call_stack[-1].globals)
|
||||
else:
|
||||
if isinstance(fn, SCons.Node.Node):
|
||||
f = fn
|
||||
|
@ -178,10 +180,10 @@ def _SConscript(fs, *files, **kw):
|
|||
fs.chdir(top, change_os_dir=1)
|
||||
if f.rexists():
|
||||
actual = f.rfile()
|
||||
_file_ = open(actual.get_abspath(), "r")
|
||||
_file_ = open(actual.get_abspath(), "rb")
|
||||
elif f.srcnode().rexists():
|
||||
actual = f.srcnode().rfile()
|
||||
_file_ = open(actual.get_abspath(), "r")
|
||||
_file_ = open(actual.get_abspath(), "rb")
|
||||
elif f.has_src_builder():
|
||||
# The SConscript file apparently exists in a source
|
||||
# code management system. Build it, but then clear
|
||||
|
@ -191,7 +193,7 @@ def _SConscript(fs, *files, **kw):
|
|||
f.built()
|
||||
f.builder_set(None)
|
||||
if f.exists():
|
||||
_file_ = open(f.get_abspath(), "r")
|
||||
_file_ = open(f.get_abspath(), "rb")
|
||||
if _file_:
|
||||
# Chdir to the SConscript directory. Use a path
|
||||
# name relative to the SConstruct file so that if
|
||||
|
@ -247,10 +249,18 @@ def _SConscript(fs, *files, **kw):
|
|||
pass
|
||||
try:
|
||||
try:
|
||||
exec _file_ in call_stack[-1].globals
|
||||
# _file_ = SCons.Util.to_str(_file_)
|
||||
if Main.print_time:
|
||||
time1 = time.time()
|
||||
exec(compile(_file_.read(), _file_.name, 'exec'),
|
||||
call_stack[-1].globals)
|
||||
except SConscriptReturn:
|
||||
pass
|
||||
finally:
|
||||
if Main.print_time:
|
||||
time2 = time.time()
|
||||
print('SConscript:%s took %0.3f ms' % (f.get_abspath(), (time2 - time1) * 1000.0))
|
||||
|
||||
if old_file is not None:
|
||||
call_stack[-1].globals.update({__file__:old_file})
|
||||
else:
|
||||
|
@ -272,7 +282,7 @@ def _SConscript(fs, *files, **kw):
|
|||
rdir._create() # Make sure there's a directory there.
|
||||
try:
|
||||
os.chdir(rdir.get_abspath())
|
||||
except OSError, e:
|
||||
except OSError as e:
|
||||
# We still couldn't chdir there, so raise the error,
|
||||
# but only if actions are being executed.
|
||||
#
|
||||
|
@ -462,15 +472,15 @@ class SConsEnvironment(SCons.Environment.Base):
|
|||
scons_ver_string = '%d.%d.%d' % (major, minor, revision)
|
||||
else:
|
||||
scons_ver_string = '%d.%d' % (major, minor)
|
||||
print "SCons %s or greater required, but you have SCons %s" % \
|
||||
(scons_ver_string, SCons.__version__)
|
||||
print("SCons %s or greater required, but you have SCons %s" % \
|
||||
(scons_ver_string, SCons.__version__))
|
||||
sys.exit(2)
|
||||
|
||||
def EnsurePythonVersion(self, major, minor):
|
||||
"""Exit abnormally if the Python version is not late enough."""
|
||||
if sys.version_info < (major, minor):
|
||||
v = sys.version.split()[0]
|
||||
print "Python %d.%d or greater required, but you have Python %s" %(major,minor,v)
|
||||
print("Python %d.%d or greater required, but you have Python %s" %(major,minor,v))
|
||||
sys.exit(2)
|
||||
|
||||
def Exit(self, value=0):
|
||||
|
@ -509,7 +519,7 @@ class SConsEnvironment(SCons.Environment.Base):
|
|||
globals[v] = exports[v]
|
||||
else:
|
||||
globals[v] = global_exports[v]
|
||||
except KeyError,x:
|
||||
except KeyError as x:
|
||||
raise SCons.Errors.UserError("Import of non-existent variable '%s'"%x)
|
||||
|
||||
def SConscript(self, *ls, **kw):
|
|
@ -12,7 +12,7 @@ it goes here.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -34,14 +34,19 @@ it goes here.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Script/__init__.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Script/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import time
|
||||
start_time = time.time()
|
||||
|
||||
import collections
|
||||
import os
|
||||
import StringIO
|
||||
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
import sys
|
||||
|
||||
# Special chicken-and-egg handling of the "--debug=memoizer" flag:
|
||||
|
@ -67,7 +72,7 @@ if "--debug=memoizer" in _args:
|
|||
except SCons.Warnings.Warning:
|
||||
# Some warning was thrown. Arrange for it to be displayed
|
||||
# or not after warnings are configured.
|
||||
import Main
|
||||
from . import Main
|
||||
exc_type, exc_value, tb = sys.exc_info()
|
||||
Main.delayed_warnings.append((exc_type, exc_value))
|
||||
del _args
|
||||
|
@ -86,7 +91,7 @@ import SCons.Util
|
|||
import SCons.Variables
|
||||
import SCons.Defaults
|
||||
|
||||
import Main
|
||||
from . import Main
|
||||
|
||||
main = Main.main
|
||||
|
||||
|
@ -130,7 +135,7 @@ GetBuildFailures = Main.GetBuildFailures
|
|||
#repositories = Main.repositories
|
||||
|
||||
#
|
||||
import SConscript
|
||||
from . import SConscript
|
||||
_SConscript = SConscript
|
||||
|
||||
call_stack = _SConscript.call_stack
|
||||
|
@ -264,7 +269,7 @@ def HelpFunction(text, append=False):
|
|||
global help_text
|
||||
if help_text is None:
|
||||
if append:
|
||||
s = StringIO.StringIO()
|
||||
s = StringIO()
|
||||
PrintHelp(s)
|
||||
help_text = s.getvalue()
|
||||
s.close()
|
||||
|
@ -332,6 +337,7 @@ GlobalDefaultEnvironmentFunctions = [
|
|||
'Local',
|
||||
'ParseDepends',
|
||||
'Precious',
|
||||
'PyPackageDir',
|
||||
'Repository',
|
||||
'Requires',
|
||||
'SConsignFile',
|
||||
|
@ -354,6 +360,7 @@ GlobalDefaultBuilders = [
|
|||
'Java',
|
||||
'JavaH',
|
||||
'Library',
|
||||
'LoadableModule',
|
||||
'M4',
|
||||
'MSVSProject',
|
||||
'Object',
|
||||
|
@ -374,7 +381,7 @@ GlobalDefaultBuilders = [
|
|||
]
|
||||
|
||||
for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders:
|
||||
exec "%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name))
|
||||
exec ("%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name)))
|
||||
del name
|
||||
|
||||
# There are a handful of variables that used to live in the
|
|
@ -5,7 +5,7 @@ SCons string substitution.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -26,7 +26,7 @@ SCons string substitution.
|
|||
# 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/Subst.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Subst.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import collections
|
||||
import re
|
||||
|
@ -338,24 +338,31 @@ SUBST_RAW = 1
|
|||
SUBST_SIG = 2
|
||||
|
||||
_rm = re.compile(r'\$[()]')
|
||||
_remove = re.compile(r'\$\([^\$]*(\$[^\)][^\$]*)*\$\)')
|
||||
|
||||
# Note the pattern below only matches $( or $) when there is no
|
||||
# preceeding $. (Thus the (?<!\$))
|
||||
_rm_split = re.compile(r'(?<!\$)(\$[()])')
|
||||
|
||||
# Indexed by the SUBST_* constants above.
|
||||
_regex_remove = [ _rm, None, _remove ]
|
||||
_regex_remove = [ _rm, None, _rm_split ]
|
||||
|
||||
def _rm_list(list):
|
||||
return [l for l in list if not l in ('$(', '$)')]
|
||||
|
||||
def _remove_list(list):
|
||||
result = []
|
||||
do_append = result.append
|
||||
depth = 0
|
||||
for l in list:
|
||||
if l == '$(':
|
||||
do_append = lambda x: None
|
||||
depth += 1
|
||||
elif l == '$)':
|
||||
do_append = result.append
|
||||
else:
|
||||
do_append(l)
|
||||
depth -= 1
|
||||
if depth < 0:
|
||||
break
|
||||
elif depth == 0:
|
||||
result.append(l)
|
||||
if depth != 0:
|
||||
return None
|
||||
return result
|
||||
|
||||
# Indexed by the SUBST_* constants above.
|
||||
|
@ -433,19 +440,23 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
|
|||
if s0 != '$':
|
||||
return s
|
||||
if s1 == '$':
|
||||
return '$'
|
||||
# In this case keep the double $'s which we'll later
|
||||
# swap for a single dollar sign as we need to retain
|
||||
# this information to properly avoid matching "$("" when
|
||||
# the actual text was "$$("" (or "$)"" when "$$)"" )
|
||||
return '$$'
|
||||
elif s1 in '()':
|
||||
return s
|
||||
else:
|
||||
key = s[1:]
|
||||
if key[0] == '{' or key.find('.') >= 0:
|
||||
if key[0] == '{' or '.' in key:
|
||||
if key[0] == '{':
|
||||
key = key[1:-1]
|
||||
try:
|
||||
s = eval(key, self.gvars, lvars)
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
if e.__class__ in AllowableExceptions:
|
||||
return ''
|
||||
raise_exception(e, lvars['TARGETS'], s)
|
||||
|
@ -562,20 +573,35 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={
|
|||
except KeyError:
|
||||
pass
|
||||
|
||||
res = result
|
||||
if is_String(result):
|
||||
# Remove $(-$) pairs and any stuff in between,
|
||||
# if that's appropriate.
|
||||
remove = _regex_remove[mode]
|
||||
if remove:
|
||||
result = remove.sub('', result)
|
||||
if mode == SUBST_SIG:
|
||||
result = _list_remove[mode](remove.split(result))
|
||||
if result is None:
|
||||
raise SCons.Errors.UserError("Unbalanced $(/$) in: " + res)
|
||||
result = ' '.join(result)
|
||||
else:
|
||||
result = remove.sub('', result)
|
||||
if mode != SUBST_RAW:
|
||||
# Compress strings of white space characters into
|
||||
# a single space.
|
||||
result = _space_sep.sub(' ', result).strip()
|
||||
|
||||
# Now replace escaped $'s currently "$$"
|
||||
# This is needed because we now retain $$ instead of
|
||||
# replacing them during substition to avoid
|
||||
# improperly trying to escape "$$(" as being "$("
|
||||
result = result.replace('$$','$')
|
||||
elif is_Sequence(result):
|
||||
remove = _list_remove[mode]
|
||||
if remove:
|
||||
result = remove(result)
|
||||
if result is None:
|
||||
raise SCons.Errors.UserError("Unbalanced $(/$) in: " + str(res))
|
||||
|
||||
return result
|
||||
|
||||
|
@ -652,7 +678,7 @@ def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gv
|
|||
s = eval(key, self.gvars, lvars)
|
||||
except KeyboardInterrupt:
|
||||
raise
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
if e.__class__ in AllowableExceptions:
|
||||
return
|
||||
raise_exception(e, lvars['TARGETS'], s)
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -20,17 +20,24 @@
|
|||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
|
||||
__doc__ = """
|
||||
Generic Taskmaster module for the SCons build engine.
|
||||
|
||||
This module contains the primary interface(s) between a wrapping user
|
||||
interface and the SCons build engine. There are two key classes here:
|
||||
|
||||
Generic Taskmaster module for the SCons build engine.
|
||||
=====================================================
|
||||
|
||||
This module contains the primary interface(s) between a wrapping user
|
||||
interface and the SCons build engine. There are two key classes here:
|
||||
|
||||
Taskmaster
|
||||
----------
|
||||
This is the main engine for walking the dependency graph and
|
||||
calling things to decide what does or doesn't need to be built.
|
||||
|
||||
Task
|
||||
----
|
||||
This is the base class for allowing a wrapping interface to
|
||||
decide what does or doesn't actually need to be done. The
|
||||
intention is for a wrapping interface to subclass this as
|
||||
|
@ -38,7 +45,7 @@ interface and the SCons build engine. There are two key classes here:
|
|||
|
||||
The canonical example is the SCons native Python interface,
|
||||
which has Task subclasses that handle its specific behavior,
|
||||
like printing "`foo' is up to date" when a top-level target
|
||||
like printing "'foo' is up to date" when a top-level target
|
||||
doesn't need to be built, and handling the -c option by removing
|
||||
targets as its "build" action. There is also a separate subclass
|
||||
for suppressing this output when the -q option is used.
|
||||
|
@ -47,7 +54,7 @@ interface and the SCons build engine. There are two key classes here:
|
|||
target(s) that it decides need to be evaluated and/or built.
|
||||
"""
|
||||
|
||||
__revision__ = "src/engine/SCons/Taskmaster.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Taskmaster.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
from itertools import chain
|
||||
import operator
|
||||
|
@ -107,7 +114,7 @@ fmt = "%(considered)3d "\
|
|||
|
||||
def dump_stats():
|
||||
for n in sorted(StatsNodes, key=lambda a: str(a)):
|
||||
print (fmt % n.attributes.stats.__dict__) + str(n)
|
||||
print((fmt % n.attributes.stats.__dict__) + str(n))
|
||||
|
||||
|
||||
|
||||
|
@ -191,13 +198,13 @@ class Task(object):
|
|||
executor.prepare()
|
||||
for t in executor.get_action_targets():
|
||||
if print_prepare:
|
||||
print "Preparing target %s..."%t
|
||||
print("Preparing target %s..."%t)
|
||||
for s in t.side_effects:
|
||||
print "...with side-effect %s..."%s
|
||||
print("...with side-effect %s..."%s)
|
||||
t.prepare()
|
||||
for s in t.side_effects:
|
||||
if print_prepare:
|
||||
print "...Preparing side-effect %s..."%s
|
||||
print("...Preparing side-effect %s..."%s)
|
||||
s.prepare()
|
||||
|
||||
def get_target(self):
|
||||
|
@ -256,7 +263,7 @@ class Task(object):
|
|||
raise
|
||||
except SCons.Errors.BuildError:
|
||||
raise
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
buildError = SCons.Errors.convert_to_BuildError(e)
|
||||
buildError.node = self.targets[0]
|
||||
buildError.exc_info = sys.exc_info()
|
||||
|
@ -305,7 +312,7 @@ class Task(object):
|
|||
t.push_to_cache()
|
||||
t.built()
|
||||
t.visited()
|
||||
if (not print_prepare and
|
||||
if (not print_prepare and
|
||||
(not hasattr(self, 'options') or not self.options.debug_includes)):
|
||||
t.release_target_info()
|
||||
else:
|
||||
|
@ -402,7 +409,7 @@ class Task(object):
|
|||
t.disambiguate().make_ready()
|
||||
is_up_to_date = not t.has_builder() or \
|
||||
(not t.always_build and t.is_up_to_date())
|
||||
except EnvironmentError, e:
|
||||
except EnvironmentError as e:
|
||||
raise SCons.Errors.BuildError(node=t, errstr=e.strerror, filename=e.filename)
|
||||
|
||||
if not is_up_to_date:
|
||||
|
@ -423,7 +430,7 @@ class Task(object):
|
|||
# parallel build...)
|
||||
t.visited()
|
||||
t.set_state(NODE_UP_TO_DATE)
|
||||
if (not print_prepare and
|
||||
if (not print_prepare and
|
||||
(not hasattr(self, 'options') or not self.options.debug_includes)):
|
||||
t.release_target_info()
|
||||
|
||||
|
@ -537,7 +544,23 @@ class Task(object):
|
|||
except ValueError:
|
||||
exc_type, exc_value = exc
|
||||
exc_traceback = None
|
||||
raise exc_type, exc_value, exc_traceback
|
||||
|
||||
# raise exc_type(exc_value).with_traceback(exc_traceback)
|
||||
if sys.version_info[0] == 2:
|
||||
exec("raise exc_type, exc_value, exc_traceback")
|
||||
else: # sys.version_info[0] == 3:
|
||||
if isinstance(exc_value, Exception): #hasattr(exc_value, 'with_traceback'):
|
||||
# If exc_value is an exception, then just reraise
|
||||
exec("raise exc_value.with_traceback(exc_traceback)")
|
||||
else:
|
||||
# else we'll create an exception using the value and raise that
|
||||
exec("raise exc_type(exc_value).with_traceback(exc_traceback)")
|
||||
|
||||
|
||||
# raise e.__class__, e.__class__(e), sys.exc_info()[2]
|
||||
# exec("raise exc_type(exc_value).with_traceback(exc_traceback)")
|
||||
|
||||
|
||||
|
||||
class AlwaysTask(Task):
|
||||
def needs_execute(self):
|
||||
|
@ -669,14 +692,14 @@ class Taskmaster(object):
|
|||
at node A. The Taskmaster first considers 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:
|
||||
dependency graph looking like::
|
||||
|
||||
Next candidate \
|
||||
\
|
||||
Node A (Pending) --> Node B(Pending) --> Node C (NoState)
|
||||
^ |
|
||||
| |
|
||||
+-------------------------------------+
|
||||
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,
|
||||
|
@ -685,15 +708,14 @@ class Taskmaster(object):
|
|||
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:
|
||||
consider the following graph::
|
||||
|
||||
|
||||
Node A (Pending) --> Node B(Pending) --> Node C (Pending) --> ...
|
||||
| ^
|
||||
| |
|
||||
+----------> Node D (NoState) --------+
|
||||
/
|
||||
Next candidate /
|
||||
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
|
||||
|
@ -761,7 +783,7 @@ class Taskmaster(object):
|
|||
self.ready_exc = None
|
||||
|
||||
T = self.trace
|
||||
if T: T.write(u'\n' + self.trace_message('Looking for a node to evaluate'))
|
||||
if T: T.write(SCons.Util.UnicodeType('\n') + self.trace_message('Looking for a node to evaluate'))
|
||||
|
||||
while True:
|
||||
node = self.next_candidate()
|
||||
|
@ -810,7 +832,7 @@ class Taskmaster(object):
|
|||
self.ready_exc = (SCons.Errors.ExplicitExit, e)
|
||||
if T: T.write(self.trace_message(' SystemExit'))
|
||||
return node
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
# We had a problem just trying to figure out the
|
||||
# children (like a child couldn't be linked in to a
|
||||
# VariantDir, or a Scanner threw something). Arrange to
|
||||
|
@ -840,13 +862,13 @@ class Taskmaster(object):
|
|||
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:
|
||||
|
||||
# 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)))
|
||||
|
||||
|
@ -943,13 +965,13 @@ class Taskmaster(object):
|
|||
executor = node.get_executor()
|
||||
if executor is None:
|
||||
return None
|
||||
|
||||
|
||||
tlist = executor.get_all_targets()
|
||||
|
||||
task = self.tasker(self, tlist, node in self.original_top, node)
|
||||
try:
|
||||
task.make_ready()
|
||||
except:
|
||||
except Exception as e :
|
||||
# We had a problem just trying to get this task ready (like
|
||||
# a child couldn't be linked to a VariantDir when deciding
|
||||
# whether this node is current). Arrange to raise the
|
|
@ -10,7 +10,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -32,12 +32,12 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/386asm.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/386asm.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
from SCons.Tool.PharLapCommon import addPharLapPaths
|
||||
import SCons.Util
|
||||
|
||||
as_module = __import__('as', globals(), locals(), [])
|
||||
as_module = __import__('as', globals(), locals(), [], 1)
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for ar to an Environment."""
|
|
@ -1,3 +1,5 @@
|
|||
from __future__ import print_function
|
||||
|
||||
"""SCons.Tool.DCommon
|
||||
|
||||
Common code for the various D tools.
|
||||
|
@ -5,8 +7,9 @@ Common code for the various D tools.
|
|||
Coded by Russel Winder (russel@winder.org.uk)
|
||||
2012-09-06
|
||||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -28,10 +31,11 @@ Coded by Russel Winder (russel@winder.org.uk)
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/DCommon.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/DCommon.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import os.path
|
||||
|
||||
|
||||
def isD(env, source):
|
||||
if not source:
|
||||
return 0
|
||||
|
@ -42,6 +46,7 @@ def isD(env, source):
|
|||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
def addDPATHToEnv(env, executable):
|
||||
dPath = env.WhereIs(executable)
|
||||
if dPath:
|
||||
|
@ -49,6 +54,14 @@ def addDPATHToEnv(env, executable):
|
|||
if os.path.isdir(phobosDir):
|
||||
env.Append(DPATH=[phobosDir])
|
||||
|
||||
|
||||
def allAtOnceEmitter(target, source, env):
|
||||
if env['DC'] in ('ldc2', 'dmd'):
|
||||
env.SideEffect(str(target[0]) + '.o', target[0])
|
||||
env.Clean(target[0], str(target[0]) + '.o')
|
||||
return target, source
|
||||
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
|
@ -5,7 +5,7 @@ Stuff for processing Fortran, common to all fortran dialects.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -26,8 +26,9 @@ Stuff for processing Fortran, common to all fortran dialects.
|
|||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
from __future__ import print_function
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/FortranCommon.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/FortranCommon.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import re
|
||||
import os.path
|
||||
|
@ -61,7 +62,7 @@ def isfortran(env, source):
|
|||
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)
|
||||
print("Could not locate " + str(node.name))
|
||||
return ([], [])
|
||||
mod_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(\w+)"""
|
||||
cre = re.compile(mod_regex,re.M)
|
||||
|
@ -167,7 +168,7 @@ def add_fortran_to_env(env):
|
|||
except KeyError:
|
||||
FortranSuffixes = ['.f', '.for', '.ftn']
|
||||
|
||||
#print "Adding %s to fortran suffixes" % FortranSuffixes
|
||||
#print("Adding %s to fortran suffixes" % FortranSuffixes)
|
||||
try:
|
||||
FortranPPSuffixes = env['FORTRANPPFILESUFFIXES']
|
||||
except KeyError:
|
||||
|
@ -191,7 +192,7 @@ def add_f77_to_env(env):
|
|||
except KeyError:
|
||||
F77Suffixes = ['.f77']
|
||||
|
||||
#print "Adding %s to f77 suffixes" % F77Suffixes
|
||||
#print("Adding %s to f77 suffixes" % F77Suffixes)
|
||||
try:
|
||||
F77PPSuffixes = env['F77PPFILESUFFIXES']
|
||||
except KeyError:
|
||||
|
@ -206,7 +207,7 @@ def add_f90_to_env(env):
|
|||
except KeyError:
|
||||
F90Suffixes = ['.f90']
|
||||
|
||||
#print "Adding %s to f90 suffixes" % F90Suffixes
|
||||
#print("Adding %s to f90 suffixes" % F90Suffixes)
|
||||
try:
|
||||
F90PPSuffixes = env['F90PPFILESUFFIXES']
|
||||
except KeyError:
|
||||
|
@ -222,7 +223,7 @@ def add_f95_to_env(env):
|
|||
except KeyError:
|
||||
F95Suffixes = ['.f95']
|
||||
|
||||
#print "Adding %s to f95 suffixes" % F95Suffixes
|
||||
#print("Adding %s to f95 suffixes" % F95Suffixes)
|
||||
try:
|
||||
F95PPSuffixes = env['F95PPFILESUFFIXES']
|
||||
except KeyError:
|
||||
|
@ -238,7 +239,7 @@ def add_f03_to_env(env):
|
|||
except KeyError:
|
||||
F03Suffixes = ['.f03']
|
||||
|
||||
#print "Adding %s to f95 suffixes" % F95Suffixes
|
||||
#print("Adding %s to f95 suffixes" % F95Suffixes)
|
||||
try:
|
||||
F03PPSuffixes = env['F03PPFILESUFFIXES']
|
||||
except KeyError:
|
469
scons/scons-local-3.0.1/SCons/Tool/GettextCommon.py
Normal file
469
scons/scons-local-3.0.1/SCons/Tool/GettextCommon.py
Normal file
|
@ -0,0 +1,469 @@
|
|||
"""SCons.Tool.GettextCommon module
|
||||
|
||||
Used by several tools of `gettext` toolset.
|
||||
"""
|
||||
|
||||
# Copyright (c) 2001 - 2017 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/GettextCommon.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.Warnings
|
||||
import re
|
||||
|
||||
|
||||
#############################################################################
|
||||
class XgettextToolWarning(SCons.Warnings.Warning): pass
|
||||
|
||||
|
||||
class XgettextNotFound(XgettextToolWarning): pass
|
||||
|
||||
|
||||
class MsginitToolWarning(SCons.Warnings.Warning): pass
|
||||
|
||||
|
||||
class MsginitNotFound(MsginitToolWarning): pass
|
||||
|
||||
|
||||
class MsgmergeToolWarning(SCons.Warnings.Warning): pass
|
||||
|
||||
|
||||
class MsgmergeNotFound(MsgmergeToolWarning): pass
|
||||
|
||||
|
||||
class MsgfmtToolWarning(SCons.Warnings.Warning): pass
|
||||
|
||||
|
||||
class MsgfmtNotFound(MsgfmtToolWarning): pass
|
||||
|
||||
|
||||
#############################################################################
|
||||
SCons.Warnings.enableWarningClass(XgettextToolWarning)
|
||||
SCons.Warnings.enableWarningClass(XgettextNotFound)
|
||||
SCons.Warnings.enableWarningClass(MsginitToolWarning)
|
||||
SCons.Warnings.enableWarningClass(MsginitNotFound)
|
||||
SCons.Warnings.enableWarningClass(MsgmergeToolWarning)
|
||||
SCons.Warnings.enableWarningClass(MsgmergeNotFound)
|
||||
SCons.Warnings.enableWarningClass(MsgfmtToolWarning)
|
||||
SCons.Warnings.enableWarningClass(MsgfmtNotFound)
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
class _POTargetFactory(object):
|
||||
""" A factory of `PO` target files.
|
||||
|
||||
Factory defaults differ from these of `SCons.Node.FS.FS`. We set `precious`
|
||||
(this is required by builders and actions gettext) and `noclean` flags by
|
||||
default for all produced nodes.
|
||||
"""
|
||||
|
||||
def __init__(self, env, nodefault=True, alias=None, precious=True
|
||||
, noclean=True):
|
||||
""" Object constructor.
|
||||
|
||||
**Arguments**
|
||||
|
||||
- *env* (`SCons.Environment.Environment`)
|
||||
- *nodefault* (`boolean`) - if `True`, produced nodes will be ignored
|
||||
from default target `'.'`
|
||||
- *alias* (`string`) - if provided, produced nodes will be automatically
|
||||
added to this alias, and alias will be set as `AlwaysBuild`
|
||||
- *precious* (`boolean`) - if `True`, the produced nodes will be set as
|
||||
`Precious`.
|
||||
- *noclen* (`boolean`) - if `True`, the produced nodes will be excluded
|
||||
from `Clean`.
|
||||
"""
|
||||
self.env = env
|
||||
self.alias = alias
|
||||
self.precious = precious
|
||||
self.noclean = noclean
|
||||
self.nodefault = nodefault
|
||||
|
||||
def _create_node(self, name, factory, directory=None, create=1):
|
||||
""" Create node, and set it up to factory settings. """
|
||||
import SCons.Util
|
||||
node = factory(name, directory, create)
|
||||
node.set_noclean(self.noclean)
|
||||
node.set_precious(self.precious)
|
||||
if self.nodefault:
|
||||
self.env.Ignore('.', node)
|
||||
if self.alias:
|
||||
self.env.AlwaysBuild(self.env.Alias(self.alias, node))
|
||||
return node
|
||||
|
||||
def Entry(self, name, directory=None, create=1):
|
||||
""" Create `SCons.Node.FS.Entry` """
|
||||
return self._create_node(name, self.env.fs.Entry, directory, create)
|
||||
|
||||
def File(self, name, directory=None, create=1):
|
||||
""" Create `SCons.Node.FS.File` """
|
||||
return self._create_node(name, self.env.fs.File, directory, create)
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
_re_comment = re.compile(r'(#[^\n\r]+)$', re.M)
|
||||
_re_lang = re.compile(r'([a-zA-Z0-9_]+)', re.M)
|
||||
|
||||
|
||||
#############################################################################
|
||||
def _read_linguas_from_files(env, linguas_files=None):
|
||||
""" Parse `LINGUAS` file and return list of extracted languages """
|
||||
import SCons.Util
|
||||
import SCons.Environment
|
||||
global _re_comment
|
||||
global _re_lang
|
||||
if not SCons.Util.is_List(linguas_files) \
|
||||
and not SCons.Util.is_String(linguas_files) \
|
||||
and not isinstance(linguas_files, SCons.Node.FS.Base) \
|
||||
and linguas_files:
|
||||
# If, linguas_files==True or such, then read 'LINGUAS' file.
|
||||
linguas_files = ['LINGUAS']
|
||||
if linguas_files is None:
|
||||
return []
|
||||
fnodes = env.arg2nodes(linguas_files)
|
||||
linguas = []
|
||||
for fnode in fnodes:
|
||||
contents = _re_comment.sub("", fnode.get_text_contents())
|
||||
ls = [l for l in _re_lang.findall(contents) if l]
|
||||
linguas.extend(ls)
|
||||
return linguas
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
from SCons.Builder import BuilderBase
|
||||
|
||||
|
||||
#############################################################################
|
||||
class _POFileBuilder(BuilderBase):
|
||||
""" `PO` file builder.
|
||||
|
||||
This is multi-target single-source builder. In typical situation the source
|
||||
is single `POT` file, e.g. `messages.pot`, and there are multiple `PO`
|
||||
targets to be updated from this `POT`. We must run
|
||||
`SCons.Builder.BuilderBase._execute()` separatelly for each target to track
|
||||
dependencies separatelly for each target file.
|
||||
|
||||
**NOTE**: if we call `SCons.Builder.BuilderBase._execute(.., target, ...)`
|
||||
with target being list of all targets, all targets would be rebuilt each time
|
||||
one of the targets from this list is missing. This would happen, for example,
|
||||
when new language `ll` enters `LINGUAS_FILE` (at this moment there is no
|
||||
`ll.po` file yet). To avoid this, we override
|
||||
`SCons.Builder.BuilerBase._execute()` and call it separatelly for each
|
||||
target. Here we also append to the target list the languages read from
|
||||
`LINGUAS_FILE`.
|
||||
"""
|
||||
|
||||
#
|
||||
# * The argument for overriding _execute(): We must use environment with
|
||||
# builder overrides applied (see BuilderBase.__init__(). Here it comes for
|
||||
# free.
|
||||
# * The argument against using 'emitter': The emitter is called too late
|
||||
# by BuilderBase._execute(). If user calls, for example:
|
||||
#
|
||||
# env.POUpdate(LINGUAS_FILE = 'LINGUAS')
|
||||
#
|
||||
# the builder throws error, because it is called with target=None,
|
||||
# source=None and is trying to "generate" sources or target list first.
|
||||
# If user calls
|
||||
#
|
||||
# env.POUpdate(['foo', 'baz'], LINGUAS_FILE = 'LINGUAS')
|
||||
#
|
||||
# the env.BuilderWrapper() calls our builder with target=None,
|
||||
# source=['foo', 'baz']. The BuilderBase._execute() then splits execution
|
||||
# and execute iterativelly (recursion) self._execute(None, source[i]).
|
||||
# After that it calls emitter (which is quite too late). The emitter is
|
||||
# also called in each iteration, what makes things yet worse.
|
||||
def __init__(self, env, **kw):
|
||||
if not 'suffix' in kw:
|
||||
kw['suffix'] = '$POSUFFIX'
|
||||
if not 'src_suffix' in kw:
|
||||
kw['src_suffix'] = '$POTSUFFIX'
|
||||
if not 'src_builder' in kw:
|
||||
kw['src_builder'] = '_POTUpdateBuilder'
|
||||
if not 'single_source' in kw:
|
||||
kw['single_source'] = True
|
||||
alias = None
|
||||
if 'target_alias' in kw:
|
||||
alias = kw['target_alias']
|
||||
del kw['target_alias']
|
||||
if not 'target_factory' in kw:
|
||||
kw['target_factory'] = _POTargetFactory(env, alias=alias).File
|
||||
BuilderBase.__init__(self, **kw)
|
||||
|
||||
def _execute(self, env, target, source, *args, **kw):
|
||||
""" Execute builder's actions.
|
||||
|
||||
Here we append to `target` the languages read from `$LINGUAS_FILE` and
|
||||
apply `SCons.Builder.BuilderBase._execute()` separatelly to each target.
|
||||
The arguments and return value are same as for
|
||||
`SCons.Builder.BuilderBase._execute()`.
|
||||
"""
|
||||
import SCons.Util
|
||||
import SCons.Node
|
||||
linguas_files = None
|
||||
if 'LINGUAS_FILE' in env and env['LINGUAS_FILE']:
|
||||
linguas_files = env['LINGUAS_FILE']
|
||||
# This prevents endless recursion loop (we'll be invoked once for
|
||||
# each target appended here, we must not extend the list again).
|
||||
env['LINGUAS_FILE'] = None
|
||||
linguas = _read_linguas_from_files(env, linguas_files)
|
||||
if SCons.Util.is_List(target):
|
||||
target.extend(linguas)
|
||||
elif target is not None:
|
||||
target = [target] + linguas
|
||||
else:
|
||||
target = linguas
|
||||
if not target:
|
||||
# Let the SCons.BuilderBase to handle this patologic situation
|
||||
return BuilderBase._execute(self, env, target, source, *args, **kw)
|
||||
# The rest is ours
|
||||
if not SCons.Util.is_List(target):
|
||||
target = [target]
|
||||
result = []
|
||||
for tgt in target:
|
||||
r = BuilderBase._execute(self, env, [tgt], source, *args, **kw)
|
||||
result.extend(r)
|
||||
if linguas_files is not None:
|
||||
env['LINGUAS_FILE'] = linguas_files
|
||||
return SCons.Node.NodeList(result)
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
||||
import SCons.Environment
|
||||
|
||||
|
||||
#############################################################################
|
||||
def _translate(env, target=None, source=SCons.Environment._null, *args, **kw):
|
||||
""" Function for `Translate()` pseudo-builder """
|
||||
if target is None: target = []
|
||||
pot = env.POTUpdate(None, source, *args, **kw)
|
||||
po = env.POUpdate(target, pot, *args, **kw)
|
||||
return po
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
class RPaths(object):
|
||||
""" Callable object, which returns pathnames relative to SCons current
|
||||
working directory.
|
||||
|
||||
It seems like `SCons.Node.FS.Base.get_path()` returns absolute paths
|
||||
for nodes that are outside of current working directory (`env.fs.getcwd()`).
|
||||
Here, we often have `SConscript`, `POT` and `PO` files within `po/`
|
||||
directory and source files (e.g. `*.c`) outside of it. When generating `POT`
|
||||
template file, references to source files are written to `POT` template, so
|
||||
a translator may later quickly jump to appropriate source file and line from
|
||||
its `PO` editor (e.g. `poedit`). Relative paths in `PO` file are usually
|
||||
interpreted by `PO` editor as paths relative to the place, where `PO` file
|
||||
lives. The absolute paths would make resultant `POT` file nonportable, as
|
||||
the references would be correct only on the machine, where `POT` file was
|
||||
recently re-created. For such reason, we need a function, which always
|
||||
returns relative paths. This is the purpose of `RPaths` callable object.
|
||||
|
||||
The `__call__` method returns paths relative to current working directory, but
|
||||
we assume, that *xgettext(1)* is run from the directory, where target file is
|
||||
going to be created.
|
||||
|
||||
Note, that this may not work for files distributed over several hosts or
|
||||
across different drives on windows. We assume here, that single local
|
||||
filesystem holds both source files and target `POT` templates.
|
||||
|
||||
Intended use of `RPaths` - in `xgettext.py`::
|
||||
|
||||
def generate(env):
|
||||
from GettextCommon import RPaths
|
||||
...
|
||||
sources = '$( ${_concat( "", SOURCES, "", __env__, XgettextRPaths, TARGET, SOURCES)} $)'
|
||||
env.Append(
|
||||
...
|
||||
XGETTEXTCOM = 'XGETTEXT ... ' + sources,
|
||||
...
|
||||
XgettextRPaths = RPaths(env)
|
||||
)
|
||||
"""
|
||||
|
||||
# NOTE: This callable object returns pathnames of dirs/files relative to
|
||||
# current working directory. The pathname remains relative also for entries
|
||||
# that are outside of current working directory (node, that
|
||||
# SCons.Node.FS.File and siblings return absolute path in such case). For
|
||||
# simplicity we compute path relative to current working directory, this
|
||||
# seems be enough for our purposes (don't need TARGET variable and
|
||||
# SCons.Defaults.Variable_Caller stuff).
|
||||
|
||||
def __init__(self, env):
|
||||
""" Initialize `RPaths` callable object.
|
||||
|
||||
**Arguments**:
|
||||
|
||||
- *env* - a `SCons.Environment.Environment` object, defines *current
|
||||
working dir*.
|
||||
"""
|
||||
self.env = env
|
||||
|
||||
# FIXME: I'm not sure, how it should be implemented (what the *args are in
|
||||
# general, what is **kw).
|
||||
def __call__(self, nodes, *args, **kw):
|
||||
""" Return nodes' paths (strings) relative to current working directory.
|
||||
|
||||
**Arguments**:
|
||||
|
||||
- *nodes* ([`SCons.Node.FS.Base`]) - list of nodes.
|
||||
- *args* - currently unused.
|
||||
- *kw* - currently unused.
|
||||
|
||||
**Returns**:
|
||||
|
||||
- Tuple of strings, which represent paths relative to current working
|
||||
directory (for given environment).
|
||||
"""
|
||||
import os
|
||||
import SCons.Node.FS
|
||||
rpaths = ()
|
||||
cwd = self.env.fs.getcwd().get_abspath()
|
||||
for node in nodes:
|
||||
rpath = None
|
||||
if isinstance(node, SCons.Node.FS.Base):
|
||||
rpath = os.path.relpath(node.get_abspath(), cwd)
|
||||
# FIXME: Other types possible here?
|
||||
if rpath is not None:
|
||||
rpaths += (rpath,)
|
||||
return rpaths
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _init_po_files(target, source, env):
|
||||
""" Action function for `POInit` builder. """
|
||||
nop = lambda target, source, env: 0
|
||||
if 'POAUTOINIT' in env:
|
||||
autoinit = env['POAUTOINIT']
|
||||
else:
|
||||
autoinit = False
|
||||
# Well, if everything outside works well, this loop should do single
|
||||
# iteration. Otherwise we are rebuilding all the targets even, if just
|
||||
# one has changed (but is this our fault?).
|
||||
for tgt in target:
|
||||
if not tgt.exists():
|
||||
if autoinit:
|
||||
action = SCons.Action.Action('$MSGINITCOM', '$MSGINITCOMSTR')
|
||||
else:
|
||||
msg = 'File ' + repr(str(tgt)) + ' does not exist. ' \
|
||||
+ 'If you are a translator, you can create it through: \n' \
|
||||
+ '$MSGINITCOM'
|
||||
action = SCons.Action.Action(nop, msg)
|
||||
status = action([tgt], source, env)
|
||||
if status: return status
|
||||
return 0
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _detect_xgettext(env):
|
||||
""" Detects *xgettext(1)* binary """
|
||||
if 'XGETTEXT' in env:
|
||||
return env['XGETTEXT']
|
||||
xgettext = env.Detect('xgettext');
|
||||
if xgettext:
|
||||
return xgettext
|
||||
raise SCons.Errors.StopError(XgettextNotFound, "Could not detect xgettext")
|
||||
return None
|
||||
|
||||
|
||||
#############################################################################
|
||||
def _xgettext_exists(env):
|
||||
return _detect_xgettext(env)
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _detect_msginit(env):
|
||||
""" Detects *msginit(1)* program. """
|
||||
if 'MSGINIT' in env:
|
||||
return env['MSGINIT']
|
||||
msginit = env.Detect('msginit');
|
||||
if msginit:
|
||||
return msginit
|
||||
raise SCons.Errors.StopError(MsginitNotFound, "Could not detect msginit")
|
||||
return None
|
||||
|
||||
|
||||
#############################################################################
|
||||
def _msginit_exists(env):
|
||||
return _detect_msginit(env)
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _detect_msgmerge(env):
|
||||
""" Detects *msgmerge(1)* program. """
|
||||
if 'MSGMERGE' in env:
|
||||
return env['MSGMERGE']
|
||||
msgmerge = env.Detect('msgmerge');
|
||||
if msgmerge:
|
||||
return msgmerge
|
||||
raise SCons.Errors.StopError(MsgmergeNotFound, "Could not detect msgmerge")
|
||||
return None
|
||||
|
||||
|
||||
#############################################################################
|
||||
def _msgmerge_exists(env):
|
||||
return _detect_msgmerge(env)
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def _detect_msgfmt(env):
|
||||
""" Detects *msgmfmt(1)* program. """
|
||||
if 'MSGFMT' in env:
|
||||
return env['MSGFMT']
|
||||
msgfmt = env.Detect('msgfmt');
|
||||
if msgfmt:
|
||||
return msgfmt
|
||||
raise SCons.Errors.StopError(MsgfmtNotFound, "Could not detect msgfmt")
|
||||
return None
|
||||
|
||||
|
||||
#############################################################################
|
||||
def _msgfmt_exists(env):
|
||||
return _detect_msgfmt(env)
|
||||
|
||||
|
||||
#############################################################################
|
||||
|
||||
#############################################################################
|
||||
def tool_list(platform, env):
|
||||
""" List tools that shall be generated by top-level `gettext` tool """
|
||||
return ['xgettext', 'msginit', 'msgmerge', 'msgfmt']
|
||||
|
||||
#############################################################################
|
|
@ -5,7 +5,7 @@ Stuff for processing Java.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ Stuff for processing Java.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/JavaCommon.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/JavaCommon.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import os
|
||||
import os.path
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/__init__.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """
|
||||
Common functions for Microsoft Visual Studio and Visual C/C++.
|
||||
|
@ -41,7 +41,8 @@ from SCons.Tool.MSCommon.sdk import mssdk_exists, \
|
|||
|
||||
from SCons.Tool.MSCommon.vc import msvc_exists, \
|
||||
msvc_setup_env, \
|
||||
msvc_setup_env_once
|
||||
msvc_setup_env_once, \
|
||||
msvc_version_to_maj_min
|
||||
|
||||
from SCons.Tool.MSCommon.vs import get_default_version, \
|
||||
get_vs_by_version, \
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/arch.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/arch.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """Module to define supported Windows chip architectures.
|
||||
"""
|
|
@ -1,5 +1,8 @@
|
|||
"""
|
||||
Common helper functions for working with the Microsoft tool chain.
|
||||
"""
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -20,12 +23,9 @@
|
|||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
from __future__ import print_function
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/common.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
|
||||
__doc__ = """
|
||||
Common helper functions for working with the Microsoft tool chain.
|
||||
"""
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/common.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import copy
|
||||
import os
|
||||
|
@ -35,17 +35,17 @@ import re
|
|||
import SCons.Util
|
||||
|
||||
|
||||
logfile = os.environ.get('SCONS_MSCOMMON_DEBUG')
|
||||
if logfile == '-':
|
||||
def debug(x):
|
||||
print x
|
||||
elif logfile:
|
||||
LOGFILE = os.environ.get('SCONS_MSCOMMON_DEBUG')
|
||||
if LOGFILE == '-':
|
||||
def debug(message):
|
||||
print(message)
|
||||
elif LOGFILE:
|
||||
try:
|
||||
import logging
|
||||
except ImportError:
|
||||
debug = lambda x: open(logfile, 'a').write(x + '\n')
|
||||
debug = lambda message: open(LOGFILE, 'a').write(message + '\n')
|
||||
else:
|
||||
logging.basicConfig(filename=logfile, level=logging.DEBUG)
|
||||
logging.basicConfig(filename=LOGFILE, level=logging.DEBUG)
|
||||
debug = logging.debug
|
||||
else:
|
||||
debug = lambda x: None
|
||||
|
@ -75,7 +75,7 @@ def is_win64():
|
|||
# I structured these tests to make it easy to add new ones or
|
||||
# add exceptions in the future, because this is a bit fragile.
|
||||
_is_win64 = False
|
||||
if os.environ.get('PROCESSOR_ARCHITECTURE','x86') != 'x86':
|
||||
if os.environ.get('PROCESSOR_ARCHITECTURE', 'x86') != 'x86':
|
||||
_is_win64 = True
|
||||
if os.environ.get('PROCESSOR_ARCHITEW6432'):
|
||||
_is_win64 = True
|
||||
|
@ -113,21 +113,30 @@ def normalize_env(env, keys, force=False):
|
|||
Note: the environment is copied."""
|
||||
normenv = {}
|
||||
if env:
|
||||
for k in env.keys():
|
||||
normenv[k] = copy.deepcopy(env[k]).encode('mbcs')
|
||||
for k in list(env.keys()):
|
||||
normenv[k] = copy.deepcopy(env[k])
|
||||
|
||||
for k in keys:
|
||||
if k in os.environ and (force or not k in normenv):
|
||||
normenv[k] = os.environ[k].encode('mbcs')
|
||||
normenv[k] = os.environ[k]
|
||||
|
||||
# This shouldn't be necessary, since the default environment should include system32,
|
||||
# but keep this here to be safe, since it's needed to find reg.exe which the MSVC
|
||||
# bat scripts use.
|
||||
sys32_dir = os.path.join(os.environ.get("SystemRoot", os.environ.get("windir",r"C:\Windows\system32")),"System32")
|
||||
sys32_dir = os.path.join(os.environ.get("SystemRoot",
|
||||
os.environ.get("windir", r"C:\Windows\system32")),
|
||||
"System32")
|
||||
|
||||
if sys32_dir not in normenv['PATH']:
|
||||
normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_dir
|
||||
|
||||
# Without Wbem in PATH, vcvarsall.bat has a "'wmic' is not recognized"
|
||||
# error starting with Visual Studio 2017, although the script still
|
||||
# seems to work anyway.
|
||||
sys32_wbem_dir = os.path.join(sys32_dir, 'Wbem')
|
||||
if sys32_wbem_dir not in normenv['PATH']:
|
||||
normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_wbem_dir
|
||||
|
||||
debug("PATH: %s"%normenv['PATH'])
|
||||
|
||||
return normenv
|
||||
|
@ -144,11 +153,13 @@ def get_output(vcbat, args = None, env = None):
|
|||
# execution to work. This list should really be either directly
|
||||
# controlled by vc.py, or else derived from the common_tools_var
|
||||
# settings in vs.py.
|
||||
vars = [
|
||||
vs_vc_vars = [
|
||||
'COMSPEC',
|
||||
# VS100 and VS110: Still set, but modern MSVC setup scripts will
|
||||
# discard these if registry has values. However Intel compiler setup
|
||||
# script still requires these as of 2013/2014.
|
||||
# VS100 and VS110: Still set, but modern MSVC setup scripts will
|
||||
# discard these if registry has values. However Intel compiler setup
|
||||
# script still requires these as of 2013/2014.
|
||||
'VS140COMNTOOLS',
|
||||
'VS120COMNTOOLS',
|
||||
'VS110COMNTOOLS',
|
||||
'VS100COMNTOOLS',
|
||||
'VS90COMNTOOLS',
|
||||
|
@ -157,22 +168,22 @@ def get_output(vcbat, args = None, env = None):
|
|||
'VS70COMNTOOLS',
|
||||
'VS60COMNTOOLS',
|
||||
]
|
||||
env['ENV'] = normalize_env(env['ENV'], vars, force=False)
|
||||
env['ENV'] = normalize_env(env['ENV'], vs_vc_vars, force=False)
|
||||
|
||||
if args:
|
||||
debug("Calling '%s %s'" % (vcbat, args))
|
||||
popen = SCons.Action._subproc(env,
|
||||
'"%s" %s & set' % (vcbat, args),
|
||||
stdin = 'devnull',
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
'"%s" %s & set' % (vcbat, args),
|
||||
stdin='devnull',
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
else:
|
||||
debug("Calling '%s'" % vcbat)
|
||||
popen = SCons.Action._subproc(env,
|
||||
'"%s" & set' % vcbat,
|
||||
stdin = 'devnull',
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
'"%s" & set' % vcbat,
|
||||
stdin='devnull',
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
|
||||
# Use the .stdout and .stderr attributes directly because the
|
||||
# .communicate() method uses the threading module on Windows
|
||||
|
@ -195,10 +206,14 @@ def get_output(vcbat, args = None, env = None):
|
|||
output = stdout.decode("mbcs")
|
||||
return output
|
||||
|
||||
def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")):
|
||||
def parse_output(output, keep=("INCLUDE", "LIB", "LIBPATH", "PATH")):
|
||||
"""
|
||||
Parse output from running visual c++/studios vcvarsall.bat and running set
|
||||
To capture the values listed in keep
|
||||
"""
|
||||
|
||||
# dkeep is a dict associating key: path_list, where key is one item from
|
||||
# keep, and pat_list the associated list of paths
|
||||
|
||||
dkeep = dict([(i, []) for i in keep])
|
||||
|
||||
# rdk will keep the regex to match the .bat file output line starts
|
||||
|
@ -207,22 +222,21 @@ def parse_output(output, keep = ("INCLUDE", "LIB", "LIBPATH", "PATH")):
|
|||
rdk[i] = re.compile('%s=(.*)' % i, re.I)
|
||||
|
||||
def add_env(rmatch, key, dkeep=dkeep):
|
||||
plist = rmatch.group(1).split(os.pathsep)
|
||||
for p in plist:
|
||||
path_list = rmatch.group(1).split(os.pathsep)
|
||||
for path in path_list:
|
||||
# Do not add empty paths (when a var ends with ;)
|
||||
if p:
|
||||
p = p.encode('mbcs')
|
||||
if path:
|
||||
# XXX: For some reason, VC98 .bat file adds "" around the PATH
|
||||
# values, and it screws up the environment later, so we strip
|
||||
# it.
|
||||
p = p.strip('"')
|
||||
dkeep[key].append(p)
|
||||
path = path.strip('"')
|
||||
dkeep[key].append(str(path))
|
||||
|
||||
for line in output.splitlines():
|
||||
for k,v in rdk.items():
|
||||
m = v.match(line)
|
||||
if m:
|
||||
add_env(m, k)
|
||||
for k, value in rdk.items():
|
||||
match = value.match(line)
|
||||
if match:
|
||||
add_env(match, k)
|
||||
|
||||
return dkeep
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -20,7 +20,7 @@
|
|||
# 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/MSCommon/netframework.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/netframework.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """
|
||||
"""
|
||||
|
@ -29,7 +29,7 @@ import os
|
|||
import re
|
||||
import SCons.Util
|
||||
|
||||
from common import read_reg, debug
|
||||
from .common import read_reg, debug
|
||||
|
||||
# Original value recorded by dcournapeau
|
||||
_FRAMEWORKDIR_HKEY_ROOT = r'Software\Microsoft\.NETFramework\InstallRoot'
|
||||
|
@ -40,13 +40,13 @@ def find_framework_root():
|
|||
# XXX: find it from environment (FrameworkDir)
|
||||
try:
|
||||
froot = read_reg(_FRAMEWORKDIR_HKEY_ROOT)
|
||||
debug("Found framework install root in registry: %s" % froot)
|
||||
except SCons.Util.WinError, e:
|
||||
debug("Could not read reg key %s" % _FRAMEWORKDIR_HKEY_ROOT)
|
||||
debug("Found framework install root in registry: {}".format(froot))
|
||||
except SCons.Util.WinError as e:
|
||||
debug("Could not read reg key {}".format(_FRAMEWORKDIR_HKEY_ROOT))
|
||||
return None
|
||||
|
||||
if not os.path.exists(froot):
|
||||
debug("%s not found on fs" % froot)
|
||||
debug("{} not found on fs".format(froot))
|
||||
return None
|
||||
|
||||
return froot
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/sdk.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/sdk.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """Module to detect the Platform/Windows SDK
|
||||
|
||||
|
@ -33,7 +33,7 @@ import os
|
|||
import SCons.Errors
|
||||
import SCons.Util
|
||||
|
||||
import common
|
||||
from . import common
|
||||
|
||||
debug = common.debug
|
||||
|
||||
|
@ -76,23 +76,23 @@ class SDKDefinition(object):
|
|||
return None
|
||||
|
||||
hkey = self.HKEY_FMT % self.hkey_data
|
||||
debug('find_sdk_dir(): checking registry:%s'%hkey)
|
||||
debug('find_sdk_dir(): checking registry:{}'.format(hkey))
|
||||
|
||||
try:
|
||||
sdk_dir = common.read_reg(hkey)
|
||||
except SCons.Util.WinError, e:
|
||||
debug('find_sdk_dir(): no SDK registry key %s' % repr(hkey))
|
||||
except SCons.Util.WinError as e:
|
||||
debug('find_sdk_dir(): no SDK registry key {}'.format(repr(hkey)))
|
||||
return None
|
||||
|
||||
debug('find_sdk_dir(): Trying SDK Dir: %s'%sdk_dir)
|
||||
debug('find_sdk_dir(): Trying SDK Dir: {}'.format(sdk_dir))
|
||||
|
||||
if not os.path.exists(sdk_dir):
|
||||
debug('find_sdk_dir(): %s not on file system' % sdk_dir)
|
||||
debug('find_sdk_dir(): {} not on file system'.format(sdk_dir))
|
||||
return None
|
||||
|
||||
ftc = os.path.join(sdk_dir, self.sanity_check_file)
|
||||
if not os.path.exists(ftc):
|
||||
debug("find_sdk_dir(): sanity check %s not found" % ftc)
|
||||
debug("find_sdk_dir(): sanity check {} not found".format(ftc))
|
||||
return None
|
||||
|
||||
return sdk_dir
|
||||
|
@ -105,7 +105,7 @@ class SDKDefinition(object):
|
|||
sdk_dir = self.find_sdk_dir()
|
||||
self._sdk_dir = sdk_dir
|
||||
return sdk_dir
|
||||
|
||||
|
||||
def get_sdk_vc_script(self,host_arch, target_arch):
|
||||
""" Return the script to initialize the VC compiler installed by SDK
|
||||
"""
|
||||
|
@ -113,11 +113,11 @@ class SDKDefinition(object):
|
|||
if (host_arch == 'amd64' and target_arch == 'x86'):
|
||||
# No cross tools needed compiling 32 bits on 64 bit machine
|
||||
host_arch=target_arch
|
||||
|
||||
|
||||
arch_string=target_arch
|
||||
if (host_arch != target_arch):
|
||||
arch_string='%s_%s'%(host_arch,target_arch)
|
||||
|
||||
|
||||
debug("sdk.py: get_sdk_vc_script():arch_string:%s host_arch:%s target_arch:%s"%(arch_string,
|
||||
host_arch,
|
||||
target_arch))
|
||||
|
@ -164,6 +164,12 @@ SDK70VCSetupScripts = { 'x86' : r'bin\vcvars32.bat',
|
|||
'x86_ia64' : r'bin\vcvarsx86_ia64.bat',
|
||||
'ia64' : r'bin\vcvarsia64.bat'}
|
||||
|
||||
SDK100VCSetupScripts = {'x86' : r'bin\vcvars32.bat',
|
||||
'amd64' : r'bin\vcvars64.bat',
|
||||
'x86_amd64': r'bin\x86_amd64\vcvarsx86_amd64.bat',
|
||||
'x86_arm' : r'bin\x86_arm\vcvarsx86_arm.bat'}
|
||||
|
||||
|
||||
# The list of support SDKs which we know how to detect.
|
||||
#
|
||||
# The first SDK found in the list is the one used by default if there
|
||||
|
@ -172,6 +178,16 @@ SDK70VCSetupScripts = { 'x86' : r'bin\vcvars32.bat',
|
|||
#
|
||||
# If you update this list, update the documentation in Tool/mssdk.xml.
|
||||
SupportedSDKList = [
|
||||
WindowsSDK('10.0',
|
||||
sanity_check_file=r'bin\SetEnv.Cmd',
|
||||
include_subdir='include',
|
||||
lib_subdir={
|
||||
'x86' : ['lib'],
|
||||
'x86_64' : [r'lib\x64'],
|
||||
'ia64' : [r'lib\ia64'],
|
||||
},
|
||||
vc_setup_scripts = SDK70VCSetupScripts,
|
||||
),
|
||||
WindowsSDK('7.1',
|
||||
sanity_check_file=r'bin\SetEnv.Cmd',
|
||||
include_subdir='include',
|
||||
|
@ -308,8 +324,7 @@ def set_sdk_by_directory(env, sdk_dir):
|
|||
|
||||
def get_sdk_by_version(mssdk):
|
||||
if mssdk not in SupportedSDKMap:
|
||||
msg = "SDK version %s is not supported" % repr(mssdk)
|
||||
raise SCons.Errors.UserError(msg)
|
||||
raise SCons.Errors.UserError("SDK version {} is not supported".format(repr(mssdk)))
|
||||
get_installed_sdks()
|
||||
return InstalledSDKMap.get(mssdk)
|
||||
|
||||
|
@ -327,16 +342,16 @@ def mssdk_setup_env(env):
|
|||
if sdk_dir is None:
|
||||
return
|
||||
sdk_dir = env.subst(sdk_dir)
|
||||
debug('sdk.py:mssdk_setup_env: Using MSSDK_DIR:%s'%sdk_dir)
|
||||
debug('sdk.py:mssdk_setup_env: Using MSSDK_DIR:{}'.format(sdk_dir))
|
||||
elif 'MSSDK_VERSION' in env:
|
||||
sdk_version = env['MSSDK_VERSION']
|
||||
if sdk_version is None:
|
||||
msg = "SDK version is specified as None"
|
||||
msg = "SDK version is specified as None"
|
||||
raise SCons.Errors.UserError(msg)
|
||||
sdk_version = env.subst(sdk_version)
|
||||
mssdk = get_sdk_by_version(sdk_version)
|
||||
if mssdk is None:
|
||||
msg = "SDK version %s is not installed" % sdk_version
|
||||
msg = "SDK version %s is not installed" % sdk_version
|
||||
raise SCons.Errors.UserError(msg)
|
||||
sdk_dir = mssdk.get_sdk_dir()
|
||||
debug('sdk.py:mssdk_setup_env: Using MSSDK_VERSION:%s'%sdk_dir)
|
||||
|
@ -347,7 +362,7 @@ def mssdk_setup_env(env):
|
|||
debug('sdk.py:mssdk_setup_env thinks msvs_version is None')
|
||||
return
|
||||
msvs_version = env.subst(msvs_version)
|
||||
import vs
|
||||
from . import vs
|
||||
msvs = vs.get_vs_by_version(msvs_version)
|
||||
debug('sdk.py:mssdk_setup_env:msvs is :%s'%msvs)
|
||||
if not msvs:
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,24 +30,25 @@
|
|||
# * test on 64 bits XP + VS 2005 (and VS 6 if possible)
|
||||
# * SDK
|
||||
# * Assembly
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/vc.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/vc.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """Module for Visual C/C++ detection and configuration.
|
||||
"""
|
||||
import SCons.compat
|
||||
import SCons.Util
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import platform
|
||||
from string import digits as string_digits
|
||||
|
||||
import SCons.Warnings
|
||||
|
||||
import common
|
||||
from . import common
|
||||
|
||||
debug = common.debug
|
||||
|
||||
import sdk
|
||||
from . import sdk
|
||||
|
||||
get_installed_sdks = sdk.get_installed_sdks
|
||||
|
||||
|
@ -108,7 +109,7 @@ def get_host_target(env):
|
|||
# PROCESSOR_ARCHITECTURE.
|
||||
if not host_platform:
|
||||
host_platform = os.environ.get('PROCESSOR_ARCHITECTURE', '')
|
||||
|
||||
|
||||
# Retain user requested TARGET_ARCH
|
||||
req_target_platform = env.get('TARGET_ARCH')
|
||||
debug('vc.py:get_host_target() req_target_platform:%s'%req_target_platform)
|
||||
|
@ -118,26 +119,28 @@ def get_host_target(env):
|
|||
target_platform = req_target_platform
|
||||
else:
|
||||
target_platform = host_platform
|
||||
|
||||
|
||||
try:
|
||||
host = _ARCH_TO_CANONICAL[host_platform.lower()]
|
||||
except KeyError, e:
|
||||
except KeyError as e:
|
||||
msg = "Unrecognized host architecture %s"
|
||||
raise ValueError(msg % repr(host_platform))
|
||||
|
||||
try:
|
||||
target = _ARCH_TO_CANONICAL[target_platform.lower()]
|
||||
except KeyError, e:
|
||||
all_archs = str(_ARCH_TO_CANONICAL.keys())
|
||||
except KeyError as e:
|
||||
all_archs = str(list(_ARCH_TO_CANONICAL.keys()))
|
||||
raise ValueError("Unrecognized target architecture %s\n\tValid architectures: %s" % (target_platform, all_archs))
|
||||
|
||||
return (host, target,req_target_platform)
|
||||
|
||||
# If you update this, update SupportedVSList in Tool/MSCommon/vs.py, and the
|
||||
# MSVC_VERSION documentation in Tool/msvc.xml.
|
||||
_VCVER = ["14.0", "14.0Exp", "12.0", "12.0Exp", "11.0", "11.0Exp", "10.0", "10.0Exp", "9.0", "9.0Exp","8.0", "8.0Exp","7.1", "7.0", "6.0"]
|
||||
_VCVER = ["14.1", "14.0", "14.0Exp", "12.0", "12.0Exp", "11.0", "11.0Exp", "10.0", "10.0Exp", "9.0", "9.0Exp","8.0", "8.0Exp","7.1", "7.0", "6.0"]
|
||||
|
||||
_VCVER_TO_PRODUCT_DIR = {
|
||||
'14.1' : [
|
||||
(SCons.Util.HKEY_LOCAL_MACHINE, r'')], # Visual Studio 2017 doesn't set this registry key anymore
|
||||
'14.0' : [
|
||||
(SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\14.0\Setup\VC\ProductDir')],
|
||||
'14.0Exp' : [
|
||||
|
@ -183,19 +186,19 @@ _VCVER_TO_PRODUCT_DIR = {
|
|||
(SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\6.0\Setup\Microsoft Visual C++\ProductDir'),
|
||||
]
|
||||
}
|
||||
|
||||
def msvc_version_to_maj_min(msvc_version):
|
||||
msvc_version_numeric = ''.join([x for x in msvc_version if x in string_digits + '.'])
|
||||
|
||||
t = msvc_version_numeric.split(".")
|
||||
if not len(t) == 2:
|
||||
raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
|
||||
try:
|
||||
maj = int(t[0])
|
||||
min = int(t[1])
|
||||
return maj, min
|
||||
except ValueError, e:
|
||||
raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
|
||||
def msvc_version_to_maj_min(msvc_version):
|
||||
msvc_version_numeric = ''.join([x for x in msvc_version if x in string_digits + '.'])
|
||||
|
||||
t = msvc_version_numeric.split(".")
|
||||
if not len(t) == 2:
|
||||
raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
|
||||
try:
|
||||
maj = int(t[0])
|
||||
min = int(t[1])
|
||||
return maj, min
|
||||
except ValueError as e:
|
||||
raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
|
||||
|
||||
def is_host_target_supported(host_target, msvc_version):
|
||||
"""Return True if the given (host, target) tuple is supported given the
|
||||
|
@ -222,6 +225,35 @@ def is_host_target_supported(host_target, msvc_version):
|
|||
|
||||
return True
|
||||
|
||||
|
||||
def find_vc_pdir_vswhere(msvc_version):
|
||||
"""
|
||||
Find the MSVC product directory using vswhere.exe .
|
||||
Run it asking for specified version and get MSVS install location
|
||||
:param msvc_version:
|
||||
:return: MSVC install dir
|
||||
"""
|
||||
vswhere_path = os.path.join(
|
||||
'C:\\',
|
||||
'Program Files (x86)',
|
||||
'Microsoft Visual Studio',
|
||||
'Installer',
|
||||
'vswhere.exe'
|
||||
)
|
||||
vswhere_cmd = [vswhere_path, '-version', msvc_version, '-property', 'installationPath']
|
||||
|
||||
if os.path.exists(vswhere_path):
|
||||
sp = subprocess.Popen(vswhere_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
vsdir, err = sp.communicate()
|
||||
vsdir = vsdir.decode("mbcs")
|
||||
vsdir = vsdir.rstrip()
|
||||
vc_pdir = os.path.join(vsdir, 'VC')
|
||||
return vc_pdir
|
||||
else:
|
||||
# No vswhere on system, no install info available
|
||||
return None
|
||||
|
||||
|
||||
def find_vc_pdir(msvc_version):
|
||||
"""Try to find the product directory for the given
|
||||
version.
|
||||
|
@ -240,26 +272,31 @@ def find_vc_pdir(msvc_version):
|
|||
for hkroot, key in hkeys:
|
||||
try:
|
||||
comps = None
|
||||
if common.is_win64():
|
||||
try:
|
||||
# ordinally at win64, try Wow6432Node first.
|
||||
comps = common.read_reg(root + 'Wow6432Node\\' + key, hkroot)
|
||||
except SCons.Util.WinError, e:
|
||||
# at Microsoft Visual Studio for Python 2.7, value is not in Wow6432Node
|
||||
pass
|
||||
if not comps:
|
||||
# not Win64, or Microsoft Visual Studio for Python 2.7
|
||||
comps = common.read_reg(root + key, hkroot)
|
||||
except SCons.Util.WinError, e:
|
||||
debug('find_vc_dir(): no VC registry key %s' % repr(key))
|
||||
if not key:
|
||||
comps = find_vc_pdir_vswhere(msvc_version)
|
||||
if not comps:
|
||||
debug('find_vc_dir(): no VC found via vswhere for version {}'.format(repr(key)))
|
||||
raise SCons.Util.WinError
|
||||
else:
|
||||
if common.is_win64():
|
||||
try:
|
||||
# ordinally at win64, try Wow6432Node first.
|
||||
comps = common.read_reg(root + 'Wow6432Node\\' + key, hkroot)
|
||||
except SCons.Util.WinError as e:
|
||||
# at Microsoft Visual Studio for Python 2.7, value is not in Wow6432Node
|
||||
pass
|
||||
if not comps:
|
||||
# not Win64, or Microsoft Visual Studio for Python 2.7
|
||||
comps = common.read_reg(root + key, hkroot)
|
||||
except SCons.Util.WinError as e:
|
||||
debug('find_vc_dir(): no VC registry key {}'.format(repr(key)))
|
||||
else:
|
||||
debug('find_vc_dir(): found VC in registry: %s' % comps)
|
||||
debug('find_vc_dir(): found VC in registry: {}'.format(comps))
|
||||
if os.path.exists(comps):
|
||||
return comps
|
||||
else:
|
||||
debug('find_vc_dir(): reg says dir is %s, but it does not exist. (ignoring)'\
|
||||
% comps)
|
||||
raise MissingConfiguration("registry dir %s not found on the filesystem" % comps)
|
||||
debug('find_vc_dir(): reg says dir is {}, but it does not exist. (ignoring)'.format(comps))
|
||||
raise MissingConfiguration("registry dir {} not found on the filesystem".format(comps))
|
||||
return None
|
||||
|
||||
def find_batch_file(env,msvc_version,host_arch,target_arch):
|
||||
|
@ -270,8 +307,8 @@ def find_batch_file(env,msvc_version,host_arch,target_arch):
|
|||
pdir = find_vc_pdir(msvc_version)
|
||||
if pdir is None:
|
||||
raise NoVersionFound("No version of Visual Studio found")
|
||||
|
||||
debug('vc.py: find_batch_file() pdir:%s'%pdir)
|
||||
|
||||
debug('vc.py: find_batch_file() pdir:{}'.format(pdir))
|
||||
|
||||
# filter out e.g. "Exp" from the version name
|
||||
msvc_ver_numeric = ''.join([x for x in msvc_version if x in string_digits + "."])
|
||||
|
@ -282,13 +319,15 @@ def find_batch_file(env,msvc_version,host_arch,target_arch):
|
|||
elif vernum < 7:
|
||||
pdir = os.path.join(pdir, "Bin")
|
||||
batfilename = os.path.join(pdir, "vcvars32.bat")
|
||||
else: # >= 8
|
||||
elif 8 <= vernum <= 14:
|
||||
batfilename = os.path.join(pdir, "vcvarsall.bat")
|
||||
else: # vernum >= 14.1 VS2017 and above
|
||||
batfilename = os.path.join(pdir, "Auxiliary", "Build", "vcvarsall.bat")
|
||||
|
||||
if not os.path.exists(batfilename):
|
||||
debug("Not found: %s" % batfilename)
|
||||
batfilename = None
|
||||
|
||||
|
||||
installed_sdks=get_installed_sdks()
|
||||
for _sdk in installed_sdks:
|
||||
sdk_bat_file = _sdk.get_sdk_vc_script(host_arch,target_arch)
|
||||
|
@ -296,7 +335,7 @@ def find_batch_file(env,msvc_version,host_arch,target_arch):
|
|||
debug("vc.py:find_batch_file() not found:%s"%_sdk)
|
||||
else:
|
||||
sdk_bat_file_path = os.path.join(pdir,sdk_bat_file)
|
||||
if os.path.exists(sdk_bat_file_path):
|
||||
if os.path.exists(sdk_bat_file_path):
|
||||
debug('vc.py:find_batch_file() sdk_bat_file_path:%s'%sdk_bat_file_path)
|
||||
return (batfilename,sdk_bat_file_path)
|
||||
return (batfilename,None)
|
||||
|
@ -323,7 +362,7 @@ def get_installed_vcs():
|
|||
installed_versions.append(ver)
|
||||
else:
|
||||
debug('find_vc_pdir return None for ver %s' % ver)
|
||||
except VisualCException, e:
|
||||
except VisualCException as e:
|
||||
debug('did not find VC %s: caught exception %s' % (ver, str(e)))
|
||||
return installed_versions
|
||||
|
||||
|
@ -359,7 +398,7 @@ def get_default_version(env):
|
|||
|
||||
msvc_version = env.get('MSVC_VERSION')
|
||||
msvs_version = env.get('MSVS_VERSION')
|
||||
|
||||
|
||||
debug('get_default_version(): msvc_version:%s msvs_version:%s'%(msvc_version,msvs_version))
|
||||
|
||||
if msvs_version and not msvc_version:
|
||||
|
@ -409,7 +448,7 @@ def msvc_find_valid_batch_script(env,version):
|
|||
try_target_archs = [target_platform]
|
||||
debug("msvs_find_valid_batch_script(): req_target_platform %s target_platform:%s"%(req_target_platform,target_platform))
|
||||
|
||||
# VS2012 has a "cross compile" environment to build 64 bit
|
||||
# VS2012 has a "cross compile" environment to build 64 bit
|
||||
# with x86_amd64 as the argument to the batch setup script
|
||||
if req_target_platform in ('amd64','x86_64'):
|
||||
try_target_archs.append('x86_amd64')
|
||||
|
@ -427,7 +466,7 @@ def msvc_find_valid_batch_script(env,version):
|
|||
for tp in try_target_archs:
|
||||
# Set to current arch.
|
||||
env['TARGET_ARCH']=tp
|
||||
|
||||
|
||||
debug("vc.py:msvc_find_valid_batch_script() trying target_platform:%s"%tp)
|
||||
host_target = (host_platform, tp)
|
||||
if not is_host_target_supported(host_target, version):
|
||||
|
@ -436,11 +475,19 @@ def msvc_find_valid_batch_script(env,version):
|
|||
SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
|
||||
arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target]
|
||||
|
||||
# Get just version numbers
|
||||
maj, min = msvc_version_to_maj_min(version)
|
||||
# VS2015+
|
||||
if maj >= 14:
|
||||
if env.get('MSVC_UWP_APP') == '1':
|
||||
# Initialize environment variables with store/universal paths
|
||||
arg += ' store'
|
||||
|
||||
# Try to locate a batch file for this host/target platform combo
|
||||
try:
|
||||
(vc_script,sdk_script) = find_batch_file(env,version,host_platform,tp)
|
||||
debug('vc.py:msvc_find_valid_batch_script() vc_script:%s sdk_script:%s'%(vc_script,sdk_script))
|
||||
except VisualCException, e:
|
||||
except VisualCException as e:
|
||||
msg = str(e)
|
||||
debug('Caught exception while looking for batch file (%s)' % msg)
|
||||
warn_msg = "VC version %s not installed. " + \
|
||||
|
@ -449,13 +496,13 @@ def msvc_find_valid_batch_script(env,version):
|
|||
warn_msg = warn_msg % (version, cached_get_installed_vcs())
|
||||
SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
|
||||
continue
|
||||
|
||||
|
||||
# Try to use the located batch file for this host/target platform combo
|
||||
debug('vc.py:msvc_find_valid_batch_script() use_script 2 %s, args:%s\n' % (repr(vc_script), arg))
|
||||
if vc_script:
|
||||
try:
|
||||
d = script_env(vc_script, args=arg)
|
||||
except BatchFileExecutionError, e:
|
||||
except BatchFileExecutionError as e:
|
||||
debug('vc.py:msvc_find_valid_batch_script() use_script 3: failed running VC script %s: %s: Error:%s'%(repr(vc_script),arg,e))
|
||||
vc_script=None
|
||||
continue
|
||||
|
@ -463,23 +510,23 @@ def msvc_find_valid_batch_script(env,version):
|
|||
debug('vc.py:msvc_find_valid_batch_script() use_script 4: trying sdk script: %s'%(sdk_script))
|
||||
try:
|
||||
d = script_env(sdk_script)
|
||||
except BatchFileExecutionError,e:
|
||||
except BatchFileExecutionError as e:
|
||||
debug('vc.py:msvc_find_valid_batch_script() use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e))
|
||||
continue
|
||||
elif not vc_script and not sdk_script:
|
||||
debug('vc.py:msvc_find_valid_batch_script() use_script 6: Neither VC script nor SDK script found')
|
||||
continue
|
||||
|
||||
|
||||
debug("vc.py:msvc_find_valid_batch_script() Found a working script/target: %s %s"%(repr(sdk_script),arg))
|
||||
break # We've found a working target_platform, so stop looking
|
||||
|
||||
|
||||
# If we cannot find a viable installed compiler, reset the TARGET_ARCH
|
||||
# To it's initial value
|
||||
if not d:
|
||||
env['TARGET_ARCH']=req_target_platform
|
||||
|
||||
|
||||
return d
|
||||
|
||||
|
||||
|
||||
def msvc_setup_env(env):
|
||||
debug('msvc_setup_env()')
|
||||
|
@ -498,12 +545,12 @@ def msvc_setup_env(env):
|
|||
env['MSVS_VERSION'] = version
|
||||
env['MSVS'] = {}
|
||||
|
||||
|
||||
|
||||
use_script = env.get('MSVC_USE_SCRIPT', True)
|
||||
if SCons.Util.is_String(use_script):
|
||||
debug('vc.py:msvc_setup_env() use_script 1 %s\n' % repr(use_script))
|
||||
d = script_env(use_script)
|
||||
elif use_script:
|
||||
elif use_script:
|
||||
d = msvc_find_valid_batch_script(env,version)
|
||||
debug('vc.py:msvc_setup_env() use_script 2 %s\n' % d)
|
||||
if not d:
|
||||
|
@ -524,4 +571,3 @@ def msvc_exists(version=None):
|
|||
if version is None:
|
||||
return len(vcs) > 0
|
||||
return version in vcs
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -21,7 +21,7 @@
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/vs.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/MSCommon/vs.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
__doc__ = """Module to detect Visual Studio and/or Visual C/C++
|
||||
"""
|
||||
|
@ -31,7 +31,7 @@ import os
|
|||
import SCons.Errors
|
||||
import SCons.Util
|
||||
|
||||
from common import debug, \
|
||||
from .common import debug, \
|
||||
get_output, \
|
||||
is_win64, \
|
||||
normalize_env, \
|
||||
|
@ -83,10 +83,10 @@ class VisualStudio(object):
|
|||
key = root + key
|
||||
try:
|
||||
comps = read_reg(key)
|
||||
except SCons.Util.WinError, e:
|
||||
debug('find_vs_dir_by_reg(): no VS registry key %s' % repr(key))
|
||||
except SCons.Util.WinError as e:
|
||||
debug('find_vs_dir_by_reg(): no VS registry key {}'.format(repr(key)))
|
||||
else:
|
||||
debug('find_vs_dir_by_reg(): found VS in registry: %s' % comps)
|
||||
debug('find_vs_dir_by_reg(): found VS in registry: {}'.format(comps))
|
||||
return comps
|
||||
return None
|
||||
|
||||
|
@ -105,12 +105,12 @@ class VisualStudio(object):
|
|||
def find_executable(self):
|
||||
vs_dir = self.get_vs_dir()
|
||||
if not vs_dir:
|
||||
debug('find_executable(): no vs_dir (%s)'%vs_dir)
|
||||
debug('find_executable(): no vs_dir ({})'.format(vs_dir))
|
||||
return None
|
||||
executable = os.path.join(vs_dir, self.executable_path)
|
||||
executable = os.path.normpath(executable)
|
||||
if not os.path.isfile(executable):
|
||||
debug('find_executable(): %s not on file system' % executable)
|
||||
debug('find_executable(): {} not on file system'.format(executable))
|
||||
return None
|
||||
return executable
|
||||
|
||||
|
@ -199,17 +199,28 @@ class VisualStudio(object):
|
|||
# Tool/MSCommon/vc.py, and the MSVC_VERSION documentation in Tool/msvc.xml.
|
||||
|
||||
SupportedVSList = [
|
||||
# Visual Studio 2017
|
||||
VisualStudio('14.1',
|
||||
vc_version='14.1',
|
||||
sdk_version='10.0A',
|
||||
hkeys=[],
|
||||
common_tools_var='VS150COMNTOOLS',
|
||||
executable_path=r'Common7\IDE\devenv.com',
|
||||
batch_file_path=r'VC\Auxiliary\Build\vsvars32.bat',
|
||||
supported_arch=['x86', 'amd64', "arm"],
|
||||
),
|
||||
|
||||
# Visual Studio 2015
|
||||
VisualStudio('14.0',
|
||||
vc_version='14.0',
|
||||
sdk_version='10.0A',
|
||||
sdk_version='10.0',
|
||||
hkeys=[r'Microsoft\VisualStudio\14.0\Setup\VS\ProductDir'],
|
||||
common_tools_var='VS140COMNTOOLS',
|
||||
executable_path=r'Common7\IDE\devenv.com',
|
||||
batch_file_path=r'Common7\Tools\vsvars32.bat',
|
||||
supported_arch=['x86', 'amd64', "arm"],
|
||||
),
|
||||
|
||||
|
||||
# Visual C++ 2015 Express Edition (for Desktop)
|
||||
VisualStudio('14.0Exp',
|
||||
vc_version='14.0',
|
|
@ -7,7 +7,7 @@ Phar Lap ETS tool chain. Right now, this is linkloc and
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -29,7 +29,7 @@ Phar Lap ETS tool chain. Right now, this is linkloc and
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/PharLapCommon.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/PharLapCommon.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import os
|
||||
import os.path
|
|
@ -14,7 +14,7 @@ tool definition.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -35,14 +35,16 @@ tool definition.
|
|||
# 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/__init__.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import imp
|
||||
import importlib
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import shutil
|
||||
|
||||
|
||||
import SCons.Builder
|
||||
import SCons.Errors
|
||||
import SCons.Node.FS
|
||||
|
@ -52,6 +54,7 @@ import SCons.Scanner.D
|
|||
import SCons.Scanner.LaTeX
|
||||
import SCons.Scanner.Prog
|
||||
import SCons.Scanner.SWIG
|
||||
import collections
|
||||
|
||||
DefaultToolpath=[]
|
||||
|
||||
|
@ -94,9 +97,20 @@ for suffix in LaTeXSuffixes:
|
|||
SourceFileScanner.add_scanner(suffix, LaTeXScanner)
|
||||
SourceFileScanner.add_scanner(suffix, PDFLaTeXScanner)
|
||||
|
||||
|
||||
# Tool aliases are needed for those tools whos module names also
|
||||
# occur in the python standard library. This causes module shadowing and
|
||||
# can break using python library functions under python3
|
||||
TOOL_ALIASES = {
|
||||
'gettext':'gettext_tool',
|
||||
'clang++': 'clangxx',
|
||||
}
|
||||
|
||||
class Tool(object):
|
||||
def __init__(self, name, toolpath=[], **kw):
|
||||
self.name = name
|
||||
|
||||
# Rename if there's a TOOL_ALIAS for this tool
|
||||
self.name = TOOL_ALIASES.get(name,name)
|
||||
self.toolpath = toolpath + DefaultToolpath
|
||||
# remember these so we can merge them into the call
|
||||
self.init_kw = kw
|
||||
|
@ -107,35 +121,130 @@ class Tool(object):
|
|||
if hasattr(module, 'options'):
|
||||
self.options = module.options
|
||||
|
||||
def _load_dotted_module_py2(self, short_name, full_name, searchpaths=None):
|
||||
splitname = short_name.split('.')
|
||||
index = 0
|
||||
srchpths = searchpaths
|
||||
for item in splitname:
|
||||
file, path, desc = imp.find_module(item, srchpths)
|
||||
mod = imp.load_module(full_name, file, path, desc)
|
||||
srchpths = [path]
|
||||
return mod, file
|
||||
|
||||
def _tool_module(self):
|
||||
# TODO: Interchange zipimport with normal initialization for better error reporting
|
||||
oldpythonpath = sys.path
|
||||
sys.path = self.toolpath + sys.path
|
||||
# sys.stderr.write("Tool:%s\nPATH:%s\n"%(self.name,sys.path))
|
||||
|
||||
try:
|
||||
if sys.version_info[0] < 3 or (sys.version_info[0] == 3 and sys.version_info[1] in (0,1,2,3,4)):
|
||||
# Py 2 code
|
||||
try:
|
||||
file, path, desc = imp.find_module(self.name, self.toolpath)
|
||||
try:
|
||||
return imp.load_module(self.name, file, path, desc)
|
||||
finally:
|
||||
if file:
|
||||
file.close()
|
||||
except ImportError, e:
|
||||
if str(e)!="No module named %s"%self.name:
|
||||
raise SCons.Errors.EnvironmentError(e)
|
||||
try:
|
||||
import zipimport
|
||||
except ImportError:
|
||||
pass
|
||||
file = None
|
||||
try:
|
||||
mod, file = self._load_dotted_module_py2(self.name, self.name, self.toolpath)
|
||||
return mod
|
||||
finally:
|
||||
if file:
|
||||
file.close()
|
||||
except ImportError as e:
|
||||
splitname = self.name.split('.')
|
||||
if str(e)!="No module named %s"%splitname[0]:
|
||||
raise SCons.Errors.EnvironmentError(e)
|
||||
try:
|
||||
import zipimport
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
for aPath in self.toolpath:
|
||||
try:
|
||||
importer = zipimport.zipimporter(aPath)
|
||||
return importer.load_module(self.name)
|
||||
except ImportError as e:
|
||||
pass
|
||||
finally:
|
||||
sys.path = oldpythonpath
|
||||
elif sys.version_info[1] > 4:
|
||||
# From: http://stackoverflow.com/questions/67631/how-to-import-a-module-given-the-full-path/67692#67692
|
||||
# import importlib.util
|
||||
# spec = importlib.util.spec_from_file_location("module.name", "/path/to/file.py")
|
||||
# foo = importlib.util.module_from_spec(spec)
|
||||
# spec.loader.exec_module(foo)
|
||||
# foo.MyClass()
|
||||
# Py 3 code
|
||||
|
||||
# import pdb; pdb.set_trace()
|
||||
import importlib.util
|
||||
|
||||
# sys.stderr.write("toolpath:%s\n" % self.toolpath)
|
||||
# sys.stderr.write("SCONS.TOOL path:%s\n" % sys.modules['SCons.Tool'].__path__)
|
||||
debug = False
|
||||
spec = None
|
||||
found_name = self.name
|
||||
add_to_scons_tools_namespace = False
|
||||
for path in self.toolpath:
|
||||
sepname = self.name.replace('.', os.path.sep)
|
||||
file_path = os.path.join(path, "%s.py"%sepname)
|
||||
file_package = os.path.join(path, sepname)
|
||||
|
||||
if debug: sys.stderr.write("Trying:%s %s\n"%(file_path, file_package))
|
||||
|
||||
if os.path.isfile(file_path):
|
||||
spec = importlib.util.spec_from_file_location(self.name, file_path)
|
||||
if debug: print("file_Path:%s FOUND"%file_path)
|
||||
break
|
||||
elif os.path.isdir(file_package):
|
||||
file_package = os.path.join(file_package, '__init__.py')
|
||||
spec = importlib.util.spec_from_file_location(self.name, file_package)
|
||||
if debug: print("PACKAGE:%s Found"%file_package)
|
||||
break
|
||||
|
||||
else:
|
||||
for aPath in self.toolpath:
|
||||
try:
|
||||
importer = zipimport.zipimporter(aPath)
|
||||
return importer.load_module(self.name)
|
||||
except ImportError, e:
|
||||
pass
|
||||
finally:
|
||||
sys.path = oldpythonpath
|
||||
continue
|
||||
|
||||
if spec is None:
|
||||
if debug: sys.stderr.write("NO SPEC :%s\n"%self.name)
|
||||
spec = importlib.util.find_spec("."+self.name, package='SCons.Tool')
|
||||
if spec:
|
||||
found_name = 'SCons.Tool.'+self.name
|
||||
add_to_scons_tools_namespace = True
|
||||
if debug: sys.stderr.write("Spec Found? .%s :%s\n"%(self.name, spec))
|
||||
|
||||
if spec is None:
|
||||
error_string = "No module named %s"%self.name
|
||||
raise SCons.Errors.EnvironmentError(error_string)
|
||||
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
if module is None:
|
||||
if debug: print("MODULE IS NONE:%s"%self.name)
|
||||
error_string = "No module named %s"%self.name
|
||||
raise SCons.Errors.EnvironmentError(error_string)
|
||||
|
||||
# Don't reload a tool we already loaded.
|
||||
sys_modules_value = sys.modules.get(found_name,False)
|
||||
|
||||
found_module = None
|
||||
if sys_modules_value and sys_modules_value.__file__ == spec.origin:
|
||||
found_module = sys.modules[found_name]
|
||||
else:
|
||||
# Not sure what to do in the case that there already
|
||||
# exists sys.modules[self.name] but the source file is
|
||||
# different.. ?
|
||||
module = spec.loader.load_module(spec.name)
|
||||
|
||||
sys.modules[found_name] = module
|
||||
if add_to_scons_tools_namespace:
|
||||
# If we found it in SCons.Tool, then add it to the module
|
||||
setattr(SCons.Tool, self.name, module)
|
||||
|
||||
found_module = module
|
||||
|
||||
if found_module is not None:
|
||||
sys.path = oldpythonpath
|
||||
return found_module
|
||||
|
||||
|
||||
sys.path = oldpythonpath
|
||||
|
||||
full_name = 'SCons.Tool.' + self.name
|
||||
try:
|
||||
|
@ -144,13 +253,12 @@ class Tool(object):
|
|||
try:
|
||||
smpath = sys.modules['SCons.Tool'].__path__
|
||||
try:
|
||||
file, path, desc = imp.find_module(self.name, smpath)
|
||||
module = imp.load_module(full_name, file, path, desc)
|
||||
module, file = self._load_dotted_module_py2(self.name, full_name, smpath)
|
||||
setattr(SCons.Tool, self.name, module)
|
||||
if file:
|
||||
file.close()
|
||||
return module
|
||||
except ImportError, e:
|
||||
except ImportError as e:
|
||||
if str(e)!="No module named %s"%self.name:
|
||||
raise SCons.Errors.EnvironmentError(e)
|
||||
try:
|
||||
|
@ -159,10 +267,10 @@ class Tool(object):
|
|||
module = importer.load_module(full_name)
|
||||
setattr(SCons.Tool, self.name, module)
|
||||
return module
|
||||
except ImportError, e:
|
||||
except ImportError as e:
|
||||
m = "No tool named '%s': %s" % (self.name, e)
|
||||
raise SCons.Errors.EnvironmentError(m)
|
||||
except ImportError, e:
|
||||
except ImportError as e:
|
||||
m = "No tool named '%s': %s" % (self.name, e)
|
||||
raise SCons.Errors.EnvironmentError(m)
|
||||
|
||||
|
@ -217,6 +325,7 @@ def createProgBuilder(env):
|
|||
|
||||
return program
|
||||
|
||||
|
||||
def createStaticLibBuilder(env):
|
||||
"""This is a utility function that creates the StaticLibrary
|
||||
Builder in an Environment if it is not there already.
|
||||
|
@ -228,7 +337,7 @@ def createStaticLibBuilder(env):
|
|||
static_lib = env['BUILDERS']['StaticLibrary']
|
||||
except KeyError:
|
||||
action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ]
|
||||
if env.Detect('ranlib'):
|
||||
if env.get('RANLIB',False) or env.Detect('ranlib'):
|
||||
ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
|
||||
action_list.append(ranlib_action)
|
||||
|
||||
|
@ -254,22 +363,22 @@ def _call_linker_cb(env, callback, args, result = None):
|
|||
Verbose = False
|
||||
|
||||
if Verbose:
|
||||
print '_call_linker_cb: args=%r' % args
|
||||
print '_call_linker_cb: callback=%r' % callback
|
||||
|
||||
print('_call_linker_cb: args=%r' % args)
|
||||
print('_call_linker_cb: callback=%r' % callback)
|
||||
|
||||
try:
|
||||
cbfun = env['LINKCALLBACKS'][callback]
|
||||
except (KeyError, TypeError):
|
||||
if Verbose:
|
||||
print '_call_linker_cb: env["LINKCALLBACKS"][%r] not found or can not be used' % callback
|
||||
print('_call_linker_cb: env["LINKCALLBACKS"][%r] not found or can not be used' % callback)
|
||||
pass
|
||||
else:
|
||||
if Verbose:
|
||||
print '_call_linker_cb: env["LINKCALLBACKS"][%r] found' % callback
|
||||
print '_call_linker_cb: env["LINKCALLBACKS"][%r]=%r' % (callback, cbfun)
|
||||
if(callable(cbfun)):
|
||||
print('_call_linker_cb: env["LINKCALLBACKS"][%r] found' % callback)
|
||||
print('_call_linker_cb: env["LINKCALLBACKS"][%r]=%r' % (callback, cbfun))
|
||||
if(isinstance(cbfun, collections.Callable)):
|
||||
if Verbose:
|
||||
print '_call_linker_cb: env["LINKCALLBACKS"][%r] is callable' % callback
|
||||
print('_call_linker_cb: env["LINKCALLBACKS"][%r] is callable' % callback)
|
||||
result = cbfun(env, *args)
|
||||
return result
|
||||
|
||||
|
@ -388,7 +497,7 @@ class _LibInfoGeneratorBase(object):
|
|||
|
||||
def generate_versioned_lib_info(self, env, args, result = None, **kw):
|
||||
callback = self.get_versioned_lib_info_generator(**kw)
|
||||
return _call_linker_cb(env, callback, args, result)
|
||||
return _call_linker_cb(env, callback, args, result)
|
||||
|
||||
class _LibPrefixGenerator(_LibInfoGeneratorBase):
|
||||
"""Library prefix generator, used as target_prefix in SharedLibrary and
|
||||
|
@ -407,17 +516,17 @@ class _LibPrefixGenerator(_LibInfoGeneratorBase):
|
|||
|
||||
prefix = self.get_lib_prefix(env,**kw2)
|
||||
if Verbose:
|
||||
print "_LibPrefixGenerator: input prefix=%r" % prefix
|
||||
print("_LibPrefixGenerator: input prefix=%r" % prefix)
|
||||
|
||||
version = self.get_lib_version(env, **kw2)
|
||||
if Verbose:
|
||||
print "_LibPrefixGenerator: version=%r" % version
|
||||
print("_LibPrefixGenerator: version=%r" % version)
|
||||
|
||||
if version:
|
||||
prefix = self.generate_versioned_lib_info(env, [prefix, version], prefix, **kw2)
|
||||
|
||||
if Verbose:
|
||||
print "_LibPrefixGenerator: return prefix=%r" % prefix
|
||||
print("_LibPrefixGenerator: return prefix=%r" % prefix)
|
||||
return prefix
|
||||
|
||||
ShLibPrefixGenerator = _LibPrefixGenerator('ShLib')
|
||||
|
@ -441,17 +550,17 @@ class _LibSuffixGenerator(_LibInfoGeneratorBase):
|
|||
|
||||
suffix = self.get_lib_suffix(env, **kw2)
|
||||
if Verbose:
|
||||
print "_LibSuffixGenerator: input suffix=%r" % suffix
|
||||
print("_LibSuffixGenerator: input suffix=%r" % suffix)
|
||||
|
||||
version = self.get_lib_version(env, **kw2)
|
||||
if Verbose:
|
||||
print "_LibSuffixGenerator: version=%r" % version
|
||||
print("_LibSuffixGenerator: version=%r" % version)
|
||||
|
||||
if version:
|
||||
suffix = self.generate_versioned_lib_info(env, [suffix, version], suffix, **kw2)
|
||||
|
||||
if Verbose:
|
||||
print "_LibSuffixGenerator: return suffix=%r" % suffix
|
||||
print("_LibSuffixGenerator: return suffix=%r" % suffix)
|
||||
return suffix
|
||||
|
||||
ShLibSuffixGenerator = _LibSuffixGenerator('ShLib')
|
||||
|
@ -474,15 +583,15 @@ class _LibSymlinkGenerator(_LibInfoGeneratorBase):
|
|||
kw2 = kw
|
||||
|
||||
if Verbose:
|
||||
print "_LibSymLinkGenerator: libnode=%r" % libnode.get_path()
|
||||
print("_LibSymLinkGenerator: libnode=%r" % libnode.get_path())
|
||||
|
||||
symlinks = None
|
||||
|
||||
version = self.get_lib_version(env, **kw2)
|
||||
disable = self.get_lib_noversionsymlinks(env, **kw2)
|
||||
if Verbose:
|
||||
print '_LibSymlinkGenerator: version=%r' % version
|
||||
print '_LibSymlinkGenerator: disable=%r' % disable
|
||||
print('_LibSymlinkGenerator: version=%r' % version)
|
||||
print('_LibSymlinkGenerator: disable=%r' % disable)
|
||||
|
||||
if version and not disable:
|
||||
prefix = self.get_lib_prefix(env,**kw2)
|
||||
|
@ -490,7 +599,7 @@ class _LibSymlinkGenerator(_LibInfoGeneratorBase):
|
|||
symlinks = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw2)
|
||||
|
||||
if Verbose:
|
||||
print '_LibSymlinkGenerator: return symlinks=%r' % StringizeLibSymlinks(symlinks)
|
||||
print('_LibSymlinkGenerator: return symlinks=%r' % StringizeLibSymlinks(symlinks))
|
||||
return symlinks
|
||||
|
||||
ShLibSymlinkGenerator = _LibSymlinkGenerator('ShLib')
|
||||
|
@ -499,7 +608,7 @@ ImpLibSymlinkGenerator = _LibSymlinkGenerator('ImpLib')
|
|||
|
||||
class _LibNameGenerator(_LibInfoGeneratorBase):
|
||||
"""Generates "unmangled" library name from a library file node.
|
||||
|
||||
|
||||
Generally, it's thought to revert modifications done by prefix/suffix
|
||||
generators (_LibPrefixGenerator/_LibSuffixGenerator) used by a library
|
||||
builder. For example, on gnulink the suffix generator used by SharedLibrary
|
||||
|
@ -509,7 +618,7 @@ class _LibNameGenerator(_LibInfoGeneratorBase):
|
|||
"$SHLIBSUFFIX" in the node's basename. So that, if $SHLIBSUFFIX is ".so",
|
||||
$SHLIBVERSION is "0.1.2" and the node path is "/foo/bar/libfoo.so.0.1.2",
|
||||
the _LibNameGenerator shall return "libfoo.so". Other link tools may
|
||||
implement it's own way of library name unmangling.
|
||||
implement it's own way of library name unmangling.
|
||||
"""
|
||||
def __init__(self, libtype):
|
||||
super(_LibNameGenerator, self).__init__(libtype, 'Name')
|
||||
|
@ -525,11 +634,11 @@ class _LibNameGenerator(_LibInfoGeneratorBase):
|
|||
kw2 = kw
|
||||
|
||||
if Verbose:
|
||||
print "_LibNameGenerator: libnode=%r" % libnode.get_path()
|
||||
print("_LibNameGenerator: libnode=%r" % libnode.get_path())
|
||||
|
||||
version = self.get_lib_version(env, **kw2)
|
||||
if Verbose:
|
||||
print '_LibNameGenerator: version=%r' % version
|
||||
print('_LibNameGenerator: version=%r' % version)
|
||||
|
||||
name = None
|
||||
if version:
|
||||
|
@ -541,7 +650,7 @@ class _LibNameGenerator(_LibInfoGeneratorBase):
|
|||
name = os.path.basename(libnode.get_path())
|
||||
|
||||
if Verbose:
|
||||
print '_LibNameGenerator: return name=%r' % name
|
||||
print('_LibNameGenerator: return name=%r' % name)
|
||||
|
||||
return name
|
||||
|
||||
|
@ -550,7 +659,7 @@ LdModNameGenerator = _LibNameGenerator('LdMod')
|
|||
ImpLibNameGenerator = _LibNameGenerator('ImpLib')
|
||||
|
||||
class _LibSonameGenerator(_LibInfoGeneratorBase):
|
||||
"""Library soname generator. Returns library soname (e.g. libfoo.so.0) for
|
||||
"""Library soname generator. Returns library soname (e.g. libfoo.so.0) for
|
||||
a given node (e.g. /foo/bar/libfoo.so.0.1.2)"""
|
||||
def __init__(self, libtype):
|
||||
super(_LibSonameGenerator, self).__init__(libtype, 'Soname')
|
||||
|
@ -566,13 +675,13 @@ class _LibSonameGenerator(_LibInfoGeneratorBase):
|
|||
kw2 = kw
|
||||
|
||||
if Verbose:
|
||||
print "_LibSonameGenerator: libnode=%r" % libnode.get_path()
|
||||
print("_LibSonameGenerator: libnode=%r" % libnode.get_path())
|
||||
|
||||
soname = _call_env_subst(env, '$SONAME', **kw2)
|
||||
if not soname:
|
||||
version = self.get_lib_version(env,**kw2)
|
||||
if Verbose:
|
||||
print "_LibSonameGenerator: version=%r" % version
|
||||
print("_LibSonameGenerator: version=%r" % version)
|
||||
if version:
|
||||
prefix = self.get_lib_prefix(env,**kw2)
|
||||
suffix = self.get_lib_suffix(env,**kw2)
|
||||
|
@ -582,10 +691,10 @@ class _LibSonameGenerator(_LibInfoGeneratorBase):
|
|||
# fallback to library name (as returned by appropriate _LibNameGenerator)
|
||||
soname = _LibNameGenerator(self.get_libtype())(env, libnode)
|
||||
if Verbose:
|
||||
print "_LibSonameGenerator: FALLBACK: soname=%r" % soname
|
||||
print("_LibSonameGenerator: FALLBACK: soname=%r" % soname)
|
||||
|
||||
if Verbose:
|
||||
print "_LibSonameGenerator: return soname=%r" % soname
|
||||
print("_LibSonameGenerator: return soname=%r" % soname)
|
||||
|
||||
return soname
|
||||
|
||||
|
@ -613,39 +722,39 @@ def EmitLibSymlinks(env, symlinks, libnode, **kw):
|
|||
clean_targets = kw.get('clean_targets', [])
|
||||
if not SCons.Util.is_List(clean_targets):
|
||||
clean_targets = [ clean_targets ]
|
||||
|
||||
|
||||
for link, linktgt in symlinks:
|
||||
env.SideEffect(link, linktgt)
|
||||
if(Verbose):
|
||||
print "EmitLibSymlinks: SideEffect(%r,%r)" % (link.get_path(), linktgt.get_path())
|
||||
clean_list = filter(lambda x : x != linktgt, nodes)
|
||||
print("EmitLibSymlinks: SideEffect(%r,%r)" % (link.get_path(), linktgt.get_path()))
|
||||
clean_list = [x for x in nodes if x != linktgt]
|
||||
env.Clean(list(set([linktgt] + clean_targets)), clean_list)
|
||||
if(Verbose):
|
||||
print "EmitLibSymlinks: Clean(%r,%r)" % (linktgt.get_path(), map(lambda x : x.get_path(), clean_list))
|
||||
print("EmitLibSymlinks: Clean(%r,%r)" % (linktgt.get_path(), [x.get_path() for x in clean_list]))
|
||||
|
||||
def CreateLibSymlinks(env, symlinks):
|
||||
"""Physically creates symlinks. The symlinks argument must be a list in
|
||||
form [ (link, linktarget), ... ], where link and linktarget are SCons
|
||||
nodes.
|
||||
"""
|
||||
|
||||
|
||||
Verbose = False
|
||||
for link, linktgt in symlinks:
|
||||
linktgt = link.get_dir().rel_path(linktgt)
|
||||
link = link.get_path()
|
||||
if(Verbose):
|
||||
print "CreateLibSymlinks: preparing to add symlink %r -> %r" % (link, linktgt)
|
||||
print("CreateLibSymlinks: preparing to add symlink %r -> %r" % (link, linktgt))
|
||||
# Delete the (previously created) symlink if exists. Let only symlinks
|
||||
# to be deleted to prevent accidental deletion of source files...
|
||||
if env.fs.islink(link):
|
||||
env.fs.unlink(link)
|
||||
if(Verbose):
|
||||
print "CreateLibSymlinks: removed old symlink %r" % link
|
||||
print("CreateLibSymlinks: removed old symlink %r" % link)
|
||||
# If a file or directory exists with the same name as link, an OSError
|
||||
# will be thrown, which should be enough, I think.
|
||||
env.fs.symlink(linktgt, link)
|
||||
if(Verbose):
|
||||
print "CreateLibSymlinks: add symlink %r -> %r" % (link, linktgt)
|
||||
print("CreateLibSymlinks: add symlink %r -> %r" % (link, linktgt))
|
||||
return 0
|
||||
|
||||
def LibSymlinksActionFunction(target, source, env):
|
||||
|
@ -670,10 +779,11 @@ def LibSymlinksStrFun(target, source, env, *args):
|
|||
else:
|
||||
cmd += ": %s" % linkstr
|
||||
return cmd
|
||||
|
||||
|
||||
|
||||
LibSymlinksAction = SCons.Action.Action(LibSymlinksActionFunction, LibSymlinksStrFun)
|
||||
|
||||
|
||||
def createSharedLibBuilder(env):
|
||||
"""This is a utility function that creates the SharedLibrary
|
||||
Builder in an Environment if it is not there already.
|
||||
|
@ -803,17 +913,25 @@ def createCFileBuilders(env):
|
|||
# Create common Java builders
|
||||
|
||||
def CreateJarBuilder(env):
|
||||
"""The Jar builder expects a list of class files
|
||||
which it can package into a jar file.
|
||||
|
||||
The jar tool provides an interface for passing other types
|
||||
of java files such as .java, directories or swig interfaces
|
||||
and will build them to class files in which it can package
|
||||
into the jar.
|
||||
"""
|
||||
try:
|
||||
java_jar = env['BUILDERS']['Jar']
|
||||
java_jar = env['BUILDERS']['JarFile']
|
||||
except KeyError:
|
||||
fs = SCons.Node.FS.get_default_fs()
|
||||
jar_com = SCons.Action.Action('$JARCOM', '$JARCOMSTR')
|
||||
java_jar = SCons.Builder.Builder(action = jar_com,
|
||||
suffix = '$JARSUFFIX',
|
||||
src_suffix = '$JAVACLASSSUFIX',
|
||||
src_suffix = '$JAVACLASSSUFFIX',
|
||||
src_builder = 'JavaClassFile',
|
||||
source_factory = fs.Entry)
|
||||
env['BUILDERS']['Jar'] = java_jar
|
||||
env['BUILDERS']['JarFile'] = java_jar
|
||||
return java_jar
|
||||
|
||||
def CreateJavaHBuilder(env):
|
||||
|
@ -890,9 +1008,9 @@ class ToolInitializerMethod(object):
|
|||
|
||||
def get_builder(self, env):
|
||||
"""
|
||||
Returns the appropriate real Builder for this method name
|
||||
after having the associated ToolInitializer object apply
|
||||
the appropriate Tool module.
|
||||
Returns the appropriate real Builder for this method name
|
||||
after having the associated ToolInitializer object apply
|
||||
the appropriate Tool module.
|
||||
"""
|
||||
builder = getattr(env, self.__name__)
|
||||
|
||||
|
@ -949,13 +1067,13 @@ class ToolInitializer(object):
|
|||
so we no longer copy and re-bind them when the construction
|
||||
environment gets cloned.
|
||||
"""
|
||||
for method in self.methods.values():
|
||||
for method in list(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.
|
||||
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)
|
||||
|
@ -1005,7 +1123,7 @@ def tool_list(platform, env):
|
|||
"prefer Microsoft tools on Windows"
|
||||
linkers = ['mslink', 'gnulink', 'ilink', 'linkloc', 'ilink32' ]
|
||||
c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ]
|
||||
cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'c++', 'bcc32' ]
|
||||
cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'cxx', 'bcc32' ]
|
||||
assemblers = ['masm', 'nasm', 'gas', '386asm' ]
|
||||
fortran_compilers = ['gfortran', 'g77', 'ifl', 'cvf', 'f95', 'f90', 'fortran']
|
||||
ars = ['mslib', 'ar', 'tlib']
|
||||
|
@ -1014,7 +1132,7 @@ def tool_list(platform, env):
|
|||
"prefer IBM tools on OS/2"
|
||||
linkers = ['ilink', 'gnulink', ]#'mslink']
|
||||
c_compilers = ['icc', 'gcc',]# 'msvc', 'cc']
|
||||
cxx_compilers = ['icc', 'g++',]# 'msvc', 'c++']
|
||||
cxx_compilers = ['icc', 'g++',]# 'msvc', 'cxx']
|
||||
assemblers = ['nasm',]# 'masm', 'gas']
|
||||
fortran_compilers = ['ifl', 'g77']
|
||||
ars = ['ar',]# 'mslib']
|
||||
|
@ -1022,7 +1140,7 @@ def tool_list(platform, env):
|
|||
"prefer MIPSPro on IRIX"
|
||||
linkers = ['sgilink', 'gnulink']
|
||||
c_compilers = ['sgicc', 'gcc', 'cc']
|
||||
cxx_compilers = ['sgic++', 'g++', 'c++']
|
||||
cxx_compilers = ['sgicxx', 'g++', 'cxx']
|
||||
assemblers = ['as', 'gas']
|
||||
fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran']
|
||||
ars = ['sgiar']
|
||||
|
@ -1030,7 +1148,7 @@ def tool_list(platform, env):
|
|||
"prefer Forte tools on SunOS"
|
||||
linkers = ['sunlink', 'gnulink']
|
||||
c_compilers = ['suncc', 'gcc', 'cc']
|
||||
cxx_compilers = ['sunc++', 'g++', 'c++']
|
||||
cxx_compilers = ['suncxx', 'g++', 'cxx']
|
||||
assemblers = ['as', 'gas']
|
||||
fortran_compilers = ['sunf95', 'sunf90', 'sunf77', 'f95', 'f90', 'f77',
|
||||
'gfortran', 'g77', 'fortran']
|
||||
|
@ -1039,7 +1157,7 @@ def tool_list(platform, env):
|
|||
"prefer aCC tools on HP-UX"
|
||||
linkers = ['hplink', 'gnulink']
|
||||
c_compilers = ['hpcc', 'gcc', 'cc']
|
||||
cxx_compilers = ['hpc++', 'g++', 'c++']
|
||||
cxx_compilers = ['hpcxx', 'g++', 'cxx']
|
||||
assemblers = ['as', 'gas']
|
||||
fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran']
|
||||
ars = ['ar']
|
||||
|
@ -1047,7 +1165,7 @@ def tool_list(platform, env):
|
|||
"prefer AIX Visual Age tools on AIX"
|
||||
linkers = ['aixlink', 'gnulink']
|
||||
c_compilers = ['aixcc', 'gcc', 'cc']
|
||||
cxx_compilers = ['aixc++', 'g++', 'c++']
|
||||
cxx_compilers = ['aixcxx', 'g++', 'cxx']
|
||||
assemblers = ['as', 'gas']
|
||||
fortran_compilers = ['f95', 'f90', 'aixf77', 'g77', 'fortran']
|
||||
ars = ['ar']
|
||||
|
@ -1055,7 +1173,7 @@ def tool_list(platform, env):
|
|||
"prefer GNU tools on Mac OS X, except for some linkers and IBM tools"
|
||||
linkers = ['applelink', 'gnulink']
|
||||
c_compilers = ['gcc', 'cc']
|
||||
cxx_compilers = ['g++', 'c++']
|
||||
cxx_compilers = ['g++', 'cxx']
|
||||
assemblers = ['as']
|
||||
fortran_compilers = ['gfortran', 'f95', 'f90', 'g77']
|
||||
ars = ['ar']
|
||||
|
@ -1063,18 +1181,18 @@ def tool_list(platform, env):
|
|||
"prefer GNU tools on Cygwin, except for a platform-specific linker"
|
||||
linkers = ['cyglink', 'mslink', 'ilink']
|
||||
c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc']
|
||||
cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++']
|
||||
cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'cxx']
|
||||
assemblers = ['gas', 'nasm', 'masm']
|
||||
fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77']
|
||||
ars = ['ar', 'mslib']
|
||||
else:
|
||||
"prefer GNU tools on all other platforms"
|
||||
linkers = ['gnulink', 'mslink', 'ilink']
|
||||
c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc']
|
||||
cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++']
|
||||
linkers = ['gnulink', 'ilink']
|
||||
c_compilers = ['gcc', 'intelc', 'icc', 'cc']
|
||||
cxx_compilers = ['g++', 'intelc', 'icc', 'cxx']
|
||||
assemblers = ['gas', 'nasm', 'masm']
|
||||
fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77']
|
||||
ars = ['ar', 'mslib']
|
||||
ars = ['ar',]
|
||||
|
||||
if not str(platform) == 'win32':
|
||||
other_plat_tools += ['m4', 'rpm']
|
||||
|
@ -1102,7 +1220,7 @@ def tool_list(platform, env):
|
|||
fortran_compiler = FindTool(fortran_compilers, env) or fortran_compilers[0]
|
||||
ar = FindTool(ars, env) or ars[0]
|
||||
|
||||
d_compilers = ['dmd', 'gdc', 'ldc']
|
||||
d_compilers = ['dmd', 'ldc', 'gdc']
|
||||
d_compiler = FindTool(d_compilers, env) or d_compilers[0]
|
||||
|
||||
other_tools = FindAllTools(other_plat_tools + [
|
||||
|
@ -1121,9 +1239,6 @@ def tool_list(platform, env):
|
|||
'tex', 'latex', 'pdflatex', 'pdftex',
|
||||
# Archivers
|
||||
'tar', 'zip',
|
||||
# SourceCode factories
|
||||
'BitKeeper', 'CVS', 'Perforce',
|
||||
'RCS', 'SCCS', # 'Subversion',
|
||||
], env)
|
||||
|
||||
tools = ([linker, c_compiler, cxx_compiler,
|
||||
|
@ -1137,4 +1252,3 @@ def tool_list(platform, env):
|
|||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
||||
|
43
scons/scons-local-3.0.1/SCons/Tool/aixc++.py
Normal file
43
scons/scons-local-3.0.1/SCons/Tool/aixc++.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
"""SCons.Tool.aixc++
|
||||
|
||||
Tool-specific initialization for IBM xlC / Visual Age C++ 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 - 2017 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/aixc++.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
#forward proxy to the preffered cxx version
|
||||
from SCons.Tool.aixcxx import *
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,13 +30,13 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/aixcc.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/aixcc.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import os.path
|
||||
|
||||
import SCons.Platform.aix
|
||||
|
||||
import cc
|
||||
from . import cc
|
||||
|
||||
packages = ['vac.C', 'ibmcxx.cmp']
|
||||
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,13 +31,15 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/aixc++.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/aixcxx.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import os.path
|
||||
|
||||
import SCons.Platform.aix
|
||||
|
||||
cplusplus = __import__('c++', globals(), locals(), [])
|
||||
import SCons.Tool.cxx
|
||||
cplusplus = SCons.Tool.cxx
|
||||
#cplusplus = __import__('cxx', globals(), locals(), [])
|
||||
|
||||
packages = ['vacpp.cmp.core', 'vacpp.cmp.batch', 'vacpp.cmp.C', 'ibmcxx.cmp']
|
||||
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,13 +30,13 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/aixf77.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/aixf77.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import os.path
|
||||
|
||||
#import SCons.Platform.aix
|
||||
|
||||
import f77
|
||||
from . import f77
|
||||
|
||||
# It would be good to look for the AIX F77 package the same way we're now
|
||||
# looking for the C and C++ packages. This should be as easy as supplying
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,16 +30,20 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/aixlink.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/aixlink.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import os
|
||||
import os.path
|
||||
|
||||
import SCons.Util
|
||||
|
||||
import link
|
||||
from . import aixcc
|
||||
from . import link
|
||||
|
||||
import SCons.Tool.cxx
|
||||
cplusplus = SCons.Tool.cxx
|
||||
#cplusplus = __import__('cxx', globals(), locals(), [])
|
||||
|
||||
cplusplus = __import__('c++', globals(), locals(), [])
|
||||
|
||||
def smart_linkflags(source, target, env, for_signature):
|
||||
if cplusplus.iscplusplus(source):
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,13 +31,13 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/applelink.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/applelink.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.Util
|
||||
|
||||
# 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
|
||||
from . import link
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for applelink to an
|
||||
|
@ -51,6 +51,14 @@ def generate(env):
|
|||
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -dynamiclib')
|
||||
env['SHLINKCOM'] = env['SHLINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS'
|
||||
|
||||
|
||||
# TODO: Work needed to generate versioned shared libraries
|
||||
# Leaving this commented out, and also going to disable versioned library checking for now
|
||||
# see: http://docstore.mik.ua/orelly/unix3/mac/ch05_04.htm for proper naming
|
||||
#link._setup_versioned_lib_variables(env, tool = 'applelink')#, use_soname = use_soname)
|
||||
#env['LINKCALLBACKS'] = link._versioned_lib_callbacks()
|
||||
|
||||
|
||||
# override the default for loadable modules, which are different
|
||||
# on OS X than dynamic shared libs. echoing what XCode does for
|
||||
# pre/suffixes:
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/ar.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/ar.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.Defaults
|
||||
import SCons.Tool
|
||||
|
@ -48,8 +48,8 @@ def generate(env):
|
|||
env['LIBPREFIX'] = 'lib'
|
||||
env['LIBSUFFIX'] = '.a'
|
||||
|
||||
if env.Detect('ranlib'):
|
||||
env['RANLIB'] = 'ranlib'
|
||||
if env.get('RANLIB',env.Detect('ranlib')) :
|
||||
env['RANLIB'] = env.get('RANLIB','ranlib')
|
||||
env['RANLIBFLAGS'] = SCons.Util.CLVar('')
|
||||
env['RANLIBCOM'] = '$RANLIB $RANLIBFLAGS $TARGET'
|
||||
|
|
@ -9,7 +9,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -31,7 +31,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/as.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/as.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.Defaults
|
||||
import SCons.Tool
|
|
@ -5,7 +5,7 @@ XXX
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,7 +27,7 @@ XXX
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/bcc32.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/bcc32.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import os
|
||||
import os.path
|
44
scons/scons-local-3.0.1/SCons/Tool/c++.py
Normal file
44
scons/scons-local-3.0.1/SCons/Tool/c++.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
"""SCons.Tool.c++
|
||||
|
||||
Tool-specific initialization for generic Posix C++ compilers.
|
||||
|
||||
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 - 2017 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/c++.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
|
||||
#forward proxy to the preffered cxx version
|
||||
from SCons.Tool.cxx import *
|
||||
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -8,7 +8,7 @@ selection method.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -30,7 +30,7 @@ selection method.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/cc.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/cc.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import SCons.Tool
|
||||
import SCons.Defaults
|
83
scons/scons-local-3.0.1/SCons/Tool/clang.py
Normal file
83
scons/scons-local-3.0.1/SCons/Tool/clang.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
"""SCons.Tool.clang
|
||||
|
||||
Tool-specific initialization for clang.
|
||||
|
||||
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 - 2017 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/clang.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
# Based on SCons/Tool/gcc.py by Paweł Tomulik 2014 as a separate tool.
|
||||
# Brought into the SCons mainline by Russel Winder 2017.
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import SCons.Util
|
||||
import SCons.Tool.cc
|
||||
|
||||
compilers = ['clang']
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for clang to an Environment."""
|
||||
SCons.Tool.cc.generate(env)
|
||||
|
||||
env['CC'] = env.Detect(compilers) or 'clang'
|
||||
if env['PLATFORM'] in ['cygwin', 'win32']:
|
||||
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS')
|
||||
else:
|
||||
env['SHCCFLAGS'] = SCons.Util.CLVar('$CCFLAGS -fPIC')
|
||||
# determine compiler version
|
||||
if env['CC']:
|
||||
#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
|
||||
# clang -dumpversion is of no use
|
||||
line = pipe.stdout.readline()
|
||||
if sys.version_info[0] > 2:
|
||||
line = line.decode()
|
||||
match = re.search(r'clang +version +([0-9]+(?:\.[0-9]+)+)', line)
|
||||
if match:
|
||||
env['CCVERSION'] = match.group(1)
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
91
scons/scons-local-3.0.1/SCons/Tool/clangxx.py
Normal file
91
scons/scons-local-3.0.1/SCons/Tool/clangxx.py
Normal file
|
@ -0,0 +1,91 @@
|
|||
# -*- coding: utf-8; -*-
|
||||
|
||||
"""SCons.Tool.clang++
|
||||
|
||||
Tool-specific initialization for clang++.
|
||||
|
||||
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 - 2017 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/clangxx.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
# Based on SCons/Tool/g++.py by Paweł Tomulik 2014 as a separate tool.
|
||||
# Brought into the SCons mainline by Russel Winder 2017.
|
||||
|
||||
import os.path
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
import SCons.Tool.cxx
|
||||
|
||||
compilers = ['clang++']
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for clang++ to an Environment."""
|
||||
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
|
||||
|
||||
SCons.Tool.cxx.generate(env)
|
||||
|
||||
env['CXX'] = env.Detect(compilers) or 'clang++'
|
||||
|
||||
# platform specific settings
|
||||
if env['PLATFORM'] == 'aix':
|
||||
env['SHCXXFLAGS'] = SCons.Util.CLVar('$CXXFLAGS -mminimal-toc')
|
||||
env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
|
||||
env['SHOBJSUFFIX'] = '$OBJSUFFIX'
|
||||
elif env['PLATFORM'] == 'hpux':
|
||||
env['SHOBJSUFFIX'] = '.pic.o'
|
||||
elif env['PLATFORM'] == 'sunos':
|
||||
env['SHOBJSUFFIX'] = '.pic.o'
|
||||
# determine compiler version
|
||||
if env['CXX']:
|
||||
pipe = SCons.Action._subproc(env, [env['CXX'], '--version'],
|
||||
stdin='devnull',
|
||||
stderr='devnull',
|
||||
stdout=subprocess.PIPE)
|
||||
if pipe.wait() != 0: return
|
||||
# clang -dumpversion is of no use
|
||||
line = pipe.stdout.readline()
|
||||
if sys.version_info[0] > 2:
|
||||
line = line.decode()
|
||||
match = re.search(r'clang +version +([0-9]+(?:\.[0-9]+)+)', line)
|
||||
if match:
|
||||
env['CXXVERSION'] = match.group(1)
|
||||
|
||||
def exists(env):
|
||||
return env.Detect(compilers)
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
|
@ -5,7 +5,7 @@ Tool-specific initialization for the Compaq Visual Fortran compiler.
|
|||
"""
|
||||
|
||||
#
|
||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
||||
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
|
@ -27,9 +27,9 @@ Tool-specific initialization for the Compaq Visual Fortran compiler.
|
|||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
#
|
||||
|
||||
__revision__ = "src/engine/SCons/Tool/cvf.py rel_2.5.0:3543:937e55cd78f7 2016/04/09 11:29:54 bdbaddog"
|
||||
__revision__ = "src/engine/SCons/Tool/cvf.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||
|
||||
import fortran
|
||||
from . import fortran
|
||||
|
||||
compilers = ['f90']
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue