"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "SCons/Tool/__init__.py" between
SCons-4.3.0.tar.gz and SCons-4.4.0.tar.gz

About: SCons is a software construction tool (a Python script and a set of modules as a superior alternative to the classic "Make" build tool).

__init__.py  (SCons-4.3.0):__init__.py  (SCons-4.4.0)
skipping to change at line 24 skipping to change at line 24
# in all copies or substantial portions of the Software. # in all copies or substantial portions of the Software.
# #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# 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.
"""SCons.Tool """SCons tool selection.
SCons tool selection. Looks for modules that define a callable object that can modify a
construction environment as appropriate for a given tool (or tool chain).
This looks for modules that define a callable object that can modify
a construction environment as appropriate for a given tool (or tool
chain).
Note that because this subsystem just *selects* a callable that can Note that because this subsystem just *selects* a callable that can
modify a construction environment, it's possible for people to define modify a construction environment, it's possible for people to define
their own "tool specification" in an arbitrary callable function. No their own "tool specification" in an arbitrary callable function. No
one needs to use or tie in to this subsystem in order to roll their own one needs to use or tie in to this subsystem in order to roll their own
tool specifications. tool specifications.
""" """
import sys import sys
import os import os
import importlib.util import importlib.util
from typing import Optional
import SCons.Builder import SCons.Builder
import SCons.Errors import SCons.Errors
import SCons.Node.FS import SCons.Node.FS
import SCons.Scanner import SCons.Scanner
import SCons.Scanner.C import SCons.Scanner.C
import SCons.Scanner.D import SCons.Scanner.D
import SCons.Scanner.Java
import SCons.Scanner.LaTeX import SCons.Scanner.LaTeX
import SCons.Scanner.Prog import SCons.Scanner.Prog
import SCons.Scanner.SWIG import SCons.Scanner.SWIG
from SCons.Tool.linkCommon import LibSymlinksActionFunction, LibSymlinksStrFun from SCons.Tool.linkCommon import LibSymlinksActionFunction, LibSymlinksStrFun
DefaultToolpath = [] DefaultToolpath = []
CScanner = SCons.Scanner.C.CScanner() CScanner = SCons.Scanner.C.CScanner()
DScanner = SCons.Scanner.D.DScanner() DScanner = SCons.Scanner.D.DScanner()
JavaScanner = SCons.Scanner.Java.JavaScanner()
LaTeXScanner = SCons.Scanner.LaTeX.LaTeXScanner() LaTeXScanner = SCons.Scanner.LaTeX.LaTeXScanner()
PDFLaTeXScanner = SCons.Scanner.LaTeX.PDFLaTeXScanner() PDFLaTeXScanner = SCons.Scanner.LaTeX.PDFLaTeXScanner()
ProgramScanner = SCons.Scanner.Prog.ProgramScanner() ProgramScanner = SCons.Scanner.Prog.ProgramScanner()
SourceFileScanner = SCons.Scanner.ScannerBase({}, name='SourceFileScanner') SourceFileScanner = SCons.Scanner.ScannerBase({}, name='SourceFileScanner')
SWIGScanner = SCons.Scanner.SWIG.SWIGScanner() SWIGScanner = SCons.Scanner.SWIG.SWIGScanner()
CSuffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc", CSuffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc",
".h", ".H", ".hxx", ".hpp", ".hh", ".h", ".H", ".hxx", ".hpp", ".hh",
".F", ".fpp", ".FPP", ".F", ".fpp", ".FPP",
".m", ".mm", ".m", ".mm",
skipping to change at line 123 skipping to change at line 123
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 = kwargs self.init_kw = kwargs
module = self._tool_module() module = self._tool_module()
self.generate = module.generate self.generate = module.generate
self.exists = module.exists self.exists = module.exists
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):
import imp
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):
"""Try to load a tool module.
This will hunt in the toolpath for both a Python file (toolname.py)
and a Python module (toolname directory), then try the regular
import machinery, then fallback to try a zipfile.
"""
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)) # These could be enabled under "if debug:"
# sys.stderr.write(f"Tool: {self.name}\n")
# From: http://stackoverflow.com/questions/67631/how-to-import-a-module- # sys.stderr.write(f"PATH: {sys.path}\n")
given-the-full-path/67692#67692 # sys.stderr.write(f"toolpath: {self.toolpath}\n")
# import importlib.util # sys.stderr.write(f"SCONS.TOOL path: {sys.modules['SCons.Tool'].__path_
# spec = importlib.util.spec_from_file_location("module.name", "/path/to _}\n")
/file.py")
# foo = importlib.util.module_from_spec(spec)
# spec.loader.exec_module(foo)
# foo.MyClass()
# Py 3 code
# sys.stderr.write("toolpath:%s\n" % self.toolpath)
# sys.stderr.write("SCONS.TOOL path:%s\n" % sys.modules['SCons.Tool'].__
path__)
debug = False debug = False
spec = None spec = None
found_name = self.name found_name = self.name
add_to_scons_tools_namespace = False add_to_scons_tools_namespace = False
# Search for the tool module, but don't import it, yet.
#
# First look in the toolpath: these take priority.
# TODO: any reason to not just use find_spec here?
for path in self.toolpath: for path in self.toolpath:
sepname = self.name.replace('.', os.path.sep) sepname = self.name.replace('.', os.path.sep)
file_path = os.path.join(path, "%s.py" % sepname) file_path = os.path.join(path, sepname + ".py")
file_package = os.path.join(path, sepname) file_package = os.path.join(path, sepname)
if debug: sys.stderr.write("Trying:%s %s\n" % (file_path, file_packa ge)) if debug: sys.stderr.write(f"Trying: {file_path} {file_package}\n")
if os.path.isfile(file_path): if os.path.isfile(file_path):
spec = importlib.util.spec_from_file_location(self.name, file_pa th) spec = importlib.util.spec_from_file_location(self.name, file_pa th)
if debug: print("file_Path:%s FOUND" % file_path) if debug: sys.stderr.write(f"file_Path: {file_path} FOUND\n")
break break
elif os.path.isdir(file_package): elif os.path.isdir(file_package):
file_package = os.path.join(file_package, '__init__.py') file_package = os.path.join(file_package, '__init__.py')
spec = importlib.util.spec_from_file_location(self.name, file_pa ckage) spec = importlib.util.spec_from_file_location(self.name, file_pa ckage)
if debug: print("PACKAGE:%s Found" % file_package) if debug: sys.stderr.write(f"PACKAGE: {file_package} Found\n")
break break
else: else:
continue continue
# Now look in the builtin tools (SCons.Tool package)
if spec is None: if spec is None:
if debug: sys.stderr.write("NO SPEC :%s\n" % self.name) if debug: sys.stderr.write(f"NO SPEC: {self.name}\n")
spec = importlib.util.find_spec("." + self.name, package='SCons.Tool ') spec = importlib.util.find_spec("." + self.name, package='SCons.Tool ')
if spec: if spec:
found_name = 'SCons.Tool.' + self.name found_name = 'SCons.Tool.' + self.name
add_to_scons_tools_namespace = True add_to_scons_tools_namespace = True
if debug: sys.stderr.write("Spec Found? .%s :%s\n" % (self.name, spe c)) if debug: sys.stderr.write(f"Spec Found? .{self.name}: {spec}\n")
if spec is None: if spec is None:
# we are going to bail out here, format up stuff for the msg
sconstools = os.path.normpath(sys.modules['SCons.Tool'].__path__[0]) sconstools = os.path.normpath(sys.modules['SCons.Tool'].__path__[0])
if self.toolpath: if self.toolpath:
sconstools = ", ".join(self.toolpath) + ", " + sconstools sconstools = ", ".join(self.toolpath) + ", " + sconstools
error_string = "No tool module '%s' found in %s" % (self.name, scons msg = f"No tool module '{self.name}' found in {sconstools}"
tools) raise SCons.Errors.UserError(msg)
raise SCons.Errors.UserError(error_string)
# We have a module spec, so we're good to go.
module = importlib.util.module_from_spec(spec) module = importlib.util.module_from_spec(spec)
if module is None: if module is None:
if debug: print("MODULE IS NONE:%s" % self.name) if debug: sys.stderr.write(f"MODULE IS NONE: {self.name}\n")
error_string = "Tool module '%s' failed import" % self.name msg = f"Tool module '{self.name}' failed import"
raise SCons.Errors.SConsEnvironmentError(error_string) raise SCons.Errors.SConsEnvironmentError(msg)
# Don't reload a tool we already loaded. # Don't reload a tool we already loaded.
sys_modules_value = sys.modules.get(found_name, False) sys_modules_value = sys.modules.get(found_name, False)
found_module = None found_module = None
if sys_modules_value and sys_modules_value.__file__ == spec.origin: if sys_modules_value and sys_modules_value.__file__ == spec.origin:
found_module = sys.modules[found_name] found_module = sys.modules[found_name]
else: else:
# Not sure what to do in the case that there already # Not sure what to do in the case that there already
# exists sys.modules[self.name] but the source file is # exists sys.modules[self.name] but the source file is
# different.. ? # different.. ?
module = spec.loader.load_module(spec.name)
sys.modules[found_name] = module sys.modules[found_name] = module
spec.loader.exec_module(module)
if add_to_scons_tools_namespace: if add_to_scons_tools_namespace:
# If we found it in SCons.Tool, then add it to the module # If we found it in SCons.Tool, add it to the module
setattr(SCons.Tool, self.name, module) setattr(SCons.Tool, self.name, module)
found_module = module found_module = module
if found_module is not None: if found_module is not None:
sys.path = oldpythonpath sys.path = oldpythonpath
return found_module return found_module
sys.path = oldpythonpath sys.path = oldpythonpath
# We try some other things here, but this is essentially dead code,
# because we bailed out above if we didn't find a module spec.
full_name = 'SCons.Tool.' + self.name full_name = 'SCons.Tool.' + self.name
try: try:
return sys.modules[full_name] return sys.modules[full_name]
except KeyError: except KeyError:
try: try:
smpath = sys.modules['SCons.Tool'].__path__ # This support was added to enable running inside
try: # a py2exe bundle a long time ago - unclear if it's
module, file = self._load_dotted_module_py2(self.name, full_ # still needed. It is *not* intended to load individual
name, smpath) # tool modules stored in a zipfile.
setattr(SCons.Tool, self.name, module) import zipimport
if file:
file.close() tooldir = sys.modules['SCons.Tool'].__path__[0]
return module importer = zipimport.zipimporter(tooldir)
except ImportError as e: if not hasattr(importer, 'find_spec'):
if str(e) != "No module named %s" % self.name: # zipimport only added find_spec, exec_module in 3.10,
raise SCons.Errors.SConsEnvironmentError(e) # unlike importlib, where they've been around since 3.4.
try: # If we don't have 'em, use the old way.
import zipimport module = importer.load_module(full_name)
importer = zipimport.zipimporter(sys.modules['SCons.Tool else:
'].__path__[0]) spec = importer.find_spec(full_name)
module = importer.load_module(full_name) module = importlib.util.module_from_spec(spec)
setattr(SCons.Tool, self.name, module) importer.exec_module(module)
return module sys.modules[full_name] = module
except ImportError as e: setattr(SCons.Tool, self.name, module)
m = "No tool named '%s': %s" % (self.name, e) return module
raise SCons.Errors.SConsEnvironmentError(m) except zipimport.ZipImportError as e:
except ImportError as e: msg = "No tool named '{self.name}': {e}"
m = "No tool named '%s': %s" % (self.name, e) raise SCons.Errors.SConsEnvironmentError(msg)
raise SCons.Errors.SConsEnvironmentError(m)
def __call__(self, env, *args, **kw): def __call__(self, env, *args, **kw):
if self.init_kw is not None: if self.init_kw is not None:
# Merge call kws into init kws; # Merge call kws into init kws;
# but don't bash self.init_kw. # but don't bash self.init_kw.
if kw is not None: if kw is not None:
call_kw = kw call_kw = kw
kw = self.init_kw.copy() kw = self.init_kw.copy()
kw.update(call_kw) kw.update(call_kw)
else: else:
skipping to change at line 510 skipping to change at line 505
java_class_file = env['BUILDERS']['JavaClassFile'] java_class_file = env['BUILDERS']['JavaClassFile']
except KeyError: except KeyError:
fs = SCons.Node.FS.get_default_fs() fs = SCons.Node.FS.get_default_fs()
javac_com = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR') javac_com = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR')
java_class_file = SCons.Builder.Builder(action=javac_com, java_class_file = SCons.Builder.Builder(action=javac_com,
emitter={}, emitter={},
# suffix = '$JAVACLASSSUFFIX', # suffix = '$JAVACLASSSUFFIX',
src_suffix='$JAVASUFFIX', src_suffix='$JAVASUFFIX',
src_builder=['JavaFile'], src_builder=['JavaFile'],
target_factory=fs.Entry, target_factory=fs.Entry,
source_factory=fs.File) source_factory=fs.File,
target_scanner=JavaScanner)
env['BUILDERS']['JavaClassFile'] = java_class_file env['BUILDERS']['JavaClassFile'] = java_class_file
return java_class_file return java_class_file
def CreateJavaClassDirBuilder(env): def CreateJavaClassDirBuilder(env):
try: try:
java_class_dir = env['BUILDERS']['JavaClassDir'] java_class_dir = env['BUILDERS']['JavaClassDir']
except KeyError: except KeyError:
fs = SCons.Node.FS.get_default_fs() fs = SCons.Node.FS.get_default_fs()
javac_com = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR') javac_com = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR')
java_class_dir = SCons.Builder.Builder(action=javac_com, java_class_dir = SCons.Builder.Builder(action=javac_com,
emitter={}, emitter={},
target_factory=fs.Dir, target_factory=fs.Dir,
source_factory=fs.Dir) source_factory=fs.Dir,
target_scanner=JavaScanner)
env['BUILDERS']['JavaClassDir'] = java_class_dir env['BUILDERS']['JavaClassDir'] = java_class_dir
return java_class_dir return java_class_dir
def CreateJavaFileBuilder(env): def CreateJavaFileBuilder(env):
try: try:
java_file = env['BUILDERS']['JavaFile'] java_file = env['BUILDERS']['JavaFile']
except KeyError: except KeyError:
java_file = SCons.Builder.Builder(action={}, java_file = SCons.Builder.Builder(action={},
emitter={}, emitter={},
suffix={None: '$JAVASUFFIX'}) suffix={None: '$JAVASUFFIX'})
skipping to change at line 810 skipping to change at line 807
c_compiler, c_compiler,
cxx_compiler, cxx_compiler,
fortran_compiler, fortran_compiler,
assembler, assembler,
ar, ar,
d_compiler, d_compiler,
] + other_tools ] + other_tools
return [x for x in tools if x] return [x for x in tools if x]
def find_program_path(env, key_program, default_paths=None): def find_program_path(env, key_program, default_paths=None, add_path=False) -> O ptional[str]:
""" """
Find the location of a tool using various means. Find the location of a tool using various means.
Mainly for windows where tools aren't all installed in /usr/bin, etc. Mainly for windows where tools aren't all installed in /usr/bin, etc.
:param env: Current Construction Environment. Args:
:param key_program: Tool to locate. env: Current Construction Environment.
:param default_paths: List of additional paths this tool might be found in. key_program: Tool to locate.
default_paths: List of additional paths this tool might be found in.
add_path: If true, add path found if it was from *default_paths*.
""" """
# First search in the SCons path # First search in the SCons path
path = env.WhereIs(key_program) path = env.WhereIs(key_program)
if path: if path:
return path return path
# Then in the OS path # Then in the OS path
path = SCons.Util.WhereIs(key_program) path = SCons.Util.WhereIs(key_program)
if path: if path:
if add_path:
env.AppendENVPath('PATH', os.path.dirname(path))
return path return path
# Finally, add the defaults and check again. Do not change # Finally, add the defaults and check again.
# ['ENV']['PATH'] permananetly, the caller can do that if needed.
if default_paths is None: if default_paths is None:
return path return path
save_path = env['ENV']['PATH'] save_path = env['ENV']['PATH']
for p in default_paths: for p in default_paths:
env.AppendENVPath('PATH', p) env.AppendENVPath('PATH', p)
path = env.WhereIs(key_program) path = env.WhereIs(key_program)
# By default, do not change ['ENV']['PATH'] permananetly
# leave that to the caller, unless add_path is true.
env['ENV']['PATH'] = save_path env['ENV']['PATH'] = save_path
if path and add_path:
env.AppendENVPath('PATH', os.path.dirname(path))
return path return path
# Local Variables: # Local Variables:
# tab-width:4 # tab-width:4
# indent-tabs-mode:nil # indent-tabs-mode:nil
# End: # End:
# vim: set expandtab tabstop=4 shiftwidth=4: # vim: set expandtab tabstop=4 shiftwidth=4:
 End of changes. 36 change blocks. 
82 lines changed or deleted 84 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)