port Scons3 support from master
This commit is contained in:
parent
f5ea42b11f
commit
b0f3f1aed7
219 changed files with 4903 additions and 3679 deletions
65
SConstruct
65
SConstruct
|
@ -1,6 +1,6 @@
|
||||||
# This file is part of Mapnik (c++ mapping toolkit)
|
# This file is part of Mapnik (c++ mapping toolkit)
|
||||||
#
|
#
|
||||||
# Copyright (C) 2015 Artem Pavlenko
|
# Copyright (C) 2017 Artem Pavlenko
|
||||||
#
|
#
|
||||||
# Mapnik is free software; you can redistribute it and/or
|
# Mapnik is free software; you can redistribute it and/or
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
# modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
# License along with this library; if not, write to the Free Software
|
# License along with this library; if not, write to the Free Software
|
||||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
from __future__ import print_function # support python2
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -136,7 +137,7 @@ env = Environment(ENV=os.environ)
|
||||||
init_environment(env)
|
init_environment(env)
|
||||||
|
|
||||||
def fix_path(path):
|
def fix_path(path):
|
||||||
return os.path.abspath(path)
|
return str(os.path.abspath(path))
|
||||||
|
|
||||||
def color_print(color,text,newline=True):
|
def color_print(color,text,newline=True):
|
||||||
# 1 - red
|
# 1 - red
|
||||||
|
@ -145,15 +146,15 @@ def color_print(color,text,newline=True):
|
||||||
# 4 - blue
|
# 4 - blue
|
||||||
text = "\033[9%sm%s\033[0m" % (color,text)
|
text = "\033[9%sm%s\033[0m" % (color,text)
|
||||||
if not newline:
|
if not newline:
|
||||||
print text,
|
print (text, end='')
|
||||||
else:
|
else:
|
||||||
print text
|
print (text)
|
||||||
|
|
||||||
def regular_print(color,text,newline=True):
|
def regular_print(color,text,newline=True):
|
||||||
if not newline:
|
if not newline:
|
||||||
print text,
|
print (text, end='')
|
||||||
else:
|
else:
|
||||||
print text
|
print (text)
|
||||||
|
|
||||||
def call(cmd, silent=False):
|
def call(cmd, silent=False):
|
||||||
stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
|
stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
|
||||||
|
@ -244,7 +245,7 @@ def sort_paths(items,priority):
|
||||||
path_types['other'].append(i)
|
path_types['other'].append(i)
|
||||||
# build up new list based on priority list
|
# build up new list based on priority list
|
||||||
for path in priority:
|
for path in priority:
|
||||||
if path_types.has_key(path):
|
if path in path_types:
|
||||||
dirs = path_types[path]
|
dirs = path_types[path]
|
||||||
new.extend(dirs)
|
new.extend(dirs)
|
||||||
path_types.pop(path)
|
path_types.pop(path)
|
||||||
|
@ -510,7 +511,7 @@ elif HELP_REQUESTED:
|
||||||
# https://github.com/mapnik/mapnik/issues/2112
|
# https://github.com/mapnik/mapnik/issues/2112
|
||||||
if not os.path.exists(SCONS_LOCAL_LOG) and not os.path.exists(SCONS_CONFIGURE_CACHE) \
|
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):
|
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)
|
Exit(0)
|
||||||
|
|
||||||
# initially populate environment with defaults and any possible custom arguments
|
# initially populate environment with defaults and any possible custom arguments
|
||||||
|
@ -520,7 +521,7 @@ opts.Update(env)
|
||||||
if not force_configure:
|
if not force_configure:
|
||||||
if os.path.exists(SCONS_CONFIGURE_CACHE):
|
if os.path.exists(SCONS_CONFIGURE_CACHE):
|
||||||
try:
|
try:
|
||||||
pickled_environment = open(SCONS_CONFIGURE_CACHE, 'r')
|
pickled_environment = open(SCONS_CONFIGURE_CACHE, 'rb')
|
||||||
pickled_values = pickle.load(pickled_environment)
|
pickled_values = pickle.load(pickled_environment)
|
||||||
for key, value in pickled_values.items():
|
for key, value in pickled_values.items():
|
||||||
env[key] = value
|
env[key] = value
|
||||||
|
@ -552,7 +553,7 @@ elif preconfigured:
|
||||||
color_print(4,'Using previous successful configuration...')
|
color_print(4,'Using previous successful configuration...')
|
||||||
color_print(4,'Re-configure by running "python scons/scons.py configure".')
|
color_print(4,'Re-configure by running "python scons/scons.py configure".')
|
||||||
|
|
||||||
if env.has_key('COLOR_PRINT') and env['COLOR_PRINT'] == False:
|
if 'COLOR_PRINT' in env and env['COLOR_PRINT'] == False:
|
||||||
color_print = regular_print
|
color_print = regular_print
|
||||||
|
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
|
@ -621,9 +622,9 @@ def parse_config(context, config, checks='--libs --cflags'):
|
||||||
else:
|
else:
|
||||||
env.ParseConfig(cmd)
|
env.ParseConfig(cmd)
|
||||||
parsed = True
|
parsed = True
|
||||||
except OSError, e:
|
except OSError as e:
|
||||||
ret = False
|
ret = False
|
||||||
print ' (xml2-config not found!)'
|
print (' (xml2-config not found!)')
|
||||||
if not parsed:
|
if not parsed:
|
||||||
if config in ('GDAL_CONFIG'):
|
if config in ('GDAL_CONFIG'):
|
||||||
# optional deps...
|
# optional deps...
|
||||||
|
@ -646,7 +647,7 @@ def get_pkg_lib(context, config, lib):
|
||||||
parsed = False
|
parsed = False
|
||||||
if ret:
|
if ret:
|
||||||
try:
|
try:
|
||||||
value = call(cmd,silent=True)
|
value = call(cmd,silent=True).decode("utf8")
|
||||||
if ' ' in value:
|
if ' ' in value:
|
||||||
parts = value.split(' ')
|
parts = value.split(' ')
|
||||||
if len(parts) > 1:
|
if len(parts) > 1:
|
||||||
|
@ -657,9 +658,9 @@ def get_pkg_lib(context, config, lib):
|
||||||
else:
|
else:
|
||||||
# osx 1.8 install gives '-framework GDAL'
|
# osx 1.8 install gives '-framework GDAL'
|
||||||
libname = 'gdal'
|
libname = 'gdal'
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
ret = False
|
ret = False
|
||||||
print ' unable to determine library name:'# %s' % str(e)
|
print (' unable to determine library name:# {0!s}'.format(e))
|
||||||
return None
|
return None
|
||||||
context.Result( libname )
|
context.Result( libname )
|
||||||
return libname
|
return libname
|
||||||
|
@ -671,8 +672,8 @@ def parse_pg_config(context, config):
|
||||||
context.Message( 'Checking for %s... ' % tool)
|
context.Message( 'Checking for %s... ' % tool)
|
||||||
ret = context.TryAction(env[config])[0]
|
ret = context.TryAction(env[config])[0]
|
||||||
if ret:
|
if ret:
|
||||||
lib_path = call('%s --libdir' % env[config])
|
lib_path = call('%s --libdir' % env[config]).decode("utf8")
|
||||||
inc_path = call('%s --includedir' % env[config])
|
inc_path = call('%s --includedir' % env[config]).decode("utf8")
|
||||||
env.AppendUnique(CPPPATH = fix_path(inc_path))
|
env.AppendUnique(CPPPATH = fix_path(inc_path))
|
||||||
env.AppendUnique(LIBPATH = fix_path(lib_path))
|
env.AppendUnique(LIBPATH = fix_path(lib_path))
|
||||||
lpq = env['PLUGINS']['postgis']['lib']
|
lpq = env['PLUGINS']['postgis']['lib']
|
||||||
|
@ -807,7 +808,7 @@ int main()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def CheckIcuData(context, silent=False):
|
def CheckIcuData(context, silent=False):
|
||||||
|
|
||||||
if not silent:
|
if not silent:
|
||||||
context.Message('Checking for ICU data directory...')
|
context.Message('Checking for ICU data directory...')
|
||||||
ret = context.TryRun("""
|
ret = context.TryRun("""
|
||||||
|
@ -834,7 +835,7 @@ int main() {
|
||||||
return ret[1].strip()
|
return ret[1].strip()
|
||||||
|
|
||||||
def CheckGdalData(context, silent=False):
|
def CheckGdalData(context, silent=False):
|
||||||
|
|
||||||
if not silent:
|
if not silent:
|
||||||
context.Message('Checking for GDAL data directory...')
|
context.Message('Checking for GDAL data directory...')
|
||||||
ret = context.TryRun("""
|
ret = context.TryRun("""
|
||||||
|
@ -857,7 +858,7 @@ int main() {
|
||||||
return ret[1].strip()
|
return ret[1].strip()
|
||||||
|
|
||||||
def CheckProjData(context, silent=False):
|
def CheckProjData(context, silent=False):
|
||||||
|
|
||||||
if not silent:
|
if not silent:
|
||||||
context.Message('Checking for PROJ_LIB directory...')
|
context.Message('Checking for PROJ_LIB directory...')
|
||||||
ret = context.TryRun("""
|
ret = context.TryRun("""
|
||||||
|
@ -1235,7 +1236,7 @@ if not preconfigured:
|
||||||
if os.path.exists(conf):
|
if os.path.exists(conf):
|
||||||
opts.files.append(conf)
|
opts.files.append(conf)
|
||||||
color_print(4,"SCons CONFIG found: '%s', variables will be inherited..." % 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(" = ","=")
|
#print optfile.read().replace("\n", " ").replace("'","").replace(" = ","=")
|
||||||
optfile.close()
|
optfile.close()
|
||||||
|
|
||||||
|
@ -1402,7 +1403,7 @@ if not preconfigured:
|
||||||
temp_env.ParseConfig('%s --libs' % env['FREETYPE_CONFIG'])
|
temp_env.ParseConfig('%s --libs' % env['FREETYPE_CONFIG'])
|
||||||
if 'bz2' in temp_env['LIBS']:
|
if 'bz2' in temp_env['LIBS']:
|
||||||
env['EXTRA_FREETYPE_LIBS'].append('bz2')
|
env['EXTRA_FREETYPE_LIBS'].append('bz2')
|
||||||
except OSError,e:
|
except OSError as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# libxml2 should be optional but is currently not
|
# libxml2 should be optional but is currently not
|
||||||
|
@ -1703,7 +1704,7 @@ if not preconfigured:
|
||||||
if not lib in env['LIBS']:
|
if not lib in env['LIBS']:
|
||||||
env["SQLITE_LINKFLAGS"].append(lib)
|
env["SQLITE_LINKFLAGS"].append(lib)
|
||||||
env.Append(LIBS=lib)
|
env.Append(LIBS=lib)
|
||||||
except OSError,e:
|
except OSError as e:
|
||||||
for lib in ["sqlite3","dl","pthread"]:
|
for lib in ["sqlite3","dl","pthread"]:
|
||||||
if not lib in env['LIBS']:
|
if not lib in env['LIBS']:
|
||||||
env["SQLITE_LINKFLAGS"].append("lib")
|
env["SQLITE_LINKFLAGS"].append("lib")
|
||||||
|
@ -1786,7 +1787,7 @@ if not preconfigured:
|
||||||
env['HAS_CAIRO'] = False
|
env['HAS_CAIRO'] = False
|
||||||
env['SKIPPED_DEPS'].append('cairo')
|
env['SKIPPED_DEPS'].append('cairo')
|
||||||
else:
|
else:
|
||||||
print 'Checking for cairo lib and include paths... ',
|
print ('Checking for cairo lib and include paths... ', end='')
|
||||||
cmd = 'pkg-config --libs --cflags cairo'
|
cmd = 'pkg-config --libs --cflags cairo'
|
||||||
if env['RUNTIME_LINK'] == 'static':
|
if env['RUNTIME_LINK'] == 'static':
|
||||||
cmd += ' --static'
|
cmd += ' --static'
|
||||||
|
@ -1803,8 +1804,8 @@ if not preconfigured:
|
||||||
if not inc in env['CPPPATH']:
|
if not inc in env['CPPPATH']:
|
||||||
env["CAIRO_CPPPATHS"].append(inc)
|
env["CAIRO_CPPPATHS"].append(inc)
|
||||||
env['HAS_CAIRO'] = True
|
env['HAS_CAIRO'] = True
|
||||||
print 'yes'
|
print ('yes')
|
||||||
except OSError,e:
|
except OSError as e:
|
||||||
color_print(1,'no')
|
color_print(1,'no')
|
||||||
env['SKIPPED_DEPS'].append('cairo')
|
env['SKIPPED_DEPS'].append('cairo')
|
||||||
color_print(1,'pkg-config reported: %s' % e)
|
color_print(1,'pkg-config reported: %s' % e)
|
||||||
|
@ -1959,7 +1960,7 @@ if not preconfigured:
|
||||||
|
|
||||||
# finish config stage and pickle results
|
# finish config stage and pickle results
|
||||||
env = conf.Finish()
|
env = conf.Finish()
|
||||||
env_cache = open(SCONS_CONFIGURE_CACHE, 'w')
|
env_cache = open(SCONS_CONFIGURE_CACHE, 'wb')
|
||||||
pickle_dict = {}
|
pickle_dict = {}
|
||||||
for i in pickle_store:
|
for i in pickle_store:
|
||||||
pickle_dict[i] = env.get(i)
|
pickle_dict[i] = env.get(i)
|
||||||
|
@ -1970,20 +1971,20 @@ if not preconfigured:
|
||||||
# with a non-root configure following a root install
|
# with a non-root configure following a root install
|
||||||
# that also triggered a re-configure
|
# that also triggered a re-configure
|
||||||
try:
|
try:
|
||||||
os.chmod(SCONS_CONFIGURE_CACHE,0666)
|
os.chmod(SCONS_CONFIGURE_CACHE,0o666)
|
||||||
except: pass
|
except: pass
|
||||||
try:
|
try:
|
||||||
os.chmod(SCONS_LOCAL_CONFIG,0666)
|
os.chmod(SCONS_LOCAL_CONFIG,0o666)
|
||||||
except: pass
|
except: pass
|
||||||
try:
|
try:
|
||||||
os.chmod('.sconsign.dblite',0666)
|
os.chmod('.sconsign.dblite',0o666)
|
||||||
except: pass
|
except: pass
|
||||||
try:
|
try:
|
||||||
os.chmod(SCONS_LOCAL_LOG,0666)
|
os.chmod(SCONS_LOCAL_LOG,0o666)
|
||||||
except: pass
|
except: pass
|
||||||
try:
|
try:
|
||||||
for item in glob('%s/*' % SCONF_TEMP_DIR):
|
for item in glob('%s/*' % SCONF_TEMP_DIR):
|
||||||
os.chmod(item,0666)
|
os.chmod(item, 0o666)
|
||||||
except: pass
|
except: pass
|
||||||
|
|
||||||
if 'configure' in command_line_args:
|
if 'configure' in command_line_args:
|
||||||
|
|
|
@ -43,5 +43,5 @@ ini = ini_template % locals()
|
||||||
open('viewer.ini','w').write(ini)
|
open('viewer.ini','w').write(ini)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.chmod('viewer.ini',0666)
|
os.chmod('viewer.ini',0o666)
|
||||||
except: pass
|
except: pass
|
||||||
|
|
|
@ -29,7 +29,7 @@ if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
||||||
can_build = True
|
can_build = True
|
||||||
|
|
||||||
if not can_build:
|
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:
|
else:
|
||||||
Import ('plugin_base')
|
Import ('plugin_base')
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
||||||
can_build = True
|
can_build = True
|
||||||
|
|
||||||
if not can_build:
|
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:
|
else:
|
||||||
|
|
||||||
Import ('plugin_base')
|
Import ('plugin_base')
|
||||||
|
|
|
@ -43,7 +43,7 @@ if env['RUNTIME_LINK'] == 'static':
|
||||||
cmd = 'pkg-config libpq --libs --static'
|
cmd = 'pkg-config libpq --libs --static'
|
||||||
try:
|
try:
|
||||||
plugin_env.ParseConfig(cmd)
|
plugin_env.ParseConfig(cmd)
|
||||||
except OSError, e:
|
except OSError as e:
|
||||||
plugin_env.Append(LIBS='pq')
|
plugin_env.Append(LIBS='pq')
|
||||||
else:
|
else:
|
||||||
plugin_env.Append(LIBS='pq')
|
plugin_env.Append(LIBS='pq')
|
||||||
|
|
|
@ -42,7 +42,7 @@ if env['RUNTIME_LINK'] == 'static':
|
||||||
cmd = 'pkg-config libpq --libs --static'
|
cmd = 'pkg-config libpq --libs --static'
|
||||||
try:
|
try:
|
||||||
plugin_env.ParseConfig(cmd)
|
plugin_env.ParseConfig(cmd)
|
||||||
except OSError, e:
|
except OSError as e:
|
||||||
plugin_env.Append(LIBS='pq')
|
plugin_env.Append(LIBS='pq')
|
||||||
else:
|
else:
|
||||||
plugin_env.Append(LIBS='pq')
|
plugin_env.Append(LIBS='pq')
|
||||||
|
|
|
@ -29,7 +29,7 @@ if env.get('BOOST_LIB_VERSION_FROM_HEADER'):
|
||||||
can_build = True
|
can_build = True
|
||||||
|
|
||||||
if not can_build:
|
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:
|
else:
|
||||||
Import ('plugin_base')
|
Import ('plugin_base')
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
This copyright and license do not apply to any other software
|
This copyright and license do not apply to any other software
|
||||||
with which this software may have been included.
|
with which this software may have been included.
|
||||||
|
|
||||||
Copyright (c) 2001 - 2016 The SCons Foundation
|
Copyright (c) 2001 - 2017 The SCons Foundation
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# Copyright (c) 2001 - 2016 The SCons Foundation
|
# Copyright (c) 2001 - 2017 The SCons Foundation
|
||||||
|
|
||||||
SCons - a software construction tool
|
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.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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,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()
|
get_presig()
|
||||||
Fetches the "contents" of a subclass for signature calculation.
|
Fetches the "contents" of a subclass for signature calculation.
|
||||||
The varlist is added to this to produce the Action's contents.
|
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()
|
strfunction()
|
||||||
Returns a substituted string representation of the Action.
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -97,15 +98,15 @@ way for wrapping up the functions.
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Action.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Action.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import dis
|
|
||||||
import os
|
import os
|
||||||
# compat layer imports "cPickle" for us if it's available.
|
|
||||||
import pickle
|
import pickle
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import itertools
|
||||||
|
import inspect
|
||||||
|
|
||||||
import SCons.Debug
|
import SCons.Debug
|
||||||
from SCons.Debug import logInstanceCreation
|
from SCons.Debug import logInstanceCreation
|
||||||
|
@ -124,37 +125,25 @@ print_actions = 1
|
||||||
execute_actions = 1
|
execute_actions = 1
|
||||||
print_actions_presub = 0
|
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):
|
def rfile(n):
|
||||||
try:
|
try:
|
||||||
return n.rfile()
|
return n.rfile()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
|
||||||
def default_exitstatfunc(s):
|
def default_exitstatfunc(s):
|
||||||
return 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('^[\'"](.*)[\'"]$')
|
strip_quotes = re.compile('^[\'"](.*)[\'"]$')
|
||||||
|
|
||||||
|
|
||||||
|
@ -163,12 +152,12 @@ def _callable_contents(obj):
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Test if obj is a method.
|
# Test if obj is a method.
|
||||||
return _function_contents(obj.im_func)
|
return _function_contents(obj.__func__)
|
||||||
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
# Test if obj is a callable object.
|
# Test if obj is a callable object.
|
||||||
return _function_contents(obj.__call__.im_func)
|
return _function_contents(obj.__call__.__func__)
|
||||||
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
|
@ -176,8 +165,8 @@ def _callable_contents(obj):
|
||||||
return _code_contents(obj)
|
return _code_contents(obj)
|
||||||
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# Test if obj is a function object.
|
# Test if obj is a function object.
|
||||||
return _function_contents(obj)
|
return _function_contents(obj)
|
||||||
|
|
||||||
|
|
||||||
def _object_contents(obj):
|
def _object_contents(obj):
|
||||||
|
@ -188,12 +177,12 @@ def _object_contents(obj):
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# Test if obj is a method.
|
# Test if obj is a method.
|
||||||
return _function_contents(obj.im_func)
|
return _function_contents(obj.__func__)
|
||||||
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
# Test if obj is a callable object.
|
# Test if obj is a callable object.
|
||||||
return _function_contents(obj.__call__.im_func)
|
return _function_contents(obj.__call__.__func__)
|
||||||
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
|
@ -205,20 +194,23 @@ def _object_contents(obj):
|
||||||
# Test if obj is a function object.
|
# Test if obj is a function object.
|
||||||
return _function_contents(obj)
|
return _function_contents(obj)
|
||||||
|
|
||||||
except AttributeError:
|
except AttributeError as ae:
|
||||||
# Should be a pickable Python object.
|
# Should be a pickle-able Python object.
|
||||||
try:
|
try:
|
||||||
return pickle.dumps(obj)
|
return _object_instance_content(obj)
|
||||||
except (pickle.PicklingError, TypeError):
|
# 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
|
# This is weird, but it seems that nested classes
|
||||||
# are unpickable. The Python docs say it should
|
# are unpickable. The Python docs say it should
|
||||||
# always be a PicklingError, but some Python
|
# always be a PicklingError, but some Python
|
||||||
# versions seem to return TypeError. Just do
|
# versions seem to return TypeError. Just do
|
||||||
# the best we can.
|
# 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.
|
"""Return the signature contents of a code object.
|
||||||
|
|
||||||
By providing direct access to the code object of the
|
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!
|
number indications in the compiled byte code. Boo!
|
||||||
So we remove the line number byte codes to prevent
|
So we remove the line number byte codes to prevent
|
||||||
recompilations from moving a Python function.
|
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
|
# The code contents depends on the number of local variables
|
||||||
# but not their actual names.
|
# but not their actual names.
|
||||||
contents.append("%s,%s" % (code.co_argcount, len(code.co_varnames)))
|
contents = bytearray("{}, {}".format(code.co_argcount, len(code.co_varnames)), 'utf-8')
|
||||||
contents.append(",%s,%s" % (len(code.co_cellvars), len(code.co_freevars)))
|
|
||||||
|
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
|
# The code contents depends on any constants accessed by the
|
||||||
# function. Note that we have to call _object_contents on each
|
# function. Note that we have to call _object_contents on each
|
||||||
# constants because the code object of nested functions can
|
# constants because the code object of nested functions can
|
||||||
# show-up among the constants.
|
# show-up among the constants.
|
||||||
#
|
|
||||||
# Note that we also always ignore the first entry of co_consts
|
z = [_object_contents(cc) for cc in code.co_consts[1:]]
|
||||||
# which contains the function doc string. We assume that the
|
contents.extend(b',(')
|
||||||
# function does not access its doc string.
|
contents.extend(bytearray(',', 'utf-8').join(z))
|
||||||
contents.append(',(' + ','.join(map(_object_contents,code.co_consts[1:])) + ')')
|
contents.extend(b')')
|
||||||
|
|
||||||
# The code contents depends on the variable names used to
|
# The code contents depends on the variable names used to
|
||||||
# accessed global variable, as changing the variable name changes
|
# accessed global variable, as changing the variable name changes
|
||||||
# the variable actually accessed and therefore changes the
|
# the variable actually accessed and therefore changes the
|
||||||
# function result.
|
# 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!!!
|
# 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):
|
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
|
# The function contents depends on the value of defaults arguments
|
||||||
if func.func_defaults:
|
if func.__defaults__:
|
||||||
contents.append(',(' + ','.join(map(_object_contents,func.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:
|
else:
|
||||||
contents.append(',()')
|
contents.append(b',()')
|
||||||
|
|
||||||
# The function contents depends on the closure captured cell values.
|
# 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:
|
try:
|
||||||
xxx = [_object_contents(x.cell_contents) for x in closure]
|
closure_contents = [_object_contents(x.cell_contents) for x in closure]
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
xxx = []
|
closure_contents = []
|
||||||
contents.append(',(' + ','.join(xxx) + ')')
|
|
||||||
|
|
||||||
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):
|
def _actionAppend(act1, act2):
|
||||||
# This function knows how to slap two actions together.
|
# This function knows how to slap two actions together.
|
||||||
|
@ -305,6 +409,7 @@ def _actionAppend(act1, act2):
|
||||||
else:
|
else:
|
||||||
return ListAction([ a1, a2 ])
|
return ListAction([ a1, a2 ])
|
||||||
|
|
||||||
|
|
||||||
def _do_create_keywords(args, kw):
|
def _do_create_keywords(args, kw):
|
||||||
"""This converts any arguments after the action argument into
|
"""This converts any arguments after the action argument into
|
||||||
their equivalent keywords and adds them to the kw argument.
|
their equivalent keywords and adds them to the kw argument.
|
||||||
|
@ -332,6 +437,7 @@ def _do_create_keywords(args, kw):
|
||||||
raise SCons.Errors.UserError(
|
raise SCons.Errors.UserError(
|
||||||
'Cannot have both strfunction and cmdstr args to Action()')
|
'Cannot have both strfunction and cmdstr args to Action()')
|
||||||
|
|
||||||
|
|
||||||
def _do_create_action(act, kw):
|
def _do_create_action(act, kw):
|
||||||
"""This is the actual "implementation" for the
|
"""This is the actual "implementation" for the
|
||||||
Action factory method, below. This handles the
|
Action factory method, below. This handles the
|
||||||
|
@ -362,7 +468,7 @@ def _do_create_action(act, kw):
|
||||||
# The list of string commands may include a LazyAction, so we
|
# The list of string commands may include a LazyAction, so we
|
||||||
# reprocess them via _do_create_list_action.
|
# reprocess them via _do_create_list_action.
|
||||||
return _do_create_list_action(commands, kw)
|
return _do_create_list_action(commands, kw)
|
||||||
|
|
||||||
if is_List(act):
|
if is_List(act):
|
||||||
return CommandAction(act, **kw)
|
return CommandAction(act, **kw)
|
||||||
|
|
||||||
|
@ -384,6 +490,7 @@ def _do_create_action(act, kw):
|
||||||
# Else fail silently (???)
|
# Else fail silently (???)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _do_create_list_action(act, kw):
|
def _do_create_list_action(act, kw):
|
||||||
"""A factory for list actions. Convert the input list into Actions
|
"""A factory for list actions. Convert the input list into Actions
|
||||||
and then wrap them in a ListAction."""
|
and then wrap them in a ListAction."""
|
||||||
|
@ -398,6 +505,7 @@ def _do_create_list_action(act, kw):
|
||||||
else:
|
else:
|
||||||
return ListAction(acts)
|
return ListAction(acts)
|
||||||
|
|
||||||
|
|
||||||
def Action(act, *args, **kw):
|
def Action(act, *args, **kw):
|
||||||
"""A factory for action objects."""
|
"""A factory for action objects."""
|
||||||
# Really simple: the _do_create_* routines do the heavy lifting.
|
# 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_list_action(act, kw)
|
||||||
return _do_create_action(act, kw)
|
return _do_create_action(act, kw)
|
||||||
|
|
||||||
|
|
||||||
class ActionBase(object):
|
class ActionBase(object):
|
||||||
"""Base class for all types of action objects that can be held by
|
"""Base class for all types of action objects that can be held by
|
||||||
other objects (Builders, Executors, etc.) This provides the
|
other objects (Builders, Executors, etc.) This provides the
|
||||||
common methods for manipulating and combining those actions."""
|
common methods for manipulating and combining those actions."""
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __eq__(self, other):
|
||||||
return cmp(self.__dict__, other)
|
return self.__dict__ == other
|
||||||
|
|
||||||
def no_batch_key(self, env, target, source):
|
def no_batch_key(self, env, target, source):
|
||||||
return None
|
return None
|
||||||
|
@ -423,7 +532,18 @@ class ActionBase(object):
|
||||||
return str(self)
|
return str(self)
|
||||||
|
|
||||||
def get_contents(self, target, source, env):
|
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
|
# This should never happen, as the Action() factory should wrap
|
||||||
# the varlist, but just in case an action is created directly,
|
# the varlist, but just in case an action is created directly,
|
||||||
# we duplicate this check here.
|
# we duplicate this check here.
|
||||||
|
@ -431,8 +551,18 @@ class ActionBase(object):
|
||||||
if is_String(vl): vl = (vl,)
|
if is_String(vl): vl = (vl,)
|
||||||
for v in vl:
|
for v in vl:
|
||||||
# do the subst this way to ignore $(...$) parts:
|
# do the subst this way to ignore $(...$) parts:
|
||||||
result.append(env.subst_target_source('${'+v+'}', SCons.Subst.SUBST_SIG, target, source))
|
if isinstance(result, bytearray):
|
||||||
return ''.join(result)
|
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):
|
def __add__(self, other):
|
||||||
return _actionAppend(self, other)
|
return _actionAppend(self, other)
|
||||||
|
@ -462,6 +592,7 @@ class ActionBase(object):
|
||||||
"""
|
"""
|
||||||
return self.targets
|
return self.targets
|
||||||
|
|
||||||
|
|
||||||
class _ActionAction(ActionBase):
|
class _ActionAction(ActionBase):
|
||||||
"""Base class for actions that create output objects."""
|
"""Base class for actions that create output objects."""
|
||||||
def __init__(self, cmdstr=_null, strfunction=_null, varlist=(),
|
def __init__(self, cmdstr=_null, strfunction=_null, varlist=(),
|
||||||
|
@ -495,16 +626,18 @@ class _ActionAction(ActionBase):
|
||||||
SCons.Util.AddMethod(self, batch_key, 'batch_key')
|
SCons.Util.AddMethod(self, batch_key, 'batch_key')
|
||||||
|
|
||||||
def print_cmd_line(self, s, target, source, env):
|
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 python 3, and in some of our tests, sys.stdout is
|
||||||
# In other cases it's a regular Python 2.x file object
|
a String io object, and it takes unicode strings only
|
||||||
# which takes strings (bytes), and if you pass those a
|
In other cases it's a regular Python 2.x file object
|
||||||
# unicode object they try to decode with 'ascii' codec
|
which takes strings (bytes), and if you pass those a
|
||||||
# which fails if the cmd line has any hi-bit-set chars.
|
unicode object they try to decode with 'ascii' codec
|
||||||
# This code assumes s is a regular string, but should
|
which fails if the cmd line has any hi-bit-set chars.
|
||||||
# work if it's unicode too.
|
This code assumes s is a regular string, but should
|
||||||
|
work if it's unicode too.
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
sys.stdout.write(unicode(s + "\n"))
|
sys.stdout.write(s + u"\n")
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
sys.stdout.write(s + "\n")
|
sys.stdout.write(s + "\n")
|
||||||
|
|
||||||
|
@ -601,13 +734,17 @@ def _string_from_cmd_list(cmd_list):
|
||||||
cl.append(arg)
|
cl.append(arg)
|
||||||
return ' '.join(cl)
|
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
|
default_ENV = None
|
||||||
|
|
||||||
|
|
||||||
def get_default_ENV(env):
|
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
|
global default_ENV
|
||||||
try:
|
try:
|
||||||
return env['ENV']
|
return env['ENV']
|
||||||
|
@ -622,12 +759,15 @@ def get_default_ENV(env):
|
||||||
default_ENV = SCons.Environment.Environment()['ENV']
|
default_ENV = SCons.Environment.Environment()['ENV']
|
||||||
return default_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):
|
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'"
|
# allow std{in,out,err} to be "'devnull'"
|
||||||
io = kw.get('stdin')
|
io = kw.get('stdin')
|
||||||
if is_String(io) and io == 'devnull':
|
if is_String(io) and io == 'devnull':
|
||||||
|
@ -664,12 +804,12 @@ def _subproc(scons_env, cmd, error = 'ignore', **kw):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return subprocess.Popen(cmd, **kw)
|
return subprocess.Popen(cmd, **kw)
|
||||||
except EnvironmentError, e:
|
except EnvironmentError as e:
|
||||||
if error == 'raise': raise
|
if error == 'raise': raise
|
||||||
# return a dummy Popen instance that only returns error
|
# return a dummy Popen instance that only returns error
|
||||||
class dummyPopen(object):
|
class dummyPopen(object):
|
||||||
def __init__(self, e): self.exception = e
|
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
|
def wait(self): return -self.exception.errno
|
||||||
stdin = None
|
stdin = None
|
||||||
class f(object):
|
class f(object):
|
||||||
|
@ -679,6 +819,7 @@ def _subproc(scons_env, cmd, error = 'ignore', **kw):
|
||||||
stdout = stderr = f()
|
stdout = stderr = f()
|
||||||
return dummyPopen(e)
|
return dummyPopen(e)
|
||||||
|
|
||||||
|
|
||||||
class CommandAction(_ActionAction):
|
class CommandAction(_ActionAction):
|
||||||
"""Class for command-execution actions."""
|
"""Class for command-execution actions."""
|
||||||
def __init__(self, cmd, **kw):
|
def __init__(self, cmd, **kw):
|
||||||
|
@ -695,7 +836,7 @@ class CommandAction(_ActionAction):
|
||||||
|
|
||||||
_ActionAction.__init__(self, **kw)
|
_ActionAction.__init__(self, **kw)
|
||||||
if is_List(cmd):
|
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 " \
|
raise TypeError("CommandAction should be given only " \
|
||||||
"a single command")
|
"a single command")
|
||||||
self.cmd_list = cmd
|
self.cmd_list = cmd
|
||||||
|
@ -845,6 +986,7 @@ class CommandAction(_ActionAction):
|
||||||
res.append(env.fs.File(d))
|
res.append(env.fs.File(d))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
class CommandGeneratorAction(ActionBase):
|
class CommandGeneratorAction(ActionBase):
|
||||||
"""Class for command-generator actions."""
|
"""Class for command-generator actions."""
|
||||||
def __init__(self, generator, kw):
|
def __init__(self, generator, kw):
|
||||||
|
@ -916,25 +1058,25 @@ class CommandGeneratorAction(ActionBase):
|
||||||
return self._generate(None, None, env, 1, executor).get_targets(env, executor)
|
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):
|
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):
|
def __init__(self, var, kw):
|
||||||
if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.LazyAction')
|
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)
|
c = env.subst(self.cmdstr, SUBST_RAW, target, source)
|
||||||
if c:
|
if c:
|
||||||
return c
|
return c
|
||||||
|
|
||||||
def array(a):
|
def array(a):
|
||||||
def quote(s):
|
def quote(s):
|
||||||
try:
|
try:
|
||||||
|
@ -1052,11 +1195,11 @@ class FunctionAction(_ActionAction):
|
||||||
rsources = list(map(rfile, source))
|
rsources = list(map(rfile, source))
|
||||||
try:
|
try:
|
||||||
result = self.execfunction(target=target, source=rsources, env=env)
|
result = self.execfunction(target=target, source=rsources, env=env)
|
||||||
except KeyboardInterrupt, e:
|
except KeyboardInterrupt as e:
|
||||||
raise
|
raise
|
||||||
except SystemExit, e:
|
except SystemExit as e:
|
||||||
raise
|
raise
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
result = e
|
result = e
|
||||||
exc_info = sys.exc_info()
|
exc_info = sys.exc_info()
|
||||||
|
|
||||||
|
@ -1086,7 +1229,6 @@ class FunctionAction(_ActionAction):
|
||||||
# more information about this issue.
|
# more information about this issue.
|
||||||
del exc_info
|
del exc_info
|
||||||
|
|
||||||
|
|
||||||
def get_presig(self, target, source, env):
|
def get_presig(self, target, source, env):
|
||||||
"""Return the signature contents of this callable action."""
|
"""Return the signature contents of this callable action."""
|
||||||
try:
|
try:
|
||||||
|
@ -1126,7 +1268,7 @@ class ListAction(ActionBase):
|
||||||
|
|
||||||
Simple concatenation of the signatures of the elements.
|
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,
|
def __call__(self, target, source, env, exitstatfunc=_null, presub=_null,
|
||||||
show=_null, execute=_null, chdir=_null, executor=None):
|
show=_null, execute=_null, chdir=_null, executor=None):
|
||||||
|
@ -1153,6 +1295,7 @@ class ListAction(ActionBase):
|
||||||
result[var] = True
|
result[var] = True
|
||||||
return list(result.keys())
|
return list(result.keys())
|
||||||
|
|
||||||
|
|
||||||
class ActionCaller(object):
|
class ActionCaller(object):
|
||||||
"""A class for delaying calling an Action function with specific
|
"""A class for delaying calling an Action function with specific
|
||||||
(positional and keyword) arguments until the Action is actually
|
(positional and keyword) arguments until the Action is actually
|
||||||
|
@ -1171,16 +1314,16 @@ class ActionCaller(object):
|
||||||
actfunc = self.parent.actfunc
|
actfunc = self.parent.actfunc
|
||||||
try:
|
try:
|
||||||
# "self.actfunc" is a function.
|
# "self.actfunc" is a function.
|
||||||
contents = str(actfunc.func_code.co_code)
|
contents = actfunc.__code__.co_code
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# "self.actfunc" is a callable object.
|
# "self.actfunc" is a callable object.
|
||||||
try:
|
try:
|
||||||
contents = str(actfunc.__call__.im_func.func_code.co_code)
|
contents = actfunc.__call__.__func__.__code__.co_code
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# No __call__() method, so it might be a builtin
|
# No __call__() method, so it might be a builtin
|
||||||
# or something like that. Do the best we can.
|
# or something like that. Do the best we can.
|
||||||
contents = str(actfunc)
|
contents = repr(actfunc)
|
||||||
contents = remove_set_lineno_codes(contents)
|
|
||||||
return contents
|
return contents
|
||||||
|
|
||||||
def subst(self, s, target, source, env):
|
def subst(self, s, target, source, env):
|
||||||
|
@ -1206,7 +1349,7 @@ class ActionCaller(object):
|
||||||
|
|
||||||
def subst_kw(self, target, source, env):
|
def subst_kw(self, target, source, env):
|
||||||
kw = {}
|
kw = {}
|
||||||
for key in self.kw.keys():
|
for key in list(self.kw.keys()):
|
||||||
kw[key] = self.subst(self.kw[key], target, source, env)
|
kw[key] = self.subst(self.kw[key], target, source, env)
|
||||||
return kw
|
return kw
|
||||||
|
|
||||||
|
@ -1223,6 +1366,7 @@ class ActionCaller(object):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.parent.strfunc(*self.args, **self.kw)
|
return self.parent.strfunc(*self.args, **self.kw)
|
||||||
|
|
||||||
|
|
||||||
class ActionFactory(object):
|
class ActionFactory(object):
|
||||||
"""A factory class that will wrap up an arbitrary function
|
"""A factory class that will wrap up an arbitrary function
|
||||||
as an SCons-executable Action object.
|
as an SCons-executable Action object.
|
|
@ -1,4 +1,5 @@
|
||||||
"""SCons.Builder
|
"""
|
||||||
|
SCons.Builder
|
||||||
|
|
||||||
Builder object subsystem.
|
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
|
Builders and their proxies have the following public interface methods
|
||||||
used by other modules:
|
used by other modules:
|
||||||
|
|
||||||
__call__()
|
- __call__()
|
||||||
THE public interface. Calling a Builder object (with the
|
THE public interface. Calling a Builder object (with the
|
||||||
use of internal helper methods) sets up the target and source
|
use of internal helper methods) sets up the target and source
|
||||||
dependencies, appropriate mapping to a specific action, and the
|
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
|
variable. This also takes care of warning about possible mistakes
|
||||||
in keyword arguments.
|
in keyword arguments.
|
||||||
|
|
||||||
add_emitter()
|
- add_emitter()
|
||||||
Adds an emitter for a specific file suffix, used by some Tool
|
Adds an emitter for a specific file suffix, used by some Tool
|
||||||
modules to specify that (for example) a yacc invocation on a .y
|
modules to specify that (for example) a yacc invocation on a .y
|
||||||
can create a .h *and* a .c file.
|
can create a .h *and* a .c file.
|
||||||
|
|
||||||
add_action()
|
- add_action()
|
||||||
Adds an action for a specific file suffix, heavily used by
|
Adds an action for a specific file suffix, heavily used by
|
||||||
Tool modules to add their specific action(s) for turning
|
Tool modules to add their specific action(s) for turning
|
||||||
a source file into an object file to the global static
|
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:
|
There are the following methods for internal use within this module:
|
||||||
|
|
||||||
_execute()
|
- _execute()
|
||||||
The internal method that handles the heavily lifting when a
|
The internal method that handles the heavily lifting when a
|
||||||
Builder is called. This is used so that the __call__() methods
|
Builder is called. This is used so that the __call__() methods
|
||||||
can set up warning about possible mistakes in keyword-argument
|
can set up warning about possible mistakes in keyword-argument
|
||||||
overrides, and *then* execute all of the steps necessary so that
|
overrides, and *then* execute all of the steps necessary so that
|
||||||
the warnings only occur once.
|
the warnings only occur once.
|
||||||
|
|
||||||
get_name()
|
- get_name()
|
||||||
Returns the Builder's name within a specific Environment,
|
Returns the Builder's name within a specific Environment,
|
||||||
primarily used to try to return helpful information in error
|
primarily used to try to return helpful information in error
|
||||||
messages.
|
messages.
|
||||||
|
|
||||||
adjust_suffix()
|
- adjust_suffix()
|
||||||
get_prefix()
|
- get_prefix()
|
||||||
get_suffix()
|
- get_suffix()
|
||||||
get_src_suffix()
|
- get_src_suffix()
|
||||||
set_src_suffix()
|
- set_src_suffix()
|
||||||
Miscellaneous stuff for handling the prefix and suffix
|
Miscellaneous stuff for handling the prefix and suffix
|
||||||
manipulation we use in turning source file names into target
|
manipulation we use in turning source file names into target
|
||||||
file names.
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -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
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Builder.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Builder.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
|
@ -166,7 +167,7 @@ class DictCmdGenerator(SCons.Util.Selector):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ret = SCons.Util.Selector.__call__(self, env, source, ext)
|
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]))
|
raise UserError("Ambiguous suffixes after environment substitution: %s == %s == %s" % (e.args[0], e.args[1], e.args[2]))
|
||||||
if ret is None:
|
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." % \
|
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):
|
def warn(self):
|
||||||
if self.already_warned:
|
if self.already_warned:
|
||||||
return
|
return
|
||||||
for k in self.keys():
|
for k in list(self.keys()):
|
||||||
if k in misleading_keywords:
|
if k in misleading_keywords:
|
||||||
alt = misleading_keywords[k]
|
alt = misleading_keywords[k]
|
||||||
msg = "Did you mean to use `%s' instead of `%s'?" % (alt, 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:
|
if t.side_effect:
|
||||||
raise UserError("Multiple ways to build the same target were specified for: %s" % t)
|
raise UserError("Multiple ways to build the same target were specified for: %s" % t)
|
||||||
if t.has_explicit_builder():
|
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
|
action = t.builder.action
|
||||||
t_contents = t.builder.action.get_contents(tlist, slist, t.env)
|
t_contents = t.builder.action.get_contents(tlist, slist, t.env)
|
||||||
contents = builder.action.get_contents(tlist, slist, 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))
|
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)
|
SCons.Warnings.warn(SCons.Warnings.DuplicateEnvironmentWarning, msg)
|
||||||
else:
|
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)
|
raise UserError(msg)
|
||||||
if builder.multi:
|
if builder.multi:
|
||||||
if t.builder != builder:
|
if t.builder != builder:
|
||||||
|
@ -344,8 +355,11 @@ class EmitterProxy(object):
|
||||||
return (target, source)
|
return (target, source)
|
||||||
|
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __eq__(self, other):
|
||||||
return cmp(self.var, other.var)
|
return self.var == other.var
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
return self.var < other.var
|
||||||
|
|
||||||
class BuilderBase(object):
|
class BuilderBase(object):
|
||||||
"""Base class for Builders, objects that create output
|
"""Base class for Builders, objects that create output
|
||||||
|
@ -423,6 +437,9 @@ class BuilderBase(object):
|
||||||
def __nonzero__(self):
|
def __nonzero__(self):
|
||||||
raise InternalError("Do not test for the Node.builder attribute directly; use Node.has_builder() instead")
|
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):
|
def get_name(self, env):
|
||||||
"""Attempts to get the name of the Builder.
|
"""Attempts to get the name of the Builder.
|
||||||
|
|
||||||
|
@ -440,8 +457,8 @@ class BuilderBase(object):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return str(self.__class__)
|
return str(self.__class__)
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __eq__(self, other):
|
||||||
return cmp(self.__dict__, other.__dict__)
|
return self.__dict__ == other.__dict__
|
||||||
|
|
||||||
def splitext(self, path, env=None):
|
def splitext(self, path, env=None):
|
||||||
if not env:
|
if not env:
|
||||||
|
@ -604,6 +621,8 @@ class BuilderBase(object):
|
||||||
else:
|
else:
|
||||||
ekw = self.executor_kw.copy()
|
ekw = self.executor_kw.copy()
|
||||||
ekw['chdir'] = chdir
|
ekw['chdir'] = chdir
|
||||||
|
if 'chdir' in ekw and SCons.Util.is_String(ekw['chdir']):
|
||||||
|
ekw['chdir'] = env.subst(ekw['chdir'])
|
||||||
if kw:
|
if kw:
|
||||||
if 'srcdir' in kw:
|
if 'srcdir' in kw:
|
||||||
def prependDirIfRelative(f, srcdir=kw['srcdir']):
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/CacheDir.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/CacheDir.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
__doc__ = """
|
__doc__ = """
|
||||||
CacheDir support
|
CacheDir support
|
|
@ -101,7 +101,6 @@ Autoconf-like configuration support; low level implementation of tests.
|
||||||
#
|
#
|
||||||
|
|
||||||
import re
|
import re
|
||||||
from types import IntType
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# PUBLIC VARIABLES
|
# PUBLIC VARIABLES
|
||||||
|
@ -707,11 +706,12 @@ def CheckProg(context, prog_name):
|
||||||
def _YesNoResult(context, ret, key, text, comment = None):
|
def _YesNoResult(context, ret, key, text, comment = None):
|
||||||
"""
|
"""
|
||||||
Handle the result of a test with a "yes" or "no" result.
|
Handle the result of a test with a "yes" or "no" result.
|
||||||
"ret" is the return value: empty if OK, error message when not.
|
|
||||||
"key" is the name of the symbol to be defined (HAVE_foo).
|
:Parameters:
|
||||||
"text" is the source code of the program used for testing.
|
- `ret` is the return value: empty if OK, error message when not.
|
||||||
"comment" is the C comment to add above the line defining the symbol (the
|
- `key` is the name of the symbol to be defined (HAVE_foo).
|
||||||
comment is automatically put inside a /* */). If None, no comment is added.
|
- `text` is the source code of the program used for testing.
|
||||||
|
- `comment` is the C comment to add above the line defining the symbol (the comment is automatically put inside a /\* \*/). If None, no comment is added.
|
||||||
"""
|
"""
|
||||||
if key:
|
if key:
|
||||||
_Have(context, key, not ret, comment)
|
_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):
|
def _Have(context, key, have, comment = None):
|
||||||
"""
|
"""
|
||||||
Store result of a test in context.havedict and context.headerfilename.
|
Store result of a test in context.havedict and context.headerfilename.
|
||||||
"key" is a "HAVE_abc" name. It is turned into all CAPITALS and non-
|
|
||||||
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:
|
The value of "have" can be:
|
||||||
1 - Feature is defined, add "#define key".
|
- 1 - Feature is defined, add "#define key".
|
||||||
0 - Feature is not defined, add "/* #undef 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.
|
||||||
Adding "undef" is what autoconf does. Not useful for the
|
- number - Feature is defined to this number "#define key have". Doesn't work for 0 or 1, use a string then.
|
||||||
compiler, but it shows that the test was done.
|
- string - Feature is defined to this string "#define key have".
|
||||||
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!
|
|
||||||
"""
|
"""
|
||||||
key_up = key.upper()
|
key_up = key.upper()
|
||||||
key_up = re.sub('[^A-Z0-9_]', '_', key_up)
|
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
|
line = "#define %s 1\n" % key_up
|
||||||
elif have == 0:
|
elif have == 0:
|
||||||
line = "/* #undef %s */\n" % key_up
|
line = "/* #undef %s */\n" % key_up
|
||||||
elif isinstance(have, IntType):
|
elif isinstance(have, int):
|
||||||
line = "#define %s %d\n" % (key_up, have)
|
line = "#define %s %d\n" % (key_up, have)
|
||||||
else:
|
else:
|
||||||
line = "#define %s %s\n" % (key_up, str(have))
|
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.
|
When "lang" is empty or None C is assumed.
|
||||||
Returns a tuple (lang, suffix, None) when it works.
|
Returns a tuple (lang, suffix, None) when it works.
|
||||||
For an unrecognized language returns (None, None, msg).
|
For an unrecognized language returns (None, None, msg).
|
||||||
|
|
||||||
Where:
|
Where:
|
||||||
lang = the unified language name
|
- lang = the unified language name
|
||||||
suffix = the suffix, including the leading dot
|
- suffix = the suffix, including the leading dot
|
||||||
msg = an error message
|
- msg = an error message
|
||||||
"""
|
"""
|
||||||
if not lang or lang in ["C", "c"]:
|
if not lang or lang in ["C", "c"]:
|
||||||
return ("C", ".c", None)
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,7 +31,7 @@ caller_trace()
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Debug.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Debug.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -97,7 +97,8 @@ def dumpLoggedInstances(classes, file=sys.stdout):
|
||||||
if sys.platform[:5] == "linux":
|
if sys.platform[:5] == "linux":
|
||||||
# Linux doesn't actually support memory usage stats from getrusage().
|
# Linux doesn't actually support memory usage stats from getrusage().
|
||||||
def memory():
|
def memory():
|
||||||
mstr = open('/proc/self/stat').read()
|
with open('/proc/self/stat') as f:
|
||||||
|
mstr = f.read()
|
||||||
mstr = mstr.split()[22]
|
mstr = mstr.split()[22]
|
||||||
return int(mstr)
|
return int(mstr)
|
||||||
elif sys.platform[:6] == 'darwin':
|
elif sys.platform[:6] == 'darwin':
|
||||||
|
@ -233,6 +234,7 @@ def Trace(msg, file=None, mode='w', tstamp=None):
|
||||||
PreviousTime = now
|
PreviousTime = now
|
||||||
fp.write(msg)
|
fp.write(msg)
|
||||||
fp.flush()
|
fp.flush()
|
||||||
|
fp.close()
|
||||||
|
|
||||||
# Local Variables:
|
# Local Variables:
|
||||||
# tab-width:4
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -33,7 +33,7 @@ from distutils.msvccompiler.
|
||||||
#
|
#
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Defaults.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Defaults.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
@ -261,9 +261,13 @@ def copy_func(dest, src, symlinks=True):
|
||||||
else:
|
else:
|
||||||
return copy_func(dest, os.path.realpath(src))
|
return copy_func(dest, os.path.realpath(src))
|
||||||
elif os.path.isfile(src):
|
elif os.path.isfile(src):
|
||||||
return shutil.copy2(src, dest)
|
shutil.copy2(src, dest)
|
||||||
|
return 0
|
||||||
else:
|
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 = ActionFactory(
|
||||||
copy_func,
|
copy_func,
|
||||||
|
@ -298,7 +302,7 @@ def mkdir_func(dest):
|
||||||
for entry in dest:
|
for entry in dest:
|
||||||
try:
|
try:
|
||||||
os.makedirs(str(entry))
|
os.makedirs(str(entry))
|
||||||
except os.error, e:
|
except os.error as e:
|
||||||
p = str(entry)
|
p = str(entry)
|
||||||
if (e.args[0] == errno.EEXIST or
|
if (e.args[0] == errno.EEXIST or
|
||||||
(sys.platform=='win32' and e.args[0]==183)) \
|
(sys.platform=='win32' and e.args[0]==183)) \
|
||||||
|
@ -458,7 +462,7 @@ def processDefines(defs):
|
||||||
else:
|
else:
|
||||||
l.append(str(d[0]))
|
l.append(str(d[0]))
|
||||||
elif SCons.Util.is_Dict(d):
|
elif SCons.Util.is_Dict(d):
|
||||||
for macro,value in d.iteritems():
|
for macro,value in d.items():
|
||||||
if value is not None:
|
if value is not None:
|
||||||
l.append(str(macro) + '=' + str(value))
|
l.append(str(macro) + '=' + str(value))
|
||||||
else:
|
else:
|
||||||
|
@ -484,6 +488,7 @@ def processDefines(defs):
|
||||||
l = [str(defs)]
|
l = [str(defs)]
|
||||||
return l
|
return l
|
||||||
|
|
||||||
|
|
||||||
def _defines(prefix, defs, suffix, env, c=_concat_ixes):
|
def _defines(prefix, defs, suffix, env, c=_concat_ixes):
|
||||||
"""A wrapper around _concat_ixes that turns a list or string
|
"""A wrapper around _concat_ixes that turns a list or string
|
||||||
into a list of C preprocessor command-line definitions.
|
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)
|
return c(prefix, env.subst_path(processDefines(defs)), suffix, env)
|
||||||
|
|
||||||
|
|
||||||
class NullCmdGenerator(object):
|
class NullCmdGenerator(object):
|
||||||
"""This is a callable class that can be used in place of other
|
"""This is a callable class that can be used in place of other
|
||||||
command generators if you don't want them to do anything.
|
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):
|
def __call__(self, target, source, env, for_signature=None):
|
||||||
return self.cmd
|
return self.cmd
|
||||||
|
|
||||||
|
|
||||||
class Variable_Method_Caller(object):
|
class Variable_Method_Caller(object):
|
||||||
"""A class for finding a construction variable on the stack and
|
"""A class for finding a construction variable on the stack and
|
||||||
calling one of its methods.
|
calling one of its methods.
|
||||||
|
@ -540,10 +547,10 @@ class Variable_Method_Caller(object):
|
||||||
frame = frame.f_back
|
frame = frame.f_back
|
||||||
return None
|
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):
|
def __libversionflags(env, version_var, flags_var):
|
||||||
try:
|
try:
|
||||||
if env[version_var]:
|
if env.subst('$'+version_var):
|
||||||
return env[flags_var]
|
return env[flags_var]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,7 +31,7 @@ Environment
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Environment.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Environment.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
@ -128,7 +128,7 @@ future_reserved_construction_var_names = [
|
||||||
|
|
||||||
def copy_non_reserved_keywords(dict):
|
def copy_non_reserved_keywords(dict):
|
||||||
result = semi_deepcopy(dict)
|
result = semi_deepcopy(dict)
|
||||||
for k in result.keys():
|
for k in list(result.keys()):
|
||||||
if k in reserved_construction_var_names:
|
if k in reserved_construction_var_names:
|
||||||
msg = "Ignoring attempt to set reserved variable `$%s'"
|
msg = "Ignoring attempt to set reserved variable `$%s'"
|
||||||
SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % k)
|
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):
|
def _set_BUILDERS(env, key, value):
|
||||||
try:
|
try:
|
||||||
bd = env._dict[key]
|
bd = env._dict[key]
|
||||||
for k in bd.keys():
|
for k in list(bd.keys()):
|
||||||
del bd[k]
|
del bd[k]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
bd = BuilderDict(kwbd, env)
|
bd = BuilderDict(kwbd, env)
|
||||||
|
@ -167,7 +167,7 @@ def _set_SCANNERS(env, key, value):
|
||||||
|
|
||||||
def _delete_duplicates(l, keep_last):
|
def _delete_duplicates(l, keep_last):
|
||||||
"""Delete duplicates from a sequence, keeping the first or last."""
|
"""Delete duplicates from a sequence, keeping the first or last."""
|
||||||
seen={}
|
seen=set()
|
||||||
result=[]
|
result=[]
|
||||||
if keep_last: # reverse in & out, then keep first
|
if keep_last: # reverse in & out, then keep first
|
||||||
l.reverse()
|
l.reverse()
|
||||||
|
@ -175,7 +175,7 @@ def _delete_duplicates(l, keep_last):
|
||||||
try:
|
try:
|
||||||
if i not in seen:
|
if i not in seen:
|
||||||
result.append(i)
|
result.append(i)
|
||||||
seen[i]=1
|
seen.add(i)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
# probably unhashable. Just keep it.
|
# probably unhashable. Just keep it.
|
||||||
result.append(i)
|
result.append(i)
|
||||||
|
@ -342,7 +342,7 @@ def is_valid_construction_var(varstr):
|
||||||
class SubstitutionEnvironment(object):
|
class SubstitutionEnvironment(object):
|
||||||
"""Base class for different flavors of construction environments.
|
"""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
|
variable expansion and conversion of strings to Nodes, which may or
|
||||||
may not be actually useful as a stand-alone class. Which methods
|
may not be actually useful as a stand-alone class. Which methods
|
||||||
ended up in this class is pretty arbitrary right now. They're
|
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.)
|
# gotten better than dict.has_key() in Python 2.5.)
|
||||||
self._special_set_keys = list(self._special_set.keys())
|
self._special_set_keys = list(self._special_set.keys())
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __eq__(self, other):
|
||||||
return cmp(self._dict, other._dict)
|
return self._dict == other._dict
|
||||||
|
|
||||||
def __delitem__(self, key):
|
def __delitem__(self, key):
|
||||||
special = self._special_del.get(key)
|
special = self._special_del.get(key)
|
||||||
|
@ -589,7 +589,7 @@ class SubstitutionEnvironment(object):
|
||||||
out,err = p.communicate()
|
out,err = p.communicate()
|
||||||
status = p.wait()
|
status = p.wait()
|
||||||
if err:
|
if err:
|
||||||
sys.stderr.write(unicode(err))
|
sys.stderr.write(u"" + err)
|
||||||
if status:
|
if status:
|
||||||
raise OSError("'%s' exited %d" % (command, status))
|
raise OSError("'%s' exited %d" % (command, status))
|
||||||
return out
|
return out
|
||||||
|
@ -1185,7 +1185,7 @@ class Base(SubstitutionEnvironment):
|
||||||
if SCons.Util.is_List(val):
|
if SCons.Util.is_List(val):
|
||||||
if key == 'CPPDEFINES':
|
if key == 'CPPDEFINES':
|
||||||
tmp = []
|
tmp = []
|
||||||
for (k, v) in orig.iteritems():
|
for (k, v) in orig.items():
|
||||||
if v is not None:
|
if v is not None:
|
||||||
tmp.append((k, v))
|
tmp.append((k, v))
|
||||||
else:
|
else:
|
||||||
|
@ -1273,7 +1273,7 @@ class Base(SubstitutionEnvironment):
|
||||||
# Construct a list of (key, value) tuples.
|
# Construct a list of (key, value) tuples.
|
||||||
if SCons.Util.is_Dict(dk):
|
if SCons.Util.is_Dict(dk):
|
||||||
tmp = []
|
tmp = []
|
||||||
for (k, v) in dk.iteritems():
|
for (k, v) in dk.items():
|
||||||
if v is not None:
|
if v is not None:
|
||||||
tmp.append((k, v))
|
tmp.append((k, v))
|
||||||
else:
|
else:
|
||||||
|
@ -1321,7 +1321,7 @@ class Base(SubstitutionEnvironment):
|
||||||
# Construct a list of (key, value) tuples.
|
# Construct a list of (key, value) tuples.
|
||||||
if SCons.Util.is_Dict(val):
|
if SCons.Util.is_Dict(val):
|
||||||
tmp = []
|
tmp = []
|
||||||
for (k, v) in val.iteritems():
|
for (k, v) in val.items():
|
||||||
if v is not None:
|
if v is not None:
|
||||||
tmp.append((k, v))
|
tmp.append((k, v))
|
||||||
else:
|
else:
|
||||||
|
@ -1330,7 +1330,7 @@ class Base(SubstitutionEnvironment):
|
||||||
elif SCons.Util.is_String(val):
|
elif SCons.Util.is_String(val):
|
||||||
val = [(val,)]
|
val = [(val,)]
|
||||||
if delete_existing:
|
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
|
self._dict[key] = dk + val
|
||||||
else:
|
else:
|
||||||
dk = [x for x in dk if x not in val]
|
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
|
# By elimination, val is not a list. Since dk is a
|
||||||
# list, wrap val in a list first.
|
# list, wrap val in a list first.
|
||||||
if delete_existing:
|
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]
|
self._dict[key] = dk + [val]
|
||||||
else:
|
else:
|
||||||
if not val in dk:
|
if not val in dk:
|
||||||
|
@ -1350,7 +1350,7 @@ class Base(SubstitutionEnvironment):
|
||||||
dk = [dk]
|
dk = [dk]
|
||||||
elif SCons.Util.is_Dict(dk):
|
elif SCons.Util.is_Dict(dk):
|
||||||
tmp = []
|
tmp = []
|
||||||
for (k, v) in dk.iteritems():
|
for (k, v) in dk.items():
|
||||||
if v is not None:
|
if v is not None:
|
||||||
tmp.append((k, v))
|
tmp.append((k, v))
|
||||||
else:
|
else:
|
||||||
|
@ -1363,7 +1363,7 @@ class Base(SubstitutionEnvironment):
|
||||||
val = [val]
|
val = [val]
|
||||||
elif SCons.Util.is_Dict(val):
|
elif SCons.Util.is_Dict(val):
|
||||||
tmp = []
|
tmp = []
|
||||||
for i,j in val.iteritems():
|
for i,j in val.items():
|
||||||
if j is not None:
|
if j is not None:
|
||||||
tmp.append((i,j))
|
tmp.append((i,j))
|
||||||
else:
|
else:
|
||||||
|
@ -1771,7 +1771,7 @@ class Base(SubstitutionEnvironment):
|
||||||
return os.path.join(dir, new_prefix+name+new_suffix)
|
return os.path.join(dir, new_prefix+name+new_suffix)
|
||||||
|
|
||||||
def SetDefault(self, **kw):
|
def SetDefault(self, **kw):
|
||||||
for k in kw.keys():
|
for k in list(kw.keys()):
|
||||||
if k in self._dict:
|
if k in self._dict:
|
||||||
del kw[k]
|
del kw[k]
|
||||||
self.Replace(**kw)
|
self.Replace(**kw)
|
||||||
|
@ -1833,7 +1833,7 @@ class Base(SubstitutionEnvironment):
|
||||||
uniq = {}
|
uniq = {}
|
||||||
for executor in [n.get_executor() for n in nodes]:
|
for executor in [n.get_executor() for n in nodes]:
|
||||||
uniq[executor] = 1
|
uniq[executor] = 1
|
||||||
for executor in uniq.keys():
|
for executor in list(uniq.keys()):
|
||||||
executor.add_pre_action(action)
|
executor.add_pre_action(action)
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
|
@ -1843,7 +1843,7 @@ class Base(SubstitutionEnvironment):
|
||||||
uniq = {}
|
uniq = {}
|
||||||
for executor in [n.get_executor() for n in nodes]:
|
for executor in [n.get_executor() for n in nodes]:
|
||||||
uniq[executor] = 1
|
uniq[executor] = 1
|
||||||
for executor in uniq.keys():
|
for executor in list(uniq.keys()):
|
||||||
executor.add_post_action(action)
|
executor.add_post_action(action)
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
|
@ -1983,6 +1983,15 @@ class Base(SubstitutionEnvironment):
|
||||||
return result
|
return result
|
||||||
return self.fs.Dir(s, *args, **kw)
|
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):
|
def NoClean(self, *targets):
|
||||||
"""Tags a target so that it will not be cleaned by -c"""
|
"""Tags a target so that it will not be cleaned by -c"""
|
||||||
tlist = []
|
tlist = []
|
||||||
|
@ -2180,13 +2189,16 @@ class Base(SubstitutionEnvironment):
|
||||||
"""This function converts a string or list into a list of strings
|
"""This function converts a string or list into a list of strings
|
||||||
or Nodes. This makes things easier for users by allowing files to
|
or Nodes. This makes things easier for users by allowing files to
|
||||||
be specified as a white-space separated list to be split.
|
be specified as a white-space separated list to be split.
|
||||||
|
|
||||||
The input rules are:
|
The input rules are:
|
||||||
- A single string containing names separated by spaces. These will be
|
- A single string containing names separated by spaces. These will be
|
||||||
split apart at the spaces.
|
split apart at the spaces.
|
||||||
- A single Node instance
|
- A single Node instance
|
||||||
- A list containing either strings or Node instances. Any strings
|
- A list containing either strings or Node instances. Any strings
|
||||||
in the list are not split at spaces.
|
in the list are not split at spaces.
|
||||||
|
|
||||||
In all cases, the function returns a list of Nodes and strings."""
|
In all cases, the function returns a list of Nodes and strings."""
|
||||||
|
|
||||||
if SCons.Util.is_List(arg):
|
if SCons.Util.is_List(arg):
|
||||||
return list(map(self.subst, arg))
|
return list(map(self.subst, arg))
|
||||||
elif SCons.Util.is_String(arg):
|
elif SCons.Util.is_String(arg):
|
||||||
|
@ -2246,7 +2258,7 @@ class Base(SubstitutionEnvironment):
|
||||||
while (node != node.srcnode()):
|
while (node != node.srcnode()):
|
||||||
node = node.srcnode()
|
node = node.srcnode()
|
||||||
return node
|
return node
|
||||||
sources = map( final_source, sources );
|
sources = list(map( final_source, sources ));
|
||||||
# remove duplicates
|
# remove duplicates
|
||||||
return list(set(sources))
|
return list(set(sources))
|
||||||
|
|
||||||
|
@ -2368,19 +2380,21 @@ class OverrideEnvironment(Base):
|
||||||
|
|
||||||
Environment = 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):
|
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):
|
class _NoSubstitutionProxy(Environment):
|
||||||
def __init__(self, subject):
|
def __init__(self, subject):
|
||||||
self.__dict__['__subject'] = subject
|
self.__dict__['__subject'] = subject
|
||||||
|
@ -2389,7 +2403,7 @@ def NoSubstitutionProxy(subject):
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
return setattr(self.__dict__['__subject'], name, value)
|
return setattr(self.__dict__['__subject'], name, value)
|
||||||
def executor_to_lvars(self, kwdict):
|
def executor_to_lvars(self, kwdict):
|
||||||
if kwdict.has_key('executor'):
|
if 'executor' in kwdict:
|
||||||
kwdict['lvars'] = kwdict['executor'].get_lvars()
|
kwdict['lvars'] = kwdict['executor'].get_lvars()
|
||||||
del kwdict['executor']
|
del kwdict['executor']
|
||||||
else:
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -28,72 +28,74 @@ and user errors in SCons.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Errors.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Errors.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
|
import shutil
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
import exceptions
|
|
||||||
|
|
||||||
class BuildError(Exception):
|
class BuildError(Exception):
|
||||||
""" Errors occuring while building.
|
""" Errors occurring while building.
|
||||||
|
|
||||||
BuildError have the following attributes:
|
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
|
status : the return code of the action that caused the build error.
|
||||||
error. Must be set to a non-zero value even if the
|
Must be set to a non-zero value even if the build error is not due
|
||||||
build error is not due to an action returning a
|
to an action returning a non-zero returned code.
|
||||||
non-zero returned code.
|
|
||||||
|
|
||||||
exitstatus : SCons exit status due to this build error.
|
exitstatus : SCons exit status due to this build error.
|
||||||
Must be nonzero unless due to an explicit Exit()
|
Must be nonzero unless due to an explicit Exit()
|
||||||
call. Not always the same as status, since
|
call. Not always the same as status, since
|
||||||
actions return a status code that should be
|
actions return a status code that should be
|
||||||
respected, but SCons typically exits with 2
|
respected, but SCons typically exits with 2
|
||||||
irrespective of the return value of the failed
|
irrespective of the return value of the failed
|
||||||
action.
|
action.
|
||||||
|
|
||||||
filename : The name of the file or directory that caused the
|
filename : The name of the file or directory that caused the
|
||||||
build error. Set to None if no files are associated with
|
build error. Set to None if no files are associated with
|
||||||
this error. This might be different from the target
|
this error. This might be different from the target
|
||||||
being built. For example, failure to create the
|
being built. For example, failure to create the
|
||||||
directory in which the target file will appear. It
|
directory in which the target file will appear. It
|
||||||
can be None if the error is not due to a particular
|
can be None if the error is not due to a particular
|
||||||
filename.
|
filename.
|
||||||
|
|
||||||
exc_info : Info about exception that caused the build
|
exc_info : Info about exception that caused the build
|
||||||
error. Set to (None, None, None) if this build
|
error. Set to (None, None, None) if this build
|
||||||
error is not due to an exception.
|
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 occured while building this target node(s)
|
node : the error occured while building this target node(s)
|
||||||
|
|
||||||
executor : the executor that caused the build to fail (might
|
|
||||||
be None if the build failures is not due to the
|
|
||||||
executor failing)
|
|
||||||
|
|
||||||
action : the action that caused the build to fail (might be
|
|
||||||
None if the build failures is not due to the an
|
|
||||||
action failure)
|
|
||||||
|
|
||||||
command : the command line for the action that caused the
|
executor : the executor that caused the build to fail (might
|
||||||
build to fail (might be None if the build failures
|
be None if the build failures is not due to the
|
||||||
is not due to the an action failure)
|
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,
|
node=None, errstr="Unknown error", status=2, exitstatus=2,
|
||||||
filename=None, executor=None, action=None, command=None,
|
filename=None, executor=None, action=None, command=None,
|
||||||
exc_info=(None, None, 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.status = status
|
||||||
self.exitstatus = exitstatus
|
self.exitstatus = exitstatus
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
|
@ -104,7 +106,7 @@ class BuildError(Exception):
|
||||||
self.action = action
|
self.action = action
|
||||||
self.command = command
|
self.command = command
|
||||||
|
|
||||||
Exception.__init__(self, node, errstr, status, exitstatus, filename,
|
Exception.__init__(self, node, errstr, status, exitstatus, filename,
|
||||||
executor, action, command, exc_info)
|
executor, action, command, exc_info)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -139,13 +141,17 @@ def convert_to_BuildError(status, exc_info=None):
|
||||||
"""
|
"""
|
||||||
Convert any return code a BuildError Exception.
|
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
|
The buildError.status we set here will normally be
|
||||||
used as the exit status of the "scons" process.
|
used as the exit status of the "scons" process.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not exc_info and isinstance(status, Exception):
|
if not exc_info and isinstance(status, Exception):
|
||||||
exc_info = (status.__class__, status, None)
|
exc_info = (status.__class__, status, None)
|
||||||
|
|
||||||
|
|
||||||
if isinstance(status, BuildError):
|
if isinstance(status, BuildError):
|
||||||
buildError = status
|
buildError = status
|
||||||
buildError.exitstatus = 2 # always exit with 2 on build errors
|
buildError.exitstatus = 2 # always exit with 2 on build errors
|
||||||
|
@ -163,14 +169,32 @@ def convert_to_BuildError(status, exc_info=None):
|
||||||
status=2,
|
status=2,
|
||||||
exitstatus=2,
|
exitstatus=2,
|
||||||
exc_info=exc_info)
|
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.
|
# If an IOError/OSError happens, raise a BuildError.
|
||||||
# Report the name of the file or directory that caused the
|
# Report the name of the file or directory that caused the
|
||||||
# error, which might be different from the target being built
|
# error, which might be different from the target being built
|
||||||
# (for example, failure to create the directory in which the
|
# (for example, failure to create the directory in which the
|
||||||
# target file will appear).
|
# target file will appear).
|
||||||
try: filename = status.filename
|
try:
|
||||||
except AttributeError: filename = None
|
filename = status.filename
|
||||||
|
except AttributeError:
|
||||||
|
filename = None
|
||||||
|
|
||||||
buildError = BuildError(
|
buildError = BuildError(
|
||||||
errstr=status.strerror,
|
errstr=status.strerror,
|
||||||
status=status.errno,
|
status=status.errno,
|
||||||
|
@ -195,7 +219,7 @@ def convert_to_BuildError(status, exc_info=None):
|
||||||
exitstatus=2)
|
exitstatus=2)
|
||||||
|
|
||||||
#import sys
|
#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
|
return buildError
|
||||||
|
|
||||||
# Local Variables:
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -26,8 +26,9 @@ Nodes.
|
||||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Executor.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Executor.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ import SCons.Debug
|
||||||
from SCons.Debug import logInstanceCreation
|
from SCons.Debug import logInstanceCreation
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
import SCons.Memoize
|
import SCons.Memoize
|
||||||
|
from SCons.compat import with_metaclass, NoSlotsPyPy
|
||||||
|
|
||||||
class Batch(object):
|
class Batch(object):
|
||||||
"""Remembers exact association between targets
|
"""Remembers exact association between targets
|
||||||
|
@ -154,7 +155,7 @@ _execute_str_map = {0 : execute_null_str,
|
||||||
1 : execute_actions_str}
|
1 : execute_actions_str}
|
||||||
|
|
||||||
|
|
||||||
class Executor(object):
|
class Executor(object, with_metaclass(NoSlotsPyPy)):
|
||||||
"""A class for controlling instances of executing an action.
|
"""A class for controlling instances of executing an action.
|
||||||
|
|
||||||
This largely exists to hold a single association of an action,
|
This largely exists to hold a single association of an action,
|
||||||
|
@ -455,10 +456,16 @@ class Executor(object):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
env = self.get_build_env()
|
env = self.get_build_env()
|
||||||
result = "".join([action.get_contents(self.get_all_targets(),
|
|
||||||
self.get_all_sources(),
|
action_list = self.get_action_list()
|
||||||
env)
|
all_targets = self.get_all_targets()
|
||||||
for action in self.get_action_list()])
|
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
|
self._memo['get_contents'] = result
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -580,7 +587,7 @@ def get_NullEnvironment():
|
||||||
nullenv = NullEnvironment()
|
nullenv = NullEnvironment()
|
||||||
return nullenv
|
return nullenv
|
||||||
|
|
||||||
class Null(object):
|
class Null(object, with_metaclass(NoSlotsPyPy)):
|
||||||
"""A null Executor, with a null build Environment, that does
|
"""A null Executor, with a null build Environment, that does
|
||||||
nothing when the rest of the methods call it.
|
nothing when the rest of the methods call it.
|
||||||
|
|
|
@ -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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -29,7 +29,7 @@ stop, and wait on jobs.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Job.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Job.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.compat
|
import SCons.compat
|
||||||
|
|
||||||
|
@ -278,14 +278,14 @@ else:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
prev_size = threading.stack_size(stack_size*1024)
|
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
|
# Only print a warning if the stack size has been
|
||||||
# explicitly set.
|
# explicitly set.
|
||||||
if not explicit_stack_size is None:
|
if not explicit_stack_size is None:
|
||||||
msg = "Setting stack size is unsupported by this version of Python:\n " + \
|
msg = "Setting stack size is unsupported by this version of Python:\n " + \
|
||||||
e.args[0]
|
e.args[0]
|
||||||
SCons.Warnings.warn(SCons.Warnings.StackSizeWarning, msg)
|
SCons.Warnings.warn(SCons.Warnings.StackSizeWarning, msg)
|
||||||
except ValueError, e:
|
except ValueError as e:
|
||||||
msg = "Setting stack size failed:\n " + str(e)
|
msg = "Setting stack size failed:\n " + str(e)
|
||||||
SCons.Warnings.warn(SCons.Warnings.StackSizeWarning, msg)
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -20,8 +20,9 @@
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Memoize.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Memoize.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
__doc__ = """Memoizer
|
__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.
|
dictionary named "_memo" to store the cached values.
|
||||||
|
|
||||||
Here is an example of wrapping a method that returns a computed value,
|
Here is an example of wrapping a method that returns a computed value,
|
||||||
with no input parameters:
|
with no input parameters::
|
||||||
|
|
||||||
@SCons.Memoize.CountMethodCall
|
@SCons.Memoize.CountMethodCall
|
||||||
def foo(self):
|
def foo(self):
|
||||||
|
@ -50,7 +51,7 @@ with no input parameters:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
Here is an example of wrapping a method that will return different values
|
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
|
def _bar_key(self, argument): # Memoization
|
||||||
return argument # Memoization
|
return argument # Memoization
|
||||||
|
@ -123,13 +124,12 @@ class Counter(object):
|
||||||
def key(self):
|
def key(self):
|
||||||
return self.cls_name+'.'+self.method_name
|
return self.cls_name+'.'+self.method_name
|
||||||
def display(self):
|
def display(self):
|
||||||
fmt = " %7d hits %7d misses %s()"
|
print(" {:7d} hits {:7d} misses {}()".format(self.hit, self.miss, self.key()))
|
||||||
print fmt % (self.hit, self.miss, self.key())
|
def __eq__(self, other):
|
||||||
def __cmp__(self, other):
|
|
||||||
try:
|
try:
|
||||||
return cmp(self.key(), other.key())
|
return self.key() == other.key()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return 0
|
return True
|
||||||
|
|
||||||
class CountValue(Counter):
|
class CountValue(Counter):
|
||||||
"""
|
"""
|
||||||
|
@ -185,7 +185,7 @@ def Dump(title=None):
|
||||||
collected so far.
|
collected so far.
|
||||||
"""
|
"""
|
||||||
if title:
|
if title:
|
||||||
print title
|
print(title)
|
||||||
for counter in sorted(CounterList):
|
for counter in sorted(CounterList):
|
||||||
CounterList[counter].display()
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,7 +30,7 @@ This creates a hash of global Aliases (dummy targets).
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Node/Alias.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Node/Alias.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import collections
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,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
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Node/FS.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Node/FS.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import fnmatch
|
import fnmatch
|
||||||
import os
|
import os
|
||||||
|
@ -122,7 +123,7 @@ def save_strings(val):
|
||||||
# tells us whether or not os.path.splitdrive() actually does anything
|
# tells us whether or not os.path.splitdrive() actually does anything
|
||||||
# on this system, and therefore whether we need to bother calling it
|
# on this system, and therefore whether we need to bother calling it
|
||||||
# when looking up path names in various methods below.
|
# when looking up path names in various methods below.
|
||||||
#
|
#
|
||||||
|
|
||||||
do_splitdrive = None
|
do_splitdrive = None
|
||||||
_my_splitdrive =None
|
_my_splitdrive =None
|
||||||
|
@ -157,7 +158,7 @@ def initialize_do_splitdrive():
|
||||||
global OS_SEP
|
global OS_SEP
|
||||||
global UNC_PREFIX
|
global UNC_PREFIX
|
||||||
global os_sep_is_slash
|
global os_sep_is_slash
|
||||||
|
|
||||||
OS_SEP = os.sep
|
OS_SEP = os.sep
|
||||||
UNC_PREFIX = OS_SEP + OS_SEP
|
UNC_PREFIX = OS_SEP + OS_SEP
|
||||||
os_sep_is_slash = 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'
|
# b) The path starts with '..'. E.g. '../' or '../moredirs'
|
||||||
# but we not match '..abc/'.
|
# but we not match '..abc/'.
|
||||||
# c) The path ends with '..'. E.g. '/..' or 'dirs/..'
|
# 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
|
# E.g. dirs/../moredirs
|
||||||
|
|
||||||
(.*/)?\.\.(?:/|$) |
|
(.*/)?\.\.(?:/|$) |
|
||||||
|
@ -200,7 +201,7 @@ needs_normpath_check = re.compile(
|
||||||
|
|
||||||
\./|.*/\.(?:/|$)
|
\./|.*/\.(?:/|$)
|
||||||
|
|
||||||
''',
|
''',
|
||||||
re.VERBOSE
|
re.VERBOSE
|
||||||
)
|
)
|
||||||
needs_normpath_match = needs_normpath_check.match
|
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)...
|
# 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):
|
def _hardlink_func(fs, src, dst):
|
||||||
# If the source is a symlink, we can't just hard-link to it
|
# If the source is a symlink, we can't just hard-link to it
|
||||||
# because a relative symlink may point somewhere completely
|
# because a relative symlink may point somewhere completely
|
||||||
|
@ -235,7 +241,7 @@ if hasattr(os, 'link'):
|
||||||
else:
|
else:
|
||||||
_hardlink_func = None
|
_hardlink_func = None
|
||||||
|
|
||||||
if hasattr(os, 'symlink'):
|
if hasattr(os, 'symlink') and sys.platform != 'win32':
|
||||||
def _softlink_func(fs, src, dst):
|
def _softlink_func(fs, src, dst):
|
||||||
fs.symlink(src, dst)
|
fs.symlink(src, dst)
|
||||||
else:
|
else:
|
||||||
|
@ -350,33 +356,6 @@ class _Null(object):
|
||||||
|
|
||||||
_null = _Null()
|
_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.
|
# Cygwin's os.path.normcase pretends it's on a case-sensitive filesystem.
|
||||||
_is_cygwin = sys.platform == "cygwin"
|
_is_cygwin = sys.platform == "cygwin"
|
||||||
if os.path.normcase("TeSt") == os.path.normpath("TeSt") and not _is_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):
|
def ignore_diskcheck_match(node, predicate, errorfmt):
|
||||||
pass
|
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_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 = [
|
diskcheckers = [
|
||||||
diskcheck_match,
|
diskcheck_match,
|
||||||
diskcheck_rcs,
|
|
||||||
diskcheck_sccs,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
def set_diskcheck(list):
|
def set_diskcheck(list):
|
||||||
|
@ -476,6 +421,11 @@ class EntryProxy(SCons.Util.Proxy):
|
||||||
|
|
||||||
__str__ = SCons.Util.Delegate('__str__')
|
__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):
|
def __get_abspath(self):
|
||||||
entry = self.get()
|
entry = self.get()
|
||||||
return SCons.Subst.SpecialAttrWrapper(entry.get_abspath(),
|
return SCons.Subst.SpecialAttrWrapper(entry.get_abspath(),
|
||||||
|
@ -564,7 +514,7 @@ class EntryProxy(SCons.Util.Proxy):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
attr = SCons.Util.Proxy.__getattr__(self, name)
|
attr = SCons.Util.Proxy.__getattr__(self, name)
|
||||||
except AttributeError, e:
|
except AttributeError as e:
|
||||||
# Raise our own AttributeError subclass with an
|
# Raise our own AttributeError subclass with an
|
||||||
# overridden __str__() method that identifies the
|
# overridden __str__() method that identifies the
|
||||||
# name of the entry that caused the exception.
|
# name of the entry that caused the exception.
|
||||||
|
@ -573,6 +523,7 @@ class EntryProxy(SCons.Util.Proxy):
|
||||||
else:
|
else:
|
||||||
return attr_function(self)
|
return attr_function(self)
|
||||||
|
|
||||||
|
|
||||||
class Base(SCons.Node.Node):
|
class Base(SCons.Node.Node):
|
||||||
"""A generic class for file system entries. This class is for
|
"""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
|
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
|
our relative and absolute paths, identify our parent
|
||||||
directory, and indicate that this node should use
|
directory, and indicate that this node should use
|
||||||
signatures."""
|
signatures."""
|
||||||
|
|
||||||
if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.Base')
|
if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.Base')
|
||||||
SCons.Node.Node.__init__(self)
|
SCons.Node.Node.__init__(self)
|
||||||
|
|
||||||
# Filenames and paths are probably reused and are intern'ed to
|
# Filenames and paths are probably reused and are intern'ed to save some memory.
|
||||||
# save some memory.
|
# 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.name = SCons.Util.silent_intern(name)
|
||||||
self.fs = fs #: Reference to parent Node.FS object
|
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.
|
single variables lazily when required, in order to save memory.
|
||||||
The redirection to the getters lets older Tools and
|
The redirection to the getters lets older Tools and
|
||||||
SConstruct continue to work without any additional changes,
|
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
|
Note, that __getattr__ is only called as fallback when the
|
||||||
requested attribute can't be found, so there should be no
|
requested attribute can't be found, so there should be no
|
||||||
speed performance penalty involved for standard builds.
|
speed performance penalty involved for standard builds.
|
||||||
"""
|
"""
|
||||||
if attr in node_bwcomp:
|
if attr in node_bwcomp:
|
||||||
return node_bwcomp[attr](self)
|
return node_bwcomp[attr](self)
|
||||||
|
|
||||||
raise AttributeError("%r object has no attribute %r" %
|
raise AttributeError("%r object has no attribute %r" %
|
||||||
(self.__class__, attr))
|
(self.__class__, attr))
|
||||||
|
|
||||||
|
@ -689,13 +639,17 @@ class Base(SCons.Node.Node):
|
||||||
return self._save_str()
|
return self._save_str()
|
||||||
return self._get_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
|
@SCons.Memoize.CountMethodCall
|
||||||
def _save_str(self):
|
def _save_str(self):
|
||||||
try:
|
try:
|
||||||
return self._memo['_save_str']
|
return self._memo['_save_str']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
result = sys.intern(self._get_str())
|
result = SCons.Util.silent_intern(self._get_str())
|
||||||
self._memo['_save_str'] = result
|
self._memo['_save_str'] = result
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -799,7 +753,7 @@ class Base(SCons.Node.Node):
|
||||||
path_elems = self.get_path_elements()
|
path_elems = self.get_path_elements()
|
||||||
pathname = ''
|
pathname = ''
|
||||||
try: i = path_elems.index(dir)
|
try: i = path_elems.index(dir)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
for p in path_elems[:-1]:
|
for p in path_elems[:-1]:
|
||||||
pathname += p.dirname
|
pathname += p.dirname
|
||||||
else:
|
else:
|
||||||
|
@ -840,13 +794,13 @@ class Base(SCons.Node.Node):
|
||||||
return self.name
|
return self.name
|
||||||
else:
|
else:
|
||||||
return self.dir.entry_path(self.name)
|
return self.dir.entry_path(self.name)
|
||||||
|
|
||||||
def get_tpath(self):
|
def get_tpath(self):
|
||||||
if self.dir._tpath == '.':
|
if self.dir._tpath == '.':
|
||||||
return self.name
|
return self.name
|
||||||
else:
|
else:
|
||||||
return self.dir.entry_tpath(self.name)
|
return self.dir.entry_tpath(self.name)
|
||||||
|
|
||||||
def get_path_elements(self):
|
def get_path_elements(self):
|
||||||
return self.dir._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):
|
def _glob1(self, pattern, ondisk=True, source=False, strings=False):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
# Dict that provides a simple backward compatibility
|
# Dict that provides a simple backward compatibility
|
||||||
# layer for the Node attributes 'abspath', 'labspath',
|
# layer for the Node attributes 'abspath', 'labspath',
|
||||||
# 'path', 'tpath' and 'path_elements'.
|
# 'path', 'tpath' and 'path_elements'.
|
||||||
|
@ -971,15 +925,13 @@ class Entry(Base):
|
||||||
'root',
|
'root',
|
||||||
'dirname',
|
'dirname',
|
||||||
'on_disk_entries',
|
'on_disk_entries',
|
||||||
'sccs_dir',
|
|
||||||
'rcs_dir',
|
|
||||||
'released_target_info',
|
'released_target_info',
|
||||||
'contentsig']
|
'contentsig']
|
||||||
|
|
||||||
def __init__(self, name, directory, fs):
|
def __init__(self, name, directory, fs):
|
||||||
Base.__init__(self, name, directory, fs)
|
Base.__init__(self, name, directory, fs)
|
||||||
self._func_exists = 3
|
self._func_exists = 3
|
||||||
self._func_get_contents = 1
|
self._func_get_contents = 1
|
||||||
|
|
||||||
def diskcheck_match(self):
|
def diskcheck_match(self):
|
||||||
pass
|
pass
|
||||||
|
@ -1198,7 +1150,7 @@ class FS(LocalFS):
|
||||||
|
|
||||||
DirNodeInfo.fs = self
|
DirNodeInfo.fs = self
|
||||||
FileNodeInfo.fs = self
|
FileNodeInfo.fs = self
|
||||||
|
|
||||||
def set_SConstruct_dir(self, dir):
|
def set_SConstruct_dir(self, dir):
|
||||||
self.SConstruct_dir = dir
|
self.SConstruct_dir = dir
|
||||||
|
|
||||||
|
@ -1210,9 +1162,9 @@ class FS(LocalFS):
|
||||||
|
|
||||||
def getcwd(self):
|
def getcwd(self):
|
||||||
if hasattr(self, "_cwd"):
|
if hasattr(self, "_cwd"):
|
||||||
return self._cwd
|
return self._cwd
|
||||||
else:
|
else:
|
||||||
return "<no cwd>"
|
return "<no cwd>"
|
||||||
|
|
||||||
def chdir(self, dir, change_os_dir=0):
|
def chdir(self, dir, change_os_dir=0):
|
||||||
"""Change the current working directory for lookups.
|
"""Change the current working directory for lookups.
|
||||||
|
@ -1310,7 +1262,7 @@ class FS(LocalFS):
|
||||||
p = p.strip('/')
|
p = p.strip('/')
|
||||||
|
|
||||||
needs_normpath = needs_normpath_match(p)
|
needs_normpath = needs_normpath_match(p)
|
||||||
|
|
||||||
# The path is relative to the top-level SCons directory.
|
# The path is relative to the top-level SCons directory.
|
||||||
if p in ('', '.'):
|
if p in ('', '.'):
|
||||||
p = directory.get_labspath()
|
p = directory.get_labspath()
|
||||||
|
@ -1437,6 +1389,35 @@ class FS(LocalFS):
|
||||||
if not isinstance(d, SCons.Node.Node):
|
if not isinstance(d, SCons.Node.Node):
|
||||||
d = self.Dir(d)
|
d = self.Dir(d)
|
||||||
self.Top.addRepository(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):
|
def variant_dir_target_climb(self, orig, dir, tail):
|
||||||
"""Create targets in corresponding variant directories
|
"""Create targets in corresponding variant directories
|
||||||
|
@ -1469,7 +1450,7 @@ class FS(LocalFS):
|
||||||
"""
|
"""
|
||||||
Globs
|
Globs
|
||||||
|
|
||||||
This is mainly a shim layer
|
This is mainly a shim layer
|
||||||
"""
|
"""
|
||||||
if cwd is None:
|
if cwd is None:
|
||||||
cwd = self.getcwd()
|
cwd = self.getcwd()
|
||||||
|
@ -1518,8 +1499,6 @@ class Dir(Base):
|
||||||
'root',
|
'root',
|
||||||
'dirname',
|
'dirname',
|
||||||
'on_disk_entries',
|
'on_disk_entries',
|
||||||
'sccs_dir',
|
|
||||||
'rcs_dir',
|
|
||||||
'released_target_info',
|
'released_target_info',
|
||||||
'contentsig']
|
'contentsig']
|
||||||
|
|
||||||
|
@ -1555,7 +1534,7 @@ class Dir(Base):
|
||||||
self._func_sconsign = 1
|
self._func_sconsign = 1
|
||||||
self._func_exists = 2
|
self._func_exists = 2
|
||||||
self._func_get_contents = 2
|
self._func_get_contents = 2
|
||||||
|
|
||||||
self._abspath = SCons.Util.silent_intern(self.dir.entry_abspath(self.name))
|
self._abspath = SCons.Util.silent_intern(self.dir.entry_abspath(self.name))
|
||||||
self._labspath = SCons.Util.silent_intern(self.dir.entry_labspath(self.name))
|
self._labspath = SCons.Util.silent_intern(self.dir.entry_labspath(self.name))
|
||||||
if self.dir._path == '.':
|
if self.dir._path == '.':
|
||||||
|
@ -1594,7 +1573,7 @@ class Dir(Base):
|
||||||
# Prepend MkdirBuilder action to existing action list
|
# Prepend MkdirBuilder action to existing action list
|
||||||
l = self.get_executor().action_list
|
l = self.get_executor().action_list
|
||||||
a = get_MkdirBuilder().action
|
a = get_MkdirBuilder().action
|
||||||
l.insert(0, a)
|
l.insert(0, a)
|
||||||
self.get_executor().set_action_list(l)
|
self.get_executor().set_action_list(l)
|
||||||
|
|
||||||
def diskcheck_match(self):
|
def diskcheck_match(self):
|
||||||
|
@ -1606,7 +1585,7 @@ class Dir(Base):
|
||||||
This clears any cached information that is invalidated by changing
|
This clears any cached information that is invalidated by changing
|
||||||
the repository."""
|
the repository."""
|
||||||
|
|
||||||
for node in self.entries.values():
|
for node in list(self.entries.values()):
|
||||||
if node != self.dir:
|
if node != self.dir:
|
||||||
if node != self and isinstance(node, Dir):
|
if node != self and isinstance(node, Dir):
|
||||||
node.__clearRepositoryCache(duplicate)
|
node.__clearRepositoryCache(duplicate)
|
||||||
|
@ -1742,7 +1721,7 @@ class Dir(Base):
|
||||||
|
|
||||||
path_elems = ['..'] * (len(self._path_elements) - i) \
|
path_elems = ['..'] * (len(self._path_elements) - i) \
|
||||||
+ [n.name for n in other._path_elements[i:]]
|
+ [n.name for n in other._path_elements[i:]]
|
||||||
|
|
||||||
result = OS_SEP.join(path_elems)
|
result = OS_SEP.join(path_elems)
|
||||||
|
|
||||||
memo_dict[other] = result
|
memo_dict[other] = result
|
||||||
|
@ -1913,10 +1892,10 @@ class Dir(Base):
|
||||||
|
|
||||||
def get_internal_path(self):
|
def get_internal_path(self):
|
||||||
return self._path
|
return self._path
|
||||||
|
|
||||||
def get_tpath(self):
|
def get_tpath(self):
|
||||||
return self._tpath
|
return self._tpath
|
||||||
|
|
||||||
def get_path_elements(self):
|
def get_path_elements(self):
|
||||||
return self._path_elements
|
return self._path_elements
|
||||||
|
|
||||||
|
@ -1936,7 +1915,7 @@ class Dir(Base):
|
||||||
""" Searches through the file/dir entries of the current
|
""" Searches through the file/dir entries of the current
|
||||||
directory, and returns True if a physical entry with the given
|
directory, and returns True if a physical entry with the given
|
||||||
name could be found.
|
name could be found.
|
||||||
|
|
||||||
@see rentry_exists_on_disk
|
@see rentry_exists_on_disk
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
@ -1970,10 +1949,10 @@ class Dir(Base):
|
||||||
The local directory (self) gets searched first, so
|
The local directory (self) gets searched first, so
|
||||||
repositories take a lower precedence regarding the
|
repositories take a lower precedence regarding the
|
||||||
searching order.
|
searching order.
|
||||||
|
|
||||||
@see entry_exists_on_disk
|
@see entry_exists_on_disk
|
||||||
"""
|
"""
|
||||||
|
|
||||||
rentry_exists = self.entry_exists_on_disk(name)
|
rentry_exists = self.entry_exists_on_disk(name)
|
||||||
if not rentry_exists:
|
if not rentry_exists:
|
||||||
# Search through the repository folders
|
# Search through the repository folders
|
||||||
|
@ -2085,9 +2064,7 @@ class Dir(Base):
|
||||||
return node
|
return node
|
||||||
|
|
||||||
def file_on_disk(self, name):
|
def file_on_disk(self, name):
|
||||||
if self.entry_exists_on_disk(name) or \
|
if self.entry_exists_on_disk(name):
|
||||||
diskcheck_rcs(self, name) or \
|
|
||||||
diskcheck_sccs(self, name):
|
|
||||||
try: return self.File(name)
|
try: return self.File(name)
|
||||||
except TypeError: pass
|
except TypeError: pass
|
||||||
node = self.srcdir_duplicate(name)
|
node = self.srcdir_duplicate(name)
|
||||||
|
@ -2178,7 +2155,7 @@ class Dir(Base):
|
||||||
for x in excludeList:
|
for x in excludeList:
|
||||||
r = self.glob(x, ondisk, source, strings)
|
r = self.glob(x, ondisk, source, strings)
|
||||||
excludes.extend(r)
|
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))
|
return sorted(result, key=lambda a: str(a))
|
||||||
|
|
||||||
def _glob1(self, pattern, ondisk=True, source=False, strings=False):
|
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
|
add a separator when creating the path names of entries within
|
||||||
this directory.
|
this directory.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ['_lookupDict']
|
__slots__ = ['_lookupDict']
|
||||||
|
|
||||||
def __init__(self, drive, fs):
|
def __init__(self, drive, fs):
|
||||||
if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.RootDir')
|
if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.RootDir')
|
||||||
SCons.Node.Node.__init__(self)
|
SCons.Node.Node.__init__(self)
|
||||||
|
@ -2266,7 +2243,7 @@ class RootDir(Dir):
|
||||||
# Handle all the types of drives:
|
# Handle all the types of drives:
|
||||||
if drive == '':
|
if drive == '':
|
||||||
# No drive, regular UNIX root or Windows default drive.
|
# No drive, regular UNIX root or Windows default drive.
|
||||||
name = OS_SEP
|
name = OS_SEP
|
||||||
dirname = OS_SEP
|
dirname = OS_SEP
|
||||||
elif drive == '//':
|
elif drive == '//':
|
||||||
# UNC path
|
# UNC path
|
||||||
|
@ -2277,8 +2254,8 @@ class RootDir(Dir):
|
||||||
name = drive
|
name = drive
|
||||||
dirname = drive + OS_SEP
|
dirname = drive + OS_SEP
|
||||||
|
|
||||||
#: Filename with extension as it was specified when the object was
|
# Filename with extension as it was specified when the object was
|
||||||
#: created; to obtain filesystem path, use Python str() function
|
# created; to obtain filesystem path, use Python str() function
|
||||||
self.name = SCons.Util.silent_intern(name)
|
self.name = SCons.Util.silent_intern(name)
|
||||||
self.fs = fs #: Reference to parent Node.FS object
|
self.fs = fs #: Reference to parent Node.FS object
|
||||||
|
|
||||||
|
@ -2336,7 +2313,7 @@ class RootDir(Dir):
|
||||||
self._func_sconsign = 1
|
self._func_sconsign = 1
|
||||||
self._func_exists = 2
|
self._func_exists = 2
|
||||||
self._func_get_contents = 2
|
self._func_get_contents = 2
|
||||||
|
|
||||||
# Don't just reset the executor, replace its action list,
|
# Don't just reset the executor, replace its action list,
|
||||||
# because it might have some pre-or post-actions that need to
|
# because it might have some pre-or post-actions that need to
|
||||||
# be preserved.
|
# be preserved.
|
||||||
|
@ -2352,9 +2329,9 @@ class RootDir(Dir):
|
||||||
# Prepend MkdirBuilder action to existing action list
|
# Prepend MkdirBuilder action to existing action list
|
||||||
l = self.get_executor().action_list
|
l = self.get_executor().action_list
|
||||||
a = get_MkdirBuilder().action
|
a = get_MkdirBuilder().action
|
||||||
l.insert(0, a)
|
l.insert(0, a)
|
||||||
self.get_executor().set_action_list(l)
|
self.get_executor().set_action_list(l)
|
||||||
|
|
||||||
|
|
||||||
def must_be_same(self, klass):
|
def must_be_same(self, klass):
|
||||||
if klass is Dir:
|
if klass is Dir:
|
||||||
|
@ -2433,6 +2410,7 @@ class RootDir(Dir):
|
||||||
def src_builder(self):
|
def src_builder(self):
|
||||||
return _null
|
return _null
|
||||||
|
|
||||||
|
|
||||||
class FileNodeInfo(SCons.Node.NodeInfoBase):
|
class FileNodeInfo(SCons.Node.NodeInfoBase):
|
||||||
__slots__ = ('csig', 'timestamp', 'size')
|
__slots__ = ('csig', 'timestamp', 'size')
|
||||||
current_version_id = 2
|
current_version_id = 2
|
||||||
|
@ -2484,6 +2462,7 @@ class FileNodeInfo(SCons.Node.NodeInfoBase):
|
||||||
if key not in ('__weakref__',):
|
if key not in ('__weakref__',):
|
||||||
setattr(self, key, value)
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
|
||||||
class FileBuildInfo(SCons.Node.BuildInfoBase):
|
class FileBuildInfo(SCons.Node.BuildInfoBase):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
current_version_id = 2
|
current_version_id = 2
|
||||||
|
@ -2514,6 +2493,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
setattr(self, attr, list(map(node_to_str, val)))
|
setattr(self, attr, list(map(node_to_str, val)))
|
||||||
|
|
||||||
def convert_from_sconsign(self, dir, name):
|
def convert_from_sconsign(self, dir, name):
|
||||||
"""
|
"""
|
||||||
Converts a newly-read FileBuildInfo object for in-SCons use
|
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.
|
perform--but we're leaving this method here to make that clear.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def prepare_dependencies(self):
|
def prepare_dependencies(self):
|
||||||
"""
|
"""
|
||||||
Prepares a FileBuildInfo object for explaining what changed
|
Prepares a FileBuildInfo object for explaining what changed
|
||||||
|
@ -2550,6 +2531,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
|
||||||
s = ni.str_to_node(s)
|
s = ni.str_to_node(s)
|
||||||
nodes.append(s)
|
nodes.append(s)
|
||||||
setattr(self, nattr, nodes)
|
setattr(self, nattr, nodes)
|
||||||
|
|
||||||
def format(self, names=0):
|
def format(self, names=0):
|
||||||
result = []
|
result = []
|
||||||
bkids = self.bsources + self.bdepends + self.bimplicit
|
bkids = self.bsources + self.bdepends + self.bimplicit
|
||||||
|
@ -2562,6 +2544,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
|
||||||
result.append('%s [%s]' % (self.bactsig, self.bact))
|
result.append('%s [%s]' % (self.bactsig, self.bact))
|
||||||
return '\n'.join(result)
|
return '\n'.join(result)
|
||||||
|
|
||||||
|
|
||||||
class File(Base):
|
class File(Base):
|
||||||
"""A class for files in a file system.
|
"""A class for files in a file system.
|
||||||
"""
|
"""
|
||||||
|
@ -2578,8 +2561,6 @@ class File(Base):
|
||||||
'root',
|
'root',
|
||||||
'dirname',
|
'dirname',
|
||||||
'on_disk_entries',
|
'on_disk_entries',
|
||||||
'sccs_dir',
|
|
||||||
'rcs_dir',
|
|
||||||
'released_target_info',
|
'released_target_info',
|
||||||
'contentsig']
|
'contentsig']
|
||||||
|
|
||||||
|
@ -2628,11 +2609,11 @@ class File(Base):
|
||||||
self.store_info = 1
|
self.store_info = 1
|
||||||
self._func_exists = 4
|
self._func_exists = 4
|
||||||
self._func_get_contents = 3
|
self._func_get_contents = 3
|
||||||
|
|
||||||
# Initialize this Node's decider function to decide_source() because
|
# Initialize this Node's decider function to decide_source() because
|
||||||
# every file is a source file until it has a Builder attached...
|
# every file is a source file until it has a Builder attached...
|
||||||
self.changed_since_last_build = 4
|
self.changed_since_last_build = 4
|
||||||
|
|
||||||
# If there was already a Builder set on this entry, then
|
# If there was already a Builder set on this entry, then
|
||||||
# we need to make sure we call the target-decider function,
|
# we need to make sure we call the target-decider function,
|
||||||
# not the source-decider. Reaching in and doing this by hand
|
# not the source-decider. Reaching in and doing this by hand
|
||||||
|
@ -2652,10 +2633,12 @@ class File(Base):
|
||||||
def get_contents(self):
|
def get_contents(self):
|
||||||
return SCons.Node._get_contents_map[self._func_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):
|
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()
|
contents = self.get_contents()
|
||||||
# The behavior of various decode() methods and functions
|
# The behavior of various decode() methods and functions
|
||||||
# w.r.t. the initial BOM bytes is different for different
|
# 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
|
# them, but has a 'utf-8-sig' which does; 'utf-16' seems to
|
||||||
# strip them; etc.) Just sidestep all the complication by
|
# strip them; etc.) Just sidestep all the complication by
|
||||||
# explicitly stripping the BOM before we decode().
|
# 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')
|
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')
|
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[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):
|
def get_content_hash(self):
|
||||||
"""
|
"""
|
||||||
|
@ -2681,12 +2671,12 @@ class File(Base):
|
||||||
try:
|
try:
|
||||||
cs = SCons.Util.MD5filesignature(fname,
|
cs = SCons.Util.MD5filesignature(fname,
|
||||||
chunksize=SCons.Node.FS.File.md5_chunksize*1024)
|
chunksize=SCons.Node.FS.File.md5_chunksize*1024)
|
||||||
except EnvironmentError, e:
|
except EnvironmentError as e:
|
||||||
if not e.filename:
|
if not e.filename:
|
||||||
e.filename = fname
|
e.filename = fname
|
||||||
raise
|
raise
|
||||||
return cs
|
return cs
|
||||||
|
|
||||||
@SCons.Memoize.CountMethodCall
|
@SCons.Memoize.CountMethodCall
|
||||||
def get_size(self):
|
def get_size(self):
|
||||||
try:
|
try:
|
||||||
|
@ -2960,30 +2950,30 @@ class File(Base):
|
||||||
def release_target_info(self):
|
def release_target_info(self):
|
||||||
"""Called just after this node has been marked
|
"""Called just after this node has been marked
|
||||||
up-to-date or was built completely.
|
up-to-date or was built completely.
|
||||||
|
|
||||||
This is where we try to release as many target node infos
|
This is where we try to release as many target node infos
|
||||||
as possible for clean builds and update runs, in order
|
as possible for clean builds and update runs, in order
|
||||||
to minimize the overall memory consumption.
|
to minimize the overall memory consumption.
|
||||||
|
|
||||||
We'd like to remove a lot more attributes like self.sources
|
We'd like to remove a lot more attributes like self.sources
|
||||||
and self.sources_set, but they might get used
|
and self.sources_set, but they might get used
|
||||||
in a next build step. For example, during configuration
|
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++)!
|
which linker to use for the resulting Program (gcc vs. g++)!
|
||||||
That's why we check for the 'keep_targetinfo' attribute,
|
That's why we check for the 'keep_targetinfo' attribute,
|
||||||
config Nodes and the Interactive mode just don't allow
|
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
|
In the same manner, we can't simply remove the self.attributes
|
||||||
here. The smart linking relies on the shared flag, and some
|
here. The smart linking relies on the shared flag, and some
|
||||||
parts of the java Tool use it to transport information
|
parts of the java Tool use it to transport information
|
||||||
about nodes...
|
about nodes...
|
||||||
|
|
||||||
@see: built() and Node.release_target_info()
|
@see: built() and Node.release_target_info()
|
||||||
"""
|
"""
|
||||||
if (self.released_target_info or SCons.Node.interactive):
|
if (self.released_target_info or SCons.Node.interactive):
|
||||||
return
|
return
|
||||||
|
|
||||||
if not hasattr(self.attributes, 'keep_targetinfo'):
|
if not hasattr(self.attributes, 'keep_targetinfo'):
|
||||||
# Cache some required values, before releasing
|
# Cache some required values, before releasing
|
||||||
# stuff like env, executor and builder...
|
# stuff like env, executor and builder...
|
||||||
|
@ -3014,12 +3004,7 @@ class File(Base):
|
||||||
return None
|
return None
|
||||||
scb = self.dir.src_builder()
|
scb = self.dir.src_builder()
|
||||||
if scb is _null:
|
if scb is _null:
|
||||||
if diskcheck_sccs(self.dir, self.name):
|
scb = None
|
||||||
scb = get_DefaultSCCSBuilder()
|
|
||||||
elif diskcheck_rcs(self.dir, self.name):
|
|
||||||
scb = get_DefaultRCSBuilder()
|
|
||||||
else:
|
|
||||||
scb = None
|
|
||||||
if scb is not None:
|
if scb is not None:
|
||||||
try:
|
try:
|
||||||
b = self.builder
|
b = self.builder
|
||||||
|
@ -3056,7 +3041,7 @@ class File(Base):
|
||||||
def _rmv_existing(self):
|
def _rmv_existing(self):
|
||||||
self.clear_memoized_values()
|
self.clear_memoized_values()
|
||||||
if SCons.Node.print_duplicate:
|
if SCons.Node.print_duplicate:
|
||||||
print "dup: removing existing target %s"%self
|
print("dup: removing existing target {}".format(self))
|
||||||
e = Unlink(self, [], None)
|
e = Unlink(self, [], None)
|
||||||
if isinstance(e, SCons.Errors.BuildError):
|
if isinstance(e, SCons.Errors.BuildError):
|
||||||
raise e
|
raise e
|
||||||
|
@ -3080,9 +3065,8 @@ class File(Base):
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
self._createDir()
|
self._createDir()
|
||||||
except SCons.Errors.StopError, drive:
|
except SCons.Errors.StopError as drive:
|
||||||
desc = "No drive `%s' for target `%s'." % (drive, self)
|
raise SCons.Errors.StopError("No drive `{}' for target `{}'.".format(drive, self))
|
||||||
raise SCons.Errors.StopError(desc)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -3098,12 +3082,11 @@ class File(Base):
|
||||||
def do_duplicate(self, src):
|
def do_duplicate(self, src):
|
||||||
self._createDir()
|
self._createDir()
|
||||||
if SCons.Node.print_duplicate:
|
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)
|
Unlink(self, None, None)
|
||||||
e = Link(self, src, None)
|
e = Link(self, src, None)
|
||||||
if isinstance(e, SCons.Errors.BuildError):
|
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("Cannot duplicate `{}' in `{}': {}.".format(src.get_internal_path(), self.dir._path, e.errstr))
|
||||||
raise SCons.Errors.StopError(desc)
|
|
||||||
self.linked = 1
|
self.linked = 1
|
||||||
# The Link() action may or may not have actually
|
# The Link() action may or may not have actually
|
||||||
# created the file, depending on whether the -n
|
# created the file, depending on whether the -n
|
||||||
|
@ -3117,7 +3100,6 @@ class File(Base):
|
||||||
return self._memo['exists']
|
return self._memo['exists']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
result = SCons.Node._exists_map[self._func_exists](self)
|
result = SCons.Node._exists_map[self._func_exists](self)
|
||||||
self._memo['exists'] = result
|
self._memo['exists'] = result
|
||||||
return result
|
return result
|
||||||
|
@ -3199,37 +3181,37 @@ class File(Base):
|
||||||
|
|
||||||
def built(self):
|
def built(self):
|
||||||
"""Called just after this File node is successfully built.
|
"""Called just after this File node is successfully built.
|
||||||
|
|
||||||
Just like for 'release_target_info' we try to release
|
Just like for 'release_target_info' we try to release
|
||||||
some more target node attributes in order to minimize the
|
some more target node attributes in order to minimize the
|
||||||
overall memory consumption.
|
overall memory consumption.
|
||||||
|
|
||||||
@see: release_target_info
|
@see: release_target_info
|
||||||
"""
|
"""
|
||||||
|
|
||||||
SCons.Node.Node.built(self)
|
SCons.Node.Node.built(self)
|
||||||
|
|
||||||
if (not SCons.Node.interactive and
|
if (not SCons.Node.interactive and
|
||||||
not hasattr(self.attributes, 'keep_targetinfo')):
|
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)
|
SCons.Node.store_info_map[self.store_info](self)
|
||||||
# ... then release some more variables.
|
# ... then release some more variables.
|
||||||
self._specific_sources = False
|
self._specific_sources = False
|
||||||
self._labspath = None
|
self._labspath = None
|
||||||
self._save_str()
|
self._save_str()
|
||||||
self.cwd = None
|
self.cwd = None
|
||||||
|
|
||||||
self.scanner_paths = None
|
self.scanner_paths = None
|
||||||
|
|
||||||
def changed(self, node=None, allowcache=False):
|
def changed(self, node=None, allowcache=False):
|
||||||
"""
|
"""
|
||||||
Returns if the node is up-to-date with respect to the BuildInfo
|
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(),
|
For File nodes this is basically a wrapper around Node.changed(),
|
||||||
but we allow the return value to get cached after the reference
|
but we allow the return value to get cached after the reference
|
||||||
to the Executor got released in release_target_info().
|
to the Executor got released in release_target_info().
|
||||||
|
|
||||||
@see: Node.changed()
|
@see: Node.changed()
|
||||||
"""
|
"""
|
||||||
if node is None:
|
if node is None:
|
||||||
|
@ -3237,7 +3219,7 @@ class File(Base):
|
||||||
return self._memo['changed']
|
return self._memo['changed']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
has_changed = SCons.Node.Node.changed(self, node)
|
has_changed = SCons.Node.Node.changed(self, node)
|
||||||
if allowcache:
|
if allowcache:
|
||||||
self._memo['changed'] = has_changed
|
self._memo['changed'] = has_changed
|
||||||
|
@ -3290,7 +3272,7 @@ class File(Base):
|
||||||
# ...and they'd like a local copy.
|
# ...and they'd like a local copy.
|
||||||
e = LocalCopy(self, r, None)
|
e = LocalCopy(self, r, None)
|
||||||
if isinstance(e, SCons.Errors.BuildError):
|
if isinstance(e, SCons.Errors.BuildError):
|
||||||
raise
|
raise
|
||||||
SCons.Node.store_info_map[self.store_info](self)
|
SCons.Node.store_info_map[self.store_info](self)
|
||||||
if T: Trace(' 1\n')
|
if T: Trace(' 1\n')
|
||||||
return 1
|
return 1
|
||||||
|
@ -3372,12 +3354,12 @@ class File(Base):
|
||||||
It computes and returns the signature for this
|
It computes and returns the signature for this
|
||||||
node's contents.
|
node's contents.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return self.contentsig
|
return self.contentsig
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
executor = self.get_executor()
|
executor = self.get_executor()
|
||||||
|
|
||||||
result = self.contentsig = SCons.Util.MD5signature(executor.get_contents())
|
result = self.contentsig = SCons.Util.MD5signature(executor.get_contents())
|
||||||
|
@ -3397,7 +3379,7 @@ class File(Base):
|
||||||
return self.cachesig
|
return self.cachesig
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Collect signatures for all children
|
# Collect signatures for all children
|
||||||
children = self.children()
|
children = self.children()
|
||||||
sigs = [n.get_cachedir_csig() for n in 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):
|
def _find_file_key(self, filename, paths, verbose=None):
|
||||||
return (filename, paths)
|
return (filename, paths)
|
||||||
|
|
||||||
@SCons.Memoize.CountDictCall(_find_file_key)
|
@SCons.Memoize.CountDictCall(_find_file_key)
|
||||||
def find_file(self, filename, paths, verbose=None):
|
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
|
Only the first file found is returned, and none is returned if no file is found.
|
||||||
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.
|
|
||||||
|
|
||||||
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
|
returns The node created from the found file.
|
||||||
that exists already.
|
|
||||||
|
|
||||||
Only the first file found is returned, and none is returned
|
|
||||||
if no file is found.
|
|
||||||
"""
|
"""
|
||||||
memo_key = self._find_file_key(filename, paths)
|
memo_key = self._find_file_key(filename, paths)
|
||||||
try:
|
try:
|
||||||
|
@ -3547,7 +3524,7 @@ def invalidate_node_memos(targets):
|
||||||
|
|
||||||
if not SCons.Util.is_List(targets):
|
if not SCons.Util.is_List(targets):
|
||||||
targets = [targets]
|
targets = [targets]
|
||||||
|
|
||||||
for entry in targets:
|
for entry in targets:
|
||||||
# If the target is a Node object, clear the cache. If it is a
|
# If the target is a Node object, clear the cache. If it is a
|
||||||
# filename, look up potentially existing Node object first.
|
# 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.
|
# do not correspond to an existing Node object.
|
||||||
node = get_default_fs().Entry(entry)
|
node = get_default_fs().Entry(entry)
|
||||||
if node:
|
if node:
|
||||||
node.clear_memoized_values()
|
node.clear_memoized_values()
|
||||||
|
|
||||||
# Local Variables:
|
# Local Variables:
|
||||||
# tab-width:4
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,7 +27,7 @@ Python nodes.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Node/Python.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Node/Python.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.Node
|
import SCons.Node
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ class ValueNodeInfo(SCons.Node.NodeInfoBase):
|
||||||
del state['__weakref__']
|
del state['__weakref__']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state):
|
||||||
|
@ -77,7 +77,7 @@ class ValueBuildInfo(SCons.Node.BuildInfoBase):
|
||||||
current_version_id = 2
|
current_version_id = 2
|
||||||
|
|
||||||
class Value(SCons.Node.Node):
|
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.
|
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
|
is_up_to_date = SCons.Node.Node.children_are_up_to_date
|
||||||
|
|
||||||
def is_under(self, dir):
|
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
|
# what directory scons was run from. Value nodes
|
||||||
# are outside the filesystem:
|
# are outside the filesystem:
|
||||||
return 1
|
return 1
|
||||||
|
@ -133,10 +133,17 @@ class Value(SCons.Node.Node):
|
||||||
###TODO: something reasonable about universal newlines
|
###TODO: something reasonable about universal newlines
|
||||||
contents = str(self.value)
|
contents = str(self.value)
|
||||||
for kid in self.children(None):
|
for kid in self.children(None):
|
||||||
contents = contents + kid.get_contents()
|
contents = contents + kid.get_contents().decode()
|
||||||
return contents
|
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):
|
def changed_since_last_build(self, target, prev_ni):
|
||||||
cur_csig = self.get_csig()
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -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
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Node/__init__.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Node/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import copy
|
import copy
|
||||||
|
@ -55,6 +57,8 @@ import SCons.Util
|
||||||
|
|
||||||
from SCons.Debug import Trace
|
from SCons.Debug import Trace
|
||||||
|
|
||||||
|
from SCons.compat import with_metaclass, NoSlotsPyPy
|
||||||
|
|
||||||
print_duplicate = 0
|
print_duplicate = 0
|
||||||
|
|
||||||
def classname(obj):
|
def classname(obj):
|
||||||
|
@ -151,7 +155,7 @@ def exists_file(node):
|
||||||
# The source file does not exist. Make sure no old
|
# The source file does not exist. Make sure no old
|
||||||
# copy remains in the variant directory.
|
# copy remains in the variant directory.
|
||||||
if print_duplicate:
|
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():
|
if exists_base(node) or node.islink():
|
||||||
node.fs.unlink(node.get_internal_path())
|
node.fs.unlink(node.get_internal_path())
|
||||||
# Return None explicitly because the Base.exists() call
|
# 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))
|
contents.append('%s %s\n' % (n.get_csig(), n.name))
|
||||||
return ''.join(contents)
|
return ''.join(contents)
|
||||||
|
|
||||||
def get_contents_file(node):
|
def get_contents_file(node):
|
||||||
if not node.rexists():
|
if not node.rexists():
|
||||||
return ''
|
return b''
|
||||||
fname = node.rfile().get_abspath()
|
fname = node.rfile().get_abspath()
|
||||||
try:
|
try:
|
||||||
contents = open(fname, "rb").read()
|
with open(fname, "rb") as fp:
|
||||||
except EnvironmentError, e:
|
contents = fp.read()
|
||||||
|
except EnvironmentError as e:
|
||||||
if not e.filename:
|
if not e.filename:
|
||||||
e.filename = fname
|
e.filename = fname
|
||||||
raise
|
raise
|
||||||
|
@ -345,6 +350,7 @@ class NodeInfoBase(object):
|
||||||
"""
|
"""
|
||||||
__slots__ = ('__weakref__',)
|
__slots__ = ('__weakref__',)
|
||||||
current_version_id = 2
|
current_version_id = 2
|
||||||
|
|
||||||
def update(self, node):
|
def update(self, node):
|
||||||
try:
|
try:
|
||||||
field_list = self.field_list
|
field_list = self.field_list
|
||||||
|
@ -361,8 +367,10 @@ class NodeInfoBase(object):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
setattr(self, f, func())
|
setattr(self, f, func())
|
||||||
|
|
||||||
def convert(self, node, val):
|
def convert(self, node, val):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def merge(self, other):
|
def merge(self, other):
|
||||||
"""
|
"""
|
||||||
Merge the fields of another object into this object. Already existing
|
Merge the fields of another object into this object. Already existing
|
||||||
|
@ -377,7 +385,7 @@ class NodeInfoBase(object):
|
||||||
try:
|
try:
|
||||||
field_list = self.field_list
|
field_list = self.field_list
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
field_list = getattr(self, '__dict__', {}).keys()
|
field_list = list(getattr(self, '__dict__', {}).keys())
|
||||||
for obj in type(self).mro():
|
for obj in type(self).mro():
|
||||||
for slot in getattr(obj, '__slots__', ()):
|
for slot in getattr(obj, '__slots__', ()):
|
||||||
if slot not in ('__weakref__', '__dict__'):
|
if slot not in ('__weakref__', '__dict__'):
|
||||||
|
@ -407,21 +415,21 @@ class NodeInfoBase(object):
|
||||||
for name in getattr(obj,'__slots__',()):
|
for name in getattr(obj,'__slots__',()):
|
||||||
if hasattr(self, name):
|
if hasattr(self, name):
|
||||||
state[name] = getattr(self, name)
|
state[name] = getattr(self, name)
|
||||||
|
|
||||||
state['_version_id'] = self.current_version_id
|
state['_version_id'] = self.current_version_id
|
||||||
try:
|
try:
|
||||||
del state['__weakref__']
|
del state['__weakref__']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
return state
|
return state
|
||||||
|
|
||||||
def __setstate__(self, state):
|
def __setstate__(self, state):
|
||||||
"""
|
"""
|
||||||
Restore the attributes from a pickled state. The version is discarded.
|
Restore the attributes from a pickled state. The version is discarded.
|
||||||
"""
|
"""
|
||||||
# TODO check or discard version
|
# TODO check or discard version
|
||||||
del state['_version_id']
|
del state['_version_id']
|
||||||
|
|
||||||
for key, value in state.items():
|
for key, value in state.items():
|
||||||
if key not in ('__weakref__',):
|
if key not in ('__weakref__',):
|
||||||
setattr(self, key, value)
|
setattr(self, key, value)
|
||||||
|
@ -440,6 +448,7 @@ class BuildInfoBase(object):
|
||||||
__slots__ = ("bsourcesigs", "bdependsigs", "bimplicitsigs", "bactsig",
|
__slots__ = ("bsourcesigs", "bdependsigs", "bimplicitsigs", "bactsig",
|
||||||
"bsources", "bdepends", "bact", "bimplicit", "__weakref__")
|
"bsources", "bdepends", "bact", "bimplicit", "__weakref__")
|
||||||
current_version_id = 2
|
current_version_id = 2
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Create an object attribute from the class attribute so it ends up
|
# Create an object attribute from the class attribute so it ends up
|
||||||
# in the pickled data in the .sconsign file.
|
# in the pickled data in the .sconsign file.
|
||||||
|
@ -447,6 +456,7 @@ class BuildInfoBase(object):
|
||||||
self.bdependsigs = []
|
self.bdependsigs = []
|
||||||
self.bimplicitsigs = []
|
self.bimplicitsigs = []
|
||||||
self.bactsig = None
|
self.bactsig = None
|
||||||
|
|
||||||
def merge(self, other):
|
def merge(self, other):
|
||||||
"""
|
"""
|
||||||
Merge the fields of another object into this object. Already existing
|
Merge the fields of another object into this object. Already existing
|
||||||
|
@ -456,7 +466,7 @@ class BuildInfoBase(object):
|
||||||
"""
|
"""
|
||||||
state = other.__getstate__()
|
state = other.__getstate__()
|
||||||
self.__setstate__(state)
|
self.__setstate__(state)
|
||||||
|
|
||||||
def __getstate__(self):
|
def __getstate__(self):
|
||||||
"""
|
"""
|
||||||
Return all fields that shall be pickled. Walk the slots in the class
|
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__',):
|
if key not in ('__weakref__',):
|
||||||
setattr(self, key, value)
|
setattr(self, key, value)
|
||||||
|
|
||||||
class Node(object):
|
|
||||||
|
class Node(object, with_metaclass(NoSlotsPyPy)):
|
||||||
"""The base Node class, for entities that we know how to
|
"""The base Node class, for entities that we know how to
|
||||||
build, or use to build other Nodes.
|
build, or use to build other Nodes.
|
||||||
"""
|
"""
|
||||||
|
@ -536,7 +547,7 @@ class Node(object):
|
||||||
|
|
||||||
class Attrs(object):
|
class Attrs(object):
|
||||||
__slots__ = ('shared', '__dict__')
|
__slots__ = ('shared', '__dict__')
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.Node')
|
if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.Node')
|
||||||
|
@ -588,7 +599,7 @@ class Node(object):
|
||||||
self._func_rexists = 1
|
self._func_rexists = 1
|
||||||
self._func_get_contents = 0
|
self._func_get_contents = 0
|
||||||
self._func_target_from_source = 0
|
self._func_target_from_source = 0
|
||||||
|
|
||||||
self.clear_memoized_values()
|
self.clear_memoized_values()
|
||||||
|
|
||||||
# Let the interface in which the build engine is embedded
|
# Let the interface in which the build engine is embedded
|
||||||
|
@ -737,7 +748,7 @@ class Node(object):
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
self.get_executor()(self, **kw)
|
self.get_executor()(self, **kw)
|
||||||
except SCons.Errors.BuildError, e:
|
except SCons.Errors.BuildError as e:
|
||||||
e.node = self
|
e.node = self
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
@ -776,16 +787,16 @@ class Node(object):
|
||||||
def release_target_info(self):
|
def release_target_info(self):
|
||||||
"""Called just after this node has been marked
|
"""Called just after this node has been marked
|
||||||
up-to-date or was built completely.
|
up-to-date or was built completely.
|
||||||
|
|
||||||
This is where we try to release as many target node infos
|
This is where we try to release as many target node infos
|
||||||
as possible for clean builds and update runs, in order
|
as possible for clean builds and update runs, in order
|
||||||
to minimize the overall memory consumption.
|
to minimize the overall memory consumption.
|
||||||
|
|
||||||
By purging attributes that aren't needed any longer after
|
By purging attributes that aren't needed any longer after
|
||||||
a Node (=File) got built, we don't have to care that much how
|
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
|
many KBytes a Node actually requires...as long as we free
|
||||||
the memory shortly afterwards.
|
the memory shortly afterwards.
|
||||||
|
|
||||||
@see: built() and File.release_target_info()
|
@see: built() and File.release_target_info()
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
@ -965,9 +976,9 @@ class Node(object):
|
||||||
# no scanner could be found for the given node's scanner key;
|
# no scanner could be found for the given node's scanner key;
|
||||||
# thus, make an attempt at using a default.
|
# thus, make an attempt at using a default.
|
||||||
scanner = root_node_scanner
|
scanner = root_node_scanner
|
||||||
|
|
||||||
return scanner
|
return scanner
|
||||||
|
|
||||||
def get_env_scanner(self, env, kw={}):
|
def get_env_scanner(self, env, kw={}):
|
||||||
return env.get_scanner(self.scanner_key())
|
return env.get_scanner(self.scanner_key())
|
||||||
|
|
||||||
|
@ -1125,38 +1136,22 @@ class Node(object):
|
||||||
binfo.bactsig = SCons.Util.MD5signature(executor.get_contents())
|
binfo.bactsig = SCons.Util.MD5signature(executor.get_contents())
|
||||||
|
|
||||||
if self._specific_sources:
|
if self._specific_sources:
|
||||||
sources = []
|
sources = [ s for s in self.sources if not s in ignore_set]
|
||||||
for s in self.sources:
|
|
||||||
if s not in ignore_set:
|
|
||||||
sources.append(s)
|
|
||||||
else:
|
else:
|
||||||
sources = executor.get_unignored_sources(self, self.ignore)
|
sources = executor.get_unignored_sources(self, self.ignore)
|
||||||
|
|
||||||
seen = set()
|
seen = set()
|
||||||
bsources = []
|
binfo.bsources = [s for s in sources if s not in seen and not seen.add(s)]
|
||||||
bsourcesigs = []
|
binfo.bsourcesigs = [s.get_ninfo() for s in binfo.bsources]
|
||||||
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
|
|
||||||
|
|
||||||
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 []
|
binfo.bdepends = self.depends
|
||||||
implicitsigs = []
|
binfo.bdependsigs = [d.get_ninfo() for d in self.depends if d not in ignore_set]
|
||||||
for i in implicit:
|
|
||||||
if i not in ignore_set:
|
binfo.bimplicit = self.implicit or []
|
||||||
implicitsigs.append(i.get_ninfo())
|
binfo.bimplicitsigs = [i.get_ninfo() for i in binfo.bimplicit if i not in ignore_set]
|
||||||
binfo.bimplicit = implicit
|
|
||||||
binfo.bimplicitsigs = implicitsigs
|
|
||||||
|
|
||||||
return binfo
|
return binfo
|
||||||
|
|
||||||
|
@ -1239,7 +1234,7 @@ class Node(object):
|
||||||
"""Adds dependencies."""
|
"""Adds dependencies."""
|
||||||
try:
|
try:
|
||||||
self._add_child(self.depends, self.depends_set, depend)
|
self._add_child(self.depends, self.depends_set, depend)
|
||||||
except TypeError, e:
|
except TypeError as e:
|
||||||
e = e.args[0]
|
e = e.args[0]
|
||||||
if SCons.Util.is_List(e):
|
if SCons.Util.is_List(e):
|
||||||
s = list(map(str, e))
|
s = list(map(str, e))
|
||||||
|
@ -1258,7 +1253,7 @@ class Node(object):
|
||||||
"""Adds dependencies to ignore."""
|
"""Adds dependencies to ignore."""
|
||||||
try:
|
try:
|
||||||
self._add_child(self.ignore, self.ignore_set, depend)
|
self._add_child(self.ignore, self.ignore_set, depend)
|
||||||
except TypeError, e:
|
except TypeError as e:
|
||||||
e = e.args[0]
|
e = e.args[0]
|
||||||
if SCons.Util.is_List(e):
|
if SCons.Util.is_List(e):
|
||||||
s = list(map(str, e))
|
s = list(map(str, e))
|
||||||
|
@ -1272,7 +1267,7 @@ class Node(object):
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self._add_child(self.sources, self.sources_set, source)
|
self._add_child(self.sources, self.sources_set, source)
|
||||||
except TypeError, e:
|
except TypeError as e:
|
||||||
e = e.args[0]
|
e = e.args[0]
|
||||||
if SCons.Util.is_List(e):
|
if SCons.Util.is_List(e):
|
||||||
s = list(map(str, e))
|
s = list(map(str, e))
|
||||||
|
@ -1332,7 +1327,7 @@ class Node(object):
|
||||||
# dictionary patterns I found all ended up using "not in"
|
# dictionary patterns I found all ended up using "not in"
|
||||||
# internally anyway...)
|
# internally anyway...)
|
||||||
if self.ignore_set:
|
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 = []
|
children = []
|
||||||
for i in iter:
|
for i in iter:
|
||||||
|
@ -1366,7 +1361,7 @@ class Node(object):
|
||||||
# using dictionary keys, lose the order, and the only ordered
|
# using dictionary keys, lose the order, and the only ordered
|
||||||
# dictionary patterns I found all ended up using "not in"
|
# dictionary patterns I found all ended up using "not in"
|
||||||
# internally anyway...)
|
# 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):
|
def children(self, scan=1):
|
||||||
"""Return a list of the node's direct children, minus those
|
"""Return a list of the node's direct children, minus those
|
||||||
|
@ -1390,7 +1385,7 @@ class Node(object):
|
||||||
|
|
||||||
def Decider(self, function):
|
def Decider(self, function):
|
||||||
foundkey = None
|
foundkey = None
|
||||||
for k, v in _decider_map.iteritems():
|
for k, v in _decider_map.items():
|
||||||
if v == function:
|
if v == function:
|
||||||
foundkey = k
|
foundkey = k
|
||||||
break
|
break
|
||||||
|
@ -1424,14 +1419,14 @@ class Node(object):
|
||||||
any difference, but we now rely on checking every dependency
|
any difference, but we now rely on checking every dependency
|
||||||
to make sure that any necessary Node information (for example,
|
to make sure that any necessary Node information (for example,
|
||||||
the content signature of an #included .h file) is updated.
|
the content signature of an #included .h file) is updated.
|
||||||
|
|
||||||
The allowcache option was added for supporting the early
|
The allowcache option was added for supporting the early
|
||||||
release of the executor/builder structures, right after
|
release of the executor/builder structures, right after
|
||||||
a File target was built. When set to true, the return
|
a File target was built. When set to true, the return
|
||||||
value of this changed method gets cached for File nodes.
|
value of this changed method gets cached for File nodes.
|
||||||
Like this, the executor isn't needed any longer for subsequent
|
Like this, the executor isn't needed any longer for subsequent
|
||||||
calls to changed().
|
calls to changed().
|
||||||
|
|
||||||
@see: FS.File.changed(), FS.File.release_target_info()
|
@see: FS.File.changed(), FS.File.release_target_info()
|
||||||
"""
|
"""
|
||||||
t = 0
|
t = 0
|
||||||
|
@ -1603,8 +1598,8 @@ class Node(object):
|
||||||
new_bkids = new.bsources + new.bdepends + new.bimplicit
|
new_bkids = new.bsources + new.bdepends + new.bimplicit
|
||||||
new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs
|
new_bkidsigs = new.bsourcesigs + new.bdependsigs + new.bimplicitsigs
|
||||||
|
|
||||||
osig = dict(zip(old_bkids, old_bkidsigs))
|
osig = dict(list(zip(old_bkids, old_bkidsigs)))
|
||||||
nsig = dict(zip(new_bkids, new_bkidsigs))
|
nsig = dict(list(zip(new_bkids, new_bkidsigs)))
|
||||||
|
|
||||||
# The sources and dependencies we'll want to report are all stored
|
# The sources and dependencies we'll want to report are all stored
|
||||||
# as relative paths to this target's directory, but we want to
|
# as relative paths to this target's directory, but we want to
|
||||||
|
@ -1645,6 +1640,9 @@ class Node(object):
|
||||||
if old.bact == new.bact:
|
if old.bact == new.bact:
|
||||||
lines.append("the contents of the build action changed\n" +
|
lines.append("the contents of the build action changed\n" +
|
||||||
fmt_with_title('action: ', new.bact))
|
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:
|
else:
|
||||||
lines.append("the build action changed:\n" +
|
lines.append("the build action changed:\n" +
|
||||||
fmt_with_title('old: ', old.bact) +
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Options/BoolOption.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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
|
__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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Options/EnumOption.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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
|
__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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Options/ListOption.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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
|
__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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Options/PackageOption.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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
|
__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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Options/PathOption.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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
|
__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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Options/__init__.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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
|
__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.Variables
|
||||||
import SCons.Warnings
|
import SCons.Warnings
|
||||||
|
|
||||||
from BoolOption import BoolOption # okay
|
from .BoolOption import BoolOption # okay
|
||||||
from EnumOption import EnumOption # okay
|
from .EnumOption import EnumOption # okay
|
||||||
from ListOption import ListOption # naja
|
from .ListOption import ListOption # naja
|
||||||
from PackageOption import PackageOption # naja
|
from .PackageOption import PackageOption # naja
|
||||||
from PathOption import PathOption # okay
|
from .PathOption import PathOption # okay
|
||||||
|
|
||||||
warned = False
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/PathList.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/PathList.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
__doc__ = """SCons.PathList
|
__doc__ = """SCons.PathList
|
||||||
|
|
||||||
|
@ -104,11 +104,11 @@ class _PathList(object):
|
||||||
pl = []
|
pl = []
|
||||||
for p in pathlist:
|
for p in pathlist:
|
||||||
try:
|
try:
|
||||||
index = p.find('$')
|
found = '$' in p
|
||||||
except (AttributeError, TypeError):
|
except (AttributeError, TypeError):
|
||||||
type = TYPE_OBJECT
|
type = TYPE_OBJECT
|
||||||
else:
|
else:
|
||||||
if index == -1:
|
if not found:
|
||||||
type = TYPE_STRING_NO_SUBST
|
type = TYPE_STRING_NO_SUBST
|
||||||
else:
|
else:
|
||||||
type = TYPE_STRING_SUBST
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
# "Software"), to deal in the Software without restriction, including
|
# "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
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Platform/__init__.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Platform/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.compat
|
import SCons.compat
|
||||||
|
|
||||||
|
@ -55,6 +56,7 @@ import SCons.Errors
|
||||||
import SCons.Subst
|
import SCons.Subst
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
|
|
||||||
|
|
||||||
def platform_default():
|
def platform_default():
|
||||||
"""Return the platform string for our execution environment.
|
"""Return the platform string for our execution environment.
|
||||||
|
|
||||||
|
@ -130,7 +132,7 @@ class PlatformSpec(object):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
class TempFileMunge(object):
|
class TempFileMunge(object):
|
||||||
"""A callable class. You can set an Environment variable to this,
|
"""A callable class. You can set an Environment variable to this,
|
||||||
then call it with a string argument, then it will perform temporary
|
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
|
node = target[0] if SCons.Util.is_List(target) else target
|
||||||
cmdlist = getattr(node.attributes, 'tempfile_cmdlist', None) \
|
cmdlist = getattr(node.attributes, 'tempfile_cmdlist', None) \
|
||||||
if node is not None else None
|
if node is not None else None
|
||||||
if cmdlist is not None :
|
if cmdlist is not None :
|
||||||
return cmdlist
|
return cmdlist
|
||||||
|
|
||||||
# We do a normpath because mktemp() has what appears to be
|
# We do a normpath because mktemp() has what appears to be
|
||||||
# a bug in Windows that will use a forward slash as a path
|
# a bug in Windows that will use a forward slash as a path
|
||||||
# delimiter. Windows's link mistakes that for a command line
|
# delimiter. Windows's link mistakes that for a command line
|
||||||
|
@ -215,7 +217,7 @@ class TempFileMunge(object):
|
||||||
prefix = '@'
|
prefix = '@'
|
||||||
|
|
||||||
args = list(map(SCons.Subst.quote_spaces, cmd[1:]))
|
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)
|
os.close(fd)
|
||||||
# XXX Using the SCons.Action.print_actions value directly
|
# XXX Using the SCons.Action.print_actions value directly
|
||||||
# like this is bogus, but expedient. This class should
|
# 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
|
# purity get in the way of just being helpful, so we'll
|
||||||
# reach into SCons.Action directly.
|
# reach into SCons.Action directly.
|
||||||
if SCons.Action.print_actions:
|
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 ''
|
source) if self.cmdstr is not None else ''
|
||||||
# Print our message only if XXXCOMSTR returns an empty string
|
# Print our message only if XXXCOMSTR returns an empty string
|
||||||
if len(cmdstr) == 0 :
|
if len(cmdstr) == 0 :
|
||||||
print("Using tempfile "+native_tmp+" for command line:\n"+
|
print("Using tempfile "+native_tmp+" for command line:\n"+
|
||||||
str(cmd[0]) + " " + " ".join(args))
|
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.
|
# to avoid creating two temporary files one for print and one for execute.
|
||||||
cmdlist = [ cmd[0], prefix + native_tmp + '\n' + rm, native_tmp ]
|
cmdlist = [ cmd[0], prefix + native_tmp + '\n' + rm, native_tmp ]
|
||||||
if node is not None:
|
if node is not None:
|
||||||
|
@ -249,7 +251,8 @@ class TempFileMunge(object):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
return cmdlist
|
return cmdlist
|
||||||
|
|
||||||
|
|
||||||
def Platform(name = platform_default()):
|
def Platform(name = platform_default()):
|
||||||
"""Select a canned Platform specification.
|
"""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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,12 +30,12 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Platform/aix.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Platform/aix.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
import posix
|
from . import posix
|
||||||
|
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
import SCons.Action
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,9 +30,9 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Platform/cygwin.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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
|
from SCons.Platform import TempFileMunge
|
||||||
|
|
||||||
def generate(env):
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,9 +30,9 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Platform/darwin.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Platform/darwin.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import posix
|
from . import posix
|
||||||
import os
|
import os
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
|
@ -63,6 +63,10 @@ def generate(env):
|
||||||
env.AppendENVPath('PATHOSX', line.strip('\n'))
|
env.AppendENVPath('PATHOSX', line.strip('\n'))
|
||||||
f.close()
|
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:
|
# Local Variables:
|
||||||
# tab-width:4
|
# tab-width:4
|
||||||
# indent-tabs-mode:nil
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,9 +30,9 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Platform/hpux.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Platform/hpux.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import posix
|
from . import posix
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
posix.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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,9 +30,9 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Platform/irix.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Platform/irix.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import posix
|
from . import posix
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
posix.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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,8 +30,8 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Platform/os2.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Platform/os2.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
import win32
|
from . import win32
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
if 'ENV' not in 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Platform/posix.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Platform/posix.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import errno
|
import errno
|
||||||
import os
|
import os
|
||||||
|
@ -56,7 +56,7 @@ def escape(arg):
|
||||||
for c in special:
|
for c in special:
|
||||||
arg = arg.replace(c, slash+c)
|
arg = arg.replace(c, slash+c)
|
||||||
|
|
||||||
# print "ESCAPE RESULT: %s"%arg
|
# print("ESCAPE RESULT: %s" % arg)
|
||||||
return '"' + 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,9 +30,9 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Platform/sunos.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Platform/sunos.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import posix
|
from . import posix
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
posix.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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Platform/win32.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Platform/win32.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -60,15 +60,8 @@ except AttributeError:
|
||||||
else:
|
else:
|
||||||
parallel_msg = None
|
parallel_msg = None
|
||||||
|
|
||||||
_builtin_file = file
|
|
||||||
_builtin_open = open
|
_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):
|
def _scons_open(*args, **kw):
|
||||||
fp = _builtin_open(*args, **kw)
|
fp = _builtin_open(*args, **kw)
|
||||||
win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()),
|
win32api.SetHandleInformation(msvcrt.get_osfhandle(fp.fileno()),
|
||||||
|
@ -76,13 +69,64 @@ else:
|
||||||
0)
|
0)
|
||||||
return fp
|
return fp
|
||||||
|
|
||||||
file = _scons_file
|
|
||||||
open = _scons_open
|
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:
|
try:
|
||||||
import threading
|
import threading
|
||||||
spawn_lock = threading.Lock()
|
spawn_lock = threading.Lock()
|
||||||
|
|
||||||
# This locked version of spawnve works around a Windows
|
# This locked version of spawnve works around a Windows
|
||||||
# MSVCRT bug, because its spawnve is not thread-safe.
|
# MSVCRT bug, because its spawnve is not thread-safe.
|
||||||
# Without this, python can randomly crash while using -jN.
|
# Without this, python can randomly crash while using -jN.
|
||||||
|
@ -111,11 +155,12 @@ except ImportError:
|
||||||
# simulating a non-existent package.
|
# simulating a non-existent package.
|
||||||
def spawnve(mode, file, args, env):
|
def spawnve(mode, file, args, env):
|
||||||
return os.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,
|
# 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
|
# you had better have cmd or command.com in your PATH when you run
|
||||||
# scons.
|
# scons.
|
||||||
|
|
||||||
|
|
||||||
def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
||||||
# There is no direct way to do that in python. What we do
|
# There is no direct way to do that in python. What we do
|
||||||
# here should work for most cases:
|
# here should work for most cases:
|
||||||
|
@ -136,8 +181,7 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
||||||
stderrRedirected = 0
|
stderrRedirected = 0
|
||||||
for arg in args:
|
for arg in args:
|
||||||
# are there more possibilities to redirect stdout ?
|
# are there more possibilities to redirect stdout ?
|
||||||
if (arg.find( ">", 0, 1 ) != -1 or
|
if arg.find( ">", 0, 1 ) != -1 or arg.find( "1>", 0, 2 ) != -1:
|
||||||
arg.find( "1>", 0, 2 ) != -1):
|
|
||||||
stdoutRedirected = 1
|
stdoutRedirected = 1
|
||||||
# are there more possibilities to redirect stderr ?
|
# are there more possibilities to redirect stderr ?
|
||||||
if arg.find( "2>", 0, 2 ) != -1:
|
if arg.find( "2>", 0, 2 ) != -1:
|
||||||
|
@ -153,7 +197,7 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
||||||
try:
|
try:
|
||||||
args = [sh, '/C', escape(' '.join(args)) ]
|
args = [sh, '/C', escape(' '.join(args)) ]
|
||||||
ret = spawnve(os.P_WAIT, sh, args, env)
|
ret = spawnve(os.P_WAIT, sh, args, env)
|
||||||
except OSError, e:
|
except OSError as e:
|
||||||
# catch any error
|
# catch any error
|
||||||
try:
|
try:
|
||||||
ret = exitvalmap[e[0]]
|
ret = exitvalmap[e[0]]
|
||||||
|
@ -178,13 +222,14 @@ def piped_spawn(sh, escape, cmd, args, env, stdout, stderr):
|
||||||
pass
|
pass
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
def exec_spawn(l, env):
|
def exec_spawn(l, env):
|
||||||
try:
|
try:
|
||||||
result = spawnve(os.P_WAIT, l[0], l, env)
|
result = spawnve(os.P_WAIT, l[0], l, env)
|
||||||
except OSError, e:
|
except (OSError, EnvironmentError) as e:
|
||||||
try:
|
try:
|
||||||
result = exitvalmap[e[0]]
|
result = exitvalmap[e.errno]
|
||||||
sys.stderr.write("scons: %s: %s\n" % (l[0], e[1]))
|
sys.stderr.write("scons: %s: %s\n" % (l[0], e.strerror))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
result = 127
|
result = 127
|
||||||
if len(l) > 2:
|
if len(l) > 2:
|
||||||
|
@ -194,9 +239,10 @@ def exec_spawn(l, env):
|
||||||
command = l[0]
|
command = l[0]
|
||||||
else:
|
else:
|
||||||
command = l[0]
|
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
|
return result
|
||||||
|
|
||||||
|
|
||||||
def spawn(sh, escape, cmd, args, env):
|
def spawn(sh, escape, cmd, args, env):
|
||||||
if not sh:
|
if not sh:
|
||||||
sys.stderr.write("scons: Could not find command interpreter, is it in your PATH?\n")
|
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
|
# Get the windows system directory name
|
||||||
_system_root = None
|
_system_root = None
|
||||||
|
|
||||||
|
|
||||||
def get_system_root():
|
def get_system_root():
|
||||||
global _system_root
|
global _system_root
|
||||||
if _system_root is not None:
|
if _system_root is not None:
|
||||||
|
@ -240,11 +287,21 @@ def get_system_root():
|
||||||
raise
|
raise
|
||||||
except:
|
except:
|
||||||
pass
|
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
|
_system_root = val
|
||||||
return val
|
return val
|
||||||
|
|
||||||
# Get the location of the program files directory
|
|
||||||
def get_program_files_dir():
|
def get_program_files_dir():
|
||||||
|
"""
|
||||||
|
Get the location of the program files directory
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
|
||||||
|
"""
|
||||||
# Now see if we can look in the registry...
|
# Now see if we can look in the registry...
|
||||||
val = ''
|
val = ''
|
||||||
if SCons.Util.can_read_reg:
|
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
|
# A reasonable default if we can't read the registry
|
||||||
# (Actually, it's pretty reasonable even if we can :-)
|
# (Actually, it's pretty reasonable even if we can :-)
|
||||||
val = os.path.join(os.path.dirname(get_system_root()),"Program Files")
|
val = os.path.join(os.path.dirname(get_system_root()),"Program Files")
|
||||||
|
|
||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Determine which windows CPU were running on.
|
|
||||||
class ArchDefinition(object):
|
class ArchDefinition(object):
|
||||||
"""
|
"""
|
||||||
|
Determine which windows CPU were running on.
|
||||||
A class for defining architecture-specific settings and logic.
|
A class for defining architecture-specific settings and logic.
|
||||||
"""
|
"""
|
||||||
def __init__(self, arch, synonyms=[]):
|
def __init__(self, arch, synonyms=[]):
|
||||||
|
@ -298,6 +354,7 @@ for a in SupportedArchitectureList:
|
||||||
for s in a.synonyms:
|
for s in a.synonyms:
|
||||||
SupportedArchitectureMap[s] = a
|
SupportedArchitectureMap[s] = a
|
||||||
|
|
||||||
|
|
||||||
def get_architecture(arch=None):
|
def get_architecture(arch=None):
|
||||||
"""Returns the definition for the specified architecture string.
|
"""Returns the definition for the specified architecture string.
|
||||||
|
|
||||||
|
@ -311,6 +368,7 @@ def get_architecture(arch=None):
|
||||||
arch = os.environ.get('PROCESSOR_ARCHITECTURE')
|
arch = os.environ.get('PROCESSOR_ARCHITECTURE')
|
||||||
return SupportedArchitectureMap.get(arch, ArchDefinition('', ['']))
|
return SupportedArchitectureMap.get(arch, ArchDefinition('', ['']))
|
||||||
|
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
# Attempt to find cmd.exe (for WinNT/2k/XP) or
|
# Attempt to find cmd.exe (for WinNT/2k/XP) or
|
||||||
# command.com for Win9x
|
# command.com for Win9x
|
||||||
|
@ -346,7 +404,7 @@ def generate(env):
|
||||||
os.path.join(systemroot,'System32')
|
os.path.join(systemroot,'System32')
|
||||||
tmp_pathext = '.com;.exe;.bat;.cmd'
|
tmp_pathext = '.com;.exe;.bat;.cmd'
|
||||||
if 'PATHEXT' in os.environ:
|
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)
|
cmd_interp = SCons.Util.WhereIs('cmd', tmp_path, tmp_pathext)
|
||||||
if not cmd_interp:
|
if not cmd_interp:
|
||||||
cmd_interp = SCons.Util.WhereIs('command', tmp_path, tmp_pathext)
|
cmd_interp = SCons.Util.WhereIs('command', tmp_path, tmp_pathext)
|
||||||
|
@ -356,7 +414,6 @@ def generate(env):
|
||||||
if not cmd_interp:
|
if not cmd_interp:
|
||||||
cmd_interp = env.Detect('command')
|
cmd_interp = env.Detect('command')
|
||||||
|
|
||||||
|
|
||||||
if 'ENV' not in env:
|
if 'ENV' not in env:
|
||||||
env['ENV'] = {}
|
env['ENV'] = {}
|
||||||
|
|
||||||
|
@ -368,7 +425,7 @@ def generate(env):
|
||||||
# for SystemDrive because it's related.
|
# for SystemDrive because it's related.
|
||||||
#
|
#
|
||||||
# Weigh the impact carefully before adding other variables to this list.
|
# 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:
|
for var in import_env:
|
||||||
v = os.environ.get(var)
|
v = os.environ.get(var)
|
||||||
if v:
|
if v:
|
||||||
|
@ -401,10 +458,10 @@ def generate(env):
|
||||||
env['TEMPFILEPREFIX'] = '@'
|
env['TEMPFILEPREFIX'] = '@'
|
||||||
env['MAXLINELENGTH'] = 2048
|
env['MAXLINELENGTH'] = 2048
|
||||||
env['ESCAPE'] = escape
|
env['ESCAPE'] = escape
|
||||||
|
|
||||||
env['HOST_OS'] = 'win32'
|
env['HOST_OS'] = 'win32'
|
||||||
env['HOST_ARCH'] = get_architecture().arch
|
env['HOST_ARCH'] = get_architecture().arch
|
||||||
|
|
||||||
|
|
||||||
# Local Variables:
|
# Local Variables:
|
||||||
# tab-width:4
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -33,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
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/SConf.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/SConf.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.compat
|
import SCons.compat
|
||||||
|
|
||||||
|
@ -109,7 +110,7 @@ def _createConfigH(target, source, env):
|
||||||
#define %(DEFNAME)s_SEEN
|
#define %(DEFNAME)s_SEEN
|
||||||
|
|
||||||
""" % {'DEFNAME' : defname})
|
""" % {'DEFNAME' : defname})
|
||||||
t.write(source[0].get_contents())
|
t.write(source[0].get_contents().decode())
|
||||||
t.write("""
|
t.write("""
|
||||||
#endif /* %(DEFNAME)s_SEEN */
|
#endif /* %(DEFNAME)s_SEEN */
|
||||||
""" % {'DEFNAME' : defname})
|
""" % {'DEFNAME' : defname})
|
||||||
|
@ -131,10 +132,10 @@ def CreateConfigHBuilder(env):
|
||||||
_stringConfigH)
|
_stringConfigH)
|
||||||
sconfigHBld = SCons.Builder.Builder(action=action)
|
sconfigHBld = SCons.Builder.Builder(action=action)
|
||||||
env.Append( BUILDERS={'SConfigHBuilder':sconfigHBld} )
|
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]))
|
env.SConfigHBuilder(k, env.Value(_ac_config_hs[k]))
|
||||||
|
|
||||||
|
|
||||||
class SConfWarning(SCons.Warnings.Warning):
|
class SConfWarning(SCons.Warnings.Warning):
|
||||||
pass
|
pass
|
||||||
SCons.Warnings.enableWarningClass(SConfWarning)
|
SCons.Warnings.enableWarningClass(SConfWarning)
|
||||||
|
@ -163,11 +164,11 @@ class ConfigureCacheError(SConfError):
|
||||||
# define actions for building text files
|
# define actions for building text files
|
||||||
def _createSource( target, source, env ):
|
def _createSource( target, source, env ):
|
||||||
fd = open(str(target[0]), "w")
|
fd = open(str(target[0]), "w")
|
||||||
fd.write(source[0].get_contents())
|
fd.write(source[0].get_contents().decode())
|
||||||
fd.close()
|
fd.close()
|
||||||
def _stringSource( target, source, env ):
|
def _stringSource( target, source, env ):
|
||||||
return (str(target[0]) + ' <-\n |' +
|
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):
|
class SConfBuildInfo(SCons.Node.FS.FileBuildInfo):
|
||||||
"""
|
"""
|
||||||
|
@ -176,7 +177,7 @@ class SConfBuildInfo(SCons.Node.FS.FileBuildInfo):
|
||||||
contains messages of the original build phase.
|
contains messages of the original build phase.
|
||||||
"""
|
"""
|
||||||
__slots__ = ('result', 'string')
|
__slots__ = ('result', 'string')
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.result = None # -> 0/None -> no error, != 0 error
|
self.result = None # -> 0/None -> no error, != 0 error
|
||||||
self.string = None # the stdout / stderr output when building the target
|
self.string = None # the stdout / stderr output when building the target
|
||||||
|
@ -217,7 +218,7 @@ class Streamer(object):
|
||||||
if self.orig:
|
if self.orig:
|
||||||
self.orig.flush()
|
self.orig.flush()
|
||||||
self.s.flush()
|
self.s.flush()
|
||||||
|
|
||||||
|
|
||||||
class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
|
class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
|
||||||
"""
|
"""
|
||||||
|
@ -311,7 +312,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
|
||||||
binfo = self.targets[0].get_stored_info().binfo
|
binfo = self.targets[0].get_stored_info().binfo
|
||||||
self.display_cached_string(binfo)
|
self.display_cached_string(binfo)
|
||||||
raise SCons.Errors.BuildError # will be 'caught' in self.failed
|
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]))
|
self.display("\"%s\" is up to date." % str(self.targets[0]))
|
||||||
binfo = self.targets[0].get_stored_info().binfo
|
binfo = self.targets[0].get_stored_info().binfo
|
||||||
self.display_cached_string(binfo)
|
self.display_cached_string(binfo)
|
||||||
|
@ -332,7 +333,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
|
||||||
env_decider=env.decide_source):
|
env_decider=env.decide_source):
|
||||||
env_decider(dependency, target, prev_ni)
|
env_decider(dependency, target, prev_ni)
|
||||||
return True
|
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.Decider(force_build)
|
||||||
env['PSTDOUT'] = env['PSTDERR'] = s
|
env['PSTDOUT'] = env['PSTDERR'] = s
|
||||||
try:
|
try:
|
||||||
|
@ -346,7 +347,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask):
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
exc_value = sys.exc_info()[1]
|
exc_value = sys.exc_info()[1]
|
||||||
raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code)
|
raise SCons.Errors.ExplicitExit(self.targets[0],exc_value.code)
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
for t in self.targets:
|
for t in self.targets:
|
||||||
binfo = SConfBuildInfo()
|
binfo = SConfBuildInfo()
|
||||||
binfo.merge(t.get_binfo())
|
binfo.merge(t.get_binfo())
|
||||||
|
@ -396,7 +397,7 @@ class SConfBase(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, env, custom_tests = {}, conf_dir='$CONFIGUREDIR',
|
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,
|
"""Constructor. Pass additional tests in the custom_tests-dictionary,
|
||||||
e.g. custom_tests={'CheckPrivate':MyPrivateTest}, where MyPrivateTest
|
e.g. custom_tests={'CheckPrivate':MyPrivateTest}, where MyPrivateTest
|
||||||
defines a custom test.
|
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
|
If value is None (default), then #define name is written. If value is not
|
||||||
none, then #define name value is written.
|
none, then #define name value is written.
|
||||||
|
|
||||||
comment is a string which will be put as a C comment in the
|
comment is a string which will be put as a C comment in the header, to explain the meaning of the value
|
||||||
header, to explain the meaning of the value (appropriate C comments /* and
|
(appropriate C comments will be added automatically).
|
||||||
*/ will be put automatically."""
|
"""
|
||||||
lines = []
|
lines = []
|
||||||
if comment:
|
if comment:
|
||||||
comment_str = "/* %s */" % comment
|
comment_str = "/* %s */" % comment
|
||||||
|
@ -608,7 +609,7 @@ class SConfBase(object):
|
||||||
ok = self.TryBuild(self.env.SConfActionBuilder, text, extension)
|
ok = self.TryBuild(self.env.SConfActionBuilder, text, extension)
|
||||||
del self.env['BUILDERS']['SConfActionBuilder']
|
del self.env['BUILDERS']['SConfActionBuilder']
|
||||||
if ok:
|
if ok:
|
||||||
outputStr = self.lastTarget.get_contents()
|
outputStr = self.lastTarget.get_contents().decode()
|
||||||
return (1, outputStr)
|
return (1, outputStr)
|
||||||
return (0, "")
|
return (0, "")
|
||||||
|
|
||||||
|
@ -642,7 +643,7 @@ class SConfBase(object):
|
||||||
node = self.env.Command(output, prog, [ [ pname, ">", "${TARGET}"] ])
|
node = self.env.Command(output, prog, [ [ pname, ">", "${TARGET}"] ])
|
||||||
ok = self.BuildNodes(node)
|
ok = self.BuildNodes(node)
|
||||||
if ok:
|
if ok:
|
||||||
outputStr = output.get_contents()
|
outputStr = SCons.Util.to_str(output.get_contents())
|
||||||
return( 1, outputStr)
|
return( 1, outputStr)
|
||||||
return (0, "")
|
return (0, "")
|
||||||
|
|
||||||
|
@ -670,7 +671,7 @@ class SConfBase(object):
|
||||||
"""Adds all the tests given in the tests dictionary to this SConf
|
"""Adds all the tests given in the tests dictionary to this SConf
|
||||||
instance
|
instance
|
||||||
"""
|
"""
|
||||||
for name in tests.keys():
|
for name in list(tests.keys()):
|
||||||
self.AddTest(name, tests[name])
|
self.AddTest(name, tests[name])
|
||||||
|
|
||||||
def _createDir( self, node ):
|
def _createDir( self, node ):
|
||||||
|
@ -689,7 +690,7 @@ class SConfBase(object):
|
||||||
global _ac_config_logs
|
global _ac_config_logs
|
||||||
global sconf_global
|
global sconf_global
|
||||||
global SConfFS
|
global SConfFS
|
||||||
|
|
||||||
self.lastEnvFs = self.env.fs
|
self.lastEnvFs = self.env.fs
|
||||||
self.env.fs = SConfFS
|
self.env.fs = SConfFS
|
||||||
self._createDir(self.confdir)
|
self._createDir(self.confdir)
|
||||||
|
@ -716,7 +717,7 @@ class SConfBase(object):
|
||||||
self.logstream.write('file %s,line %d:\n\tConfigure(confdir = %s)\n' %
|
self.logstream.write('file %s,line %d:\n\tConfigure(confdir = %s)\n' %
|
||||||
(tb[0], tb[1], str(self.confdir)) )
|
(tb[0], tb[1], str(self.confdir)) )
|
||||||
SConfFS.chdir(old_fs_dir)
|
SConfFS.chdir(old_fs_dir)
|
||||||
else:
|
else:
|
||||||
self.logstream = None
|
self.logstream = None
|
||||||
# we use a special builder to create source files from TEXT
|
# we use a special builder to create source files from TEXT
|
||||||
action = SCons.Action.Action(_createSource,
|
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):
|
def CheckTypeSize(context, type_name, includes = "", language = None, expect = None):
|
||||||
res = SCons.Conftest.CheckTypeSize(context, type_name,
|
res = SCons.Conftest.CheckTypeSize(context, type_name,
|
||||||
header = includes, language = language,
|
header = includes, language = language,
|
||||||
expect = expect)
|
expect = expect)
|
||||||
context.did_show_result = 1
|
context.did_show_result = 1
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def CheckDeclaration(context, declaration, includes = "", language = None):
|
def CheckDeclaration(context, declaration, includes = "", language = None):
|
||||||
res = SCons.Conftest.CheckDeclaration(context, declaration,
|
res = SCons.Conftest.CheckDeclaration(context, declaration,
|
||||||
includes = includes,
|
includes = includes,
|
||||||
language = language)
|
language = language)
|
||||||
context.did_show_result = 1
|
context.did_show_result = 1
|
||||||
return not res
|
return not res
|
||||||
|
@ -1004,7 +1005,7 @@ def CheckLib(context, library = None, symbol = "main",
|
||||||
|
|
||||||
if not SCons.Util.is_List(library):
|
if not SCons.Util.is_List(library):
|
||||||
library = [library]
|
library = [library]
|
||||||
|
|
||||||
# ToDo: accept path for the library
|
# ToDo: accept path for the library
|
||||||
res = SCons.Conftest.CheckLib(context, library, symbol, header = header,
|
res = SCons.Conftest.CheckLib(context, library, symbol, header = header,
|
||||||
language = language, autoadd = autoadd)
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,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.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/SConsign.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
from __future__ import print_function
|
||||||
|
|
||||||
|
__revision__ = "src/engine/SCons/SConsign.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.compat
|
import SCons.compat
|
||||||
|
|
||||||
import os
|
import os
|
||||||
# compat layer imports "cPickle" for us if it's available.
|
|
||||||
import pickle
|
import pickle
|
||||||
|
|
||||||
import SCons.dblite
|
import SCons.dblite
|
||||||
import SCons.Warnings
|
import SCons.Warnings
|
||||||
|
|
||||||
|
from SCons.compat import PICKLE_PROTOCOL
|
||||||
|
|
||||||
|
|
||||||
def corrupt_dblite_warning(filename):
|
def corrupt_dblite_warning(filename):
|
||||||
SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning,
|
SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning,
|
||||||
"Ignoring corrupt .sconsign file: %s"%filename)
|
"Ignoring corrupt .sconsign file: %s"%filename)
|
||||||
|
@ -45,7 +49,7 @@ def corrupt_dblite_warning(filename):
|
||||||
SCons.dblite.ignore_corrupt_dbfiles = 1
|
SCons.dblite.ignore_corrupt_dbfiles = 1
|
||||||
SCons.dblite.corruption_warning = corrupt_dblite_warning
|
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 = []
|
sig_files = []
|
||||||
|
|
||||||
# Info for the database SConsign implementation (now the default):
|
# Info for the database SConsign implementation (now the default):
|
||||||
|
@ -59,6 +63,7 @@ DB_Module = SCons.dblite
|
||||||
DB_Name = ".sconsign"
|
DB_Name = ".sconsign"
|
||||||
DB_sync_list = []
|
DB_sync_list = []
|
||||||
|
|
||||||
|
|
||||||
def Get_DataBase(dir):
|
def Get_DataBase(dir):
|
||||||
global DataBase, DB_Module, DB_Name
|
global DataBase, DB_Module, DB_Name
|
||||||
top = dir.fs.Top
|
top = dir.fs.Top
|
||||||
|
@ -84,9 +89,10 @@ def Get_DataBase(dir):
|
||||||
DB_sync_list.append(db)
|
DB_sync_list.append(db)
|
||||||
return db, "c"
|
return db, "c"
|
||||||
except TypeError:
|
except TypeError:
|
||||||
print "DataBase =", DataBase
|
print("DataBase =", DataBase)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def Reset():
|
def Reset():
|
||||||
"""Reset global state. Used by unit tests that end up using
|
"""Reset global state. Used by unit tests that end up using
|
||||||
SConsign multiple times to get a clean slate for each test."""
|
SConsign multiple times to get a clean slate for each test."""
|
||||||
|
@ -96,6 +102,7 @@ def Reset():
|
||||||
|
|
||||||
normcase = os.path.normcase
|
normcase = os.path.normcase
|
||||||
|
|
||||||
|
|
||||||
def write():
|
def write():
|
||||||
global sig_files
|
global sig_files
|
||||||
for sig_file in sig_files:
|
for sig_file in sig_files:
|
||||||
|
@ -114,6 +121,7 @@ def write():
|
||||||
else:
|
else:
|
||||||
closemethod()
|
closemethod()
|
||||||
|
|
||||||
|
|
||||||
class SConsignEntry(object):
|
class SConsignEntry(object):
|
||||||
"""
|
"""
|
||||||
Wrapper class for the generic entry in a .sconsign file.
|
Wrapper class for the generic entry in a .sconsign file.
|
||||||
|
@ -124,16 +132,16 @@ class SConsignEntry(object):
|
||||||
"""
|
"""
|
||||||
__slots__ = ("binfo", "ninfo", "__weakref__")
|
__slots__ = ("binfo", "ninfo", "__weakref__")
|
||||||
current_version_id = 2
|
current_version_id = 2
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# Create an object attribute from the class attribute so it ends up
|
# Create an object attribute from the class attribute so it ends up
|
||||||
# in the pickled data in the .sconsign file.
|
# in the pickled data in the .sconsign file.
|
||||||
#_version_id = self.current_version_id
|
#_version_id = self.current_version_id
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def convert_to_sconsign(self):
|
def convert_to_sconsign(self):
|
||||||
self.binfo.convert_to_sconsign()
|
self.binfo.convert_to_sconsign()
|
||||||
|
|
||||||
def convert_from_sconsign(self, dir, name):
|
def convert_from_sconsign(self, dir, name):
|
||||||
self.binfo.convert_from_sconsign(dir, name)
|
self.binfo.convert_from_sconsign(dir, name)
|
||||||
|
|
||||||
|
@ -155,7 +163,8 @@ class SConsignEntry(object):
|
||||||
for key, value in state.items():
|
for key, value in state.items():
|
||||||
if key not in ('_version_id','__weakref__'):
|
if key not in ('_version_id','__weakref__'):
|
||||||
setattr(self, key, value)
|
setattr(self, key, value)
|
||||||
|
|
||||||
|
|
||||||
class Base(object):
|
class Base(object):
|
||||||
"""
|
"""
|
||||||
This is the controlling class for the signatures for the collection of
|
This is the controlling class for the signatures for the collection of
|
||||||
|
@ -210,6 +219,7 @@ class Base(object):
|
||||||
self.entries[key] = entry
|
self.entries[key] = entry
|
||||||
self.to_be_merged = {}
|
self.to_be_merged = {}
|
||||||
|
|
||||||
|
|
||||||
class DB(Base):
|
class DB(Base):
|
||||||
"""
|
"""
|
||||||
A Base subclass that reads and writes signature information
|
A Base subclass that reads and writes signature information
|
||||||
|
@ -239,7 +249,7 @@ class DB(Base):
|
||||||
raise TypeError
|
raise TypeError
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning,
|
SCons.Warnings.warn(SCons.Warnings.CorruptSConsignWarning,
|
||||||
"Ignoring corrupt sconsign entry : %s (%s)\n"%(self.dir.get_tpath(), e))
|
"Ignoring corrupt sconsign entry : %s (%s)\n"%(self.dir.get_tpath(), e))
|
||||||
for key, entry in self.entries.items():
|
for key, entry in self.entries.items():
|
||||||
|
@ -271,7 +281,7 @@ class DB(Base):
|
||||||
path = normcase(self.dir.get_internal_path())
|
path = normcase(self.dir.get_internal_path())
|
||||||
for key, entry in self.entries.items():
|
for key, entry in self.entries.items():
|
||||||
entry.convert_to_sconsign()
|
entry.convert_to_sconsign()
|
||||||
db[path] = pickle.dumps(self.entries, 1)
|
db[path] = pickle.dumps(self.entries, PICKLE_PROTOCOL)
|
||||||
|
|
||||||
if sync:
|
if sync:
|
||||||
try:
|
try:
|
||||||
|
@ -282,6 +292,7 @@ class DB(Base):
|
||||||
else:
|
else:
|
||||||
syncmethod()
|
syncmethod()
|
||||||
|
|
||||||
|
|
||||||
class Dir(Base):
|
class Dir(Base):
|
||||||
def __init__(self, fp=None, dir=None):
|
def __init__(self, fp=None, dir=None):
|
||||||
"""
|
"""
|
||||||
|
@ -301,6 +312,7 @@ class Dir(Base):
|
||||||
for key, entry in self.entries.items():
|
for key, entry in self.entries.items():
|
||||||
entry.convert_from_sconsign(dir, key)
|
entry.convert_from_sconsign(dir, key)
|
||||||
|
|
||||||
|
|
||||||
class DirFile(Dir):
|
class DirFile(Dir):
|
||||||
"""
|
"""
|
||||||
Encapsulates reading and writing a per-directory .sconsign file.
|
Encapsulates reading and writing a per-directory .sconsign file.
|
||||||
|
@ -359,12 +371,12 @@ class DirFile(Dir):
|
||||||
return
|
return
|
||||||
for key, entry in self.entries.items():
|
for key, entry in self.entries.items():
|
||||||
entry.convert_to_sconsign()
|
entry.convert_to_sconsign()
|
||||||
pickle.dump(self.entries, file, 1)
|
pickle.dump(self.entries, file, PICKLE_PROTOCOL)
|
||||||
file.close()
|
file.close()
|
||||||
if fname != self.sconsign:
|
if fname != self.sconsign:
|
||||||
try:
|
try:
|
||||||
mode = os.stat(self.sconsign)[0]
|
mode = os.stat(self.sconsign)[0]
|
||||||
os.chmod(self.sconsign, 0666)
|
os.chmod(self.sconsign, 0o666)
|
||||||
os.unlink(self.sconsign)
|
os.unlink(self.sconsign)
|
||||||
except (IOError, OSError):
|
except (IOError, OSError):
|
||||||
# Try to carry on in the face of either OSError
|
# Try to carry on in the face of either OSError
|
||||||
|
@ -391,6 +403,7 @@ class DirFile(Dir):
|
||||||
|
|
||||||
ForDirectory = DB
|
ForDirectory = DB
|
||||||
|
|
||||||
|
|
||||||
def File(name, dbm_module=None):
|
def File(name, dbm_module=None):
|
||||||
"""
|
"""
|
||||||
Arrange for all signatures to be stored in a global .sconsign.db*
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,7 +27,7 @@ This module implements the dependency scanner for C/C++ code.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Scanner/C.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Scanner/C.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
||||||
|
@ -58,12 +58,11 @@ class SConsCPPScanner(SCons.cpp.PreProcessor):
|
||||||
return result
|
return result
|
||||||
def read_file(self, file):
|
def read_file(self, file):
|
||||||
try:
|
try:
|
||||||
fp = open(str(file.rfile()))
|
with open(str(file.rfile())) as fp:
|
||||||
except EnvironmentError, e:
|
return fp.read()
|
||||||
|
except EnvironmentError as e:
|
||||||
self.missing.append((file, self.current_file))
|
self.missing.append((file, self.current_file))
|
||||||
return ''
|
return ''
|
||||||
else:
|
|
||||||
return fp.read()
|
|
||||||
|
|
||||||
def dictify_CPPDEFINES(env):
|
def dictify_CPPDEFINES(env):
|
||||||
cppdefines = env.get('CPPDEFINES', {})
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,9 +30,7 @@ Coded by Andy Friesen
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Scanner/D.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Scanner/D.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
||||||
|
|
||||||
|
@ -43,13 +41,13 @@ def DScanner():
|
||||||
|
|
||||||
class D(SCons.Scanner.Classic):
|
class D(SCons.Scanner.Classic):
|
||||||
def __init__ (self):
|
def __init__ (self):
|
||||||
SCons.Scanner.Classic.__init__ (self,
|
SCons.Scanner.Classic.__init__ (
|
||||||
|
self,
|
||||||
name = "DScanner",
|
name = "DScanner",
|
||||||
suffixes = '$DSUFFIXES',
|
suffixes = '$DSUFFIXES',
|
||||||
path_variable = 'DPATH',
|
path_variable = 'DPATH',
|
||||||
regex = 'import\s+(?:[a-zA-Z0-9_.]+)\s*(?:,\s*(?:[a-zA-Z0-9_.]+)\s*)*;')
|
regex = '(?:import\s+)([\w\s=,.]+)(?:\s*:[\s\w,=]+)?(?:;)'
|
||||||
|
)
|
||||||
self.cre2 = re.compile ('(?:import\s)?\s*([a-zA-Z0-9_.]+)\s*(?:,|;)', re.M)
|
|
||||||
|
|
||||||
def find_include(self, include, source_dir, path):
|
def find_include(self, include, source_dir, path):
|
||||||
# translate dots (package separators) to slashes
|
# translate dots (package separators) to slashes
|
||||||
|
@ -62,8 +60,10 @@ class D(SCons.Scanner.Classic):
|
||||||
|
|
||||||
def find_include_names(self, node):
|
def find_include_names(self, node):
|
||||||
includes = []
|
includes = []
|
||||||
for i in self.cre.findall(node.get_text_contents()):
|
for iii in self.cre.findall(node.get_text_contents()):
|
||||||
includes = includes + self.cre2.findall(i)
|
for jjj in iii.split(','):
|
||||||
|
kkk = jjj.split('=')[-1]
|
||||||
|
includes.append(kkk.strip())
|
||||||
return includes
|
return includes
|
||||||
|
|
||||||
# Local Variables:
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -20,14 +20,14 @@
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Scanner/Dir.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Scanner/Dir.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
||||||
|
|
||||||
def only_dirs(nodes):
|
def only_dirs(nodes):
|
||||||
is_Dir = lambda n: isinstance(n.disambiguate(), SCons.Node.FS.Dir)
|
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):
|
def DirScanner(**kw):
|
||||||
"""Return a prototype Scanner instance for scanning
|
"""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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -26,7 +26,7 @@ This module implements the dependency scanner for Fortran code.
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Scanner/Fortran.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Scanner/Fortran.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import re
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -28,7 +28,7 @@ Definition Language) files.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Scanner/IDL.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Scanner/IDL.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Scanner
|
import SCons.Scanner
|
|
@ -5,7 +5,7 @@ This module implements the dependency scanner for 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,7 +27,7 @@ This module implements the dependency scanner for LaTeX code.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Scanner/LaTeX.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Scanner/LaTeX.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
||||||
|
@ -37,7 +37,9 @@ import SCons.Util
|
||||||
|
|
||||||
# list of graphics file extensions for TeX and LaTeX
|
# list of graphics file extensions for TeX and LaTeX
|
||||||
TexGraphics = ['.eps', '.ps']
|
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.
|
# Used as a return value of modify_env_var if the variable is not set.
|
||||||
class _Null(object):
|
class _Null(object):
|
||||||
|
@ -76,8 +78,10 @@ def modify_env_var(env, var, abspath):
|
||||||
return save
|
return save
|
||||||
|
|
||||||
class FindENVPathDirs(object):
|
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):
|
def __init__(self, variable):
|
||||||
self.variable = variable
|
self.variable = variable
|
||||||
def __call__(self, env, dir=None, target=None, source=None, argument=None):
|
def __call__(self, env, dir=None, target=None, source=None, argument=None):
|
||||||
|
@ -94,7 +98,8 @@ class FindENVPathDirs(object):
|
||||||
|
|
||||||
|
|
||||||
def LaTeXScanner():
|
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.
|
when built with latex.
|
||||||
"""
|
"""
|
||||||
ds = LaTeX(name = "LaTeXScanner",
|
ds = LaTeX(name = "LaTeXScanner",
|
||||||
|
@ -105,7 +110,8 @@ def LaTeXScanner():
|
||||||
return ds
|
return ds
|
||||||
|
|
||||||
def PDFLaTeXScanner():
|
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.
|
when built with pdflatex.
|
||||||
"""
|
"""
|
||||||
ds = LaTeX(name = "PDFLaTeXScanner",
|
ds = LaTeX(name = "PDFLaTeXScanner",
|
||||||
|
@ -116,7 +122,8 @@ def PDFLaTeXScanner():
|
||||||
return ds
|
return ds
|
||||||
|
|
||||||
class LaTeX(SCons.Scanner.Base):
|
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
|
Unlike most scanners, which use regular expressions that just
|
||||||
return the included file name, this returns a tuple consisting
|
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
|
The actual subset and search order may be altered by
|
||||||
DeclareGraphicsExtensions command. This complication is ignored.
|
DeclareGraphicsExtensions command. This complication is ignored.
|
||||||
The default order corresponds to experimentation with teTeX
|
The default order corresponds to experimentation with teTeX::
|
||||||
|
|
||||||
$ latex --version
|
$ latex --version
|
||||||
pdfeTeX 3.141592-1.21a-2.2 (Web2C 7.5.4)
|
pdfeTeX 3.141592-1.21a-2.2 (Web2C 7.5.4)
|
||||||
kpathsea version 3.5.4
|
kpathsea version 3.5.4
|
||||||
|
|
||||||
The order is:
|
The order is:
|
||||||
['.eps', '.ps'] for latex
|
['.eps', '.ps'] for latex
|
||||||
['.png', '.pdf', '.jpg', '.tif'].
|
['.png', '.pdf', '.jpg', '.tif'].
|
||||||
|
@ -148,8 +157,7 @@ class LaTeX(SCons.Scanner.Base):
|
||||||
env['TEXINPUTS'] for "lstinputlisting" keyword
|
env['TEXINPUTS'] for "lstinputlisting" keyword
|
||||||
env['BIBINPUTS'] for "bibliography" keyword
|
env['BIBINPUTS'] for "bibliography" keyword
|
||||||
env['BSTINPUTS'] for "bibliographystyle" keyword
|
env['BSTINPUTS'] for "bibliographystyle" keyword
|
||||||
env['INDEXSTYLE'] for "makeindex" keyword, no scanning support needed
|
env['INDEXSTYLE'] for "makeindex" keyword, no scanning support needed just allows user to set it if 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 class or style in document[class|style]{}
|
||||||
FIXME: also look for the argument of bibliographystyle{}
|
FIXME: also look for the argument of bibliographystyle{}
|
||||||
|
@ -166,6 +174,9 @@ class LaTeX(SCons.Scanner.Base):
|
||||||
'usepackage': 'TEXINPUTS',
|
'usepackage': 'TEXINPUTS',
|
||||||
'lstinputlisting': 'TEXINPUTS'}
|
'lstinputlisting': 'TEXINPUTS'}
|
||||||
env_variables = SCons.Util.unique(list(keyword_paths.values()))
|
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):
|
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
|
# line followed by one or more newline characters (i.e. blank
|
||||||
# lines), interfering with a match on the next line.
|
# lines), interfering with a match on the next line.
|
||||||
# add option for whitespace before the '[options]' or the '{filename}'
|
# add option for whitespace before the '[options]' or the '{filename}'
|
||||||
regex = r'^[^%\n]*\\(include|includegraphics(?:\s*\[[^\]]+\])?|lstinputlisting(?:\[[^\]]+\])?|input|bibliography|addbibresource|addglobalbib|addsectionbib|usepackage)\s*{([^}]*)}'
|
regex = r'''
|
||||||
self.cre = re.compile(regex, re.M)
|
^[^%\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.comment_re = re.compile(r'^((?:(?:\\%)|[^%\n])*)(.*)$', re.M)
|
||||||
|
|
||||||
self.graphics_extensions = graphics_extensions
|
self.graphics_extensions = graphics_extensions
|
||||||
|
@ -236,23 +268,26 @@ class LaTeX(SCons.Scanner.Base):
|
||||||
|
|
||||||
SCons.Scanner.Base.__init__(self, *args, **kw)
|
SCons.Scanner.Base.__init__(self, *args, **kw)
|
||||||
|
|
||||||
def _latex_names(self, include):
|
def _latex_names(self, include_type, filename):
|
||||||
filename = include[1]
|
if include_type == 'input':
|
||||||
if include[0] == 'input':
|
|
||||||
base, ext = os.path.splitext( filename )
|
base, ext = os.path.splitext( filename )
|
||||||
if ext == "":
|
if ext == "":
|
||||||
return [filename + '.tex']
|
return [filename + '.tex']
|
||||||
if (include[0] == 'include'):
|
if include_type in ('include', 'import', 'subimport',
|
||||||
return [filename + '.tex']
|
'includefrom', 'subincludefrom',
|
||||||
if include[0] == 'bibliography':
|
'inputfrom', 'subinputfrom'):
|
||||||
|
base, ext = os.path.splitext( filename )
|
||||||
|
if ext == "":
|
||||||
|
return [filename + '.tex']
|
||||||
|
if include_type == 'bibliography':
|
||||||
base, ext = os.path.splitext( filename )
|
base, ext = os.path.splitext( filename )
|
||||||
if ext == "":
|
if ext == "":
|
||||||
return [filename + '.bib']
|
return [filename + '.bib']
|
||||||
if include[0] == 'usepackage':
|
if include_type == 'usepackage':
|
||||||
base, ext = os.path.splitext( filename )
|
base, ext = os.path.splitext( filename )
|
||||||
if ext == "":
|
if ext == "":
|
||||||
return [filename + '.sty']
|
return [filename + '.sty']
|
||||||
if include[0] == 'includegraphics':
|
if include_type == 'includegraphics':
|
||||||
base, ext = os.path.splitext( filename )
|
base, ext = os.path.splitext( filename )
|
||||||
if ext == "":
|
if ext == "":
|
||||||
#return [filename+e for e in self.graphics_extensions + TexGraphics]
|
#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))
|
return SCons.Node.FS._my_normcase(str(include))
|
||||||
|
|
||||||
def find_include(self, include, source_dir, path):
|
def find_include(self, include, source_dir, path):
|
||||||
|
inc_type, inc_subdir, inc_filename = include
|
||||||
try:
|
try:
|
||||||
sub_path = path[include[0]]
|
sub_paths = path[inc_type]
|
||||||
except (IndexError, KeyError):
|
except (IndexError, KeyError):
|
||||||
sub_path = ()
|
sub_paths = ((), ())
|
||||||
try_names = self._latex_names(include)
|
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:
|
for n in try_names:
|
||||||
# see if we find it using the path in env[var]
|
for search_path in search_paths:
|
||||||
i = SCons.Node.FS.find_file(n, (source_dir,) + sub_path[0])
|
paths = tuple([d.Dir(inc_subdir) for d in search_path])
|
||||||
if i:
|
i = SCons.Node.FS.find_file(n, paths)
|
||||||
return i, include
|
if i:
|
||||||
# see if we find it using the path in env['ENV'][var]
|
return i, include
|
||||||
i = SCons.Node.FS.find_file(n, (source_dir,) + sub_path[1])
|
return None, include
|
||||||
if i:
|
|
||||||
return i, include
|
|
||||||
return i, include
|
|
||||||
|
|
||||||
def canonical_text(self, text):
|
def canonical_text(self, text):
|
||||||
"""Standardize an input TeX-file contents.
|
"""Standardize an input TeX-file contents.
|
||||||
|
@ -300,7 +340,7 @@ class LaTeX(SCons.Scanner.Base):
|
||||||
line_continues_a_comment = len(comment) > 0
|
line_continues_a_comment = len(comment) > 0
|
||||||
return '\n'.join(out).rstrip()+'\n'
|
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
|
# Modify the default scan function to allow for the regular
|
||||||
# expression to return a comma separated list of file names
|
# expression to return a comma separated list of file names
|
||||||
# as can be the case with the bibliography keyword.
|
# as can be the case with the bibliography keyword.
|
||||||
|
@ -326,9 +366,14 @@ class LaTeX(SCons.Scanner.Base):
|
||||||
split_includes = []
|
split_includes = []
|
||||||
for include in includes:
|
for include in includes:
|
||||||
inc_type = noopt_cre.sub('', include[0])
|
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)):
|
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
|
includes = split_includes
|
||||||
node.includes = includes
|
node.includes = includes
|
||||||
|
@ -359,11 +404,13 @@ class LaTeX(SCons.Scanner.Base):
|
||||||
while queue:
|
while queue:
|
||||||
|
|
||||||
include = queue.pop()
|
include = queue.pop()
|
||||||
|
inc_type, inc_subdir, inc_filename = include
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if seen[include[1]] == 1:
|
if seen[inc_filename] == 1:
|
||||||
continue
|
continue
|
||||||
except KeyError:
|
except KeyError:
|
||||||
seen[include[1]] = 1
|
seen[inc_filename] = 1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Handle multiple filenames in include[1]
|
# Handle multiple filenames in include[1]
|
||||||
|
@ -372,14 +419,14 @@ class LaTeX(SCons.Scanner.Base):
|
||||||
if n is None:
|
if n is None:
|
||||||
# Do not bother with 'usepackage' warnings, as they most
|
# Do not bother with 'usepackage' warnings, as they most
|
||||||
# likely refer to system-level files
|
# likely refer to system-level files
|
||||||
if include[0] != 'usepackage':
|
if inc_type != 'usepackage':
|
||||||
SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
|
SCons.Warnings.warn(SCons.Warnings.DependencyWarning,
|
||||||
"No dependency generated for file: %s (included from: %s) -- file not found" % (i, node))
|
"No dependency generated for file: %s (included from: %s) -- file not found" % (i, node))
|
||||||
else:
|
else:
|
||||||
sortkey = self.sort_key(n)
|
sortkey = self.sort_key(n)
|
||||||
nodes.append((sortkey, n))
|
nodes.append((sortkey, n))
|
||||||
# recurse down
|
# recurse down
|
||||||
queue.extend( self.scan(n) )
|
queue.extend( self.scan(n, inc_subdir) )
|
||||||
|
|
||||||
return [pair[1] for pair in sorted(nodes)]
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Scanner/Prog.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Scanner/Prog.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.Node
|
import SCons.Node
|
||||||
import SCons.Node.FS
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -28,23 +28,34 @@ Definition Language) files.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Scanner/RC.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Scanner/RC.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
import SCons.Scanner
|
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():
|
def RCScan():
|
||||||
"""Return a prototype Scanner instance for scanning RC source files"""
|
"""Return a prototype Scanner instance for scanning RC source files"""
|
||||||
|
|
||||||
res_re= r'^(?:\s*#\s*(?:include)|' \
|
res_re= r'^(?:\s*#\s*(?:include)|' \
|
||||||
'.*?\s+(?:ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)' \
|
'.*?\s+(?:ICON|BITMAP|CURSOR|HTML|FONT|MESSAGETABLE|TYPELIB|REGISTRY|D3DFX)' \
|
||||||
'\s*.*?)' \
|
'\s*.*?)' \
|
||||||
'\s*(<|"| )([^>"\s]+)(?:[>"\s])*$'
|
'\s*(<|"| )([^>"\s]+)(?:[>"\s])*$'
|
||||||
resScanner = SCons.Scanner.ClassicCPP( "ResourceScanner",
|
resScanner = SCons.Scanner.ClassicCPP("ResourceScanner",
|
||||||
"$RCSUFFIXES",
|
"$RCSUFFIXES",
|
||||||
"CPPPATH",
|
"CPPPATH",
|
||||||
res_re )
|
res_re,
|
||||||
|
recursive=no_tlb)
|
||||||
|
|
||||||
return resScanner
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,7 +27,7 @@ This module implements the dependency scanner for SWIG code.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Scanner/SWIG.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Scanner/SWIG.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.Scanner
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,7 +27,7 @@ The Scanner package for the SCons software construction utility.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Scanner/__init__.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Scanner/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
@ -62,8 +62,10 @@ def Scanner(function, *args, **kw):
|
||||||
|
|
||||||
|
|
||||||
class FindPathDirs(object):
|
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):
|
def __init__(self, variable):
|
||||||
self.variable = variable
|
self.variable = variable
|
||||||
def __call__(self, env, dir=None, target=None, source=None, argument=None):
|
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):
|
def path(self, env, dir=None, target=None, source=None):
|
||||||
if not self.path_function:
|
if not self.path_function:
|
||||||
return ()
|
return ()
|
||||||
if not self.argument is _null:
|
if self.argument is not _null:
|
||||||
return self.path_function(env, dir, target, source, self.argument)
|
return self.path_function(env, dir, target, source, self.argument)
|
||||||
else:
|
else:
|
||||||
return self.path_function(env, dir, target, source)
|
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
|
This method scans a single object. 'node' is the node
|
||||||
that will be passed to the scanner function, and 'env' is the
|
that will be passed to the scanner function, and 'env' is the
|
||||||
|
@ -206,27 +208,27 @@ class Base(object):
|
||||||
self = self.select(node)
|
self = self.select(node)
|
||||||
|
|
||||||
if not self.argument is _null:
|
if not self.argument is _null:
|
||||||
list = self.function(node, env, path, self.argument)
|
node_list = self.function(node, env, path, self.argument)
|
||||||
else:
|
else:
|
||||||
list = self.function(node, env, path)
|
node_list = self.function(node, env, path)
|
||||||
|
|
||||||
kw = {}
|
kw = {}
|
||||||
if hasattr(node, 'dir'):
|
if hasattr(node, 'dir'):
|
||||||
kw['directory'] = node.dir
|
kw['directory'] = node.dir
|
||||||
node_factory = env.get_factory(self.node_factory)
|
node_factory = env.get_factory(self.node_factory)
|
||||||
nodes = []
|
nodes = []
|
||||||
for l in list:
|
for l in node_list:
|
||||||
if self.node_class and not isinstance(l, self.node_class):
|
if self.node_class and not isinstance(l, self.node_class):
|
||||||
l = node_factory(l, **kw)
|
l = node_factory(l, **kw)
|
||||||
nodes.append(l)
|
nodes.append(l)
|
||||||
return nodes
|
return nodes
|
||||||
|
|
||||||
def __cmp__(self, other):
|
def __eq__(self, other):
|
||||||
try:
|
try:
|
||||||
return cmp(self.__dict__, other.__dict__)
|
return self.__dict__ == other.__dict__
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# other probably doesn't have a __dict__
|
# other probably doesn't have a __dict__
|
||||||
return cmp(self.__dict__, other)
|
return self.__dict__ == other
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
return id(self)
|
return id(self)
|
||||||
|
@ -259,7 +261,7 @@ class Base(object):
|
||||||
def _recurse_no_nodes(self, nodes):
|
def _recurse_no_nodes(self, nodes):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
recurse_nodes = _recurse_no_nodes
|
# recurse_nodes = _recurse_no_nodes
|
||||||
|
|
||||||
def add_scanner(self, skey, scanner):
|
def add_scanner(self, skey, scanner):
|
||||||
self.function[skey] = scanner
|
self.function[skey] = scanner
|
||||||
|
@ -283,7 +285,7 @@ class Selector(Base):
|
||||||
self.dict = dict
|
self.dict = dict
|
||||||
self.skeys = list(dict.keys())
|
self.skeys = list(dict.keys())
|
||||||
|
|
||||||
def __call__(self, node, env, path = ()):
|
def __call__(self, node, env, path=()):
|
||||||
return self.select(node)(node, env, path)
|
return self.select(node)(node, env, path)
|
||||||
|
|
||||||
def select(self, node):
|
def select(self, node):
|
||||||
|
@ -326,7 +328,7 @@ class Classic(Current):
|
||||||
|
|
||||||
self.cre = re.compile(regex, re.M)
|
self.cre = re.compile(regex, re.M)
|
||||||
|
|
||||||
def _scan(node, env, path=(), self=self):
|
def _scan(node, _, path=(), self=self):
|
||||||
node = node.rfile()
|
node = node.rfile()
|
||||||
if not node.exists():
|
if not node.exists():
|
||||||
return []
|
return []
|
||||||
|
@ -334,7 +336,12 @@ class Classic(Current):
|
||||||
|
|
||||||
kw['function'] = _scan
|
kw['function'] = _scan
|
||||||
kw['path_function'] = FindPathDirs(path_variable)
|
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['skeys'] = suffixes
|
||||||
kw['name'] = name
|
kw['name'] = name
|
||||||
|
|
||||||
|
@ -356,7 +363,7 @@ class Classic(Current):
|
||||||
if node.includes is not None:
|
if node.includes is not None:
|
||||||
includes = node.includes
|
includes = node.includes
|
||||||
else:
|
else:
|
||||||
includes = self.find_include_names (node)
|
includes = self.find_include_names(node)
|
||||||
# Intern the names of the include files. Saves some memory
|
# Intern the names of the include files. Saves some memory
|
||||||
# if the same header is included many times.
|
# if the same header is included many times.
|
||||||
node.includes = list(map(SCons.Util.silent_intern, includes))
|
node.includes = list(map(SCons.Util.silent_intern, includes))
|
||||||
|
@ -393,6 +400,7 @@ class ClassicCPP(Classic):
|
||||||
the contained filename in group 1.
|
the contained filename in group 1.
|
||||||
"""
|
"""
|
||||||
def find_include(self, include, source_dir, path):
|
def find_include(self, include, source_dir, path):
|
||||||
|
include = list(map(SCons.Util.to_str, include))
|
||||||
if include[0] == '"':
|
if include[0] == '"':
|
||||||
paths = (source_dir,) + tuple(path)
|
paths = (source_dir,) + tuple(path)
|
||||||
else:
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -19,8 +19,9 @@
|
||||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Script/Interactive.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Script/Interactive.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
__doc__ = """
|
__doc__ = """
|
||||||
SCons interactive mode
|
SCons interactive mode
|
||||||
|
@ -98,17 +99,14 @@ except ImportError:
|
||||||
|
|
||||||
class SConsInteractiveCmd(cmd.Cmd):
|
class SConsInteractiveCmd(cmd.Cmd):
|
||||||
"""\
|
"""\
|
||||||
build [TARGETS] Build the specified TARGETS and their dependencies.
|
|
||||||
'b' is a synonym.
|
build [TARGETS] Build the specified TARGETS and their dependencies. 'b' is a synonym.
|
||||||
clean [TARGETS] Clean (remove) the specified TARGETS and their
|
clean [TARGETS] Clean (remove) the specified TARGETS and their dependencies. 'c' is a synonym.
|
||||||
dependencies. 'c' is a synonym.
|
exit Exit SCons interactive mode.
|
||||||
exit Exit SCons interactive mode.
|
help [COMMAND] Prints help for the specified COMMAND. 'h' and '?' are synonyms.
|
||||||
help [COMMAND] Prints help for the specified COMMAND. 'h' and
|
shell [COMMANDLINE] Execute COMMANDLINE in a subshell. 'sh' and '!' are synonyms.
|
||||||
'?' are synonyms.
|
version Prints SCons version information.
|
||||||
shell [COMMANDLINE] Execute COMMANDLINE in a subshell. 'sh' and '!'
|
"""
|
||||||
are synonyms.
|
|
||||||
version Prints SCons version information.
|
|
||||||
"""
|
|
||||||
|
|
||||||
synonyms = {
|
synonyms = {
|
||||||
'b' : 'build',
|
'b' : 'build',
|
||||||
|
@ -129,12 +127,12 @@ class SConsInteractiveCmd(cmd.Cmd):
|
||||||
self.shell_variable = 'SHELL'
|
self.shell_variable = 'SHELL'
|
||||||
|
|
||||||
def default(self, argv):
|
def default(self, argv):
|
||||||
print "*** Unknown command: %s" % argv[0]
|
print("*** Unknown command: %s" % argv[0])
|
||||||
|
|
||||||
def onecmd(self, line):
|
def onecmd(self, line):
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line:
|
if not line:
|
||||||
print self.lastcmd
|
print(self.lastcmd)
|
||||||
return self.emptyline()
|
return self.emptyline()
|
||||||
self.lastcmd = line
|
self.lastcmd = line
|
||||||
if line[0] == '!':
|
if line[0] == '!':
|
||||||
|
@ -221,7 +219,7 @@ class SConsInteractiveCmd(cmd.Cmd):
|
||||||
def get_unseen_children(node, parent, seen_nodes=seen_nodes):
|
def get_unseen_children(node, parent, seen_nodes=seen_nodes):
|
||||||
def is_unseen(node, seen_nodes=seen_nodes):
|
def is_unseen(node, seen_nodes=seen_nodes):
|
||||||
return node not in 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):
|
def add_to_seen_nodes(node, parent, seen_nodes=seen_nodes):
|
||||||
seen_nodes[node] = 1
|
seen_nodes[node] = 1
|
||||||
|
@ -249,7 +247,7 @@ class SConsInteractiveCmd(cmd.Cmd):
|
||||||
while n:
|
while n:
|
||||||
n = walker.get_next()
|
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
|
# Call node.clear() to clear most of the state
|
||||||
node.clear()
|
node.clear()
|
||||||
# node.clear() doesn't reset node.state, so call
|
# 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:])
|
return self.do_build(['build', '--clean'] + argv[1:])
|
||||||
|
|
||||||
def do_EOF(self, argv):
|
def do_EOF(self, argv):
|
||||||
print
|
print()
|
||||||
self.do_exit(argv)
|
self.do_exit(argv)
|
||||||
|
|
||||||
def _do_one_help(self, arg):
|
def _do_one_help(self, arg):
|
||||||
|
@ -351,7 +349,7 @@ class SConsInteractiveCmd(cmd.Cmd):
|
||||||
# Doing the right thing with an argument list currently
|
# Doing the right thing with an argument list currently
|
||||||
# requires different shell= values on Windows and Linux.
|
# requires different shell= values on Windows and Linux.
|
||||||
p = subprocess.Popen(argv, shell=(sys.platform=='win32'))
|
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))
|
sys.stderr.write('scons: %s: %s\n' % (argv[0], e.strerror))
|
||||||
else:
|
else:
|
||||||
p.wait()
|
p.wait()
|
|
@ -10,10 +10,14 @@ some other module. If it's specific to the "scons" script invocation,
|
||||||
it goes here.
|
it goes here.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
|
||||||
unsupported_python_version = (2, 6, 0)
|
unsupported_python_version = (2, 6, 0)
|
||||||
deprecated_python_version = (2, 7, 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -34,7 +38,8 @@ deprecated_python_version = (2, 7, 0)
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Script/Main.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Script/Main.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
|
|
||||||
import SCons.compat
|
import SCons.compat
|
||||||
|
|
||||||
|
@ -42,6 +47,7 @@ import os
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
import sysconfig
|
||||||
|
|
||||||
import SCons.CacheDir
|
import SCons.CacheDir
|
||||||
import SCons.Debug
|
import SCons.Debug
|
||||||
|
@ -60,6 +66,7 @@ import SCons.Warnings
|
||||||
|
|
||||||
import SCons.Script.Interactive
|
import SCons.Script.Interactive
|
||||||
|
|
||||||
|
|
||||||
def fetch_win32_parallel_msg():
|
def fetch_win32_parallel_msg():
|
||||||
# A subsidiary function that exists solely to isolate this import
|
# 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
|
# 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
|
import SCons.Platform.win32
|
||||||
return SCons.Platform.win32.parallel_msg
|
return SCons.Platform.win32.parallel_msg
|
||||||
|
|
||||||
|
|
||||||
def revert_io():
|
def revert_io():
|
||||||
# This call is added to revert stderr and stdout to the original
|
# 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
|
# 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
|
first_command_start = None
|
||||||
last_command_end = None
|
last_command_end = None
|
||||||
|
|
||||||
|
|
||||||
class Progressor(object):
|
class Progressor(object):
|
||||||
prev = ''
|
prev = ''
|
||||||
count = 0
|
count = 0
|
||||||
|
@ -149,9 +158,11 @@ def Progress(*args, **kw):
|
||||||
|
|
||||||
_BuildFailures = []
|
_BuildFailures = []
|
||||||
|
|
||||||
|
|
||||||
def GetBuildFailures():
|
def GetBuildFailures():
|
||||||
return _BuildFailures
|
return _BuildFailures
|
||||||
|
|
||||||
|
|
||||||
class BuildTask(SCons.Taskmaster.OutOfDateTask):
|
class BuildTask(SCons.Taskmaster.OutOfDateTask):
|
||||||
"""An SCons build task."""
|
"""An SCons build task."""
|
||||||
progress = ProgressObject
|
progress = ProgressObject
|
||||||
|
@ -220,7 +231,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask):
|
||||||
self.exception_set()
|
self.exception_set()
|
||||||
self.do_failed()
|
self.do_failed()
|
||||||
else:
|
else:
|
||||||
print "scons: Nothing to be done for `%s'." % t
|
print("scons: Nothing to be done for `%s'." % t)
|
||||||
SCons.Taskmaster.OutOfDateTask.executed(self)
|
SCons.Taskmaster.OutOfDateTask.executed(self)
|
||||||
else:
|
else:
|
||||||
SCons.Taskmaster.OutOfDateTask.executed(self)
|
SCons.Taskmaster.OutOfDateTask.executed(self)
|
||||||
|
@ -289,8 +300,8 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask):
|
||||||
if self.options.debug_includes:
|
if self.options.debug_includes:
|
||||||
tree = t.render_include_tree()
|
tree = t.render_include_tree()
|
||||||
if tree:
|
if tree:
|
||||||
print
|
print()
|
||||||
print tree
|
print(tree)
|
||||||
SCons.Taskmaster.OutOfDateTask.postprocess(self)
|
SCons.Taskmaster.OutOfDateTask.postprocess(self)
|
||||||
|
|
||||||
def make_ready(self):
|
def make_ready(self):
|
||||||
|
@ -301,6 +312,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask):
|
||||||
if explanation:
|
if explanation:
|
||||||
sys.stdout.write("scons: " + explanation)
|
sys.stdout.write("scons: " + explanation)
|
||||||
|
|
||||||
|
|
||||||
class CleanTask(SCons.Taskmaster.AlwaysTask):
|
class CleanTask(SCons.Taskmaster.AlwaysTask):
|
||||||
"""An SCons clean task."""
|
"""An SCons clean task."""
|
||||||
def fs_delete(self, path, pathstr, remove=True):
|
def fs_delete(self, path, pathstr, remove=True):
|
||||||
|
@ -325,10 +337,10 @@ class CleanTask(SCons.Taskmaster.AlwaysTask):
|
||||||
else:
|
else:
|
||||||
errstr = "Path '%s' exists but isn't a file or directory."
|
errstr = "Path '%s' exists but isn't a file or directory."
|
||||||
raise SCons.Errors.UserError(errstr % (pathstr))
|
raise SCons.Errors.UserError(errstr % (pathstr))
|
||||||
except SCons.Errors.UserError, e:
|
except SCons.Errors.UserError as e:
|
||||||
print e
|
print(e)
|
||||||
except (IOError, OSError), e:
|
except (IOError, OSError) as e:
|
||||||
print "scons: Could not remove '%s':" % pathstr, e.strerror
|
print("scons: Could not remove '%s':" % pathstr, e.strerror)
|
||||||
|
|
||||||
def _get_files_to_clean(self):
|
def _get_files_to_clean(self):
|
||||||
result = []
|
result = []
|
||||||
|
@ -354,13 +366,13 @@ class CleanTask(SCons.Taskmaster.AlwaysTask):
|
||||||
for t in self._get_files_to_clean():
|
for t in self._get_files_to_clean():
|
||||||
try:
|
try:
|
||||||
removed = t.remove()
|
removed = t.remove()
|
||||||
except OSError, e:
|
except OSError as e:
|
||||||
# An OSError may indicate something like a permissions
|
# An OSError may indicate something like a permissions
|
||||||
# issue, an IOError would indicate something like
|
# issue, an IOError would indicate something like
|
||||||
# the file not existing. In either case, print a
|
# the file not existing. In either case, print a
|
||||||
# message and keep going to try to remove as many
|
# message and keep going to try to remove as many
|
||||||
# targets as possible.
|
# 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:
|
else:
|
||||||
if removed:
|
if removed:
|
||||||
display("Removed " + str(t))
|
display("Removed " + str(t))
|
||||||
|
@ -600,7 +612,7 @@ def _scons_internal_error():
|
||||||
"""Handle all errors but user errors. Print out a message telling
|
"""Handle all errors but user errors. Print out a message telling
|
||||||
the user what to do in this case and print a normal trace.
|
the user what to do in this case and print a normal trace.
|
||||||
"""
|
"""
|
||||||
print 'internal error'
|
print('internal error')
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
|
@ -714,7 +726,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None):
|
||||||
# the error checking makes it longer.
|
# the error checking makes it longer.
|
||||||
try:
|
try:
|
||||||
m = sys.modules['SCons.Script']
|
m = sys.modules['SCons.Script']
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
fmt = 'cannot import site_init.py: missing SCons.Script module %s'
|
fmt = 'cannot import site_init.py: missing SCons.Script module %s'
|
||||||
raise SCons.Errors.InternalError(fmt % repr(e))
|
raise SCons.Errors.InternalError(fmt % repr(e))
|
||||||
try:
|
try:
|
||||||
|
@ -722,15 +734,15 @@ def _load_site_scons_dir(topdir, site_dir_name=None):
|
||||||
modname = os.path.basename(pathname)[:-len(sfx)]
|
modname = os.path.basename(pathname)[:-len(sfx)]
|
||||||
site_m = {"__file__": pathname, "__name__": modname, "__doc__": None}
|
site_m = {"__file__": pathname, "__name__": modname, "__doc__": None}
|
||||||
re_special = re.compile("__[^_]+__")
|
re_special = re.compile("__[^_]+__")
|
||||||
for k in m.__dict__.keys():
|
for k in list(m.__dict__.keys()):
|
||||||
if not re_special.match(k):
|
if not re_special.match(k):
|
||||||
site_m[k] = m.__dict__[k]
|
site_m[k] = m.__dict__[k]
|
||||||
|
|
||||||
# This is the magic.
|
# This is the magic.
|
||||||
exec fp in site_m
|
exec(compile(fp.read(), fp.name, 'exec'), site_m)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
fmt = '*** Error loading site_init file %s:\n'
|
fmt = '*** Error loading site_init file %s:\n'
|
||||||
sys.stderr.write(fmt % repr(site_init_file))
|
sys.stderr.write(fmt % repr(site_init_file))
|
||||||
raise
|
raise
|
||||||
|
@ -740,7 +752,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None):
|
||||||
m.__dict__[k] = site_m[k]
|
m.__dict__[k] = site_m[k]
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except ImportError, e:
|
except ImportError as e:
|
||||||
fmt = '*** cannot import site init file %s:\n'
|
fmt = '*** cannot import site init file %s:\n'
|
||||||
sys.stderr.write(fmt % repr(site_init_file))
|
sys.stderr.write(fmt % repr(site_init_file))
|
||||||
raise
|
raise
|
||||||
|
@ -792,7 +804,7 @@ def _load_all_site_scons_dirs(topdir, verbose=None):
|
||||||
dirs=sysdirs + [topdir]
|
dirs=sysdirs + [topdir]
|
||||||
for d in dirs:
|
for d in dirs:
|
||||||
if verbose: # this is used by unit tests.
|
if verbose: # this is used by unit tests.
|
||||||
print "Loading site dir ", d
|
print("Loading site dir ", d)
|
||||||
_load_site_scons_dir(d)
|
_load_site_scons_dir(d)
|
||||||
|
|
||||||
def test_load_all_site_scons_dirs(d):
|
def test_load_all_site_scons_dirs(d):
|
||||||
|
@ -992,7 +1004,7 @@ def _main(parser):
|
||||||
try:
|
try:
|
||||||
for script in scripts:
|
for script in scripts:
|
||||||
SCons.Script._SConscript._SConscript(fs, script)
|
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
|
# We had problems reading an SConscript file, such as it
|
||||||
# couldn't be copied in to the VariantDir. Since we're just
|
# couldn't be copied in to the VariantDir. Since we're just
|
||||||
# reading SConscript files and haven't started building
|
# reading SConscript files and haven't started building
|
||||||
|
@ -1053,8 +1065,8 @@ def _main(parser):
|
||||||
# SConscript files. Give them the options usage.
|
# SConscript files. Give them the options usage.
|
||||||
raise SConsPrintHelpException
|
raise SConsPrintHelpException
|
||||||
else:
|
else:
|
||||||
print help_text
|
print(help_text)
|
||||||
print "Use scons -H for help about command-line options."
|
print("Use scons -H for help about command-line options.")
|
||||||
exit_status = 0
|
exit_status = 0
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1091,7 +1103,7 @@ def _main(parser):
|
||||||
nodes = _build_targets(fs, options, targets, target_top)
|
nodes = _build_targets(fs, options, targets, target_top)
|
||||||
if not nodes:
|
if not nodes:
|
||||||
revert_io()
|
revert_io()
|
||||||
print 'Found nothing to build'
|
print('Found nothing to build')
|
||||||
exit_status = 2
|
exit_status = 2
|
||||||
|
|
||||||
def _build_targets(fs, options, targets, target_top):
|
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
|
# or not a file, so go ahead and keep it as a default
|
||||||
# target and let the engine sort it out:
|
# target and let the engine sort it out:
|
||||||
return 1
|
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
|
SCons.Script.DEFAULT_TARGETS[:] = d
|
||||||
target_top = None
|
target_top = None
|
||||||
lookup_top = None
|
lookup_top = None
|
||||||
|
@ -1231,7 +1243,7 @@ def _build_targets(fs, options, targets, target_top):
|
||||||
if options.taskmastertrace_file == '-':
|
if options.taskmastertrace_file == '-':
|
||||||
tmtrace = sys.stdout
|
tmtrace = sys.stdout
|
||||||
elif options.taskmastertrace_file:
|
elif options.taskmastertrace_file:
|
||||||
tmtrace = open(options.taskmastertrace_file, 'wb')
|
tmtrace = open(options.taskmastertrace_file, 'w')
|
||||||
else:
|
else:
|
||||||
tmtrace = None
|
tmtrace = None
|
||||||
taskmaster = SCons.Taskmaster.Taskmaster(nodes, task_class, order, tmtrace)
|
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.
|
# various print_* settings, tree_printer list, etc.
|
||||||
BuildTask.options = options
|
BuildTask.options = options
|
||||||
|
|
||||||
|
|
||||||
|
python_has_threads = sysconfig.get_config_var('WITH_THREAD')
|
||||||
|
# to check if python configured with threads.
|
||||||
global num_jobs
|
global num_jobs
|
||||||
num_jobs = options.num_jobs
|
num_jobs = options.num_jobs
|
||||||
jobs = SCons.Job.Jobs(num_jobs, taskmaster)
|
jobs = SCons.Job.Jobs(num_jobs, taskmaster)
|
||||||
if num_jobs > 1:
|
if num_jobs > 1:
|
||||||
msg = None
|
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" + \
|
msg = "parallel builds are unsupported by this version of Python;\n" + \
|
||||||
"\tignoring -j or num_jobs option.\n"
|
"\tignoring -j or num_jobs option.\n"
|
||||||
elif sys.platform == 'win32':
|
|
||||||
msg = fetch_win32_parallel_msg()
|
|
||||||
if msg:
|
if msg:
|
||||||
SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg)
|
SCons.Warnings.warn(SCons.Warnings.NoParallelSupportWarning, msg)
|
||||||
|
|
||||||
|
@ -1332,10 +1347,10 @@ def main():
|
||||||
pass
|
pass
|
||||||
parts.append(version_string("engine", SCons))
|
parts.append(version_string("engine", SCons))
|
||||||
parts.append(path_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)
|
version = ''.join(parts)
|
||||||
|
|
||||||
import SConsOptions
|
from . import SConsOptions
|
||||||
parser = SConsOptions.Parser(version)
|
parser = SConsOptions.Parser(version)
|
||||||
values = SConsOptions.SConsValues(parser.get_default_values())
|
values = SConsOptions.SConsValues(parser.get_default_values())
|
||||||
|
|
||||||
|
@ -1346,23 +1361,23 @@ def main():
|
||||||
_exec_main(parser, values)
|
_exec_main(parser, values)
|
||||||
finally:
|
finally:
|
||||||
revert_io()
|
revert_io()
|
||||||
except SystemExit, s:
|
except SystemExit as s:
|
||||||
if s:
|
if s:
|
||||||
exit_status = s
|
exit_status = s
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("scons: Build interrupted.")
|
print("scons: Build interrupted.")
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
except SyntaxError, e:
|
except SyntaxError as e:
|
||||||
_scons_syntax_error(e)
|
_scons_syntax_error(e)
|
||||||
except SCons.Errors.InternalError:
|
except SCons.Errors.InternalError:
|
||||||
_scons_internal_error()
|
_scons_internal_error()
|
||||||
except SCons.Errors.UserError, e:
|
except SCons.Errors.UserError as e:
|
||||||
_scons_user_error(e)
|
_scons_user_error(e)
|
||||||
except SConsPrintHelpException:
|
except SConsPrintHelpException:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit_status = 0
|
exit_status = 0
|
||||||
except SCons.Errors.BuildError, e:
|
except SCons.Errors.BuildError as e:
|
||||||
print e
|
print(e)
|
||||||
exit_status = e.exitstatus
|
exit_status = e.exitstatus
|
||||||
except:
|
except:
|
||||||
# An exception here is likely a builtin Python exception Python
|
# An exception here is likely a builtin Python exception Python
|
||||||
|
@ -1398,10 +1413,10 @@ def main():
|
||||||
else:
|
else:
|
||||||
ct = last_command_end - first_command_start
|
ct = last_command_end - first_command_start
|
||||||
scons_time = total_time - sconscript_time - ct
|
scons_time = total_time - sconscript_time - ct
|
||||||
print "Total build time: %f seconds"%total_time
|
print("Total build time: %f seconds"%total_time)
|
||||||
print "Total SConscript file execution time: %f seconds"%sconscript_time
|
print("Total SConscript file execution time: %f seconds"%sconscript_time)
|
||||||
print "Total SCons execution time: %f seconds"%scons_time
|
print("Total SCons execution time: %f seconds"%scons_time)
|
||||||
print "Total command execution time: %f seconds"%ct
|
print("Total command execution time: %f seconds"%ct)
|
||||||
|
|
||||||
sys.exit(exit_status)
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Script/SConsOptions.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Script/SConsOptions.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import optparse
|
import optparse
|
||||||
import re
|
import re
|
||||||
|
@ -63,6 +63,7 @@ def diskcheck_convert(value):
|
||||||
raise ValueError(v)
|
raise ValueError(v)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
class SConsValues(optparse.Values):
|
class SConsValues(optparse.Values):
|
||||||
"""
|
"""
|
||||||
Holder class for uniform access to SCons options, regardless
|
Holder class for uniform access to SCons options, regardless
|
||||||
|
@ -112,7 +113,18 @@ class SConsValues(optparse.Values):
|
||||||
try:
|
try:
|
||||||
return self.__dict__['__SConscript_settings__'][attr]
|
return self.__dict__['__SConscript_settings__'][attr]
|
||||||
except KeyError:
|
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 = [
|
settable = [
|
||||||
'clean',
|
'clean',
|
||||||
|
@ -127,6 +139,7 @@ class SConsValues(optparse.Values):
|
||||||
'random',
|
'random',
|
||||||
'stack_size',
|
'stack_size',
|
||||||
'warn',
|
'warn',
|
||||||
|
'silent'
|
||||||
]
|
]
|
||||||
|
|
||||||
def set_option(self, name, value):
|
def set_option(self, name, value):
|
||||||
|
@ -161,7 +174,7 @@ class SConsValues(optparse.Values):
|
||||||
elif name == 'diskcheck':
|
elif name == 'diskcheck':
|
||||||
try:
|
try:
|
||||||
value = diskcheck_convert(value)
|
value = diskcheck_convert(value)
|
||||||
except ValueError, v:
|
except ValueError as v:
|
||||||
raise SCons.Errors.UserError("Not a valid diskcheck value: %s"%v)
|
raise SCons.Errors.UserError("Not a valid diskcheck value: %s"%v)
|
||||||
if 'diskcheck' not in self.__dict__:
|
if 'diskcheck' not in self.__dict__:
|
||||||
# No --diskcheck= option was specified on the command line.
|
# No --diskcheck= option was specified on the command line.
|
||||||
|
@ -186,6 +199,7 @@ class SConsValues(optparse.Values):
|
||||||
|
|
||||||
self.__SConscript_settings__[name] = value
|
self.__SConscript_settings__[name] = value
|
||||||
|
|
||||||
|
|
||||||
class SConsOption(optparse.Option):
|
class SConsOption(optparse.Option):
|
||||||
def convert_value(self, opt, value):
|
def convert_value(self, opt, value):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
|
@ -638,7 +652,7 @@ def Parser(version):
|
||||||
for value in value__.split(','):
|
for value in value__.split(','):
|
||||||
if value in debug_options:
|
if value in debug_options:
|
||||||
parser.values.debug.append(value)
|
parser.values.debug.append(value)
|
||||||
elif value in deprecated_debug_options.keys():
|
elif value in list(deprecated_debug_options.keys()):
|
||||||
parser.values.debug.append(value)
|
parser.values.debug.append(value)
|
||||||
try:
|
try:
|
||||||
parser.values.delayed_warnings
|
parser.values.delayed_warnings
|
||||||
|
@ -663,7 +677,7 @@ def Parser(version):
|
||||||
def opt_diskcheck(option, opt, value, parser):
|
def opt_diskcheck(option, opt, value, parser):
|
||||||
try:
|
try:
|
||||||
diskcheck_value = diskcheck_convert(value)
|
diskcheck_value = diskcheck_convert(value)
|
||||||
except ValueError, e:
|
except ValueError as e:
|
||||||
raise OptionValueError("`%s' is not a valid diskcheck type" % e)
|
raise OptionValueError("`%s' is not a valid diskcheck type" % e)
|
||||||
setattr(parser.values, option.dest, diskcheck_value)
|
setattr(parser.values, option.dest, diskcheck_value)
|
||||||
|
|
||||||
|
@ -830,7 +844,7 @@ def Parser(version):
|
||||||
tree_options = ["all", "derived", "prune", "status"]
|
tree_options = ["all", "derived", "prune", "status"]
|
||||||
|
|
||||||
def opt_tree(option, opt, value, parser, tree_options=tree_options):
|
def opt_tree(option, opt, value, parser, tree_options=tree_options):
|
||||||
import Main
|
from . import Main
|
||||||
tp = Main.TreePrinter()
|
tp = Main.TreePrinter()
|
||||||
for o in value.split(','):
|
for o in value.split(','):
|
||||||
if o == 'all':
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -26,9 +26,8 @@ files.
|
||||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
from __future__ import division
|
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Script/SConscript.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Script/SConscript.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons
|
import SCons
|
||||||
import SCons.Action
|
import SCons.Action
|
||||||
|
@ -45,12 +44,15 @@ import SCons.Script.Main
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
from . import Main
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
import time
|
||||||
|
|
||||||
class SConscriptReturn(Exception):
|
class SConscriptReturn(Exception):
|
||||||
pass
|
pass
|
||||||
|
@ -69,7 +71,7 @@ def get_calling_namespaces():
|
||||||
"""Return the locals and globals for the function that called
|
"""Return the locals and globals for the function that called
|
||||||
into this module in the current call stack."""
|
into this module in the current call stack."""
|
||||||
try: 1//0
|
try: 1//0
|
||||||
except ZeroDivisionError:
|
except ZeroDivisionError:
|
||||||
# Don't start iterating with the current stack-frame to
|
# Don't start iterating with the current stack-frame to
|
||||||
# prevent creating reference cycles (f_back is safe).
|
# prevent creating reference cycles (f_back is safe).
|
||||||
frame = sys.exc_info()[2].tb_frame.f_back
|
frame = sys.exc_info()[2].tb_frame.f_back
|
||||||
|
@ -103,7 +105,7 @@ def compute_exports(exports):
|
||||||
retval[export] = loc[export]
|
retval[export] = loc[export]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
retval[export] = glob[export]
|
retval[export] = glob[export]
|
||||||
except KeyError, x:
|
except KeyError as x:
|
||||||
raise SCons.Errors.UserError("Export of non-existent variable '%s'"%x)
|
raise SCons.Errors.UserError("Export of non-existent variable '%s'"%x)
|
||||||
|
|
||||||
return retval
|
return retval
|
||||||
|
@ -135,7 +137,7 @@ def Return(*vars, **kw):
|
||||||
for var in fvars:
|
for var in fvars:
|
||||||
for v in var.split():
|
for v in var.split():
|
||||||
retval.append(call_stack[-1].globals[v])
|
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)
|
raise SCons.Errors.UserError("Return of non-existent variable '%s'"%x)
|
||||||
|
|
||||||
if len(retval) == 1:
|
if len(retval) == 1:
|
||||||
|
@ -164,7 +166,7 @@ def _SConscript(fs, *files, **kw):
|
||||||
try:
|
try:
|
||||||
SCons.Script.sconscript_reading = SCons.Script.sconscript_reading + 1
|
SCons.Script.sconscript_reading = SCons.Script.sconscript_reading + 1
|
||||||
if fn == "-":
|
if fn == "-":
|
||||||
exec sys.stdin in call_stack[-1].globals
|
exec(sys.stdin.read(), call_stack[-1].globals)
|
||||||
else:
|
else:
|
||||||
if isinstance(fn, SCons.Node.Node):
|
if isinstance(fn, SCons.Node.Node):
|
||||||
f = fn
|
f = fn
|
||||||
|
@ -178,10 +180,10 @@ def _SConscript(fs, *files, **kw):
|
||||||
fs.chdir(top, change_os_dir=1)
|
fs.chdir(top, change_os_dir=1)
|
||||||
if f.rexists():
|
if f.rexists():
|
||||||
actual = f.rfile()
|
actual = f.rfile()
|
||||||
_file_ = open(actual.get_abspath(), "r")
|
_file_ = open(actual.get_abspath(), "rb")
|
||||||
elif f.srcnode().rexists():
|
elif f.srcnode().rexists():
|
||||||
actual = f.srcnode().rfile()
|
actual = f.srcnode().rfile()
|
||||||
_file_ = open(actual.get_abspath(), "r")
|
_file_ = open(actual.get_abspath(), "rb")
|
||||||
elif f.has_src_builder():
|
elif f.has_src_builder():
|
||||||
# The SConscript file apparently exists in a source
|
# The SConscript file apparently exists in a source
|
||||||
# code management system. Build it, but then clear
|
# code management system. Build it, but then clear
|
||||||
|
@ -191,7 +193,7 @@ def _SConscript(fs, *files, **kw):
|
||||||
f.built()
|
f.built()
|
||||||
f.builder_set(None)
|
f.builder_set(None)
|
||||||
if f.exists():
|
if f.exists():
|
||||||
_file_ = open(f.get_abspath(), "r")
|
_file_ = open(f.get_abspath(), "rb")
|
||||||
if _file_:
|
if _file_:
|
||||||
# Chdir to the SConscript directory. Use a path
|
# Chdir to the SConscript directory. Use a path
|
||||||
# name relative to the SConstruct file so that if
|
# name relative to the SConstruct file so that if
|
||||||
|
@ -247,10 +249,18 @@ def _SConscript(fs, *files, **kw):
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
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:
|
except SConscriptReturn:
|
||||||
pass
|
pass
|
||||||
finally:
|
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:
|
if old_file is not None:
|
||||||
call_stack[-1].globals.update({__file__:old_file})
|
call_stack[-1].globals.update({__file__:old_file})
|
||||||
else:
|
else:
|
||||||
|
@ -272,7 +282,7 @@ def _SConscript(fs, *files, **kw):
|
||||||
rdir._create() # Make sure there's a directory there.
|
rdir._create() # Make sure there's a directory there.
|
||||||
try:
|
try:
|
||||||
os.chdir(rdir.get_abspath())
|
os.chdir(rdir.get_abspath())
|
||||||
except OSError, e:
|
except OSError as e:
|
||||||
# We still couldn't chdir there, so raise the error,
|
# We still couldn't chdir there, so raise the error,
|
||||||
# but only if actions are being executed.
|
# 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)
|
scons_ver_string = '%d.%d.%d' % (major, minor, revision)
|
||||||
else:
|
else:
|
||||||
scons_ver_string = '%d.%d' % (major, minor)
|
scons_ver_string = '%d.%d' % (major, minor)
|
||||||
print "SCons %s or greater required, but you have SCons %s" % \
|
print("SCons %s or greater required, but you have SCons %s" % \
|
||||||
(scons_ver_string, SCons.__version__)
|
(scons_ver_string, SCons.__version__))
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
def EnsurePythonVersion(self, major, minor):
|
def EnsurePythonVersion(self, major, minor):
|
||||||
"""Exit abnormally if the Python version is not late enough."""
|
"""Exit abnormally if the Python version is not late enough."""
|
||||||
if sys.version_info < (major, minor):
|
if sys.version_info < (major, minor):
|
||||||
v = sys.version.split()[0]
|
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)
|
sys.exit(2)
|
||||||
|
|
||||||
def Exit(self, value=0):
|
def Exit(self, value=0):
|
||||||
|
@ -509,7 +519,7 @@ class SConsEnvironment(SCons.Environment.Base):
|
||||||
globals[v] = exports[v]
|
globals[v] = exports[v]
|
||||||
else:
|
else:
|
||||||
globals[v] = global_exports[v]
|
globals[v] = global_exports[v]
|
||||||
except KeyError,x:
|
except KeyError as x:
|
||||||
raise SCons.Errors.UserError("Import of non-existent variable '%s'"%x)
|
raise SCons.Errors.UserError("Import of non-existent variable '%s'"%x)
|
||||||
|
|
||||||
def SConscript(self, *ls, **kw):
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -34,14 +34,19 @@ it goes here.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Script/__init__.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Script/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import time
|
import time
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import os
|
import os
|
||||||
import StringIO
|
|
||||||
|
try:
|
||||||
|
from StringIO import StringIO
|
||||||
|
except ImportError:
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
# Special chicken-and-egg handling of the "--debug=memoizer" flag:
|
# Special chicken-and-egg handling of the "--debug=memoizer" flag:
|
||||||
|
@ -67,7 +72,7 @@ if "--debug=memoizer" in _args:
|
||||||
except SCons.Warnings.Warning:
|
except SCons.Warnings.Warning:
|
||||||
# Some warning was thrown. Arrange for it to be displayed
|
# Some warning was thrown. Arrange for it to be displayed
|
||||||
# or not after warnings are configured.
|
# or not after warnings are configured.
|
||||||
import Main
|
from . import Main
|
||||||
exc_type, exc_value, tb = sys.exc_info()
|
exc_type, exc_value, tb = sys.exc_info()
|
||||||
Main.delayed_warnings.append((exc_type, exc_value))
|
Main.delayed_warnings.append((exc_type, exc_value))
|
||||||
del _args
|
del _args
|
||||||
|
@ -86,7 +91,7 @@ import SCons.Util
|
||||||
import SCons.Variables
|
import SCons.Variables
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
|
|
||||||
import Main
|
from . import Main
|
||||||
|
|
||||||
main = Main.main
|
main = Main.main
|
||||||
|
|
||||||
|
@ -130,7 +135,7 @@ GetBuildFailures = Main.GetBuildFailures
|
||||||
#repositories = Main.repositories
|
#repositories = Main.repositories
|
||||||
|
|
||||||
#
|
#
|
||||||
import SConscript
|
from . import SConscript
|
||||||
_SConscript = SConscript
|
_SConscript = SConscript
|
||||||
|
|
||||||
call_stack = _SConscript.call_stack
|
call_stack = _SConscript.call_stack
|
||||||
|
@ -264,7 +269,7 @@ def HelpFunction(text, append=False):
|
||||||
global help_text
|
global help_text
|
||||||
if help_text is None:
|
if help_text is None:
|
||||||
if append:
|
if append:
|
||||||
s = StringIO.StringIO()
|
s = StringIO()
|
||||||
PrintHelp(s)
|
PrintHelp(s)
|
||||||
help_text = s.getvalue()
|
help_text = s.getvalue()
|
||||||
s.close()
|
s.close()
|
||||||
|
@ -332,6 +337,7 @@ GlobalDefaultEnvironmentFunctions = [
|
||||||
'Local',
|
'Local',
|
||||||
'ParseDepends',
|
'ParseDepends',
|
||||||
'Precious',
|
'Precious',
|
||||||
|
'PyPackageDir',
|
||||||
'Repository',
|
'Repository',
|
||||||
'Requires',
|
'Requires',
|
||||||
'SConsignFile',
|
'SConsignFile',
|
||||||
|
@ -354,6 +360,7 @@ GlobalDefaultBuilders = [
|
||||||
'Java',
|
'Java',
|
||||||
'JavaH',
|
'JavaH',
|
||||||
'Library',
|
'Library',
|
||||||
|
'LoadableModule',
|
||||||
'M4',
|
'M4',
|
||||||
'MSVSProject',
|
'MSVSProject',
|
||||||
'Object',
|
'Object',
|
||||||
|
@ -374,7 +381,7 @@ GlobalDefaultBuilders = [
|
||||||
]
|
]
|
||||||
|
|
||||||
for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders:
|
for name in GlobalDefaultEnvironmentFunctions + GlobalDefaultBuilders:
|
||||||
exec "%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name))
|
exec ("%s = _SConscript.DefaultEnvironmentCall(%s)" % (name, repr(name)))
|
||||||
del name
|
del name
|
||||||
|
|
||||||
# There are a handful of variables that used to live in the
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -26,7 +26,7 @@ SCons string substitution.
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Subst.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Subst.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import collections
|
import collections
|
||||||
import re
|
import re
|
||||||
|
@ -338,24 +338,31 @@ SUBST_RAW = 1
|
||||||
SUBST_SIG = 2
|
SUBST_SIG = 2
|
||||||
|
|
||||||
_rm = re.compile(r'\$[()]')
|
_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.
|
# Indexed by the SUBST_* constants above.
|
||||||
_regex_remove = [ _rm, None, _remove ]
|
_regex_remove = [ _rm, None, _rm_split ]
|
||||||
|
|
||||||
def _rm_list(list):
|
def _rm_list(list):
|
||||||
return [l for l in list if not l in ('$(', '$)')]
|
return [l for l in list if not l in ('$(', '$)')]
|
||||||
|
|
||||||
def _remove_list(list):
|
def _remove_list(list):
|
||||||
result = []
|
result = []
|
||||||
do_append = result.append
|
depth = 0
|
||||||
for l in list:
|
for l in list:
|
||||||
if l == '$(':
|
if l == '$(':
|
||||||
do_append = lambda x: None
|
depth += 1
|
||||||
elif l == '$)':
|
elif l == '$)':
|
||||||
do_append = result.append
|
depth -= 1
|
||||||
else:
|
if depth < 0:
|
||||||
do_append(l)
|
break
|
||||||
|
elif depth == 0:
|
||||||
|
result.append(l)
|
||||||
|
if depth != 0:
|
||||||
|
return None
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# Indexed by the SUBST_* constants above.
|
# 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 != '$':
|
if s0 != '$':
|
||||||
return s
|
return s
|
||||||
if s1 == '$':
|
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 '()':
|
elif s1 in '()':
|
||||||
return s
|
return s
|
||||||
else:
|
else:
|
||||||
key = s[1:]
|
key = s[1:]
|
||||||
if key[0] == '{' or key.find('.') >= 0:
|
if key[0] == '{' or '.' in key:
|
||||||
if key[0] == '{':
|
if key[0] == '{':
|
||||||
key = key[1:-1]
|
key = key[1:-1]
|
||||||
try:
|
try:
|
||||||
s = eval(key, self.gvars, lvars)
|
s = eval(key, self.gvars, lvars)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
if e.__class__ in AllowableExceptions:
|
if e.__class__ in AllowableExceptions:
|
||||||
return ''
|
return ''
|
||||||
raise_exception(e, lvars['TARGETS'], s)
|
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:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
res = result
|
||||||
if is_String(result):
|
if is_String(result):
|
||||||
# Remove $(-$) pairs and any stuff in between,
|
# Remove $(-$) pairs and any stuff in between,
|
||||||
# if that's appropriate.
|
# if that's appropriate.
|
||||||
remove = _regex_remove[mode]
|
remove = _regex_remove[mode]
|
||||||
if remove:
|
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:
|
if mode != SUBST_RAW:
|
||||||
# Compress strings of white space characters into
|
# Compress strings of white space characters into
|
||||||
# a single space.
|
# a single space.
|
||||||
result = _space_sep.sub(' ', result).strip()
|
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):
|
elif is_Sequence(result):
|
||||||
remove = _list_remove[mode]
|
remove = _list_remove[mode]
|
||||||
if remove:
|
if remove:
|
||||||
result = remove(result)
|
result = remove(result)
|
||||||
|
if result is None:
|
||||||
|
raise SCons.Errors.UserError("Unbalanced $(/$) in: " + str(res))
|
||||||
|
|
||||||
return result
|
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)
|
s = eval(key, self.gvars, lvars)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
if e.__class__ in AllowableExceptions:
|
if e.__class__ in AllowableExceptions:
|
||||||
return
|
return
|
||||||
raise_exception(e, lvars['TARGETS'], s)
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -20,17 +20,24 @@
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
__doc__ = """
|
__doc__ = """
|
||||||
Generic Taskmaster module for the SCons build engine.
|
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:
|
This module contains the primary interface(s) between a wrapping user
|
||||||
|
interface and the SCons build engine. There are two key classes here:
|
||||||
|
|
||||||
Taskmaster
|
Taskmaster
|
||||||
|
----------
|
||||||
This is the main engine for walking the dependency graph and
|
This is the main engine for walking the dependency graph and
|
||||||
calling things to decide what does or doesn't need to be built.
|
calling things to decide what does or doesn't need to be built.
|
||||||
|
|
||||||
Task
|
Task
|
||||||
|
----
|
||||||
This is the base class for allowing a wrapping interface to
|
This is the base class for allowing a wrapping interface to
|
||||||
decide what does or doesn't actually need to be done. The
|
decide what does or doesn't actually need to be done. The
|
||||||
intention is for a wrapping interface to subclass this as
|
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,
|
The canonical example is the SCons native Python interface,
|
||||||
which has Task subclasses that handle its specific behavior,
|
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
|
doesn't need to be built, and handling the -c option by removing
|
||||||
targets as its "build" action. There is also a separate subclass
|
targets as its "build" action. There is also a separate subclass
|
||||||
for suppressing this output when the -q option is used.
|
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.
|
target(s) that it decides need to be evaluated and/or built.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Taskmaster.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Taskmaster.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
import operator
|
import operator
|
||||||
|
@ -107,7 +114,7 @@ fmt = "%(considered)3d "\
|
||||||
|
|
||||||
def dump_stats():
|
def dump_stats():
|
||||||
for n in sorted(StatsNodes, key=lambda a: str(a)):
|
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()
|
executor.prepare()
|
||||||
for t in executor.get_action_targets():
|
for t in executor.get_action_targets():
|
||||||
if print_prepare:
|
if print_prepare:
|
||||||
print "Preparing target %s..."%t
|
print("Preparing target %s..."%t)
|
||||||
for s in t.side_effects:
|
for s in t.side_effects:
|
||||||
print "...with side-effect %s..."%s
|
print("...with side-effect %s..."%s)
|
||||||
t.prepare()
|
t.prepare()
|
||||||
for s in t.side_effects:
|
for s in t.side_effects:
|
||||||
if print_prepare:
|
if print_prepare:
|
||||||
print "...Preparing side-effect %s..."%s
|
print("...Preparing side-effect %s..."%s)
|
||||||
s.prepare()
|
s.prepare()
|
||||||
|
|
||||||
def get_target(self):
|
def get_target(self):
|
||||||
|
@ -256,7 +263,7 @@ class Task(object):
|
||||||
raise
|
raise
|
||||||
except SCons.Errors.BuildError:
|
except SCons.Errors.BuildError:
|
||||||
raise
|
raise
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
buildError = SCons.Errors.convert_to_BuildError(e)
|
buildError = SCons.Errors.convert_to_BuildError(e)
|
||||||
buildError.node = self.targets[0]
|
buildError.node = self.targets[0]
|
||||||
buildError.exc_info = sys.exc_info()
|
buildError.exc_info = sys.exc_info()
|
||||||
|
@ -305,7 +312,7 @@ class Task(object):
|
||||||
t.push_to_cache()
|
t.push_to_cache()
|
||||||
t.built()
|
t.built()
|
||||||
t.visited()
|
t.visited()
|
||||||
if (not print_prepare and
|
if (not print_prepare and
|
||||||
(not hasattr(self, 'options') or not self.options.debug_includes)):
|
(not hasattr(self, 'options') or not self.options.debug_includes)):
|
||||||
t.release_target_info()
|
t.release_target_info()
|
||||||
else:
|
else:
|
||||||
|
@ -402,7 +409,7 @@ class Task(object):
|
||||||
t.disambiguate().make_ready()
|
t.disambiguate().make_ready()
|
||||||
is_up_to_date = not t.has_builder() or \
|
is_up_to_date = not t.has_builder() or \
|
||||||
(not t.always_build and t.is_up_to_date())
|
(not t.always_build and t.is_up_to_date())
|
||||||
except EnvironmentError, e:
|
except EnvironmentError as e:
|
||||||
raise SCons.Errors.BuildError(node=t, errstr=e.strerror, filename=e.filename)
|
raise SCons.Errors.BuildError(node=t, errstr=e.strerror, filename=e.filename)
|
||||||
|
|
||||||
if not is_up_to_date:
|
if not is_up_to_date:
|
||||||
|
@ -423,7 +430,7 @@ class Task(object):
|
||||||
# parallel build...)
|
# parallel build...)
|
||||||
t.visited()
|
t.visited()
|
||||||
t.set_state(NODE_UP_TO_DATE)
|
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)):
|
(not hasattr(self, 'options') or not self.options.debug_includes)):
|
||||||
t.release_target_info()
|
t.release_target_info()
|
||||||
|
|
||||||
|
@ -537,7 +544,23 @@ class Task(object):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
exc_type, exc_value = exc
|
exc_type, exc_value = exc
|
||||||
exc_traceback = None
|
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):
|
class AlwaysTask(Task):
|
||||||
def needs_execute(self):
|
def needs_execute(self):
|
||||||
|
@ -669,14 +692,14 @@ class Taskmaster(object):
|
||||||
at node A. The Taskmaster first considers whether node A's
|
at node A. The Taskmaster first considers whether node A's
|
||||||
child B is up-to-date. Then, recursively, node B needs to
|
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
|
check whether node C is up-to-date. This leaves us with a
|
||||||
dependency graph looking like:
|
dependency graph looking like::
|
||||||
|
|
||||||
Next candidate \
|
Next candidate \
|
||||||
\
|
\
|
||||||
Node A (Pending) --> Node B(Pending) --> Node C (NoState)
|
Node A (Pending) --> Node B(Pending) --> Node C (NoState)
|
||||||
^ |
|
^ |
|
||||||
| |
|
| |
|
||||||
+-------------------------------------+
|
+-------------------------------------+
|
||||||
|
|
||||||
Now, when the Taskmaster examines the Node C's child Node A,
|
Now, when the Taskmaster examines the Node C's child Node A,
|
||||||
it finds that Node A is in the "pending" state. Therefore,
|
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
|
Pending children indicate that the Taskmaster has potentially
|
||||||
loop back through a cycle. We say potentially because it could
|
loop back through a cycle. We say potentially because it could
|
||||||
also occur when a DAG is evaluated in parallel. For example,
|
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 A (Pending) --> Node B(Pending) --> Node C (Pending) --> ...
|
| ^
|
||||||
| ^
|
| |
|
||||||
| |
|
+----------> Node D (NoState) --------+
|
||||||
+----------> Node D (NoState) --------+
|
/
|
||||||
/
|
Next candidate /
|
||||||
Next candidate /
|
|
||||||
|
|
||||||
The Taskmaster first evaluates the nodes A, B, and C and
|
The Taskmaster first evaluates the nodes A, B, and C and
|
||||||
starts building some children of node C. Assuming, that the
|
starts building some children of node C. Assuming, that the
|
||||||
|
@ -761,7 +783,7 @@ class Taskmaster(object):
|
||||||
self.ready_exc = None
|
self.ready_exc = None
|
||||||
|
|
||||||
T = self.trace
|
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:
|
while True:
|
||||||
node = self.next_candidate()
|
node = self.next_candidate()
|
||||||
|
@ -810,7 +832,7 @@ class Taskmaster(object):
|
||||||
self.ready_exc = (SCons.Errors.ExplicitExit, e)
|
self.ready_exc = (SCons.Errors.ExplicitExit, e)
|
||||||
if T: T.write(self.trace_message(' SystemExit'))
|
if T: T.write(self.trace_message(' SystemExit'))
|
||||||
return node
|
return node
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
# We had a problem just trying to figure out the
|
# We had a problem just trying to figure out the
|
||||||
# children (like a child couldn't be linked in to a
|
# children (like a child couldn't be linked in to a
|
||||||
# VariantDir, or a Scanner threw something). Arrange to
|
# VariantDir, or a Scanner threw something). Arrange to
|
||||||
|
@ -840,13 +862,13 @@ class Taskmaster(object):
|
||||||
if childstate <= NODE_EXECUTING:
|
if childstate <= NODE_EXECUTING:
|
||||||
children_not_ready.append(child)
|
children_not_ready.append(child)
|
||||||
|
|
||||||
|
|
||||||
# These nodes have not even been visited yet. Add
|
# These nodes have not even been visited yet. Add
|
||||||
# them to the list so that on some next pass we can
|
# them to the list so that on some next pass we can
|
||||||
# take a stab at evaluating them (or their children).
|
# take a stab at evaluating them (or their children).
|
||||||
children_not_visited.reverse()
|
children_not_visited.reverse()
|
||||||
self.candidates.extend(self.order(children_not_visited))
|
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(' adding to candidates: %s' % map(str, children_not_visited)))
|
||||||
# T.write(self.trace_message(' candidates now: %s\n' % map(str, self.candidates)))
|
# T.write(self.trace_message(' candidates now: %s\n' % map(str, self.candidates)))
|
||||||
|
|
||||||
|
@ -943,13 +965,13 @@ class Taskmaster(object):
|
||||||
executor = node.get_executor()
|
executor = node.get_executor()
|
||||||
if executor is None:
|
if executor is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
tlist = executor.get_all_targets()
|
tlist = executor.get_all_targets()
|
||||||
|
|
||||||
task = self.tasker(self, tlist, node in self.original_top, node)
|
task = self.tasker(self, tlist, node in self.original_top, node)
|
||||||
try:
|
try:
|
||||||
task.make_ready()
|
task.make_ready()
|
||||||
except:
|
except Exception as e :
|
||||||
# We had a problem just trying to get this task ready (like
|
# We had a problem just trying to get this task ready (like
|
||||||
# a child couldn't be linked to a VariantDir when deciding
|
# a child couldn't be linked to a VariantDir when deciding
|
||||||
# whether this node is current). Arrange to raise the
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -32,12 +32,12 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/386asm.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/386asm.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
from SCons.Tool.PharLapCommon import addPharLapPaths
|
from SCons.Tool.PharLapCommon import addPharLapPaths
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
as_module = __import__('as', globals(), locals(), [])
|
as_module = __import__('as', globals(), locals(), [], 1)
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
"""Add Builders and construction variables for ar to an Environment."""
|
"""Add Builders and construction variables for ar to an Environment."""
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
"""SCons.Tool.DCommon
|
"""SCons.Tool.DCommon
|
||||||
|
|
||||||
Common code for the various D tools.
|
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)
|
Coded by Russel Winder (russel@winder.org.uk)
|
||||||
2012-09-06
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -28,10 +31,11 @@ Coded by Russel Winder (russel@winder.org.uk)
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/DCommon.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/DCommon.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
|
|
||||||
def isD(env, source):
|
def isD(env, source):
|
||||||
if not source:
|
if not source:
|
||||||
return 0
|
return 0
|
||||||
|
@ -42,6 +46,7 @@ def isD(env, source):
|
||||||
return 1
|
return 1
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
def addDPATHToEnv(env, executable):
|
def addDPATHToEnv(env, executable):
|
||||||
dPath = env.WhereIs(executable)
|
dPath = env.WhereIs(executable)
|
||||||
if dPath:
|
if dPath:
|
||||||
|
@ -49,6 +54,14 @@ def addDPATHToEnv(env, executable):
|
||||||
if os.path.isdir(phobosDir):
|
if os.path.isdir(phobosDir):
|
||||||
env.Append(DPATH=[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:
|
# Local Variables:
|
||||||
# tab-width:4
|
# tab-width:4
|
||||||
# indent-tabs-mode:nil
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -26,8 +26,9 @@ Stuff for processing Fortran, common to all fortran dialects.
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/FortranCommon.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/FortranCommon.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import os.path
|
import os.path
|
||||||
|
@ -61,7 +62,7 @@ def isfortran(env, source):
|
||||||
def _fortranEmitter(target, source, env):
|
def _fortranEmitter(target, source, env):
|
||||||
node = source[0].rfile()
|
node = source[0].rfile()
|
||||||
if not node.exists() and not node.is_derived():
|
if not node.exists() and not node.is_derived():
|
||||||
print "Could not locate " + str(node.name)
|
print("Could not locate " + str(node.name))
|
||||||
return ([], [])
|
return ([], [])
|
||||||
mod_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(\w+)"""
|
mod_regex = """(?i)^\s*MODULE\s+(?!PROCEDURE)(\w+)"""
|
||||||
cre = re.compile(mod_regex,re.M)
|
cre = re.compile(mod_regex,re.M)
|
||||||
|
@ -167,7 +168,7 @@ def add_fortran_to_env(env):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
FortranSuffixes = ['.f', '.for', '.ftn']
|
FortranSuffixes = ['.f', '.for', '.ftn']
|
||||||
|
|
||||||
#print "Adding %s to fortran suffixes" % FortranSuffixes
|
#print("Adding %s to fortran suffixes" % FortranSuffixes)
|
||||||
try:
|
try:
|
||||||
FortranPPSuffixes = env['FORTRANPPFILESUFFIXES']
|
FortranPPSuffixes = env['FORTRANPPFILESUFFIXES']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -191,7 +192,7 @@ def add_f77_to_env(env):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
F77Suffixes = ['.f77']
|
F77Suffixes = ['.f77']
|
||||||
|
|
||||||
#print "Adding %s to f77 suffixes" % F77Suffixes
|
#print("Adding %s to f77 suffixes" % F77Suffixes)
|
||||||
try:
|
try:
|
||||||
F77PPSuffixes = env['F77PPFILESUFFIXES']
|
F77PPSuffixes = env['F77PPFILESUFFIXES']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -206,7 +207,7 @@ def add_f90_to_env(env):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
F90Suffixes = ['.f90']
|
F90Suffixes = ['.f90']
|
||||||
|
|
||||||
#print "Adding %s to f90 suffixes" % F90Suffixes
|
#print("Adding %s to f90 suffixes" % F90Suffixes)
|
||||||
try:
|
try:
|
||||||
F90PPSuffixes = env['F90PPFILESUFFIXES']
|
F90PPSuffixes = env['F90PPFILESUFFIXES']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -222,7 +223,7 @@ def add_f95_to_env(env):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
F95Suffixes = ['.f95']
|
F95Suffixes = ['.f95']
|
||||||
|
|
||||||
#print "Adding %s to f95 suffixes" % F95Suffixes
|
#print("Adding %s to f95 suffixes" % F95Suffixes)
|
||||||
try:
|
try:
|
||||||
F95PPSuffixes = env['F95PPFILESUFFIXES']
|
F95PPSuffixes = env['F95PPFILESUFFIXES']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -238,7 +239,7 @@ def add_f03_to_env(env):
|
||||||
except KeyError:
|
except KeyError:
|
||||||
F03Suffixes = ['.f03']
|
F03Suffixes = ['.f03']
|
||||||
|
|
||||||
#print "Adding %s to f95 suffixes" % F95Suffixes
|
#print("Adding %s to f95 suffixes" % F95Suffixes)
|
||||||
try:
|
try:
|
||||||
F03PPSuffixes = env['F03PPFILESUFFIXES']
|
F03PPSuffixes = env['F03PPFILESUFFIXES']
|
||||||
except KeyError:
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,7 +27,7 @@ Stuff for processing Java.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/JavaCommon.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/JavaCommon.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/MSCommon/__init__.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/MSCommon/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
__doc__ = """
|
__doc__ = """
|
||||||
Common functions for Microsoft Visual Studio and Visual C/C++.
|
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, \
|
from SCons.Tool.MSCommon.vc import msvc_exists, \
|
||||||
msvc_setup_env, \
|
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, \
|
from SCons.Tool.MSCommon.vs import get_default_version, \
|
||||||
get_vs_by_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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/MSCommon/arch.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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.
|
__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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -20,12 +23,9 @@
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/MSCommon/common.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/MSCommon/common.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
__doc__ = """
|
|
||||||
Common helper functions for working with the Microsoft tool chain.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
import os
|
import os
|
||||||
|
@ -35,17 +35,17 @@ import re
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
|
||||||
logfile = os.environ.get('SCONS_MSCOMMON_DEBUG')
|
LOGFILE = os.environ.get('SCONS_MSCOMMON_DEBUG')
|
||||||
if logfile == '-':
|
if LOGFILE == '-':
|
||||||
def debug(x):
|
def debug(message):
|
||||||
print x
|
print(message)
|
||||||
elif logfile:
|
elif LOGFILE:
|
||||||
try:
|
try:
|
||||||
import logging
|
import logging
|
||||||
except ImportError:
|
except ImportError:
|
||||||
debug = lambda x: open(logfile, 'a').write(x + '\n')
|
debug = lambda message: open(LOGFILE, 'a').write(message + '\n')
|
||||||
else:
|
else:
|
||||||
logging.basicConfig(filename=logfile, level=logging.DEBUG)
|
logging.basicConfig(filename=LOGFILE, level=logging.DEBUG)
|
||||||
debug = logging.debug
|
debug = logging.debug
|
||||||
else:
|
else:
|
||||||
debug = lambda x: None
|
debug = lambda x: None
|
||||||
|
@ -75,7 +75,7 @@ def is_win64():
|
||||||
# I structured these tests to make it easy to add new ones or
|
# I structured these tests to make it easy to add new ones or
|
||||||
# add exceptions in the future, because this is a bit fragile.
|
# add exceptions in the future, because this is a bit fragile.
|
||||||
_is_win64 = False
|
_is_win64 = False
|
||||||
if os.environ.get('PROCESSOR_ARCHITECTURE','x86') != 'x86':
|
if os.environ.get('PROCESSOR_ARCHITECTURE', 'x86') != 'x86':
|
||||||
_is_win64 = True
|
_is_win64 = True
|
||||||
if os.environ.get('PROCESSOR_ARCHITEW6432'):
|
if os.environ.get('PROCESSOR_ARCHITEW6432'):
|
||||||
_is_win64 = True
|
_is_win64 = True
|
||||||
|
@ -113,21 +113,30 @@ def normalize_env(env, keys, force=False):
|
||||||
Note: the environment is copied."""
|
Note: the environment is copied."""
|
||||||
normenv = {}
|
normenv = {}
|
||||||
if env:
|
if env:
|
||||||
for k in env.keys():
|
for k in list(env.keys()):
|
||||||
normenv[k] = copy.deepcopy(env[k]).encode('mbcs')
|
normenv[k] = copy.deepcopy(env[k])
|
||||||
|
|
||||||
for k in keys:
|
for k in keys:
|
||||||
if k in os.environ and (force or not k in normenv):
|
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,
|
# 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
|
# but keep this here to be safe, since it's needed to find reg.exe which the MSVC
|
||||||
# bat scripts use.
|
# 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']:
|
if sys32_dir not in normenv['PATH']:
|
||||||
normenv['PATH'] = normenv['PATH'] + os.pathsep + sys32_dir
|
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'])
|
debug("PATH: %s"%normenv['PATH'])
|
||||||
|
|
||||||
return normenv
|
return normenv
|
||||||
|
@ -144,11 +153,13 @@ def get_output(vcbat, args = None, env = None):
|
||||||
# execution to work. This list should really be either directly
|
# execution to work. This list should really be either directly
|
||||||
# controlled by vc.py, or else derived from the common_tools_var
|
# controlled by vc.py, or else derived from the common_tools_var
|
||||||
# settings in vs.py.
|
# settings in vs.py.
|
||||||
vars = [
|
vs_vc_vars = [
|
||||||
'COMSPEC',
|
'COMSPEC',
|
||||||
# VS100 and VS110: Still set, but modern MSVC setup scripts will
|
# VS100 and VS110: Still set, but modern MSVC setup scripts will
|
||||||
# discard these if registry has values. However Intel compiler setup
|
# discard these if registry has values. However Intel compiler setup
|
||||||
# script still requires these as of 2013/2014.
|
# script still requires these as of 2013/2014.
|
||||||
|
'VS140COMNTOOLS',
|
||||||
|
'VS120COMNTOOLS',
|
||||||
'VS110COMNTOOLS',
|
'VS110COMNTOOLS',
|
||||||
'VS100COMNTOOLS',
|
'VS100COMNTOOLS',
|
||||||
'VS90COMNTOOLS',
|
'VS90COMNTOOLS',
|
||||||
|
@ -157,22 +168,22 @@ def get_output(vcbat, args = None, env = None):
|
||||||
'VS70COMNTOOLS',
|
'VS70COMNTOOLS',
|
||||||
'VS60COMNTOOLS',
|
'VS60COMNTOOLS',
|
||||||
]
|
]
|
||||||
env['ENV'] = normalize_env(env['ENV'], vars, force=False)
|
env['ENV'] = normalize_env(env['ENV'], vs_vc_vars, force=False)
|
||||||
|
|
||||||
if args:
|
if args:
|
||||||
debug("Calling '%s %s'" % (vcbat, args))
|
debug("Calling '%s %s'" % (vcbat, args))
|
||||||
popen = SCons.Action._subproc(env,
|
popen = SCons.Action._subproc(env,
|
||||||
'"%s" %s & set' % (vcbat, args),
|
'"%s" %s & set' % (vcbat, args),
|
||||||
stdin = 'devnull',
|
stdin='devnull',
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE)
|
stderr=subprocess.PIPE)
|
||||||
else:
|
else:
|
||||||
debug("Calling '%s'" % vcbat)
|
debug("Calling '%s'" % vcbat)
|
||||||
popen = SCons.Action._subproc(env,
|
popen = SCons.Action._subproc(env,
|
||||||
'"%s" & set' % vcbat,
|
'"%s" & set' % vcbat,
|
||||||
stdin = 'devnull',
|
stdin='devnull',
|
||||||
stdout=subprocess.PIPE,
|
stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE)
|
stderr=subprocess.PIPE)
|
||||||
|
|
||||||
# Use the .stdout and .stderr attributes directly because the
|
# Use the .stdout and .stderr attributes directly because the
|
||||||
# .communicate() method uses the threading module on Windows
|
# .communicate() method uses the threading module on Windows
|
||||||
|
@ -195,10 +206,14 @@ def get_output(vcbat, args = None, env = None):
|
||||||
output = stdout.decode("mbcs")
|
output = stdout.decode("mbcs")
|
||||||
return output
|
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
|
# dkeep is a dict associating key: path_list, where key is one item from
|
||||||
# keep, and pat_list the associated list of paths
|
# keep, and pat_list the associated list of paths
|
||||||
|
|
||||||
dkeep = dict([(i, []) for i in keep])
|
dkeep = dict([(i, []) for i in keep])
|
||||||
|
|
||||||
# rdk will keep the regex to match the .bat file output line starts
|
# 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)
|
rdk[i] = re.compile('%s=(.*)' % i, re.I)
|
||||||
|
|
||||||
def add_env(rmatch, key, dkeep=dkeep):
|
def add_env(rmatch, key, dkeep=dkeep):
|
||||||
plist = rmatch.group(1).split(os.pathsep)
|
path_list = rmatch.group(1).split(os.pathsep)
|
||||||
for p in plist:
|
for path in path_list:
|
||||||
# Do not add empty paths (when a var ends with ;)
|
# Do not add empty paths (when a var ends with ;)
|
||||||
if p:
|
if path:
|
||||||
p = p.encode('mbcs')
|
|
||||||
# XXX: For some reason, VC98 .bat file adds "" around the PATH
|
# XXX: For some reason, VC98 .bat file adds "" around the PATH
|
||||||
# values, and it screws up the environment later, so we strip
|
# values, and it screws up the environment later, so we strip
|
||||||
# it.
|
# it.
|
||||||
p = p.strip('"')
|
path = path.strip('"')
|
||||||
dkeep[key].append(p)
|
dkeep[key].append(str(path))
|
||||||
|
|
||||||
for line in output.splitlines():
|
for line in output.splitlines():
|
||||||
for k,v in rdk.items():
|
for k, value in rdk.items():
|
||||||
m = v.match(line)
|
match = value.match(line)
|
||||||
if m:
|
if match:
|
||||||
add_env(m, k)
|
add_env(match, k)
|
||||||
|
|
||||||
return dkeep
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/MSCommon/netframework.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/MSCommon/netframework.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
__doc__ = """
|
__doc__ = """
|
||||||
"""
|
"""
|
||||||
|
@ -29,7 +29,7 @@ import os
|
||||||
import re
|
import re
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
from common import read_reg, debug
|
from .common import read_reg, debug
|
||||||
|
|
||||||
# Original value recorded by dcournapeau
|
# Original value recorded by dcournapeau
|
||||||
_FRAMEWORKDIR_HKEY_ROOT = r'Software\Microsoft\.NETFramework\InstallRoot'
|
_FRAMEWORKDIR_HKEY_ROOT = r'Software\Microsoft\.NETFramework\InstallRoot'
|
||||||
|
@ -40,13 +40,13 @@ def find_framework_root():
|
||||||
# XXX: find it from environment (FrameworkDir)
|
# XXX: find it from environment (FrameworkDir)
|
||||||
try:
|
try:
|
||||||
froot = read_reg(_FRAMEWORKDIR_HKEY_ROOT)
|
froot = read_reg(_FRAMEWORKDIR_HKEY_ROOT)
|
||||||
debug("Found framework install root in registry: %s" % froot)
|
debug("Found framework install root in registry: {}".format(froot))
|
||||||
except SCons.Util.WinError, e:
|
except SCons.Util.WinError as e:
|
||||||
debug("Could not read reg key %s" % _FRAMEWORKDIR_HKEY_ROOT)
|
debug("Could not read reg key {}".format(_FRAMEWORKDIR_HKEY_ROOT))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if not os.path.exists(froot):
|
if not os.path.exists(froot):
|
||||||
debug("%s not found on fs" % froot)
|
debug("{} not found on fs".format(froot))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return froot
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/MSCommon/sdk.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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
|
__doc__ = """Module to detect the Platform/Windows SDK
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ import os
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
import common
|
from . import common
|
||||||
|
|
||||||
debug = common.debug
|
debug = common.debug
|
||||||
|
|
||||||
|
@ -76,23 +76,23 @@ class SDKDefinition(object):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
hkey = self.HKEY_FMT % self.hkey_data
|
hkey = self.HKEY_FMT % self.hkey_data
|
||||||
debug('find_sdk_dir(): checking registry:%s'%hkey)
|
debug('find_sdk_dir(): checking registry:{}'.format(hkey))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sdk_dir = common.read_reg(hkey)
|
sdk_dir = common.read_reg(hkey)
|
||||||
except SCons.Util.WinError, e:
|
except SCons.Util.WinError as e:
|
||||||
debug('find_sdk_dir(): no SDK registry key %s' % repr(hkey))
|
debug('find_sdk_dir(): no SDK registry key {}'.format(repr(hkey)))
|
||||||
return None
|
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):
|
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
|
return None
|
||||||
|
|
||||||
ftc = os.path.join(sdk_dir, self.sanity_check_file)
|
ftc = os.path.join(sdk_dir, self.sanity_check_file)
|
||||||
if not os.path.exists(ftc):
|
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 None
|
||||||
|
|
||||||
return sdk_dir
|
return sdk_dir
|
||||||
|
@ -105,7 +105,7 @@ class SDKDefinition(object):
|
||||||
sdk_dir = self.find_sdk_dir()
|
sdk_dir = self.find_sdk_dir()
|
||||||
self._sdk_dir = sdk_dir
|
self._sdk_dir = sdk_dir
|
||||||
return sdk_dir
|
return sdk_dir
|
||||||
|
|
||||||
def get_sdk_vc_script(self,host_arch, target_arch):
|
def get_sdk_vc_script(self,host_arch, target_arch):
|
||||||
""" Return the script to initialize the VC compiler installed by SDK
|
""" 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'):
|
if (host_arch == 'amd64' and target_arch == 'x86'):
|
||||||
# No cross tools needed compiling 32 bits on 64 bit machine
|
# No cross tools needed compiling 32 bits on 64 bit machine
|
||||||
host_arch=target_arch
|
host_arch=target_arch
|
||||||
|
|
||||||
arch_string=target_arch
|
arch_string=target_arch
|
||||||
if (host_arch != target_arch):
|
if (host_arch != target_arch):
|
||||||
arch_string='%s_%s'%(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,
|
debug("sdk.py: get_sdk_vc_script():arch_string:%s host_arch:%s target_arch:%s"%(arch_string,
|
||||||
host_arch,
|
host_arch,
|
||||||
target_arch))
|
target_arch))
|
||||||
|
@ -164,6 +164,12 @@ SDK70VCSetupScripts = { 'x86' : r'bin\vcvars32.bat',
|
||||||
'x86_ia64' : r'bin\vcvarsx86_ia64.bat',
|
'x86_ia64' : r'bin\vcvarsx86_ia64.bat',
|
||||||
'ia64' : r'bin\vcvarsia64.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 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
|
# 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.
|
# If you update this list, update the documentation in Tool/mssdk.xml.
|
||||||
SupportedSDKList = [
|
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',
|
WindowsSDK('7.1',
|
||||||
sanity_check_file=r'bin\SetEnv.Cmd',
|
sanity_check_file=r'bin\SetEnv.Cmd',
|
||||||
include_subdir='include',
|
include_subdir='include',
|
||||||
|
@ -308,8 +324,7 @@ def set_sdk_by_directory(env, sdk_dir):
|
||||||
|
|
||||||
def get_sdk_by_version(mssdk):
|
def get_sdk_by_version(mssdk):
|
||||||
if mssdk not in SupportedSDKMap:
|
if mssdk not in SupportedSDKMap:
|
||||||
msg = "SDK version %s is not supported" % repr(mssdk)
|
raise SCons.Errors.UserError("SDK version {} is not supported".format(repr(mssdk)))
|
||||||
raise SCons.Errors.UserError(msg)
|
|
||||||
get_installed_sdks()
|
get_installed_sdks()
|
||||||
return InstalledSDKMap.get(mssdk)
|
return InstalledSDKMap.get(mssdk)
|
||||||
|
|
||||||
|
@ -327,16 +342,16 @@ def mssdk_setup_env(env):
|
||||||
if sdk_dir is None:
|
if sdk_dir is None:
|
||||||
return
|
return
|
||||||
sdk_dir = env.subst(sdk_dir)
|
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:
|
elif 'MSSDK_VERSION' in env:
|
||||||
sdk_version = env['MSSDK_VERSION']
|
sdk_version = env['MSSDK_VERSION']
|
||||||
if sdk_version is None:
|
if sdk_version is None:
|
||||||
msg = "SDK version is specified as None"
|
msg = "SDK version is specified as None"
|
||||||
raise SCons.Errors.UserError(msg)
|
raise SCons.Errors.UserError(msg)
|
||||||
sdk_version = env.subst(sdk_version)
|
sdk_version = env.subst(sdk_version)
|
||||||
mssdk = get_sdk_by_version(sdk_version)
|
mssdk = get_sdk_by_version(sdk_version)
|
||||||
if mssdk is None:
|
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)
|
raise SCons.Errors.UserError(msg)
|
||||||
sdk_dir = mssdk.get_sdk_dir()
|
sdk_dir = mssdk.get_sdk_dir()
|
||||||
debug('sdk.py:mssdk_setup_env: Using MSSDK_VERSION:%s'%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')
|
debug('sdk.py:mssdk_setup_env thinks msvs_version is None')
|
||||||
return
|
return
|
||||||
msvs_version = env.subst(msvs_version)
|
msvs_version = env.subst(msvs_version)
|
||||||
import vs
|
from . import vs
|
||||||
msvs = vs.get_vs_by_version(msvs_version)
|
msvs = vs.get_vs_by_version(msvs_version)
|
||||||
debug('sdk.py:mssdk_setup_env:msvs is :%s'%msvs)
|
debug('sdk.py:mssdk_setup_env:msvs is :%s'%msvs)
|
||||||
if not 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,24 +30,25 @@
|
||||||
# * test on 64 bits XP + VS 2005 (and VS 6 if possible)
|
# * test on 64 bits XP + VS 2005 (and VS 6 if possible)
|
||||||
# * SDK
|
# * SDK
|
||||||
# * Assembly
|
# * Assembly
|
||||||
__revision__ = "src/engine/SCons/Tool/MSCommon/vc.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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.
|
__doc__ = """Module for Visual C/C++ detection and configuration.
|
||||||
"""
|
"""
|
||||||
import SCons.compat
|
import SCons.compat
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
|
import subprocess
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
from string import digits as string_digits
|
from string import digits as string_digits
|
||||||
|
|
||||||
import SCons.Warnings
|
import SCons.Warnings
|
||||||
|
|
||||||
import common
|
from . import common
|
||||||
|
|
||||||
debug = common.debug
|
debug = common.debug
|
||||||
|
|
||||||
import sdk
|
from . import sdk
|
||||||
|
|
||||||
get_installed_sdks = sdk.get_installed_sdks
|
get_installed_sdks = sdk.get_installed_sdks
|
||||||
|
|
||||||
|
@ -108,7 +109,7 @@ def get_host_target(env):
|
||||||
# PROCESSOR_ARCHITECTURE.
|
# PROCESSOR_ARCHITECTURE.
|
||||||
if not host_platform:
|
if not host_platform:
|
||||||
host_platform = os.environ.get('PROCESSOR_ARCHITECTURE', '')
|
host_platform = os.environ.get('PROCESSOR_ARCHITECTURE', '')
|
||||||
|
|
||||||
# Retain user requested TARGET_ARCH
|
# Retain user requested TARGET_ARCH
|
||||||
req_target_platform = env.get('TARGET_ARCH')
|
req_target_platform = env.get('TARGET_ARCH')
|
||||||
debug('vc.py:get_host_target() req_target_platform:%s'%req_target_platform)
|
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
|
target_platform = req_target_platform
|
||||||
else:
|
else:
|
||||||
target_platform = host_platform
|
target_platform = host_platform
|
||||||
|
|
||||||
try:
|
try:
|
||||||
host = _ARCH_TO_CANONICAL[host_platform.lower()]
|
host = _ARCH_TO_CANONICAL[host_platform.lower()]
|
||||||
except KeyError, e:
|
except KeyError as e:
|
||||||
msg = "Unrecognized host architecture %s"
|
msg = "Unrecognized host architecture %s"
|
||||||
raise ValueError(msg % repr(host_platform))
|
raise ValueError(msg % repr(host_platform))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
target = _ARCH_TO_CANONICAL[target_platform.lower()]
|
target = _ARCH_TO_CANONICAL[target_platform.lower()]
|
||||||
except KeyError, e:
|
except KeyError as e:
|
||||||
all_archs = str(_ARCH_TO_CANONICAL.keys())
|
all_archs = str(list(_ARCH_TO_CANONICAL.keys()))
|
||||||
raise ValueError("Unrecognized target architecture %s\n\tValid architectures: %s" % (target_platform, all_archs))
|
raise ValueError("Unrecognized target architecture %s\n\tValid architectures: %s" % (target_platform, all_archs))
|
||||||
|
|
||||||
return (host, target,req_target_platform)
|
return (host, target,req_target_platform)
|
||||||
|
|
||||||
# If you update this, update SupportedVSList in Tool/MSCommon/vs.py, and the
|
# If you update this, update SupportedVSList in Tool/MSCommon/vs.py, and the
|
||||||
# MSVC_VERSION documentation in Tool/msvc.xml.
|
# 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 = {
|
_VCVER_TO_PRODUCT_DIR = {
|
||||||
|
'14.1' : [
|
||||||
|
(SCons.Util.HKEY_LOCAL_MACHINE, r'')], # Visual Studio 2017 doesn't set this registry key anymore
|
||||||
'14.0' : [
|
'14.0' : [
|
||||||
(SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\14.0\Setup\VC\ProductDir')],
|
(SCons.Util.HKEY_LOCAL_MACHINE, r'Microsoft\VisualStudio\14.0\Setup\VC\ProductDir')],
|
||||||
'14.0Exp' : [
|
'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'),
|
(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(".")
|
def msvc_version_to_maj_min(msvc_version):
|
||||||
if not len(t) == 2:
|
msvc_version_numeric = ''.join([x for x in msvc_version if x in string_digits + '.'])
|
||||||
raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
|
|
||||||
try:
|
t = msvc_version_numeric.split(".")
|
||||||
maj = int(t[0])
|
if not len(t) == 2:
|
||||||
min = int(t[1])
|
raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
|
||||||
return maj, min
|
try:
|
||||||
except ValueError, e:
|
maj = int(t[0])
|
||||||
raise ValueError("Unrecognized version %s (%s)" % (msvc_version,msvc_version_numeric))
|
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):
|
def is_host_target_supported(host_target, msvc_version):
|
||||||
"""Return True if the given (host, target) tuple is supported given the
|
"""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
|
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):
|
def find_vc_pdir(msvc_version):
|
||||||
"""Try to find the product directory for the given
|
"""Try to find the product directory for the given
|
||||||
version.
|
version.
|
||||||
|
@ -240,26 +272,31 @@ def find_vc_pdir(msvc_version):
|
||||||
for hkroot, key in hkeys:
|
for hkroot, key in hkeys:
|
||||||
try:
|
try:
|
||||||
comps = None
|
comps = None
|
||||||
if common.is_win64():
|
if not key:
|
||||||
try:
|
comps = find_vc_pdir_vswhere(msvc_version)
|
||||||
# ordinally at win64, try Wow6432Node first.
|
if not comps:
|
||||||
comps = common.read_reg(root + 'Wow6432Node\\' + key, hkroot)
|
debug('find_vc_dir(): no VC found via vswhere for version {}'.format(repr(key)))
|
||||||
except SCons.Util.WinError, e:
|
raise SCons.Util.WinError
|
||||||
# at Microsoft Visual Studio for Python 2.7, value is not in Wow6432Node
|
else:
|
||||||
pass
|
if common.is_win64():
|
||||||
if not comps:
|
try:
|
||||||
# not Win64, or Microsoft Visual Studio for Python 2.7
|
# ordinally at win64, try Wow6432Node first.
|
||||||
comps = common.read_reg(root + key, hkroot)
|
comps = common.read_reg(root + 'Wow6432Node\\' + key, hkroot)
|
||||||
except SCons.Util.WinError, e:
|
except SCons.Util.WinError as e:
|
||||||
debug('find_vc_dir(): no VC registry key %s' % repr(key))
|
# 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:
|
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):
|
if os.path.exists(comps):
|
||||||
return comps
|
return comps
|
||||||
else:
|
else:
|
||||||
debug('find_vc_dir(): reg says dir is %s, but it does not exist. (ignoring)'\
|
debug('find_vc_dir(): reg says dir is {}, but it does not exist. (ignoring)'.format(comps))
|
||||||
% comps)
|
raise MissingConfiguration("registry dir {} not found on the filesystem".format(comps))
|
||||||
raise MissingConfiguration("registry dir %s not found on the filesystem" % comps)
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def find_batch_file(env,msvc_version,host_arch,target_arch):
|
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)
|
pdir = find_vc_pdir(msvc_version)
|
||||||
if pdir is None:
|
if pdir is None:
|
||||||
raise NoVersionFound("No version of Visual Studio found")
|
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
|
# filter out e.g. "Exp" from the version name
|
||||||
msvc_ver_numeric = ''.join([x for x in msvc_version if x in string_digits + "."])
|
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:
|
elif vernum < 7:
|
||||||
pdir = os.path.join(pdir, "Bin")
|
pdir = os.path.join(pdir, "Bin")
|
||||||
batfilename = os.path.join(pdir, "vcvars32.bat")
|
batfilename = os.path.join(pdir, "vcvars32.bat")
|
||||||
else: # >= 8
|
elif 8 <= vernum <= 14:
|
||||||
batfilename = os.path.join(pdir, "vcvarsall.bat")
|
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):
|
if not os.path.exists(batfilename):
|
||||||
debug("Not found: %s" % batfilename)
|
debug("Not found: %s" % batfilename)
|
||||||
batfilename = None
|
batfilename = None
|
||||||
|
|
||||||
installed_sdks=get_installed_sdks()
|
installed_sdks=get_installed_sdks()
|
||||||
for _sdk in installed_sdks:
|
for _sdk in installed_sdks:
|
||||||
sdk_bat_file = _sdk.get_sdk_vc_script(host_arch,target_arch)
|
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)
|
debug("vc.py:find_batch_file() not found:%s"%_sdk)
|
||||||
else:
|
else:
|
||||||
sdk_bat_file_path = os.path.join(pdir,sdk_bat_file)
|
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)
|
debug('vc.py:find_batch_file() sdk_bat_file_path:%s'%sdk_bat_file_path)
|
||||||
return (batfilename,sdk_bat_file_path)
|
return (batfilename,sdk_bat_file_path)
|
||||||
return (batfilename,None)
|
return (batfilename,None)
|
||||||
|
@ -323,7 +362,7 @@ def get_installed_vcs():
|
||||||
installed_versions.append(ver)
|
installed_versions.append(ver)
|
||||||
else:
|
else:
|
||||||
debug('find_vc_pdir return None for ver %s' % ver)
|
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)))
|
debug('did not find VC %s: caught exception %s' % (ver, str(e)))
|
||||||
return installed_versions
|
return installed_versions
|
||||||
|
|
||||||
|
@ -359,7 +398,7 @@ def get_default_version(env):
|
||||||
|
|
||||||
msvc_version = env.get('MSVC_VERSION')
|
msvc_version = env.get('MSVC_VERSION')
|
||||||
msvs_version = env.get('MSVS_VERSION')
|
msvs_version = env.get('MSVS_VERSION')
|
||||||
|
|
||||||
debug('get_default_version(): msvc_version:%s msvs_version:%s'%(msvc_version,msvs_version))
|
debug('get_default_version(): msvc_version:%s msvs_version:%s'%(msvc_version,msvs_version))
|
||||||
|
|
||||||
if msvs_version and not msvc_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]
|
try_target_archs = [target_platform]
|
||||||
debug("msvs_find_valid_batch_script(): req_target_platform %s target_platform:%s"%(req_target_platform,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
|
# with x86_amd64 as the argument to the batch setup script
|
||||||
if req_target_platform in ('amd64','x86_64'):
|
if req_target_platform in ('amd64','x86_64'):
|
||||||
try_target_archs.append('x86_amd64')
|
try_target_archs.append('x86_amd64')
|
||||||
|
@ -427,7 +466,7 @@ def msvc_find_valid_batch_script(env,version):
|
||||||
for tp in try_target_archs:
|
for tp in try_target_archs:
|
||||||
# Set to current arch.
|
# Set to current arch.
|
||||||
env['TARGET_ARCH']=tp
|
env['TARGET_ARCH']=tp
|
||||||
|
|
||||||
debug("vc.py:msvc_find_valid_batch_script() trying target_platform:%s"%tp)
|
debug("vc.py:msvc_find_valid_batch_script() trying target_platform:%s"%tp)
|
||||||
host_target = (host_platform, tp)
|
host_target = (host_platform, tp)
|
||||||
if not is_host_target_supported(host_target, version):
|
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)
|
SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
|
||||||
arg = _HOST_TARGET_ARCH_TO_BAT_ARCH[host_target]
|
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 to locate a batch file for this host/target platform combo
|
||||||
try:
|
try:
|
||||||
(vc_script,sdk_script) = find_batch_file(env,version,host_platform,tp)
|
(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))
|
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)
|
msg = str(e)
|
||||||
debug('Caught exception while looking for batch file (%s)' % msg)
|
debug('Caught exception while looking for batch file (%s)' % msg)
|
||||||
warn_msg = "VC version %s not installed. " + \
|
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())
|
warn_msg = warn_msg % (version, cached_get_installed_vcs())
|
||||||
SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
|
SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Try to use the located batch file for this host/target platform combo
|
# 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))
|
debug('vc.py:msvc_find_valid_batch_script() use_script 2 %s, args:%s\n' % (repr(vc_script), arg))
|
||||||
if vc_script:
|
if vc_script:
|
||||||
try:
|
try:
|
||||||
d = script_env(vc_script, args=arg)
|
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))
|
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
|
vc_script=None
|
||||||
continue
|
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))
|
debug('vc.py:msvc_find_valid_batch_script() use_script 4: trying sdk script: %s'%(sdk_script))
|
||||||
try:
|
try:
|
||||||
d = script_env(sdk_script)
|
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))
|
debug('vc.py:msvc_find_valid_batch_script() use_script 5: failed running SDK script %s: Error:%s'%(repr(sdk_script),e))
|
||||||
continue
|
continue
|
||||||
elif not vc_script and not sdk_script:
|
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')
|
debug('vc.py:msvc_find_valid_batch_script() use_script 6: Neither VC script nor SDK script found')
|
||||||
continue
|
continue
|
||||||
|
|
||||||
debug("vc.py:msvc_find_valid_batch_script() Found a working script/target: %s %s"%(repr(sdk_script),arg))
|
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
|
break # We've found a working target_platform, so stop looking
|
||||||
|
|
||||||
# If we cannot find a viable installed compiler, reset the TARGET_ARCH
|
# If we cannot find a viable installed compiler, reset the TARGET_ARCH
|
||||||
# To it's initial value
|
# To it's initial value
|
||||||
if not d:
|
if not d:
|
||||||
env['TARGET_ARCH']=req_target_platform
|
env['TARGET_ARCH']=req_target_platform
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
def msvc_setup_env(env):
|
def msvc_setup_env(env):
|
||||||
debug('msvc_setup_env()')
|
debug('msvc_setup_env()')
|
||||||
|
@ -498,12 +545,12 @@ def msvc_setup_env(env):
|
||||||
env['MSVS_VERSION'] = version
|
env['MSVS_VERSION'] = version
|
||||||
env['MSVS'] = {}
|
env['MSVS'] = {}
|
||||||
|
|
||||||
|
|
||||||
use_script = env.get('MSVC_USE_SCRIPT', True)
|
use_script = env.get('MSVC_USE_SCRIPT', True)
|
||||||
if SCons.Util.is_String(use_script):
|
if SCons.Util.is_String(use_script):
|
||||||
debug('vc.py:msvc_setup_env() use_script 1 %s\n' % repr(use_script))
|
debug('vc.py:msvc_setup_env() use_script 1 %s\n' % repr(use_script))
|
||||||
d = script_env(use_script)
|
d = script_env(use_script)
|
||||||
elif use_script:
|
elif use_script:
|
||||||
d = msvc_find_valid_batch_script(env,version)
|
d = msvc_find_valid_batch_script(env,version)
|
||||||
debug('vc.py:msvc_setup_env() use_script 2 %s\n' % d)
|
debug('vc.py:msvc_setup_env() use_script 2 %s\n' % d)
|
||||||
if not d:
|
if not d:
|
||||||
|
@ -524,4 +571,3 @@ def msvc_exists(version=None):
|
||||||
if version is None:
|
if version is None:
|
||||||
return len(vcs) > 0
|
return len(vcs) > 0
|
||||||
return version in vcs
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/MSCommon/vs.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 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++
|
__doc__ = """Module to detect Visual Studio and/or Visual C/C++
|
||||||
"""
|
"""
|
||||||
|
@ -31,7 +31,7 @@ import os
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
from common import debug, \
|
from .common import debug, \
|
||||||
get_output, \
|
get_output, \
|
||||||
is_win64, \
|
is_win64, \
|
||||||
normalize_env, \
|
normalize_env, \
|
||||||
|
@ -83,10 +83,10 @@ class VisualStudio(object):
|
||||||
key = root + key
|
key = root + key
|
||||||
try:
|
try:
|
||||||
comps = read_reg(key)
|
comps = read_reg(key)
|
||||||
except SCons.Util.WinError, e:
|
except SCons.Util.WinError as e:
|
||||||
debug('find_vs_dir_by_reg(): no VS registry key %s' % repr(key))
|
debug('find_vs_dir_by_reg(): no VS registry key {}'.format(repr(key)))
|
||||||
else:
|
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 comps
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -105,12 +105,12 @@ class VisualStudio(object):
|
||||||
def find_executable(self):
|
def find_executable(self):
|
||||||
vs_dir = self.get_vs_dir()
|
vs_dir = self.get_vs_dir()
|
||||||
if not 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
|
return None
|
||||||
executable = os.path.join(vs_dir, self.executable_path)
|
executable = os.path.join(vs_dir, self.executable_path)
|
||||||
executable = os.path.normpath(executable)
|
executable = os.path.normpath(executable)
|
||||||
if not os.path.isfile(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 None
|
||||||
return executable
|
return executable
|
||||||
|
|
||||||
|
@ -199,17 +199,28 @@ class VisualStudio(object):
|
||||||
# Tool/MSCommon/vc.py, and the MSVC_VERSION documentation in Tool/msvc.xml.
|
# Tool/MSCommon/vc.py, and the MSVC_VERSION documentation in Tool/msvc.xml.
|
||||||
|
|
||||||
SupportedVSList = [
|
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
|
# Visual Studio 2015
|
||||||
VisualStudio('14.0',
|
VisualStudio('14.0',
|
||||||
vc_version='14.0',
|
vc_version='14.0',
|
||||||
sdk_version='10.0A',
|
sdk_version='10.0',
|
||||||
hkeys=[r'Microsoft\VisualStudio\14.0\Setup\VS\ProductDir'],
|
hkeys=[r'Microsoft\VisualStudio\14.0\Setup\VS\ProductDir'],
|
||||||
common_tools_var='VS140COMNTOOLS',
|
common_tools_var='VS140COMNTOOLS',
|
||||||
executable_path=r'Common7\IDE\devenv.com',
|
executable_path=r'Common7\IDE\devenv.com',
|
||||||
batch_file_path=r'Common7\Tools\vsvars32.bat',
|
batch_file_path=r'Common7\Tools\vsvars32.bat',
|
||||||
supported_arch=['x86', 'amd64', "arm"],
|
supported_arch=['x86', 'amd64', "arm"],
|
||||||
),
|
),
|
||||||
|
|
||||||
# Visual C++ 2015 Express Edition (for Desktop)
|
# Visual C++ 2015 Express Edition (for Desktop)
|
||||||
VisualStudio('14.0Exp',
|
VisualStudio('14.0Exp',
|
||||||
vc_version='14.0',
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -29,7 +29,7 @@ Phar Lap ETS tool chain. Right now, this is linkloc and
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/PharLapCommon.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/PharLapCommon.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -35,14 +35,16 @@ tool definition.
|
||||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/__init__.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/__init__.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import imp
|
import imp
|
||||||
|
import importlib
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
|
|
||||||
import SCons.Builder
|
import SCons.Builder
|
||||||
import SCons.Errors
|
import SCons.Errors
|
||||||
import SCons.Node.FS
|
import SCons.Node.FS
|
||||||
|
@ -52,6 +54,7 @@ import SCons.Scanner.D
|
||||||
import SCons.Scanner.LaTeX
|
import SCons.Scanner.LaTeX
|
||||||
import SCons.Scanner.Prog
|
import SCons.Scanner.Prog
|
||||||
import SCons.Scanner.SWIG
|
import SCons.Scanner.SWIG
|
||||||
|
import collections
|
||||||
|
|
||||||
DefaultToolpath=[]
|
DefaultToolpath=[]
|
||||||
|
|
||||||
|
@ -94,9 +97,20 @@ for suffix in LaTeXSuffixes:
|
||||||
SourceFileScanner.add_scanner(suffix, LaTeXScanner)
|
SourceFileScanner.add_scanner(suffix, LaTeXScanner)
|
||||||
SourceFileScanner.add_scanner(suffix, PDFLaTeXScanner)
|
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):
|
class Tool(object):
|
||||||
def __init__(self, name, toolpath=[], **kw):
|
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
|
self.toolpath = toolpath + DefaultToolpath
|
||||||
# remember these so we can merge them into the call
|
# remember these so we can merge them into the call
|
||||||
self.init_kw = kw
|
self.init_kw = kw
|
||||||
|
@ -107,35 +121,130 @@ class Tool(object):
|
||||||
if hasattr(module, 'options'):
|
if hasattr(module, 'options'):
|
||||||
self.options = 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):
|
def _tool_module(self):
|
||||||
# TODO: Interchange zipimport with normal initialization for better error reporting
|
|
||||||
oldpythonpath = sys.path
|
oldpythonpath = sys.path
|
||||||
sys.path = self.toolpath + 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:
|
try:
|
||||||
file, path, desc = imp.find_module(self.name, self.toolpath)
|
|
||||||
try:
|
try:
|
||||||
return imp.load_module(self.name, file, path, desc)
|
file = None
|
||||||
finally:
|
try:
|
||||||
if file:
|
mod, file = self._load_dotted_module_py2(self.name, self.name, self.toolpath)
|
||||||
file.close()
|
return mod
|
||||||
except ImportError, e:
|
finally:
|
||||||
if str(e)!="No module named %s"%self.name:
|
if file:
|
||||||
raise SCons.Errors.EnvironmentError(e)
|
file.close()
|
||||||
try:
|
except ImportError as e:
|
||||||
import zipimport
|
splitname = self.name.split('.')
|
||||||
except ImportError:
|
if str(e)!="No module named %s"%splitname[0]:
|
||||||
pass
|
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:
|
else:
|
||||||
for aPath in self.toolpath:
|
continue
|
||||||
try:
|
|
||||||
importer = zipimport.zipimporter(aPath)
|
if spec is None:
|
||||||
return importer.load_module(self.name)
|
if debug: sys.stderr.write("NO SPEC :%s\n"%self.name)
|
||||||
except ImportError, e:
|
spec = importlib.util.find_spec("."+self.name, package='SCons.Tool')
|
||||||
pass
|
if spec:
|
||||||
finally:
|
found_name = 'SCons.Tool.'+self.name
|
||||||
sys.path = oldpythonpath
|
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
|
full_name = 'SCons.Tool.' + self.name
|
||||||
try:
|
try:
|
||||||
|
@ -144,13 +253,12 @@ class Tool(object):
|
||||||
try:
|
try:
|
||||||
smpath = sys.modules['SCons.Tool'].__path__
|
smpath = sys.modules['SCons.Tool'].__path__
|
||||||
try:
|
try:
|
||||||
file, path, desc = imp.find_module(self.name, smpath)
|
module, file = self._load_dotted_module_py2(self.name, full_name, smpath)
|
||||||
module = imp.load_module(full_name, file, path, desc)
|
|
||||||
setattr(SCons.Tool, self.name, module)
|
setattr(SCons.Tool, self.name, module)
|
||||||
if file:
|
if file:
|
||||||
file.close()
|
file.close()
|
||||||
return module
|
return module
|
||||||
except ImportError, e:
|
except ImportError as e:
|
||||||
if str(e)!="No module named %s"%self.name:
|
if str(e)!="No module named %s"%self.name:
|
||||||
raise SCons.Errors.EnvironmentError(e)
|
raise SCons.Errors.EnvironmentError(e)
|
||||||
try:
|
try:
|
||||||
|
@ -159,10 +267,10 @@ class Tool(object):
|
||||||
module = importer.load_module(full_name)
|
module = importer.load_module(full_name)
|
||||||
setattr(SCons.Tool, self.name, module)
|
setattr(SCons.Tool, self.name, module)
|
||||||
return module
|
return module
|
||||||
except ImportError, e:
|
except ImportError as e:
|
||||||
m = "No tool named '%s': %s" % (self.name, e)
|
m = "No tool named '%s': %s" % (self.name, e)
|
||||||
raise SCons.Errors.EnvironmentError(m)
|
raise SCons.Errors.EnvironmentError(m)
|
||||||
except ImportError, e:
|
except ImportError as e:
|
||||||
m = "No tool named '%s': %s" % (self.name, e)
|
m = "No tool named '%s': %s" % (self.name, e)
|
||||||
raise SCons.Errors.EnvironmentError(m)
|
raise SCons.Errors.EnvironmentError(m)
|
||||||
|
|
||||||
|
@ -217,6 +325,7 @@ def createProgBuilder(env):
|
||||||
|
|
||||||
return program
|
return program
|
||||||
|
|
||||||
|
|
||||||
def createStaticLibBuilder(env):
|
def createStaticLibBuilder(env):
|
||||||
"""This is a utility function that creates the StaticLibrary
|
"""This is a utility function that creates the StaticLibrary
|
||||||
Builder in an Environment if it is not there already.
|
Builder in an Environment if it is not there already.
|
||||||
|
@ -228,7 +337,7 @@ def createStaticLibBuilder(env):
|
||||||
static_lib = env['BUILDERS']['StaticLibrary']
|
static_lib = env['BUILDERS']['StaticLibrary']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
action_list = [ SCons.Action.Action("$ARCOM", "$ARCOMSTR") ]
|
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")
|
ranlib_action = SCons.Action.Action("$RANLIBCOM", "$RANLIBCOMSTR")
|
||||||
action_list.append(ranlib_action)
|
action_list.append(ranlib_action)
|
||||||
|
|
||||||
|
@ -254,22 +363,22 @@ def _call_linker_cb(env, callback, args, result = None):
|
||||||
Verbose = False
|
Verbose = False
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print '_call_linker_cb: args=%r' % args
|
print('_call_linker_cb: args=%r' % args)
|
||||||
print '_call_linker_cb: callback=%r' % callback
|
print('_call_linker_cb: callback=%r' % callback)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
cbfun = env['LINKCALLBACKS'][callback]
|
cbfun = env['LINKCALLBACKS'][callback]
|
||||||
except (KeyError, TypeError):
|
except (KeyError, TypeError):
|
||||||
if Verbose:
|
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
|
pass
|
||||||
else:
|
else:
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print '_call_linker_cb: env["LINKCALLBACKS"][%r] found' % callback
|
print('_call_linker_cb: env["LINKCALLBACKS"][%r] found' % callback)
|
||||||
print '_call_linker_cb: env["LINKCALLBACKS"][%r]=%r' % (callback, cbfun)
|
print('_call_linker_cb: env["LINKCALLBACKS"][%r]=%r' % (callback, cbfun))
|
||||||
if(callable(cbfun)):
|
if(isinstance(cbfun, collections.Callable)):
|
||||||
if Verbose:
|
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)
|
result = cbfun(env, *args)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -388,7 +497,7 @@ class _LibInfoGeneratorBase(object):
|
||||||
|
|
||||||
def generate_versioned_lib_info(self, env, args, result = None, **kw):
|
def generate_versioned_lib_info(self, env, args, result = None, **kw):
|
||||||
callback = self.get_versioned_lib_info_generator(**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):
|
class _LibPrefixGenerator(_LibInfoGeneratorBase):
|
||||||
"""Library prefix generator, used as target_prefix in SharedLibrary and
|
"""Library prefix generator, used as target_prefix in SharedLibrary and
|
||||||
|
@ -407,17 +516,17 @@ class _LibPrefixGenerator(_LibInfoGeneratorBase):
|
||||||
|
|
||||||
prefix = self.get_lib_prefix(env,**kw2)
|
prefix = self.get_lib_prefix(env,**kw2)
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_LibPrefixGenerator: input prefix=%r" % prefix
|
print("_LibPrefixGenerator: input prefix=%r" % prefix)
|
||||||
|
|
||||||
version = self.get_lib_version(env, **kw2)
|
version = self.get_lib_version(env, **kw2)
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_LibPrefixGenerator: version=%r" % version
|
print("_LibPrefixGenerator: version=%r" % version)
|
||||||
|
|
||||||
if version:
|
if version:
|
||||||
prefix = self.generate_versioned_lib_info(env, [prefix, version], prefix, **kw2)
|
prefix = self.generate_versioned_lib_info(env, [prefix, version], prefix, **kw2)
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_LibPrefixGenerator: return prefix=%r" % prefix
|
print("_LibPrefixGenerator: return prefix=%r" % prefix)
|
||||||
return prefix
|
return prefix
|
||||||
|
|
||||||
ShLibPrefixGenerator = _LibPrefixGenerator('ShLib')
|
ShLibPrefixGenerator = _LibPrefixGenerator('ShLib')
|
||||||
|
@ -441,17 +550,17 @@ class _LibSuffixGenerator(_LibInfoGeneratorBase):
|
||||||
|
|
||||||
suffix = self.get_lib_suffix(env, **kw2)
|
suffix = self.get_lib_suffix(env, **kw2)
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_LibSuffixGenerator: input suffix=%r" % suffix
|
print("_LibSuffixGenerator: input suffix=%r" % suffix)
|
||||||
|
|
||||||
version = self.get_lib_version(env, **kw2)
|
version = self.get_lib_version(env, **kw2)
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_LibSuffixGenerator: version=%r" % version
|
print("_LibSuffixGenerator: version=%r" % version)
|
||||||
|
|
||||||
if version:
|
if version:
|
||||||
suffix = self.generate_versioned_lib_info(env, [suffix, version], suffix, **kw2)
|
suffix = self.generate_versioned_lib_info(env, [suffix, version], suffix, **kw2)
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_LibSuffixGenerator: return suffix=%r" % suffix
|
print("_LibSuffixGenerator: return suffix=%r" % suffix)
|
||||||
return suffix
|
return suffix
|
||||||
|
|
||||||
ShLibSuffixGenerator = _LibSuffixGenerator('ShLib')
|
ShLibSuffixGenerator = _LibSuffixGenerator('ShLib')
|
||||||
|
@ -474,15 +583,15 @@ class _LibSymlinkGenerator(_LibInfoGeneratorBase):
|
||||||
kw2 = kw
|
kw2 = kw
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_LibSymLinkGenerator: libnode=%r" % libnode.get_path()
|
print("_LibSymLinkGenerator: libnode=%r" % libnode.get_path())
|
||||||
|
|
||||||
symlinks = None
|
symlinks = None
|
||||||
|
|
||||||
version = self.get_lib_version(env, **kw2)
|
version = self.get_lib_version(env, **kw2)
|
||||||
disable = self.get_lib_noversionsymlinks(env, **kw2)
|
disable = self.get_lib_noversionsymlinks(env, **kw2)
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print '_LibSymlinkGenerator: version=%r' % version
|
print('_LibSymlinkGenerator: version=%r' % version)
|
||||||
print '_LibSymlinkGenerator: disable=%r' % disable
|
print('_LibSymlinkGenerator: disable=%r' % disable)
|
||||||
|
|
||||||
if version and not disable:
|
if version and not disable:
|
||||||
prefix = self.get_lib_prefix(env,**kw2)
|
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)
|
symlinks = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw2)
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print '_LibSymlinkGenerator: return symlinks=%r' % StringizeLibSymlinks(symlinks)
|
print('_LibSymlinkGenerator: return symlinks=%r' % StringizeLibSymlinks(symlinks))
|
||||||
return symlinks
|
return symlinks
|
||||||
|
|
||||||
ShLibSymlinkGenerator = _LibSymlinkGenerator('ShLib')
|
ShLibSymlinkGenerator = _LibSymlinkGenerator('ShLib')
|
||||||
|
@ -499,7 +608,7 @@ ImpLibSymlinkGenerator = _LibSymlinkGenerator('ImpLib')
|
||||||
|
|
||||||
class _LibNameGenerator(_LibInfoGeneratorBase):
|
class _LibNameGenerator(_LibInfoGeneratorBase):
|
||||||
"""Generates "unmangled" library name from a library file node.
|
"""Generates "unmangled" library name from a library file node.
|
||||||
|
|
||||||
Generally, it's thought to revert modifications done by prefix/suffix
|
Generally, it's thought to revert modifications done by prefix/suffix
|
||||||
generators (_LibPrefixGenerator/_LibSuffixGenerator) used by a library
|
generators (_LibPrefixGenerator/_LibSuffixGenerator) used by a library
|
||||||
builder. For example, on gnulink the suffix generator used by SharedLibrary
|
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",
|
"$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",
|
$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
|
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):
|
def __init__(self, libtype):
|
||||||
super(_LibNameGenerator, self).__init__(libtype, 'Name')
|
super(_LibNameGenerator, self).__init__(libtype, 'Name')
|
||||||
|
@ -525,11 +634,11 @@ class _LibNameGenerator(_LibInfoGeneratorBase):
|
||||||
kw2 = kw
|
kw2 = kw
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_LibNameGenerator: libnode=%r" % libnode.get_path()
|
print("_LibNameGenerator: libnode=%r" % libnode.get_path())
|
||||||
|
|
||||||
version = self.get_lib_version(env, **kw2)
|
version = self.get_lib_version(env, **kw2)
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print '_LibNameGenerator: version=%r' % version
|
print('_LibNameGenerator: version=%r' % version)
|
||||||
|
|
||||||
name = None
|
name = None
|
||||||
if version:
|
if version:
|
||||||
|
@ -541,7 +650,7 @@ class _LibNameGenerator(_LibInfoGeneratorBase):
|
||||||
name = os.path.basename(libnode.get_path())
|
name = os.path.basename(libnode.get_path())
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print '_LibNameGenerator: return name=%r' % name
|
print('_LibNameGenerator: return name=%r' % name)
|
||||||
|
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
@ -550,7 +659,7 @@ LdModNameGenerator = _LibNameGenerator('LdMod')
|
||||||
ImpLibNameGenerator = _LibNameGenerator('ImpLib')
|
ImpLibNameGenerator = _LibNameGenerator('ImpLib')
|
||||||
|
|
||||||
class _LibSonameGenerator(_LibInfoGeneratorBase):
|
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)"""
|
a given node (e.g. /foo/bar/libfoo.so.0.1.2)"""
|
||||||
def __init__(self, libtype):
|
def __init__(self, libtype):
|
||||||
super(_LibSonameGenerator, self).__init__(libtype, 'Soname')
|
super(_LibSonameGenerator, self).__init__(libtype, 'Soname')
|
||||||
|
@ -566,13 +675,13 @@ class _LibSonameGenerator(_LibInfoGeneratorBase):
|
||||||
kw2 = kw
|
kw2 = kw
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_LibSonameGenerator: libnode=%r" % libnode.get_path()
|
print("_LibSonameGenerator: libnode=%r" % libnode.get_path())
|
||||||
|
|
||||||
soname = _call_env_subst(env, '$SONAME', **kw2)
|
soname = _call_env_subst(env, '$SONAME', **kw2)
|
||||||
if not soname:
|
if not soname:
|
||||||
version = self.get_lib_version(env,**kw2)
|
version = self.get_lib_version(env,**kw2)
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_LibSonameGenerator: version=%r" % version
|
print("_LibSonameGenerator: version=%r" % version)
|
||||||
if version:
|
if version:
|
||||||
prefix = self.get_lib_prefix(env,**kw2)
|
prefix = self.get_lib_prefix(env,**kw2)
|
||||||
suffix = self.get_lib_suffix(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)
|
# fallback to library name (as returned by appropriate _LibNameGenerator)
|
||||||
soname = _LibNameGenerator(self.get_libtype())(env, libnode)
|
soname = _LibNameGenerator(self.get_libtype())(env, libnode)
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_LibSonameGenerator: FALLBACK: soname=%r" % soname
|
print("_LibSonameGenerator: FALLBACK: soname=%r" % soname)
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_LibSonameGenerator: return soname=%r" % soname
|
print("_LibSonameGenerator: return soname=%r" % soname)
|
||||||
|
|
||||||
return soname
|
return soname
|
||||||
|
|
||||||
|
@ -613,39 +722,39 @@ def EmitLibSymlinks(env, symlinks, libnode, **kw):
|
||||||
clean_targets = kw.get('clean_targets', [])
|
clean_targets = kw.get('clean_targets', [])
|
||||||
if not SCons.Util.is_List(clean_targets):
|
if not SCons.Util.is_List(clean_targets):
|
||||||
clean_targets = [ clean_targets ]
|
clean_targets = [ clean_targets ]
|
||||||
|
|
||||||
for link, linktgt in symlinks:
|
for link, linktgt in symlinks:
|
||||||
env.SideEffect(link, linktgt)
|
env.SideEffect(link, linktgt)
|
||||||
if(Verbose):
|
if(Verbose):
|
||||||
print "EmitLibSymlinks: SideEffect(%r,%r)" % (link.get_path(), linktgt.get_path())
|
print("EmitLibSymlinks: SideEffect(%r,%r)" % (link.get_path(), linktgt.get_path()))
|
||||||
clean_list = filter(lambda x : x != linktgt, nodes)
|
clean_list = [x for x in nodes if x != linktgt]
|
||||||
env.Clean(list(set([linktgt] + clean_targets)), clean_list)
|
env.Clean(list(set([linktgt] + clean_targets)), clean_list)
|
||||||
if(Verbose):
|
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):
|
def CreateLibSymlinks(env, symlinks):
|
||||||
"""Physically creates symlinks. The symlinks argument must be a list in
|
"""Physically creates symlinks. The symlinks argument must be a list in
|
||||||
form [ (link, linktarget), ... ], where link and linktarget are SCons
|
form [ (link, linktarget), ... ], where link and linktarget are SCons
|
||||||
nodes.
|
nodes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Verbose = False
|
Verbose = False
|
||||||
for link, linktgt in symlinks:
|
for link, linktgt in symlinks:
|
||||||
linktgt = link.get_dir().rel_path(linktgt)
|
linktgt = link.get_dir().rel_path(linktgt)
|
||||||
link = link.get_path()
|
link = link.get_path()
|
||||||
if(Verbose):
|
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
|
# Delete the (previously created) symlink if exists. Let only symlinks
|
||||||
# to be deleted to prevent accidental deletion of source files...
|
# to be deleted to prevent accidental deletion of source files...
|
||||||
if env.fs.islink(link):
|
if env.fs.islink(link):
|
||||||
env.fs.unlink(link)
|
env.fs.unlink(link)
|
||||||
if(Verbose):
|
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
|
# If a file or directory exists with the same name as link, an OSError
|
||||||
# will be thrown, which should be enough, I think.
|
# will be thrown, which should be enough, I think.
|
||||||
env.fs.symlink(linktgt, link)
|
env.fs.symlink(linktgt, link)
|
||||||
if(Verbose):
|
if(Verbose):
|
||||||
print "CreateLibSymlinks: add symlink %r -> %r" % (link, linktgt)
|
print("CreateLibSymlinks: add symlink %r -> %r" % (link, linktgt))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
def LibSymlinksActionFunction(target, source, env):
|
def LibSymlinksActionFunction(target, source, env):
|
||||||
|
@ -670,10 +779,11 @@ def LibSymlinksStrFun(target, source, env, *args):
|
||||||
else:
|
else:
|
||||||
cmd += ": %s" % linkstr
|
cmd += ": %s" % linkstr
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
|
|
||||||
LibSymlinksAction = SCons.Action.Action(LibSymlinksActionFunction, LibSymlinksStrFun)
|
LibSymlinksAction = SCons.Action.Action(LibSymlinksActionFunction, LibSymlinksStrFun)
|
||||||
|
|
||||||
|
|
||||||
def createSharedLibBuilder(env):
|
def createSharedLibBuilder(env):
|
||||||
"""This is a utility function that creates the SharedLibrary
|
"""This is a utility function that creates the SharedLibrary
|
||||||
Builder in an Environment if it is not there already.
|
Builder in an Environment if it is not there already.
|
||||||
|
@ -803,17 +913,25 @@ def createCFileBuilders(env):
|
||||||
# Create common Java builders
|
# Create common Java builders
|
||||||
|
|
||||||
def CreateJarBuilder(env):
|
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:
|
try:
|
||||||
java_jar = env['BUILDERS']['Jar']
|
java_jar = env['BUILDERS']['JarFile']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
fs = SCons.Node.FS.get_default_fs()
|
fs = SCons.Node.FS.get_default_fs()
|
||||||
jar_com = SCons.Action.Action('$JARCOM', '$JARCOMSTR')
|
jar_com = SCons.Action.Action('$JARCOM', '$JARCOMSTR')
|
||||||
java_jar = SCons.Builder.Builder(action = jar_com,
|
java_jar = SCons.Builder.Builder(action = jar_com,
|
||||||
suffix = '$JARSUFFIX',
|
suffix = '$JARSUFFIX',
|
||||||
src_suffix = '$JAVACLASSSUFIX',
|
src_suffix = '$JAVACLASSSUFFIX',
|
||||||
src_builder = 'JavaClassFile',
|
src_builder = 'JavaClassFile',
|
||||||
source_factory = fs.Entry)
|
source_factory = fs.Entry)
|
||||||
env['BUILDERS']['Jar'] = java_jar
|
env['BUILDERS']['JarFile'] = java_jar
|
||||||
return java_jar
|
return java_jar
|
||||||
|
|
||||||
def CreateJavaHBuilder(env):
|
def CreateJavaHBuilder(env):
|
||||||
|
@ -890,9 +1008,9 @@ class ToolInitializerMethod(object):
|
||||||
|
|
||||||
def get_builder(self, env):
|
def get_builder(self, env):
|
||||||
"""
|
"""
|
||||||
Returns the appropriate real Builder for this method name
|
Returns the appropriate real Builder for this method name
|
||||||
after having the associated ToolInitializer object apply
|
after having the associated ToolInitializer object apply
|
||||||
the appropriate Tool module.
|
the appropriate Tool module.
|
||||||
"""
|
"""
|
||||||
builder = getattr(env, self.__name__)
|
builder = getattr(env, self.__name__)
|
||||||
|
|
||||||
|
@ -949,13 +1067,13 @@ class ToolInitializer(object):
|
||||||
so we no longer copy and re-bind them when the construction
|
so we no longer copy and re-bind them when the construction
|
||||||
environment gets cloned.
|
environment gets cloned.
|
||||||
"""
|
"""
|
||||||
for method in self.methods.values():
|
for method in list(self.methods.values()):
|
||||||
env.RemoveMethod(method)
|
env.RemoveMethod(method)
|
||||||
|
|
||||||
def apply_tools(self, env):
|
def apply_tools(self, env):
|
||||||
"""
|
"""
|
||||||
Searches the list of associated Tool modules for one that
|
Searches the list of associated Tool modules for one that
|
||||||
exists, and applies that to the construction environment.
|
exists, and applies that to the construction environment.
|
||||||
"""
|
"""
|
||||||
for t in self.tools:
|
for t in self.tools:
|
||||||
tool = SCons.Tool.Tool(t)
|
tool = SCons.Tool.Tool(t)
|
||||||
|
@ -1005,7 +1123,7 @@ def tool_list(platform, env):
|
||||||
"prefer Microsoft tools on Windows"
|
"prefer Microsoft tools on Windows"
|
||||||
linkers = ['mslink', 'gnulink', 'ilink', 'linkloc', 'ilink32' ]
|
linkers = ['mslink', 'gnulink', 'ilink', 'linkloc', 'ilink32' ]
|
||||||
c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ]
|
c_compilers = ['msvc', 'mingw', 'gcc', 'intelc', 'icl', 'icc', 'cc', 'bcc32' ]
|
||||||
cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'c++', 'bcc32' ]
|
cxx_compilers = ['msvc', 'intelc', 'icc', 'g++', 'cxx', 'bcc32' ]
|
||||||
assemblers = ['masm', 'nasm', 'gas', '386asm' ]
|
assemblers = ['masm', 'nasm', 'gas', '386asm' ]
|
||||||
fortran_compilers = ['gfortran', 'g77', 'ifl', 'cvf', 'f95', 'f90', 'fortran']
|
fortran_compilers = ['gfortran', 'g77', 'ifl', 'cvf', 'f95', 'f90', 'fortran']
|
||||||
ars = ['mslib', 'ar', 'tlib']
|
ars = ['mslib', 'ar', 'tlib']
|
||||||
|
@ -1014,7 +1132,7 @@ def tool_list(platform, env):
|
||||||
"prefer IBM tools on OS/2"
|
"prefer IBM tools on OS/2"
|
||||||
linkers = ['ilink', 'gnulink', ]#'mslink']
|
linkers = ['ilink', 'gnulink', ]#'mslink']
|
||||||
c_compilers = ['icc', 'gcc',]# 'msvc', 'cc']
|
c_compilers = ['icc', 'gcc',]# 'msvc', 'cc']
|
||||||
cxx_compilers = ['icc', 'g++',]# 'msvc', 'c++']
|
cxx_compilers = ['icc', 'g++',]# 'msvc', 'cxx']
|
||||||
assemblers = ['nasm',]# 'masm', 'gas']
|
assemblers = ['nasm',]# 'masm', 'gas']
|
||||||
fortran_compilers = ['ifl', 'g77']
|
fortran_compilers = ['ifl', 'g77']
|
||||||
ars = ['ar',]# 'mslib']
|
ars = ['ar',]# 'mslib']
|
||||||
|
@ -1022,7 +1140,7 @@ def tool_list(platform, env):
|
||||||
"prefer MIPSPro on IRIX"
|
"prefer MIPSPro on IRIX"
|
||||||
linkers = ['sgilink', 'gnulink']
|
linkers = ['sgilink', 'gnulink']
|
||||||
c_compilers = ['sgicc', 'gcc', 'cc']
|
c_compilers = ['sgicc', 'gcc', 'cc']
|
||||||
cxx_compilers = ['sgic++', 'g++', 'c++']
|
cxx_compilers = ['sgicxx', 'g++', 'cxx']
|
||||||
assemblers = ['as', 'gas']
|
assemblers = ['as', 'gas']
|
||||||
fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran']
|
fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran']
|
||||||
ars = ['sgiar']
|
ars = ['sgiar']
|
||||||
|
@ -1030,7 +1148,7 @@ def tool_list(platform, env):
|
||||||
"prefer Forte tools on SunOS"
|
"prefer Forte tools on SunOS"
|
||||||
linkers = ['sunlink', 'gnulink']
|
linkers = ['sunlink', 'gnulink']
|
||||||
c_compilers = ['suncc', 'gcc', 'cc']
|
c_compilers = ['suncc', 'gcc', 'cc']
|
||||||
cxx_compilers = ['sunc++', 'g++', 'c++']
|
cxx_compilers = ['suncxx', 'g++', 'cxx']
|
||||||
assemblers = ['as', 'gas']
|
assemblers = ['as', 'gas']
|
||||||
fortran_compilers = ['sunf95', 'sunf90', 'sunf77', 'f95', 'f90', 'f77',
|
fortran_compilers = ['sunf95', 'sunf90', 'sunf77', 'f95', 'f90', 'f77',
|
||||||
'gfortran', 'g77', 'fortran']
|
'gfortran', 'g77', 'fortran']
|
||||||
|
@ -1039,7 +1157,7 @@ def tool_list(platform, env):
|
||||||
"prefer aCC tools on HP-UX"
|
"prefer aCC tools on HP-UX"
|
||||||
linkers = ['hplink', 'gnulink']
|
linkers = ['hplink', 'gnulink']
|
||||||
c_compilers = ['hpcc', 'gcc', 'cc']
|
c_compilers = ['hpcc', 'gcc', 'cc']
|
||||||
cxx_compilers = ['hpc++', 'g++', 'c++']
|
cxx_compilers = ['hpcxx', 'g++', 'cxx']
|
||||||
assemblers = ['as', 'gas']
|
assemblers = ['as', 'gas']
|
||||||
fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran']
|
fortran_compilers = ['f95', 'f90', 'f77', 'g77', 'fortran']
|
||||||
ars = ['ar']
|
ars = ['ar']
|
||||||
|
@ -1047,7 +1165,7 @@ def tool_list(platform, env):
|
||||||
"prefer AIX Visual Age tools on AIX"
|
"prefer AIX Visual Age tools on AIX"
|
||||||
linkers = ['aixlink', 'gnulink']
|
linkers = ['aixlink', 'gnulink']
|
||||||
c_compilers = ['aixcc', 'gcc', 'cc']
|
c_compilers = ['aixcc', 'gcc', 'cc']
|
||||||
cxx_compilers = ['aixc++', 'g++', 'c++']
|
cxx_compilers = ['aixcxx', 'g++', 'cxx']
|
||||||
assemblers = ['as', 'gas']
|
assemblers = ['as', 'gas']
|
||||||
fortran_compilers = ['f95', 'f90', 'aixf77', 'g77', 'fortran']
|
fortran_compilers = ['f95', 'f90', 'aixf77', 'g77', 'fortran']
|
||||||
ars = ['ar']
|
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"
|
"prefer GNU tools on Mac OS X, except for some linkers and IBM tools"
|
||||||
linkers = ['applelink', 'gnulink']
|
linkers = ['applelink', 'gnulink']
|
||||||
c_compilers = ['gcc', 'cc']
|
c_compilers = ['gcc', 'cc']
|
||||||
cxx_compilers = ['g++', 'c++']
|
cxx_compilers = ['g++', 'cxx']
|
||||||
assemblers = ['as']
|
assemblers = ['as']
|
||||||
fortran_compilers = ['gfortran', 'f95', 'f90', 'g77']
|
fortran_compilers = ['gfortran', 'f95', 'f90', 'g77']
|
||||||
ars = ['ar']
|
ars = ['ar']
|
||||||
|
@ -1063,18 +1181,18 @@ def tool_list(platform, env):
|
||||||
"prefer GNU tools on Cygwin, except for a platform-specific linker"
|
"prefer GNU tools on Cygwin, except for a platform-specific linker"
|
||||||
linkers = ['cyglink', 'mslink', 'ilink']
|
linkers = ['cyglink', 'mslink', 'ilink']
|
||||||
c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc']
|
c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc']
|
||||||
cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++']
|
cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'cxx']
|
||||||
assemblers = ['gas', 'nasm', 'masm']
|
assemblers = ['gas', 'nasm', 'masm']
|
||||||
fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77']
|
fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77']
|
||||||
ars = ['ar', 'mslib']
|
ars = ['ar', 'mslib']
|
||||||
else:
|
else:
|
||||||
"prefer GNU tools on all other platforms"
|
"prefer GNU tools on all other platforms"
|
||||||
linkers = ['gnulink', 'mslink', 'ilink']
|
linkers = ['gnulink', 'ilink']
|
||||||
c_compilers = ['gcc', 'msvc', 'intelc', 'icc', 'cc']
|
c_compilers = ['gcc', 'intelc', 'icc', 'cc']
|
||||||
cxx_compilers = ['g++', 'msvc', 'intelc', 'icc', 'c++']
|
cxx_compilers = ['g++', 'intelc', 'icc', 'cxx']
|
||||||
assemblers = ['gas', 'nasm', 'masm']
|
assemblers = ['gas', 'nasm', 'masm']
|
||||||
fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77']
|
fortran_compilers = ['gfortran', 'g77', 'ifort', 'ifl', 'f95', 'f90', 'f77']
|
||||||
ars = ['ar', 'mslib']
|
ars = ['ar',]
|
||||||
|
|
||||||
if not str(platform) == 'win32':
|
if not str(platform) == 'win32':
|
||||||
other_plat_tools += ['m4', 'rpm']
|
other_plat_tools += ['m4', 'rpm']
|
||||||
|
@ -1102,7 +1220,7 @@ def tool_list(platform, env):
|
||||||
fortran_compiler = FindTool(fortran_compilers, env) or fortran_compilers[0]
|
fortran_compiler = FindTool(fortran_compilers, env) or fortran_compilers[0]
|
||||||
ar = FindTool(ars, env) or ars[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]
|
d_compiler = FindTool(d_compilers, env) or d_compilers[0]
|
||||||
|
|
||||||
other_tools = FindAllTools(other_plat_tools + [
|
other_tools = FindAllTools(other_plat_tools + [
|
||||||
|
@ -1121,9 +1239,6 @@ def tool_list(platform, env):
|
||||||
'tex', 'latex', 'pdflatex', 'pdftex',
|
'tex', 'latex', 'pdflatex', 'pdftex',
|
||||||
# Archivers
|
# Archivers
|
||||||
'tar', 'zip',
|
'tar', 'zip',
|
||||||
# SourceCode factories
|
|
||||||
'BitKeeper', 'CVS', 'Perforce',
|
|
||||||
'RCS', 'SCCS', # 'Subversion',
|
|
||||||
], env)
|
], env)
|
||||||
|
|
||||||
tools = ([linker, c_compiler, cxx_compiler,
|
tools = ([linker, c_compiler, cxx_compiler,
|
||||||
|
@ -1137,4 +1252,3 @@ def tool_list(platform, env):
|
||||||
# indent-tabs-mode:nil
|
# indent-tabs-mode:nil
|
||||||
# End:
|
# End:
|
||||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,13 +30,13 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/aixcc.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/aixcc.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import SCons.Platform.aix
|
import SCons.Platform.aix
|
||||||
|
|
||||||
import cc
|
from . import cc
|
||||||
|
|
||||||
packages = ['vac.C', 'ibmcxx.cmp']
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,13 +31,15 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/aixc++.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/aixcxx.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import SCons.Platform.aix
|
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']
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,13 +30,13 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/aixf77.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/aixf77.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
#import SCons.Platform.aix
|
#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
|
# 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
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,16 +30,20 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/aixlink.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/aixlink.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import SCons.Util
|
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):
|
def smart_linkflags(source, target, env, for_signature):
|
||||||
if cplusplus.iscplusplus(source):
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,13 +31,13 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/applelink.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/applelink.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
|
|
||||||
# Even though the Mac is based on the GNU toolchain, it doesn't understand
|
# 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".
|
# the -rpath option, so we use the "link" tool instead of "gnulink".
|
||||||
import link
|
from . import link
|
||||||
|
|
||||||
def generate(env):
|
def generate(env):
|
||||||
"""Add Builders and construction variables for applelink to an
|
"""Add Builders and construction variables for applelink to an
|
||||||
|
@ -51,6 +51,14 @@ def generate(env):
|
||||||
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -dynamiclib')
|
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -dynamiclib')
|
||||||
env['SHLINKCOM'] = env['SHLINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS'
|
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
|
# override the default for loadable modules, which are different
|
||||||
# on OS X than dynamic shared libs. echoing what XCode does for
|
# on OS X than dynamic shared libs. echoing what XCode does for
|
||||||
# pre/suffixes:
|
# 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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/ar.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/ar.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
|
@ -48,8 +48,8 @@ def generate(env):
|
||||||
env['LIBPREFIX'] = 'lib'
|
env['LIBPREFIX'] = 'lib'
|
||||||
env['LIBSUFFIX'] = '.a'
|
env['LIBSUFFIX'] = '.a'
|
||||||
|
|
||||||
if env.Detect('ranlib'):
|
if env.get('RANLIB',env.Detect('ranlib')) :
|
||||||
env['RANLIB'] = 'ranlib'
|
env['RANLIB'] = env.get('RANLIB','ranlib')
|
||||||
env['RANLIBFLAGS'] = SCons.Util.CLVar('')
|
env['RANLIBFLAGS'] = SCons.Util.CLVar('')
|
||||||
env['RANLIBCOM'] = '$RANLIB $RANLIBFLAGS $TARGET'
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -31,7 +31,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/as.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/as.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.Defaults
|
import SCons.Defaults
|
||||||
import SCons.Tool
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,7 +27,7 @@ XXX
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/bcc32.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/bcc32.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/cc.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/cc.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
import SCons.Defaults
|
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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -27,9 +27,9 @@ Tool-specific initialization for the Compaq Visual Fortran compiler.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/cvf.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/cvf.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import fortran
|
from . import fortran
|
||||||
|
|
||||||
compilers = ['f90']
|
compilers = ['f90']
|
||||||
|
|
|
@ -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
|
# Permission is hereby granted, free of charge, to any person obtaining
|
||||||
# a copy of this software and associated documentation files (the
|
# a copy of this software and associated documentation files (the
|
||||||
|
@ -30,7 +30,7 @@ selection method.
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
__revision__ = "src/engine/SCons/Tool/c++.py rel_2.5.1:3735:9dc6cee5c168 2016/11/03 14:02:02 bdbaddog"
|
__revision__ = "src/engine/SCons/Tool/cxx.py 74b2c53bc42290e911b334a6b44f187da698a668 2017/11/14 13:16:53 bdbaddog"
|
||||||
|
|
||||||
import os.path
|
import os.path
|
||||||
|
|
|
@ -7,6 +7,9 @@ It will usually be imported through the generic SCons.Tool.Tool()
|
||||||
selection method.
|
selection method.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import absolute_import, print_function
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
@ -14,12 +17,13 @@ import SCons.Action
|
||||||
import SCons.Util
|
import SCons.Util
|
||||||
import SCons.Tool
|
import SCons.Tool
|
||||||
|
|
||||||
import gnulink
|
#MAYBE: from . import gnulink
|
||||||
import link
|
from . import gnulink
|
||||||
|
from . import link
|
||||||
|
|
||||||
def _lib_generator(target, source, env, for_signature, **kw):
|
def _lib_generator(target, source, env, for_signature, **kw):
|
||||||
try: cmd = kw['cmd']
|
try: cmd = kw['cmd']
|
||||||
except KeyError: cmd = SCons.Util.CLVar(['$SHLINK'])
|
except KeyError: cmd = SCons.Util.CLVar(['$SHLINK'])
|
||||||
|
|
||||||
try: vp = kw['varprefix']
|
try: vp = kw['varprefix']
|
||||||
except KeyError: vp = 'SHLIB'
|
except KeyError: vp = 'SHLIB'
|
||||||
|
@ -40,7 +44,7 @@ def _lib_generator(target, source, env, for_signature, **kw):
|
||||||
])
|
])
|
||||||
else:
|
else:
|
||||||
cmd.extend(['$SOURCES', '$_LIBDIRFLAGS', '$_LIBFLAGS'])
|
cmd.extend(['$SOURCES', '$_LIBDIRFLAGS', '$_LIBFLAGS'])
|
||||||
|
|
||||||
return [cmd]
|
return [cmd]
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,37 +62,37 @@ def _lib_emitter(target, source, env, **kw):
|
||||||
Verbose = False
|
Verbose = False
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_lib_emitter: target[0]=%r" % target[0].get_path()
|
print("_lib_emitter: target[0]=%r" % target[0].get_path())
|
||||||
|
|
||||||
try: vp = kw['varprefix']
|
try: vp = kw['varprefix']
|
||||||
except KeyError: vp = 'SHLIB'
|
except KeyError: vp = 'SHLIB'
|
||||||
|
|
||||||
try: libtype = kw['libtype']
|
try: libtype = kw['libtype']
|
||||||
except KeyError: libtype = 'ShLib'
|
except KeyError: libtype = 'ShLib'
|
||||||
|
|
||||||
dll = env.FindIxes(target, '%sPREFIX' % vp, '%sSUFFIX' % vp)
|
dll = env.FindIxes(target, '%sPREFIX' % vp, '%sSUFFIX' % vp)
|
||||||
no_import_lib = env.get('no_import_lib', 0)
|
no_import_lib = env.get('no_import_lib', 0)
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_lib_emitter: dll=%r" % dll.get_path()
|
print("_lib_emitter: dll=%r" % dll.get_path())
|
||||||
|
|
||||||
if not dll or len(target) > 1:
|
if not dll or len(target) > 1:
|
||||||
raise SCons.Errors.UserError("A shared library should have exactly one target with the suffix: %s" % env.subst("$%sSUFFIX" % vp))
|
raise SCons.Errors.UserError("A shared library should have exactly one target with the suffix: %s" % env.subst("$%sSUFFIX" % vp))
|
||||||
|
|
||||||
# Remove any "lib" after the prefix
|
# Remove any "lib" after the prefix
|
||||||
pre = env.subst('$%sPREFIX' % vp)
|
pre = env.subst('$%sPREFIX' % vp)
|
||||||
if dll.name[len(pre):len(pre)+3] == 'lib':
|
if dll.name[len(pre):len(pre)+3] == 'lib':
|
||||||
dll.name = pre + dll.name[len(pre)+3:]
|
dll.name = pre + dll.name[len(pre)+3:]
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_lib_emitter: dll.name=%r" % dll.name
|
print("_lib_emitter: dll.name=%r" % dll.name)
|
||||||
|
|
||||||
orig_target = target
|
orig_target = target
|
||||||
target = [env.fs.File(dll)]
|
target = [env.fs.File(dll)]
|
||||||
target[0].attributes.shared = 1
|
target[0].attributes.shared = 1
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_lib_emitter: after target=[env.fs.File(dll)]: target[0]=%r" % target[0].get_path()
|
print("_lib_emitter: after target=[env.fs.File(dll)]: target[0]=%r" % target[0].get_path())
|
||||||
|
|
||||||
# Append an import lib target
|
# Append an import lib target
|
||||||
if not no_import_lib:
|
if not no_import_lib:
|
||||||
|
@ -97,11 +101,11 @@ def _lib_emitter(target, source, env, **kw):
|
||||||
'%sPREFIX' % vp, '%sSUFFIX' % vp,
|
'%sPREFIX' % vp, '%sSUFFIX' % vp,
|
||||||
'IMPLIBPREFIX', 'IMPLIBSUFFIX')
|
'IMPLIBPREFIX', 'IMPLIBSUFFIX')
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_lib_emitter: target_strings=%r" % target_strings
|
print("_lib_emitter: target_strings=%r" % target_strings)
|
||||||
|
|
||||||
implib_target = env.fs.File(target_strings)
|
implib_target = env.fs.File(target_strings)
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_lib_emitter: implib_target=%r" % implib_target.get_path()
|
print("_lib_emitter: implib_target=%r" % implib_target.get_path())
|
||||||
implib_target.attributes.shared = 1
|
implib_target.attributes.shared = 1
|
||||||
target.append(implib_target)
|
target.append(implib_target)
|
||||||
|
|
||||||
|
@ -109,7 +113,7 @@ def _lib_emitter(target, source, env, **kw):
|
||||||
implib_libtype=libtype,
|
implib_libtype=libtype,
|
||||||
generator_libtype=libtype+'ImpLib')
|
generator_libtype=libtype+'ImpLib')
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_lib_emitter: implib symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks)
|
print("_lib_emitter: implib symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks))
|
||||||
if symlinks:
|
if symlinks:
|
||||||
SCons.Tool.EmitLibSymlinks(env, symlinks, implib_target, clean_targets = target[0])
|
SCons.Tool.EmitLibSymlinks(env, symlinks, implib_target, clean_targets = target[0])
|
||||||
implib_target.attributes.shliblinks = symlinks
|
implib_target.attributes.shliblinks = symlinks
|
||||||
|
@ -121,19 +125,19 @@ def shlib_emitter(target, source, env):
|
||||||
|
|
||||||
def ldmod_emitter(target, source, env):
|
def ldmod_emitter(target, source, env):
|
||||||
return _lib_emitter(target, source, env, varprefix='LDMODULE', libtype='LdMod')
|
return _lib_emitter(target, source, env, varprefix='LDMODULE', libtype='LdMod')
|
||||||
|
|
||||||
def _versioned_lib_suffix(env, suffix, version):
|
def _versioned_lib_suffix(env, suffix, version):
|
||||||
"""Generate versioned shared library suffix from a unversioned one.
|
"""Generate versioned shared library suffix from a unversioned one.
|
||||||
If suffix='.dll', and version='0.1.2', then it returns '-0-1-2.dll'"""
|
If suffix='.dll', and version='0.1.2', then it returns '-0-1-2.dll'"""
|
||||||
Verbose = False
|
Verbose = False
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_versioned_lib_suffix: suffix= ", suffix
|
print("_versioned_lib_suffix: suffix= ", suffix)
|
||||||
print "_versioned_lib_suffix: version= ", version
|
print("_versioned_lib_suffix: version= ", version)
|
||||||
cygversion = re.sub('\.', '-', version)
|
cygversion = re.sub('\.', '-', version)
|
||||||
if not suffix.startswith('-' + cygversion):
|
if not suffix.startswith('-' + cygversion):
|
||||||
suffix = '-' + cygversion + suffix
|
suffix = '-' + cygversion + suffix
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_versioned_lib_suffix: return suffix= ", suffix
|
print("_versioned_lib_suffix: return suffix= ", suffix)
|
||||||
return suffix
|
return suffix
|
||||||
|
|
||||||
def _versioned_implib_name(env, libnode, version, prefix, suffix, **kw):
|
def _versioned_implib_name(env, libnode, version, prefix, suffix, **kw):
|
||||||
|
@ -149,8 +153,8 @@ def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw):
|
||||||
Verbose = False
|
Verbose = False
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_versioned_implib_symlinks: libnode=%r" % libnode.get_path()
|
print("_versioned_implib_symlinks: libnode=%r" % libnode.get_path())
|
||||||
print "_versioned_implib_symlinks: version=%r" % version
|
print("_versioned_implib_symlinks: version=%r" % version)
|
||||||
|
|
||||||
try: libtype = kw['libtype']
|
try: libtype = kw['libtype']
|
||||||
except KeyError: libtype = 'ShLib'
|
except KeyError: libtype = 'ShLib'
|
||||||
|
@ -158,13 +162,13 @@ def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw):
|
||||||
|
|
||||||
linkdir = os.path.dirname(libnode.get_path())
|
linkdir = os.path.dirname(libnode.get_path())
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_versioned_implib_symlinks: linkdir=%r" % linkdir
|
print("_versioned_implib_symlinks: linkdir=%r" % linkdir)
|
||||||
|
|
||||||
name = SCons.Tool.ImpLibNameGenerator(env, libnode,
|
name = SCons.Tool.ImpLibNameGenerator(env, libnode,
|
||||||
implib_libtype=libtype,
|
implib_libtype=libtype,
|
||||||
generator_libtype=libtype+'ImpLib')
|
generator_libtype=libtype+'ImpLib')
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_versioned_implib_symlinks: name=%r" % name
|
print("_versioned_implib_symlinks: name=%r" % name)
|
||||||
|
|
||||||
major = version.split('.')[0]
|
major = version.split('.')[0]
|
||||||
|
|
||||||
|
@ -172,7 +176,7 @@ def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw):
|
||||||
symlinks = [(link0, libnode)]
|
symlinks = [(link0, libnode)]
|
||||||
|
|
||||||
if Verbose:
|
if Verbose:
|
||||||
print "_versioned_implib_symlinks: return symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks)
|
print("_versioned_implib_symlinks: return symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks))
|
||||||
|
|
||||||
return symlinks
|
return symlinks
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue