summaryrefslogtreecommitdiffstats
path: root/SCons/Tool
diff options
context:
space:
mode:
Diffstat (limited to 'SCons/Tool')
-rw-r--r--SCons/Tool/JavaCommon.py3
-rw-r--r--SCons/Tool/JavaCommonTests.py42
-rw-r--r--SCons/Tool/MSCommon/__init__.py4
-rw-r--r--SCons/Tool/MSCommon/arch.py1
-rw-r--r--SCons/Tool/MSCommon/common.py31
-rw-r--r--SCons/Tool/MSCommon/vc.py21
-rw-r--r--SCons/Tool/ToolTests.py17
-rw-r--r--SCons/Tool/__init__.py494
-rw-r--r--SCons/Tool/applelink.py26
-rw-r--r--SCons/Tool/clang.py3
-rw-r--r--SCons/Tool/clangxx.py3
-rw-r--r--SCons/Tool/cyglink.py131
-rw-r--r--SCons/Tool/dmd.py17
-rw-r--r--SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py2
-rw-r--r--SCons/Tool/fortran.py1
-rw-r--r--SCons/Tool/gcc.py1
-rw-r--r--SCons/Tool/gdc.py3
-rw-r--r--SCons/Tool/gxx.py3
-rw-r--r--SCons/Tool/install.py8
-rw-r--r--SCons/Tool/intelc.py6
-rw-r--r--SCons/Tool/ldc.py10
-rw-r--r--SCons/Tool/link.py28
-rw-r--r--SCons/Tool/linkCommon/__init__.py502
-rw-r--r--SCons/Tool/linkloc.py1
-rw-r--r--SCons/Tool/msginit.py1
-rw-r--r--SCons/Tool/msvc.py2
-rw-r--r--SCons/Tool/packaging/rpm.py1
-rw-r--r--SCons/Tool/qt.py1
-rw-r--r--SCons/Tool/textfile.py6
-rw-r--r--SCons/Tool/wixTests.py1
-rw-r--r--SCons/Tool/yacc.py28
-rw-r--r--SCons/Tool/zip.py32
32 files changed, 767 insertions, 663 deletions
diff --git a/SCons/Tool/JavaCommon.py b/SCons/Tool/JavaCommon.py
index bb05977..d869b38 100644
--- a/SCons/Tool/JavaCommon.py
+++ b/SCons/Tool/JavaCommon.py
@@ -87,9 +87,10 @@ if java_parsing:
# any alphanumeric token surrounded by angle brackets (generics);
# the multi-line comment begin and end tokens /* and */;
# array declarations "[]".
+ # Lambda function symbols: ->
_reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"{\};.()]|' +
r'\d*\.\d*|[A-Za-z_][\w$.]*|<[A-Za-z_]\w+>|' +
- r'/\*|\*/|\[\])')
+ r'/\*|\*/|\[\]|->)')
class OuterState:
diff --git a/SCons/Tool/JavaCommonTests.py b/SCons/Tool/JavaCommonTests.py
index b0a788e..f35cb9e 100644
--- a/SCons/Tool/JavaCommonTests.py
+++ b/SCons/Tool/JavaCommonTests.py
@@ -24,7 +24,6 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os.path
-import sys
import unittest
import fnmatch
@@ -97,7 +96,7 @@ public class Foo
"""Test class names with $ in them"""
input = """\
-public class BadDep {
+public class BadDep {
public void new$rand () {}
}
"""
@@ -484,6 +483,43 @@ public class NestedExample
expect = [ 'NestedExample$1', 'NestedExample$1$1', 'NestedExample' ]
assert expect == classes, (expect, classes)
+ def test_lambda_after_new(self):
+ """Test lamdas after new"""
+
+ input = """\
+// import java.util.*;
+
+public class LamdaExample
+{
+
+ public void testFunc (int arg1, String arg2, Runnable lambda){
+ }
+ public LamdaExample()
+ {
+ testFunc(
+ 5,
+ new String("test"),
+ // Lambda symbol is after new, and used curly braces so
+ // we should not parse this as a new class.
+ () -> {}
+ );
+ }
+
+
+ public static void main(String argv[])
+ {
+ LamdaExample e = new LamdaExample();
+ }
+}
+"""
+ pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4')
+ expect = [ 'LamdaExample' ]
+ assert expect == classes, (expect, classes)
+
+ pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.8')
+ expect = [ 'LamdaExample' ]
+ assert expect == classes, (expect, classes)
+
def test_private_inner_class_instantiation(self):
"""Test anonymous inner class generated by private instantiation"""
@@ -532,7 +568,7 @@ class Broken
* Detected.
*/
class InnerOK { InnerOK () { } }
-
+
{
System.out.println("a number: " + 1000.0 + "");
}
diff --git a/SCons/Tool/MSCommon/__init__.py b/SCons/Tool/MSCommon/__init__.py
index be7720a..ee8f2bd 100644
--- a/SCons/Tool/MSCommon/__init__.py
+++ b/SCons/Tool/MSCommon/__init__.py
@@ -27,10 +27,6 @@ __doc__ = """
Common functions for Microsoft Visual Studio and Visual C/C++.
"""
-import copy
-import os
-import re
-import subprocess
import SCons.Errors
import SCons.Platform.win32
diff --git a/SCons/Tool/MSCommon/arch.py b/SCons/Tool/MSCommon/arch.py
index ba57a2c..0032422 100644
--- a/SCons/Tool/MSCommon/arch.py
+++ b/SCons/Tool/MSCommon/arch.py
@@ -26,7 +26,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
__doc__ = """Module to define supported Windows chip architectures.
"""
-import os
class ArchDefinition:
"""
diff --git a/SCons/Tool/MSCommon/common.py b/SCons/Tool/MSCommon/common.py
index e1a82f2..81004df 100644
--- a/SCons/Tool/MSCommon/common.py
+++ b/SCons/Tool/MSCommon/common.py
@@ -42,19 +42,46 @@ if LOGFILE == '-':
print(message)
elif LOGFILE:
import logging
+ modulelist = (
+ # root module and parent/root module
+ 'MSCommon', 'Tool',
+ # python library and below: correct iff scons does not have a lib folder
+ 'lib',
+ # scons modules
+ 'SCons', 'test', 'scons'
+ )
+ def get_relative_filename(filename, module_list):
+ if not filename:
+ return filename
+ for module in module_list:
+ try:
+ ind = filename.rindex(module)
+ return filename[ind:]
+ except ValueError:
+ pass
+ return filename
+ class _Debug_Filter(logging.Filter):
+ # custom filter for module relative filename
+ def filter(self, record):
+ relfilename = get_relative_filename(record.pathname, modulelist)
+ relfilename = relfilename.replace('\\', '/')
+ record.relfilename = relfilename
+ return True
logging.basicConfig(
# This looks like:
# 00109ms:MSCommon/vc.py:find_vc_pdir#447:
format=(
'%(relativeCreated)05dms'
- ':MSCommon/%(filename)s'
+ ':%(relfilename)s'
':%(funcName)s'
'#%(lineno)s'
':%(message)s: '
),
filename=LOGFILE,
level=logging.DEBUG)
- debug = logging.getLogger(name=__name__).debug
+ logger = logging.getLogger(name=__name__)
+ logger.addFilter(_Debug_Filter())
+ debug = logger.debug
else:
def debug(x): return None
diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py
index c6417e9..9a43ae1 100644
--- a/SCons/Tool/MSCommon/vc.py
+++ b/SCons/Tool/MSCommon/vc.py
@@ -43,7 +43,6 @@ import SCons.Util
import subprocess
import os
import platform
-import sys
from string import digits as string_digits
from subprocess import PIPE
@@ -657,16 +656,12 @@ def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version):
return False
-def cached_get_installed_vcs(env=None):
+def get_installed_vcs(env=None):
global __INSTALLED_VCS_RUN
- if __INSTALLED_VCS_RUN is None:
- ret = get_installed_vcs(env)
- __INSTALLED_VCS_RUN = ret
-
- return __INSTALLED_VCS_RUN
+ if __INSTALLED_VCS_RUN is not None:
+ return __INSTALLED_VCS_RUN
-def get_installed_vcs(env=None):
installed_versions = []
for ver in _VCVER:
@@ -687,7 +682,9 @@ def get_installed_vcs(env=None):
raise
except VisualCException as e:
debug('did not find VC %s: caught exception %s' % (ver, str(e)))
- return installed_versions
+
+ __INSTALLED_VCS_RUN = installed_versions
+ return __INSTALLED_VCS_RUN
def reset_installed_vcs():
"""Make it try again to find VC. This is just for the tests."""
@@ -758,7 +755,7 @@ def get_default_version(env):
return msvs_version
if not msvc_version:
- installed_vcs = cached_get_installed_vcs(env)
+ installed_vcs = get_installed_vcs(env)
debug('installed_vcs:%s' % installed_vcs)
if not installed_vcs:
#msg = 'No installed VCs'
@@ -853,7 +850,7 @@ def msvc_find_valid_batch_script(env, version):
warn_msg = "VC version %s not installed. " + \
"C/C++ compilers are most likely not set correctly.\n" + \
" Installed versions are: %s"
- warn_msg = warn_msg % (version, cached_get_installed_vcs(env))
+ warn_msg = warn_msg % (version, get_installed_vcs(env))
SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
continue
@@ -948,7 +945,7 @@ def msvc_setup_env(env):
SCons.Warnings.warn(SCons.Warnings.VisualCMissingWarning, warn_msg)
def msvc_exists(env=None, version=None):
- vcs = cached_get_installed_vcs(env)
+ vcs = get_installed_vcs(env)
if version is None:
return len(vcs) > 0
return version in vcs
diff --git a/SCons/Tool/ToolTests.py b/SCons/Tool/ToolTests.py
index 75a9454..9a6d9b5 100644
--- a/SCons/Tool/ToolTests.py
+++ b/SCons/Tool/ToolTests.py
@@ -24,7 +24,6 @@
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
-import sys
import unittest
import TestUnit
@@ -84,19 +83,21 @@ class ToolTestCase(unittest.TestCase):
assert env['INCPREFIX'] == '-I', env['INCPREFIX']
assert env['TOOLS'] == ['g++'], env['TOOLS']
+ exc_caught = None
try:
SCons.Tool.Tool()
except TypeError:
- pass
- else: # TODO pylint E0704: bare raise not inside except
- raise
+ exc_caught = 1
+ assert exc_caught, "did not catch expected UserError"
+ exc_caught = None
try:
p = SCons.Tool.Tool('_does_not_exist_')
- except SCons.Errors.SConsEnvironmentError:
- pass
- else: # TODO pylint E0704: bare raise not inside except
- raise
+ except SCons.Errors.UserError as e:
+ exc_caught = 1
+ # Old msg was Python-style "No tool named", check for new msg:
+ assert "No tool module" in str(e), e
+ assert exc_caught, "did not catch expected UserError"
def test_pathfind(self):
diff --git a/SCons/Tool/__init__.py b/SCons/Tool/__init__.py
index 32017cb..0c7afb8 100644
--- a/SCons/Tool/__init__.py
+++ b/SCons/Tool/__init__.py
@@ -39,7 +39,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import sys
import os
-from collections.abc import Callable
import importlib.util
import SCons.Builder
@@ -51,6 +50,8 @@ import SCons.Scanner.D
import SCons.Scanner.LaTeX
import SCons.Scanner.Prog
import SCons.Scanner.SWIG
+from SCons.Tool.linkCommon import ShLibPrefixGenerator, LdModPrefixGenerator, ShLibSuffixGenerator, \
+ LdModSuffixGenerator, LibSymlinksActionFunction, LibSymlinksStrFun
DefaultToolpath = []
@@ -183,13 +184,16 @@ class Tool:
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.SConsEnvironmentError(error_string)
+ sconstools = os.path.normpath(sys.modules['SCons.Tool'].__path__[0])
+ if self.toolpath:
+ sconstools = ", ".join(self.toolpath) + ", " + sconstools
+ error_string = "No tool module '%s' found in %s" % (self.name, sconstools)
+ raise SCons.Errors.UserError(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
+ error_string = "Tool module '%s' failed import" % self.name
raise SCons.Errors.SConsEnvironmentError(error_string)
# Don't reload a tool we already loaded.
@@ -272,6 +276,9 @@ class Tool:
return self.name
+LibSymlinksAction = SCons.Action.Action(LibSymlinksActionFunction, LibSymlinksStrFun)
+
+
##########################################################################
# Create common executable program / library / object builders
@@ -325,485 +332,6 @@ def createStaticLibBuilder(env):
return static_lib
-def _call_linker_cb(env, callback, args, result=None):
- """Returns the result of env['LINKCALLBACKS'][callback](*args)
- if env['LINKCALLBACKS'] is a dictionary and env['LINKCALLBACKS'][callback]
- is callable. If these conditions are not met, return the value provided as
- the *result* argument. This function is mainly used for generating library
- info such as versioned suffixes, symlink maps, sonames etc. by delegating
- the core job to callbacks configured by current linker tool"""
-
- Verbose = False
-
- if Verbose:
- print('_call_linker_cb: args=%r' % args)
- print('_call_linker_cb: callback=%r' % callback)
-
- try:
- cbfun = env['LINKCALLBACKS'][callback]
- except (KeyError, TypeError):
- if Verbose:
- print('_call_linker_cb: env["LINKCALLBACKS"][%r] not found or can not be used' % callback)
- pass
- else:
- if Verbose:
- print('_call_linker_cb: env["LINKCALLBACKS"][%r] found' % callback)
- print('_call_linker_cb: env["LINKCALLBACKS"][%r]=%r' % (callback, cbfun))
- if isinstance(cbfun, Callable):
- if Verbose:
- print('_call_linker_cb: env["LINKCALLBACKS"][%r] is callable' % callback)
- result = cbfun(env, *args)
- return result
-
-
-def _call_env_subst(env, string, *args, **kw):
- kw2 = {}
- for k in ('raw', 'target', 'source', 'conv', 'executor'):
- try:
- kw2[k] = kw[k]
- except KeyError:
- pass
- return env.subst(string, *args, **kw2)
-
-
-class _ShLibInfoSupport:
- @property
- def libtype(self):
- return 'ShLib'
-
- def get_lib_prefix(self, env, *args, **kw):
- return _call_env_subst(env, '$SHLIBPREFIX', *args, **kw)
-
- def get_lib_suffix(self, env, *args, **kw):
- return _call_env_subst(env, '$SHLIBSUFFIX', *args, **kw)
-
- def get_lib_version(self, env, *args, **kw):
- return _call_env_subst(env, '$SHLIBVERSION', *args, **kw)
-
- def get_lib_noversionsymlinks(self, env, *args, **kw):
- return _call_env_subst(env, '$SHLIBNOVERSIONSYMLINKS', *args, **kw)
-
-
-class _LdModInfoSupport:
- @property
- def libtype(self):
- return 'LdMod'
-
- def get_lib_prefix(self, env, *args, **kw):
- return _call_env_subst(env, '$LDMODULEPREFIX', *args, **kw)
-
- def get_lib_suffix(self, env, *args, **kw):
- return _call_env_subst(env, '$LDMODULESUFFIX', *args, **kw)
-
- def get_lib_version(self, env, *args, **kw):
- return _call_env_subst(env, '$LDMODULEVERSION', *args, **kw)
-
- def get_lib_noversionsymlinks(self, env, *args, **kw):
- return _call_env_subst(env, '$LDMODULENOVERSIONSYMLINKS', *args, **kw)
-
-
-class _ImpLibInfoSupport:
- @property
- def libtype(self):
- return 'ImpLib'
-
- def get_lib_prefix(self, env, *args, **kw):
- return _call_env_subst(env, '$IMPLIBPREFIX', *args, **kw)
-
- def get_lib_suffix(self, env, *args, **kw):
- return _call_env_subst(env, '$IMPLIBSUFFIX', *args, **kw)
-
- def get_lib_version(self, env, *args, **kw):
- version = _call_env_subst(env, '$IMPLIBVERSION', *args, **kw)
- if not version:
- try:
- lt = kw['implib_libtype']
- except KeyError:
- pass
- else:
- if lt == 'ShLib':
- version = _call_env_subst(env, '$SHLIBVERSION', *args, **kw)
- elif lt == 'LdMod':
- version = _call_env_subst(env, '$LDMODULEVERSION', *args, **kw)
- return version
-
- def get_lib_noversionsymlinks(self, env, *args, **kw):
- disable = None
- try:
- env['IMPLIBNOVERSIONSYMLINKS']
- except KeyError:
- try:
- lt = kw['implib_libtype']
- except KeyError:
- pass
- else:
- if lt == 'ShLib':
- disable = _call_env_subst(env, '$SHLIBNOVERSIONSYMLINKS', *args, **kw)
- elif lt == 'LdMod':
- disable = _call_env_subst(env, '$LDMODULENOVERSIONSYMLINKS', *args, **kw)
- else:
- disable = _call_env_subst(env, '$IMPLIBNOVERSIONSYMLINKS', *args, **kw)
- return disable
-
-
-class _LibInfoGeneratorBase:
- """Generator base class for library-related info such as suffixes for
- versioned libraries, symlink maps, sonames etc. It handles commonities
- of SharedLibrary and LoadableModule
- """
- _support_classes = {'ShLib': _ShLibInfoSupport,
- 'LdMod': _LdModInfoSupport,
- 'ImpLib': _ImpLibInfoSupport}
-
- def __init__(self, libtype, infoname):
- self.libtype = libtype
- self.infoname = infoname
-
- @property
- def libtype(self):
- return self._support.libtype
-
- @libtype.setter
- def libtype(self, libtype):
- try:
- support_class = self._support_classes[libtype]
- except KeyError:
- raise ValueError('unsupported libtype %r' % libtype)
- self._support = support_class()
-
- def get_lib_prefix(self, env, *args, **kw):
- return self._support.get_lib_prefix(env, *args, **kw)
-
- def get_lib_suffix(self, env, *args, **kw):
- return self._support.get_lib_suffix(env, *args, **kw)
-
- def get_lib_version(self, env, *args, **kw):
- return self._support.get_lib_version(env, *args, **kw)
-
- def get_lib_noversionsymlinks(self, env, *args, **kw):
- return self._support.get_lib_noversionsymlinks(env, *args, **kw)
-
- def get_versioned_lib_info_generator(self, **kw):
- """
- Returns name of generator linker callback that will be used to generate
- our info for a versioned library. For example, if our libtype is 'ShLib'
- and infoname is 'Prefix', it would return 'VersionedShLibPrefix'.
- """
- try:
- libtype = kw['generator_libtype']
- except KeyError:
- libtype = self.libtype
- return 'Versioned%s%s' % (libtype, self.infoname)
-
- def generate_versioned_lib_info(self, env, args, result=None, **kw):
- callback = self.get_versioned_lib_info_generator(**kw)
- return _call_linker_cb(env, callback, args, result)
-
-
-class _LibPrefixGenerator(_LibInfoGeneratorBase):
- """Library prefix generator, used as target_prefix in SharedLibrary and
- LoadableModule builders"""
-
- def __init__(self, libtype):
- super(_LibPrefixGenerator, self).__init__(libtype, 'Prefix')
-
- def __call__(self, env, sources=None, **kw):
- Verbose = False
-
- if sources and 'source' not in kw:
- kw2 = kw.copy()
- kw2['source'] = sources
- else:
- kw2 = kw
-
- prefix = self.get_lib_prefix(env, **kw2)
- if Verbose:
- print("_LibPrefixGenerator: input prefix=%r" % prefix)
-
- version = self.get_lib_version(env, **kw2)
- if Verbose:
- print("_LibPrefixGenerator: version=%r" % version)
-
- if version:
- prefix = self.generate_versioned_lib_info(env, [prefix, version], prefix, **kw2)
-
- if Verbose:
- print("_LibPrefixGenerator: return prefix=%r" % prefix)
- return prefix
-
-
-ShLibPrefixGenerator = _LibPrefixGenerator('ShLib')
-LdModPrefixGenerator = _LibPrefixGenerator('LdMod')
-ImpLibPrefixGenerator = _LibPrefixGenerator('ImpLib')
-
-
-class _LibSuffixGenerator(_LibInfoGeneratorBase):
- """Library suffix generator, used as target_suffix in SharedLibrary and
- LoadableModule builders"""
-
- def __init__(self, libtype):
- super(_LibSuffixGenerator, self).__init__(libtype, 'Suffix')
-
- def __call__(self, env, sources=None, **kw):
- Verbose = False
-
- if sources and 'source' not in kw:
- kw2 = kw.copy()
- kw2['source'] = sources
- else:
- kw2 = kw
-
- suffix = self.get_lib_suffix(env, **kw2)
- if Verbose:
- print("_LibSuffixGenerator: input suffix=%r" % suffix)
-
- version = self.get_lib_version(env, **kw2)
- if Verbose:
- print("_LibSuffixGenerator: version=%r" % version)
-
- if version:
- suffix = self.generate_versioned_lib_info(env, [suffix, version], suffix, **kw2)
-
- if Verbose:
- print("_LibSuffixGenerator: return suffix=%r" % suffix)
- return suffix
-
-
-ShLibSuffixGenerator = _LibSuffixGenerator('ShLib')
-LdModSuffixGenerator = _LibSuffixGenerator('LdMod')
-ImpLibSuffixGenerator = _LibSuffixGenerator('ImpLib')
-
-
-class _LibSymlinkGenerator(_LibInfoGeneratorBase):
- """Library symlink map generator. It generates a list of symlinks that
- should be created by SharedLibrary or LoadableModule builders"""
-
- def __init__(self, libtype):
- super(_LibSymlinkGenerator, self).__init__(libtype, 'Symlinks')
-
- def __call__(self, env, libnode, **kw):
- Verbose = False
-
- if libnode and 'target' not in kw:
- kw2 = kw.copy()
- kw2['target'] = libnode
- else:
- kw2 = kw
-
- if Verbose:
- print("_LibSymLinkGenerator: libnode=%r" % libnode.get_path())
-
- symlinks = None
-
- version = self.get_lib_version(env, **kw2)
- disable = self.get_lib_noversionsymlinks(env, **kw2)
- if Verbose:
- print('_LibSymlinkGenerator: version=%r' % version)
- print('_LibSymlinkGenerator: disable=%r' % disable)
-
- if version and not disable:
- prefix = self.get_lib_prefix(env, **kw2)
- suffix = self.get_lib_suffix(env, **kw2)
- symlinks = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw2)
-
- if Verbose:
- print('_LibSymlinkGenerator: return symlinks=%r' % StringizeLibSymlinks(symlinks))
- return symlinks
-
-
-ShLibSymlinkGenerator = _LibSymlinkGenerator('ShLib')
-LdModSymlinkGenerator = _LibSymlinkGenerator('LdMod')
-ImpLibSymlinkGenerator = _LibSymlinkGenerator('ImpLib')
-
-
-class _LibNameGenerator(_LibInfoGeneratorBase):
- """Generates "unmangled" library name from a library file node.
-
- Generally, it's thought to revert modifications done by prefix/suffix
- generators (_LibPrefixGenerator/_LibSuffixGenerator) used by a library
- builder. For example, on gnulink the suffix generator used by SharedLibrary
- builder appends $SHLIBVERSION to $SHLIBSUFFIX producing node name which
- ends with "$SHLIBSUFFIX.$SHLIBVERSION". Correspondingly, the implementation
- of _LibNameGenerator replaces "$SHLIBSUFFIX.$SHLIBVERSION" with
- "$SHLIBSUFFIX" in the node's basename. So that, if $SHLIBSUFFIX is ".so",
- $SHLIBVERSION is "0.1.2" and the node path is "/foo/bar/libfoo.so.0.1.2",
- the _LibNameGenerator shall return "libfoo.so". Other link tools may
- implement it's own way of library name unmangling.
- """
-
- def __init__(self, libtype):
- super(_LibNameGenerator, self).__init__(libtype, 'Name')
-
- def __call__(self, env, libnode, **kw):
- """Returns "demangled" library name"""
- Verbose = False
-
- if libnode and 'target' not in kw:
- kw2 = kw.copy()
- kw2['target'] = libnode
- else:
- kw2 = kw
-
- if Verbose:
- print("_LibNameGenerator: libnode=%r" % libnode.get_path())
-
- version = self.get_lib_version(env, **kw2)
- if Verbose:
- print('_LibNameGenerator: version=%r' % version)
-
- name = None
- if version:
- prefix = self.get_lib_prefix(env, **kw2)
- suffix = self.get_lib_suffix(env, **kw2)
- name = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw2)
-
- if not name:
- name = os.path.basename(libnode.get_path())
-
- if Verbose:
- print('_LibNameGenerator: return name=%r' % name)
-
- return name
-
-
-ShLibNameGenerator = _LibNameGenerator('ShLib')
-LdModNameGenerator = _LibNameGenerator('LdMod')
-ImpLibNameGenerator = _LibNameGenerator('ImpLib')
-
-
-class _LibSonameGenerator(_LibInfoGeneratorBase):
- """Library soname generator. Returns library soname (e.g. libfoo.so.0) for
- a given node (e.g. /foo/bar/libfoo.so.0.1.2)"""
-
- def __init__(self, libtype):
- super(_LibSonameGenerator, self).__init__(libtype, 'Soname')
-
- def __call__(self, env, libnode, **kw):
- """Returns a SONAME based on a shared library's node path"""
- Verbose = False
-
- if libnode and 'target' not in kw:
- kw2 = kw.copy()
- kw2['target'] = libnode
- else:
- kw2 = kw
-
- if Verbose:
- print("_LibSonameGenerator: libnode=%r" % libnode.get_path())
-
- soname = _call_env_subst(env, '$SONAME', **kw2)
- if not soname:
- version = self.get_lib_version(env, **kw2)
- if Verbose:
- print("_LibSonameGenerator: version=%r" % version)
- if version:
- prefix = self.get_lib_prefix(env, **kw2)
- suffix = self.get_lib_suffix(env, **kw2)
- soname = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw2)
-
- if not soname:
- # fallback to library name (as returned by appropriate _LibNameGenerator)
- soname = _LibNameGenerator(self.libtype)(env, libnode)
- if Verbose:
- print("_LibSonameGenerator: FALLBACK: soname=%r" % soname)
-
- if Verbose:
- print("_LibSonameGenerator: return soname=%r" % soname)
-
- return soname
-
-
-ShLibSonameGenerator = _LibSonameGenerator('ShLib')
-LdModSonameGenerator = _LibSonameGenerator('LdMod')
-
-
-def StringizeLibSymlinks(symlinks):
- """Converts list with pairs of nodes to list with pairs of node paths
- (strings). Used mainly for debugging."""
- if SCons.Util.is_List(symlinks):
- try:
- return [(k.get_path(), v.get_path()) for k, v in symlinks]
- except (TypeError, ValueError):
- return symlinks
- else:
- return symlinks
-
-
-def EmitLibSymlinks(env, symlinks, libnode, **kw):
- """Used by emitters to handle (shared/versioned) library symlinks"""
- Verbose = False
-
- # nodes involved in process... all symlinks + library
- nodes = list(set([x for x, y in symlinks] + [libnode]))
-
- clean_targets = kw.get('clean_targets', [])
- if not SCons.Util.is_List(clean_targets):
- clean_targets = [clean_targets]
-
- for link, linktgt in symlinks:
- env.SideEffect(link, linktgt)
- if Verbose:
- print("EmitLibSymlinks: SideEffect(%r,%r)" % (link.get_path(), linktgt.get_path()))
- clean_list = [x for x in nodes if x != linktgt]
- env.Clean(list(set([linktgt] + clean_targets)), clean_list)
- if Verbose:
- print("EmitLibSymlinks: Clean(%r,%r)" % (linktgt.get_path(), [x.get_path() for x in clean_list]))
-
-
-def CreateLibSymlinks(env, symlinks):
- """Physically creates symlinks. The symlinks argument must be a list in
- form [ (link, linktarget), ... ], where link and linktarget are SCons
- nodes.
- """
-
- Verbose = False
- for link, linktgt in symlinks:
- linktgt = link.get_dir().rel_path(linktgt)
- link = link.get_path()
- if Verbose:
- print("CreateLibSymlinks: preparing to add symlink %r -> %r" % (link, linktgt))
- # Delete the (previously created) symlink if exists. Let only symlinks
- # to be deleted to prevent accidental deletion of source files...
- if env.fs.islink(link):
- env.fs.unlink(link)
- if Verbose:
- print("CreateLibSymlinks: removed old symlink %r" % link)
- # If a file or directory exists with the same name as link, an OSError
- # will be thrown, which should be enough, I think.
- env.fs.symlink(linktgt, link)
- if Verbose:
- print("CreateLibSymlinks: add symlink %r -> %r" % (link, linktgt))
- return 0
-
-
-def LibSymlinksActionFunction(target, source, env):
- for tgt in target:
- symlinks = getattr(getattr(tgt, 'attributes', None), 'shliblinks', None)
- if symlinks:
- CreateLibSymlinks(env, symlinks)
- return 0
-
-
-def LibSymlinksStrFun(target, source, env, *args):
- cmd = None
- for tgt in target:
- symlinks = getattr(getattr(tgt, 'attributes', None), 'shliblinks', None)
- if symlinks:
- if cmd is None: cmd = ""
- if cmd: cmd += "\n"
- cmd += "Create symlinks for: %r" % tgt.get_path()
- try:
- linkstr = ', '.join(["%r->%r" % (k, v) for k, v in StringizeLibSymlinks(symlinks)])
- except (KeyError, ValueError):
- pass
- else:
- cmd += ": %s" % linkstr
- return cmd
-
-
-LibSymlinksAction = SCons.Action.Action(LibSymlinksActionFunction, LibSymlinksStrFun)
-
-
def createSharedLibBuilder(env):
"""This is a utility function that creates the SharedLibrary
Builder in an Environment if it is not there already.
diff --git a/SCons/Tool/applelink.py b/SCons/Tool/applelink.py
index 8c081a2..aec8b93 100644
--- a/SCons/Tool/applelink.py
+++ b/SCons/Tool/applelink.py
@@ -39,11 +39,13 @@ import SCons.Util
# the -rpath option, so we use the "link" tool instead of "gnulink".
from . import link
-from SCons.Tool import ShLibSonameGenerator
+from .linkCommon import ShLibSonameGenerator
+
class AppleLinkInvalidCurrentVersionException(Exception):
pass
+
class AppleLinkInvalidCompatibilityVersionException(Exception):
pass
@@ -70,7 +72,7 @@ def _applelib_versioned_lib_soname(env, libnode, version, prefix, suffix, name_f
if Verbose:
print("_applelib_versioned_lib_soname: name={!r}".format(name))
major = version.split('.')[0]
- (libname,_suffix) = name.split('.')
+ (libname, _suffix) = name.split('.')
# if a desired SONAME was supplied, use that, otherwise create
# a default from the major version
if env.get('SONAME'):
@@ -81,12 +83,15 @@ def _applelib_versioned_lib_soname(env, libnode, version, prefix, suffix, name_f
print("_applelib_versioned_lib_soname: soname={!r}".format(soname))
return soname
+
def _applelib_versioned_shlib_soname(env, libnode, version, prefix, suffix):
return _applelib_versioned_lib_soname(env, libnode, version, prefix, suffix, link._versioned_shlib_name)
# User programmatically describes how SHLIBVERSION maps to values for compat/current.
_applelib_max_version_values = (65535, 255, 255)
+
+
def _applelib_check_valid_version(version_string):
"""
Check that the version # is valid.
@@ -99,17 +104,18 @@ def _applelib_check_valid_version(version_string):
"""
parts = version_string.split('.')
if len(parts) > 3:
- return False, "Version string has too many periods [%s]"%version_string
+ return False, "Version string has too many periods [%s]" % version_string
if len(parts) <= 0:
- return False, "Version string unspecified [%s]"%version_string
+ return False, "Version string unspecified [%s]" % version_string
for (i, p) in enumerate(parts):
try:
p_i = int(p)
except ValueError:
- return False, "Version component %s (from %s) is not a number"%(p, version_string)
+ return False, "Version component %s (from %s) is not a number" % (p, version_string)
if p_i < 0 or p_i > _applelib_max_version_values[i]:
- return False, "Version component %s (from %s) is not valid value should be between 0 and %d"%(p, version_string, _applelib_max_version_values[i])
+ return False, "Version component %s (from %s) is not valid value should be between 0 and %d" % (
+ p, version_string, _applelib_max_version_values[i])
return True, ""
@@ -190,9 +196,8 @@ def generate(env):
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -dynamiclib')
env['SHLINKCOM'] = env['SHLINKCOM'] + ' $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS'
-
# 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)
+ link._setup_versioned_lib_variables(env, tool='applelink') #, use_soname=True)
env['LINKCALLBACKS'] = link._versioned_lib_callbacks()
env['LINKCALLBACKS']['VersionedShLibSuffix'] = _applelib_versioned_lib_suffix
env['LINKCALLBACKS']['VersionedShLibSoname'] = _applelib_versioned_shlib_soname
@@ -205,15 +210,14 @@ def generate(env):
# override the default for loadable modules, which are different
# on OS X than dynamic shared libs. echoing what XCode does for
# pre/suffixes:
- env['LDMODULEPREFIX'] = ''
- env['LDMODULESUFFIX'] = ''
+ env['LDMODULEPREFIX'] = ''
+ env['LDMODULESUFFIX'] = ''
env['LDMODULEFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -bundle')
env['LDMODULECOM'] = '$LDMODULE -o ${TARGET} $LDMODULEFLAGS $SOURCES $_LIBDIRFLAGS $_LIBFLAGS $_FRAMEWORKPATH $_FRAMEWORKS $FRAMEWORKSFLAGS'
env['__SHLIBVERSIONFLAGS'] = '${__libversionflags(__env__,"SHLIBVERSION","_SHLIBVERSIONFLAGS")}'
-
def exists(env):
return env['PLATFORM'] == 'darwin'
diff --git a/SCons/Tool/clang.py b/SCons/Tool/clang.py
index 162daad..e39c742 100644
--- a/SCons/Tool/clang.py
+++ b/SCons/Tool/clang.py
@@ -84,8 +84,7 @@ def generate(env):
# clang -dumpversion is of no use
with pipe.stdout:
line = pipe.stdout.readline()
- if sys.version_info[0] > 2:
- line = line.decode()
+ line = line.decode()
match = re.search(r'clang +version +([0-9]+(?:\.[0-9]+)+)', line)
if match:
env['CCVERSION'] = match.group(1)
diff --git a/SCons/Tool/clangxx.py b/SCons/Tool/clangxx.py
index b1dc6f3..736d455 100644
--- a/SCons/Tool/clangxx.py
+++ b/SCons/Tool/clangxx.py
@@ -92,8 +92,7 @@ def generate(env):
# clang -dumpversion is of no use
with pipe.stdout:
line = pipe.stdout.readline()
- if sys.version_info[0] > 2:
- line = line.decode()
+ line = line.decode()
match = re.search(r'clang +version +([0-9]+(?:\.[0-9]+)+)', line)
if match:
env['CXXVERSION'] = match.group(1)
diff --git a/SCons/Tool/cyglink.py b/SCons/Tool/cyglink.py
index fbb6d24..08b8a98 100644
--- a/SCons/Tool/cyglink.py
+++ b/SCons/Tool/cyglink.py
@@ -12,19 +12,25 @@ import re
import os
import SCons.Action
+from SCons.Tool.linkCommon import ImpLibSymlinkGenerator, StringizeLibSymlinks, EmitLibSymlinks, ImpLibPrefixGenerator, \
+ ImpLibSuffixGenerator, ImpLibNameGenerator
import SCons.Util
import SCons.Tool
-#MAYBE: from . import gnulink
from . import gnulink
from . import link
+
def _lib_generator(target, source, env, for_signature, **kw):
- try: cmd = kw['cmd']
- except KeyError: cmd = SCons.Util.CLVar(['$SHLINK'])
+ try:
+ cmd = kw['cmd']
+ except KeyError:
+ cmd = SCons.Util.CLVar(['$SHLINK'])
- try: vp = kw['varprefix']
- except KeyError: vp = 'SHLIB'
+ try:
+ vp = kw['varprefix']
+ except KeyError:
+ vp = 'SHLIB'
dll = env.FindIxes(target, '%sPREFIX' % vp, '%sSUFFIX' % vp)
if dll: cmd.extend(['-o', dll])
@@ -34,12 +40,12 @@ def _lib_generator(target, source, env, for_signature, **kw):
implib = env.FindIxes(target, 'IMPLIBPREFIX', 'IMPLIBSUFFIX')
if implib:
cmd.extend([
- '-Wl,--out-implib='+implib.get_string(for_signature),
+ '-Wl,--out-implib=' + implib.get_string(for_signature),
'-Wl,--export-all-symbols',
'-Wl,--enable-auto-import',
'-Wl,--whole-archive', '$SOURCES',
'-Wl,--no-whole-archive', '$_LIBDIRFLAGS', '$_LIBFLAGS'
- ])
+ ])
else:
cmd.extend(['$SOURCES', '$_LIBDIRFLAGS', '$_LIBFLAGS'])
@@ -49,12 +55,14 @@ def _lib_generator(target, source, env, for_signature, **kw):
def shlib_generator(target, source, env, for_signature):
return _lib_generator(target, source, env, for_signature,
varprefix='SHLIB',
- cmd = SCons.Util.CLVar(['$SHLINK']))
+ cmd=SCons.Util.CLVar(['$SHLINK']))
+
def ldmod_generator(target, source, env, for_signature):
return _lib_generator(target, source, env, for_signature,
varprefix='LDMODULE',
- cmd = SCons.Util.CLVar(['$LDMODULE']))
+ cmd=SCons.Util.CLVar(['$LDMODULE']))
+
def _lib_emitter(target, source, env, **kw):
Verbose = False
@@ -62,11 +70,15 @@ def _lib_emitter(target, source, env, **kw):
if Verbose:
print("_lib_emitter: target[0]=%r" % target[0].get_path())
- try: vp = kw['varprefix']
- except KeyError: vp = 'SHLIB'
+ try:
+ vp = kw['varprefix']
+ except KeyError:
+ vp = 'SHLIB'
- try: libtype = kw['libtype']
- except KeyError: libtype = 'ShLib'
+ try:
+ libtype = kw['libtype']
+ except KeyError:
+ libtype = 'ShLib'
dll = env.FindIxes(target, '%sPREFIX' % vp, '%sSUFFIX' % vp)
no_import_lib = env.get('no_import_lib', 0)
@@ -75,12 +87,13 @@ def _lib_emitter(target, source, env, **kw):
print("_lib_emitter: dll=%r" % dll.get_path())
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
pre = env.subst('$%sPREFIX' % vp)
- if dll.name[len(pre):len(pre)+3] == 'lib':
- dll.name = pre + dll.name[len(pre)+3:]
+ if dll.name[len(pre):len(pre) + 3] == 'lib':
+ dll.name = pre + dll.name[len(pre) + 3:]
if Verbose:
print("_lib_emitter: dll.name=%r" % dll.name)
@@ -107,23 +120,26 @@ def _lib_emitter(target, source, env, **kw):
implib_target.attributes.shared = 1
target.append(implib_target)
- symlinks = SCons.Tool.ImpLibSymlinkGenerator(env, implib_target,
- implib_libtype=libtype,
- generator_libtype=libtype+'ImpLib')
+ symlinks = ImpLibSymlinkGenerator(env, implib_target,
+ implib_libtype=libtype,
+ generator_libtype=libtype + 'ImpLib')
if Verbose:
- print("_lib_emitter: implib symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks))
+ print("_lib_emitter: implib symlinks=%r" % StringizeLibSymlinks(symlinks))
if symlinks:
- SCons.Tool.EmitLibSymlinks(env, symlinks, implib_target, clean_targets = target[0])
+ EmitLibSymlinks(env, symlinks, implib_target, clean_targets=target[0])
implib_target.attributes.shliblinks = symlinks
return (target, source)
+
def shlib_emitter(target, source, env):
return _lib_emitter(target, source, env, varprefix='SHLIB', libtype='ShLib')
+
def ldmod_emitter(target, source, env):
return _lib_emitter(target, source, env, varprefix='LDMODULE', libtype='LdMod')
+
def _versioned_lib_suffix(env, suffix, version):
"""Generate versioned shared library suffix from a unversioned one.
If suffix='.dll', and version='0.1.2', then it returns '-0-1-2.dll'"""
@@ -138,12 +154,14 @@ def _versioned_lib_suffix(env, suffix, version):
print("_versioned_lib_suffix: return suffix= ", suffix)
return suffix
+
def _versioned_implib_name(env, libnode, version, prefix, suffix, **kw):
return link._versioned_lib_name(env, libnode, version, prefix, suffix,
- SCons.Tool.ImpLibPrefixGenerator,
- SCons.Tool.ImpLibSuffixGenerator,
+ ImpLibPrefixGenerator,
+ ImpLibSuffixGenerator,
implib_libtype=kw['libtype'])
+
def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw):
"""Generate link names that should be created for a versioned shared library.
Returns a list in the form [ (link, linktarget), ... ]
@@ -154,17 +172,18 @@ def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw):
print("_versioned_implib_symlinks: libnode=%r" % libnode.get_path())
print("_versioned_implib_symlinks: version=%r" % version)
- try: libtype = kw['libtype']
- except KeyError: libtype = 'ShLib'
-
+ try:
+ libtype = kw['libtype']
+ except KeyError:
+ libtype = 'ShLib'
linkdir = os.path.dirname(libnode.get_path())
if Verbose:
print("_versioned_implib_symlinks: linkdir=%r" % linkdir)
- name = SCons.Tool.ImpLibNameGenerator(env, libnode,
- implib_libtype=libtype,
- generator_libtype=libtype+'ImpLib')
+ name = ImpLibNameGenerator(env, libnode,
+ implib_libtype=libtype,
+ generator_libtype=libtype + 'ImpLib')
if Verbose:
print("_versioned_implib_symlinks: name=%r" % name)
@@ -174,59 +193,65 @@ def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw):
symlinks = [(link0, libnode)]
if Verbose:
- print("_versioned_implib_symlinks: return symlinks=%r" % SCons.Tool.StringizeLibSymlinks(symlinks))
+ print("_versioned_implib_symlinks: return symlinks=%r" % StringizeLibSymlinks(symlinks))
return symlinks
+
shlib_action = SCons.Action.Action(shlib_generator, generator=1)
ldmod_action = SCons.Action.Action(ldmod_generator, generator=1)
+
def generate(env):
"""Add Builders and construction variables for cyglink to an Environment."""
gnulink.generate(env)
- env['LINKFLAGS'] = SCons.Util.CLVar('-Wl,-no-undefined')
+ env['LINKFLAGS'] = SCons.Util.CLVar('-Wl,-no-undefined')
env['SHLINKCOM'] = shlib_action
env['LDMODULECOM'] = ldmod_action
- env.Append(SHLIBEMITTER = [shlib_emitter])
- env.Append(LDMODULEEMITTER = [ldmod_emitter])
+ env.Append(SHLIBEMITTER=[shlib_emitter])
+ env.Append(LDMODULEEMITTER=[ldmod_emitter])
- env['SHLIBPREFIX'] = 'cyg'
- env['SHLIBSUFFIX'] = '.dll'
+ env['SHLIBPREFIX'] = 'cyg'
+ env['SHLIBSUFFIX'] = '.dll'
- env['IMPLIBPREFIX'] = 'lib'
- env['IMPLIBSUFFIX'] = '.dll.a'
+ env['IMPLIBPREFIX'] = 'lib'
+ env['IMPLIBSUFFIX'] = '.dll.a'
# Variables used by versioned shared libraries
- env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS'
- env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS'
+ env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS'
+ env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS'
# SHLIBVERSIONFLAGS and LDMODULEVERSIONFLAGS are same as in gnulink...
# LINKCALLBACKS are NOT inherited from gnulink
env['LINKCALLBACKS'] = {
- 'VersionedShLibSuffix' : _versioned_lib_suffix,
- 'VersionedLdModSuffix' : _versioned_lib_suffix,
- 'VersionedImpLibSuffix' : _versioned_lib_suffix,
- 'VersionedShLibName' : link._versioned_shlib_name,
- 'VersionedLdModName' : link._versioned_ldmod_name,
- 'VersionedShLibImpLibName' : lambda *args: _versioned_implib_name(*args, libtype='ShLib'),
- 'VersionedLdModImpLibName' : lambda *args: _versioned_implib_name(*args, libtype='LdMod'),
- 'VersionedShLibImpLibSymlinks' : lambda *args: _versioned_implib_symlinks(*args, libtype='ShLib'),
- 'VersionedLdModImpLibSymlinks' : lambda *args: _versioned_implib_symlinks(*args, libtype='LdMod'),
+ 'VersionedShLibSuffix': _versioned_lib_suffix,
+ 'VersionedLdModSuffix': _versioned_lib_suffix,
+ 'VersionedImpLibSuffix': _versioned_lib_suffix,
+ 'VersionedShLibName': link._versioned_shlib_name,
+ 'VersionedLdModName': link._versioned_ldmod_name,
+ 'VersionedShLibImpLibName': lambda *args: _versioned_implib_name(*args, libtype='ShLib'),
+ 'VersionedLdModImpLibName': lambda *args: _versioned_implib_name(*args, libtype='LdMod'),
+ 'VersionedShLibImpLibSymlinks': lambda *args: _versioned_implib_symlinks(*args, libtype='ShLib'),
+ 'VersionedLdModImpLibSymlinks': lambda *args: _versioned_implib_symlinks(*args, libtype='LdMod'),
}
# these variables were set by gnulink but are not used in cyglink
- try: del env['_SHLIBSONAME']
- except KeyError: pass
- try: del env['_LDMODULESONAME']
- except KeyError: pass
+ try:
+ del env['_SHLIBSONAME']
+ except KeyError:
+ pass
+ try:
+ del env['_LDMODULESONAME']
+ except KeyError:
+ pass
+
def exists(env):
return gnulink.exists(env)
-
# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
diff --git a/SCons/Tool/dmd.py b/SCons/Tool/dmd.py
index ba12131..5970246 100644
--- a/SCons/Tool/dmd.py
+++ b/SCons/Tool/dmd.py
@@ -50,8 +50,6 @@ LIBS
"""
#
-# __COPYRIGHT__
-#
# 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
@@ -72,11 +70,6 @@ LIBS
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-import os
-import subprocess
-
import SCons.Action
import SCons.Builder
import SCons.Defaults
@@ -84,6 +77,7 @@ import SCons.Scanner.D
import SCons.Tool
import SCons.Tool.DCommon as DCommon
+from SCons.Tool.linkCommon import ShLibSonameGenerator
def generate(env):
@@ -128,7 +122,8 @@ def generate(env):
env['SHDLINK'] = '$DC'
env['SHDLINKFLAGS'] = SCons.Util.CLVar('$DLINKFLAGS -shared -defaultlib=libphobos2.so')
- env['SHDLINKCOM'] = '$DLINK -of$TARGET $SHDLINKFLAGS $__SHDLIBVERSIONFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS'
+ env[
+ 'SHDLINKCOM'] = '$DLINK -of$TARGET $SHDLINKFLAGS $__SHDLIBVERSIONFLAGS $__DRPATH $SOURCES $_DLIBDIRFLAGS $_DLIBFLAGS'
env['DLIBLINKPREFIX'] = '' if env['PLATFORM'] == 'win32' else '-L-l'
env['DLIBLINKSUFFIX'] = '.lib' if env['PLATFORM'] == 'win32' else ''
@@ -139,7 +134,8 @@ def generate(env):
env['_DLIBDIRFLAGS'] = '${_concat(DLIBDIRPREFIX, LIBPATH, DLIBDIRSUFFIX, __env__, RDirs, TARGET, SOURCE)}'
env['DLIB'] = 'lib' if env['PLATFORM'] == 'win32' else 'ar cr'
- env['DLIBCOM'] = '$DLIB $_DLIBFLAGS {0}$TARGET $SOURCES $_DLIBFLAGS'.format('-c ' if env['PLATFORM'] == 'win32' else '')
+ env['DLIBCOM'] = '$DLIB $_DLIBFLAGS {0}$TARGET $SOURCES $_DLIBFLAGS'.format(
+ '-c ' if env['PLATFORM'] == 'win32' else '')
# env['_DLIBFLAGS'] = '${_concat(DLIBFLAGPREFIX, DLIBFLAGS, DLIBFLAGSUFFIX, __env__)}'
@@ -157,7 +153,7 @@ def generate(env):
env['_SHDLIBSONAME'] = '${DShLibSonameGenerator(__env__,TARGET)}'
# NOTE: this is a quick hack, the soname will only work if there is
# c/c++ linker loaded which provides callback for the ShLibSonameGenerator
- env['DShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator
+ env['DShLibSonameGenerator'] = ShLibSonameGenerator
# NOTE: this is only for further reference, currently $SHDLIBVERSION does
# not work, the user must use $SHLIBVERSION
env['SHDLIBVERSION'] = '$SHLIBVERSION'
@@ -172,7 +168,6 @@ def generate(env):
def exists(env):
return env.Detect(['dmd', 'ldmd2', 'gdmd'])
-
# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
diff --git a/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py b/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py
index 3d53bf7..d79ece3 100644
--- a/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py
+++ b/SCons/Tool/docbook/docbook-xsl-1.76.1/extensions/docbook.py
@@ -1,7 +1,5 @@
# docbook.py: extension module
# $Id: docbook.py 8353 2009-03-17 16:57:50Z mzjn $
-import sys
-import string
import libxml2
import libxslt
import re
diff --git a/SCons/Tool/fortran.py b/SCons/Tool/fortran.py
index aeb9130..0a68df6 100644
--- a/SCons/Tool/fortran.py
+++ b/SCons/Tool/fortran.py
@@ -33,7 +33,6 @@ selection method.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import re
import SCons.Action
import SCons.Defaults
diff --git a/SCons/Tool/gcc.py b/SCons/Tool/gcc.py
index d56f6a0..37626ef 100644
--- a/SCons/Tool/gcc.py
+++ b/SCons/Tool/gcc.py
@@ -34,7 +34,6 @@ selection method.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
from . import cc
-import os
import re
import subprocess
diff --git a/SCons/Tool/gdc.py b/SCons/Tool/gdc.py
index ecf4f3a..12c327e 100644
--- a/SCons/Tool/gdc.py
+++ b/SCons/Tool/gdc.py
@@ -53,6 +53,7 @@ import SCons.Defaults
import SCons.Tool
import SCons.Tool.DCommon as DCommon
+import SCons.Tool.linkCommon
def generate(env):
@@ -120,7 +121,7 @@ def generate(env):
env['_SHDLIBSONAME'] = '${DShLibSonameGenerator(__env__,TARGET)}'
# NOTE: this is a quick hack, the soname will only work if there is
# c/c++ linker loaded which provides callback for the ShLibSonameGenerator
- env['DShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator
+ env['DShLibSonameGenerator'] = SCons.Tool.linkCommon.ShLibSonameGenerator
# NOTE: this is only for further reference, currently $SHDLIBVERSION does
# not work, the user must use $SHLIBVERSION
env['SHDLIBVERSION'] = '$SHLIBVERSION'
diff --git a/SCons/Tool/gxx.py b/SCons/Tool/gxx.py
index 4b86327..88186cb 100644
--- a/SCons/Tool/gxx.py
+++ b/SCons/Tool/gxx.py
@@ -33,9 +33,6 @@ selection method.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import os.path
-import re
-import subprocess
import SCons.Tool
import SCons.Util
diff --git a/SCons/Tool/install.py b/SCons/Tool/install.py
index 67c9ec8..e79203e 100644
--- a/SCons/Tool/install.py
+++ b/SCons/Tool/install.py
@@ -29,13 +29,13 @@ selection method.
# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os
from shutil import copy2, copymode, copystat
import SCons.Action
import SCons.Tool
+from SCons.Tool.linkCommon import StringizeLibSymlinks, CreateLibSymlinks, EmitLibSymlinks
import SCons.Util
#
@@ -213,9 +213,9 @@ def installShlibLinks(dest, source, env):
Verbose = False
symlinks = listShlibLinksToInstall(dest, source, env)
if Verbose:
- print('installShlibLinks: symlinks={!r}'.format(SCons.Tool.StringizeLibSymlinks(symlinks)))
+ print('installShlibLinks: symlinks={!r}'.format(StringizeLibSymlinks(symlinks)))
if symlinks:
- SCons.Tool.CreateLibSymlinks(env, symlinks)
+ CreateLibSymlinks(env, symlinks)
return
def installFunc(target, source, env):
@@ -292,7 +292,7 @@ def add_versioned_targets_to_INSTALLED_FILES(target, source, env):
print("add_versioned_targets_to_INSTALLED_FILES: target={!r}".format(list(map(str, target))))
symlinks = listShlibLinksToInstall(target[0], source, env)
if symlinks:
- SCons.Tool.EmitLibSymlinks(env, symlinks, target[0])
+ EmitLibSymlinks(env, symlinks, target[0])
_UNIQUE_INSTALLED_FILES = None
return (target, source)
diff --git a/SCons/Tool/intelc.py b/SCons/Tool/intelc.py
index 38bdc32..5025719 100644
--- a/SCons/Tool/intelc.py
+++ b/SCons/Tool/intelc.py
@@ -32,7 +32,11 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import math, sys, os.path, glob, string, re
+import glob
+import math
+import os.path
+import re
+import sys
is_windows = sys.platform == 'win32'
is_win64 = is_windows and (os.environ['PROCESSOR_ARCHITECTURE'] == 'AMD64' or
diff --git a/SCons/Tool/ldc.py b/SCons/Tool/ldc.py
index f915569..d893841 100644
--- a/SCons/Tool/ldc.py
+++ b/SCons/Tool/ldc.py
@@ -24,8 +24,6 @@ Lib tool variables:
"""
#
-# __COPYRIGHT__
-#
# 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
@@ -46,11 +44,6 @@ Lib tool variables:
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-import os
-import subprocess
-
import SCons.Action
import SCons.Builder
import SCons.Defaults
@@ -58,6 +51,7 @@ import SCons.Scanner.D
import SCons.Tool
import SCons.Tool.DCommon as DCommon
+from SCons.Tool.linkCommon import ShLibSonameGenerator
def generate(env):
@@ -133,7 +127,7 @@ def generate(env):
env['_SHDLIBSONAME'] = '${DShLibSonameGenerator(__env__,TARGET)}'
# NOTE: this is a quick hack, the soname will only work if there is
# c/c++ linker loaded which provides callback for the ShLibSonameGenerator
- env['DShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator
+ env['DShLibSonameGenerator'] = ShLibSonameGenerator
# NOTE: this is only for further reference, currently $SHDLIBVERSION does
# not work, the user must use $SHLIBVERSION
env['SHDLIBVERSION'] = '$SHLIBVERSION'
diff --git a/SCons/Tool/link.py b/SCons/Tool/link.py
index a3567aa..de377ac 100644
--- a/SCons/Tool/link.py
+++ b/SCons/Tool/link.py
@@ -9,8 +9,6 @@ selection method.
"""
#
-# __COPYRIGHT__
-#
# 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
@@ -30,7 +28,6 @@ selection method.
# 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__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import sys
import re
@@ -46,7 +43,9 @@ from SCons.Tool.DCommon import isD
from SCons.Tool.cxx import iscplusplus
-from SCons.Tool import ShLibSonameGenerator
+from SCons.Tool.linkCommon import StringizeLibSymlinks, ShLibSonameGenerator, EmitLibSymlinks, ShLibSymlinkGenerator, \
+ LdModSymlinkGenerator, ShLibPrefixGenerator, ShLibSuffixGenerator, LdModPrefixGenerator, LdModSuffixGenerator, \
+ LdModSonameGenerator
issued_mixed_link_warning = False
@@ -97,17 +96,17 @@ def _lib_emitter(target, source, env, **kw):
print("_lib_emitter: symlinks={!r}".format(symlinks))
if symlinks:
- SCons.Tool.EmitLibSymlinks(env, symlinks, target[0])
+ EmitLibSymlinks(env, symlinks, target[0])
target[0].attributes.shliblinks = symlinks
return (target, source)
def shlib_emitter(target, source, env):
- return _lib_emitter(target, source, env, symlink_generator=SCons.Tool.ShLibSymlinkGenerator)
+ return _lib_emitter(target, source, env, symlink_generator=ShLibSymlinkGenerator)
def ldmod_emitter(target, source, env):
- return _lib_emitter(target, source, env, symlink_generator=SCons.Tool.LdModSymlinkGenerator)
+ return _lib_emitter(target, source, env, symlink_generator=LdModSymlinkGenerator)
# This is generic enough to be included here...
@@ -142,14 +141,14 @@ def _versioned_lib_name(env, libnode, version, prefix, suffix, prefix_generator,
def _versioned_shlib_name(env, libnode, version, prefix, suffix, **kw):
- prefix_generator = SCons.Tool.ShLibPrefixGenerator
- suffix_generator = SCons.Tool.ShLibSuffixGenerator
+ prefix_generator = ShLibPrefixGenerator
+ suffix_generator = ShLibSuffixGenerator
return _versioned_lib_name(env, libnode, version, prefix, suffix, prefix_generator, suffix_generator, **kw)
def _versioned_ldmod_name(env, libnode, version, prefix, suffix, **kw):
- prefix_generator = SCons.Tool.LdModPrefixGenerator
- suffix_generator = SCons.Tool.LdModSuffixGenerator
+ prefix_generator = LdModPrefixGenerator
+ suffix_generator = LdModSuffixGenerator
return _versioned_lib_name(env, libnode, version, prefix, suffix, prefix_generator, suffix_generator, **kw)
@@ -236,7 +235,8 @@ def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, so
symlinks = [(link0, libnode), (link1, libnode)]
if Verbose:
- print("_versioned_lib_symlinks: return symlinks={!r}".format(SCons.Tool.StringizeLibSymlinks(symlinks)))
+ print("_versioned_lib_symlinks: return symlinks={!r}".format(
+ StringizeLibSymlinks(symlinks)))
return symlinks
@@ -301,8 +301,8 @@ def _setup_versioned_lib_variables(env, **kw):
env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -Wl,-soname=$_LDMODULESONAME'
env['_SHLIBSONAME'] = '${ShLibSonameGenerator(__env__,TARGET)}'
env['_LDMODULESONAME'] = '${LdModSonameGenerator(__env__,TARGET)}'
- env['ShLibSonameGenerator'] = SCons.Tool.ShLibSonameGenerator
- env['LdModSonameGenerator'] = SCons.Tool.LdModSonameGenerator
+ env['ShLibSonameGenerator'] = ShLibSonameGenerator
+ env['LdModSonameGenerator'] = LdModSonameGenerator
else:
env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS'
env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS'
diff --git a/SCons/Tool/linkCommon/__init__.py b/SCons/Tool/linkCommon/__init__.py
new file mode 100644
index 0000000..f66ad6d
--- /dev/null
+++ b/SCons/Tool/linkCommon/__init__.py
@@ -0,0 +1,502 @@
+"""SCons.Tool.linkCommon
+
+Common link/shared library logic
+"""
+
+#
+# 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.
+import os
+from typing import Callable
+from SCons.Util import is_List
+
+
+def _call_linker_cb(env, callback, args, result=None):
+ """Returns the result of env['LINKCALLBACKS'][callback](*args)
+ if env['LINKCALLBACKS'] is a dictionary and env['LINKCALLBACKS'][callback]
+ is callable. If these conditions are not met, return the value provided as
+ the *result* argument. This function is mainly used for generating library
+ info such as versioned suffixes, symlink maps, sonames etc. by delegating
+ the core job to callbacks configured by current linker tool"""
+
+ Verbose = False
+
+ if Verbose:
+ print('_call_linker_cb: args=%r' % args)
+ print('_call_linker_cb: callback=%r' % callback)
+
+ try:
+ cbfun = env['LINKCALLBACKS'][callback]
+ except (KeyError, TypeError):
+ if Verbose:
+ print('_call_linker_cb: env["LINKCALLBACKS"][%r] not found or can not be used' % callback)
+ else:
+ if Verbose:
+ print('_call_linker_cb: env["LINKCALLBACKS"][%r] found' % callback)
+ print('_call_linker_cb: env["LINKCALLBACKS"][%r]=%r' % (callback, cbfun))
+ if isinstance(cbfun, Callable):
+ if Verbose:
+ print('_call_linker_cb: env["LINKCALLBACKS"][%r] is callable' % callback)
+ result = cbfun(env, *args)
+ return result
+
+
+class _ShLibInfoSupport:
+ @property
+ def libtype(self):
+ return 'ShLib'
+
+ def get_lib_prefix(self, env, *args, **kw):
+ return _call_env_subst(env, '$SHLIBPREFIX', *args, **kw)
+
+ def get_lib_suffix(self, env, *args, **kw):
+ return _call_env_subst(env, '$SHLIBSUFFIX', *args, **kw)
+
+ def get_lib_version(self, env, *args, **kw):
+ return _call_env_subst(env, '$SHLIBVERSION', *args, **kw)
+
+ def get_lib_noversionsymlinks(self, env, *args, **kw):
+ return _call_env_subst(env, '$SHLIBNOVERSIONSYMLINKS', *args, **kw)
+
+
+class _LdModInfoSupport:
+ @property
+ def libtype(self):
+ return 'LdMod'
+
+ def get_lib_prefix(self, env, *args, **kw):
+ return _call_env_subst(env, '$LDMODULEPREFIX', *args, **kw)
+
+ def get_lib_suffix(self, env, *args, **kw):
+ return _call_env_subst(env, '$LDMODULESUFFIX', *args, **kw)
+
+ def get_lib_version(self, env, *args, **kw):
+ return _call_env_subst(env, '$LDMODULEVERSION', *args, **kw)
+
+ def get_lib_noversionsymlinks(self, env, *args, **kw):
+ return _call_env_subst(env, '$LDMODULENOVERSIONSYMLINKS', *args, **kw)
+
+
+class _ImpLibInfoSupport:
+ @property
+ def libtype(self):
+ return 'ImpLib'
+
+ def get_lib_prefix(self, env, *args, **kw):
+ return _call_env_subst(env, '$IMPLIBPREFIX', *args, **kw)
+
+ def get_lib_suffix(self, env, *args, **kw):
+ return _call_env_subst(env, '$IMPLIBSUFFIX', *args, **kw)
+
+ def get_lib_version(self, env, *args, **kw):
+ version = _call_env_subst(env, '$IMPLIBVERSION', *args, **kw)
+ if not version:
+ try:
+ lt = kw['implib_libtype']
+ except KeyError:
+ pass
+ else:
+ if lt == 'ShLib':
+ version = _call_env_subst(env, '$SHLIBVERSION', *args, **kw)
+ elif lt == 'LdMod':
+ version = _call_env_subst(env, '$LDMODULEVERSION', *args, **kw)
+ return version
+
+ def get_lib_noversionsymlinks(self, env, *args, **kw):
+ disable = None
+ try:
+ env['IMPLIBNOVERSIONSYMLINKS']
+ except KeyError:
+ try:
+ lt = kw['implib_libtype']
+ except KeyError:
+ pass
+ else:
+ if lt == 'ShLib':
+ disable = _call_env_subst(env, '$SHLIBNOVERSIONSYMLINKS', *args, **kw)
+ elif lt == 'LdMod':
+ disable = _call_env_subst(env, '$LDMODULENOVERSIONSYMLINKS', *args, **kw)
+ else:
+ disable = _call_env_subst(env, '$IMPLIBNOVERSIONSYMLINKS', *args, **kw)
+ return disable
+
+
+class _LibInfoGeneratorBase:
+ """Generator base class for library-related info such as suffixes for
+ versioned libraries, symlink maps, sonames etc. It handles commonities
+ of SharedLibrary and LoadableModule
+ """
+ _support_classes = {'ShLib': _ShLibInfoSupport,
+ 'LdMod': _LdModInfoSupport,
+ 'ImpLib': _ImpLibInfoSupport}
+
+ def __init__(self, libtype, infoname):
+ self.libtype = libtype
+ self.infoname = infoname
+
+ @property
+ def libtype(self):
+ return self._support.libtype
+
+ @libtype.setter
+ def libtype(self, libtype):
+ try:
+ support_class = self._support_classes[libtype]
+ except KeyError:
+ raise ValueError('unsupported libtype %r' % libtype)
+ self._support = support_class()
+
+ def get_lib_prefix(self, env, *args, **kw):
+ return self._support.get_lib_prefix(env, *args, **kw)
+
+ def get_lib_suffix(self, env, *args, **kw):
+ return self._support.get_lib_suffix(env, *args, **kw)
+
+ def get_lib_version(self, env, *args, **kw):
+ return self._support.get_lib_version(env, *args, **kw)
+
+ def get_lib_noversionsymlinks(self, env, *args, **kw):
+ return self._support.get_lib_noversionsymlinks(env, *args, **kw)
+
+ def get_versioned_lib_info_generator(self, **kw):
+ """
+ Returns name of generator linker callback that will be used to generate
+ our info for a versioned library. For example, if our libtype is 'ShLib'
+ and infoname is 'Prefix', it would return 'VersionedShLibPrefix'.
+ """
+ try:
+ libtype = kw['generator_libtype']
+ except KeyError:
+ libtype = self.libtype
+ return 'Versioned%s%s' % (libtype, self.infoname)
+
+ def generate_versioned_lib_info(self, env, args, result=None, **kw):
+ callback = self.get_versioned_lib_info_generator(**kw)
+ return _call_linker_cb(env, callback, args, result)
+
+
+class _LibPrefixGenerator(_LibInfoGeneratorBase):
+ """Library prefix generator, used as target_prefix in SharedLibrary and
+ LoadableModule builders"""
+
+ def __init__(self, libtype):
+ super(_LibPrefixGenerator, self).__init__(libtype, 'Prefix')
+
+ def __call__(self, env, sources=None, **kw):
+ Verbose = False
+
+ if sources and 'source' not in kw:
+ kw2 = kw.copy()
+ kw2['source'] = sources
+ else:
+ kw2 = kw
+
+ prefix = self.get_lib_prefix(env, **kw2)
+ if Verbose:
+ print("_LibPrefixGenerator: input prefix=%r" % prefix)
+
+ version = self.get_lib_version(env, **kw2)
+ if Verbose:
+ print("_LibPrefixGenerator: version=%r" % version)
+
+ if version:
+ prefix = self.generate_versioned_lib_info(env, [prefix, version], prefix, **kw2)
+
+ if Verbose:
+ print("_LibPrefixGenerator: return prefix=%r" % prefix)
+ return prefix
+
+
+ShLibPrefixGenerator = _LibPrefixGenerator('ShLib')
+LdModPrefixGenerator = _LibPrefixGenerator('LdMod')
+ImpLibPrefixGenerator = _LibPrefixGenerator('ImpLib')
+
+
+class _LibSuffixGenerator(_LibInfoGeneratorBase):
+ """Library suffix generator, used as target_suffix in SharedLibrary and
+ LoadableModule builders"""
+
+ def __init__(self, libtype):
+ super(_LibSuffixGenerator, self).__init__(libtype, 'Suffix')
+
+ def __call__(self, env, sources=None, **kw):
+ Verbose = False
+
+ if sources and 'source' not in kw:
+ kw2 = kw.copy()
+ kw2['source'] = sources
+ else:
+ kw2 = kw
+
+ suffix = self.get_lib_suffix(env, **kw2)
+ if Verbose:
+ print("_LibSuffixGenerator: input suffix=%r" % suffix)
+
+ version = self.get_lib_version(env, **kw2)
+ if Verbose:
+ print("_LibSuffixGenerator: version=%r" % version)
+
+ if version:
+ suffix = self.generate_versioned_lib_info(env, [suffix, version], suffix, **kw2)
+
+ if Verbose:
+ print("_LibSuffixGenerator: return suffix=%r" % suffix)
+ return suffix
+
+
+ShLibSuffixGenerator = _LibSuffixGenerator('ShLib')
+LdModSuffixGenerator = _LibSuffixGenerator('LdMod')
+ImpLibSuffixGenerator = _LibSuffixGenerator('ImpLib')
+
+
+class _LibSymlinkGenerator(_LibInfoGeneratorBase):
+ """Library symlink map generator. It generates a list of symlinks that
+ should be created by SharedLibrary or LoadableModule builders"""
+
+ def __init__(self, libtype):
+ super(_LibSymlinkGenerator, self).__init__(libtype, 'Symlinks')
+
+ def __call__(self, env, libnode, **kw):
+ Verbose = False
+
+ if libnode and 'target' not in kw:
+ kw2 = kw.copy()
+ kw2['target'] = libnode
+ else:
+ kw2 = kw
+
+ if Verbose:
+ print("_LibSymLinkGenerator: libnode=%r" % libnode.get_path())
+
+ symlinks = None
+
+ version = self.get_lib_version(env, **kw2)
+ disable = self.get_lib_noversionsymlinks(env, **kw2)
+ if Verbose:
+ print('_LibSymlinkGenerator: version=%r' % version)
+ print('_LibSymlinkGenerator: disable=%r' % disable)
+
+ if version and not disable:
+ prefix = self.get_lib_prefix(env, **kw2)
+ suffix = self.get_lib_suffix(env, **kw2)
+ symlinks = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw2)
+
+ if Verbose:
+ print('_LibSymlinkGenerator: return symlinks=%r' % StringizeLibSymlinks(symlinks))
+ return symlinks
+
+
+ShLibSymlinkGenerator = _LibSymlinkGenerator('ShLib')
+LdModSymlinkGenerator = _LibSymlinkGenerator('LdMod')
+ImpLibSymlinkGenerator = _LibSymlinkGenerator('ImpLib')
+
+
+class _LibNameGenerator(_LibInfoGeneratorBase):
+ """Generates "unmangled" library name from a library file node.
+
+ Generally, it's thought to revert modifications done by prefix/suffix
+ generators (_LibPrefixGenerator/_LibSuffixGenerator) used by a library
+ builder. For example, on gnulink the suffix generator used by SharedLibrary
+ builder appends $SHLIBVERSION to $SHLIBSUFFIX producing node name which
+ ends with "$SHLIBSUFFIX.$SHLIBVERSION". Correspondingly, the implementation
+ of _LibNameGenerator replaces "$SHLIBSUFFIX.$SHLIBVERSION" with
+ "$SHLIBSUFFIX" in the node's basename. So that, if $SHLIBSUFFIX is ".so",
+ $SHLIBVERSION is "0.1.2" and the node path is "/foo/bar/libfoo.so.0.1.2",
+ the _LibNameGenerator shall return "libfoo.so". Other link tools may
+ implement it's own way of library name unmangling.
+ """
+
+ def __init__(self, libtype):
+ super(_LibNameGenerator, self).__init__(libtype, 'Name')
+
+ def __call__(self, env, libnode, **kw):
+ """Returns "demangled" library name"""
+ Verbose = False
+
+ if libnode and 'target' not in kw:
+ kw2 = kw.copy()
+ kw2['target'] = libnode
+ else:
+ kw2 = kw
+
+ if Verbose:
+ print("_LibNameGenerator: libnode=%r" % libnode.get_path())
+
+ version = self.get_lib_version(env, **kw2)
+ if Verbose:
+ print('_LibNameGenerator: version=%r' % version)
+
+ name = None
+ if version:
+ prefix = self.get_lib_prefix(env, **kw2)
+ suffix = self.get_lib_suffix(env, **kw2)
+ name = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw2)
+
+ if not name:
+ name = os.path.basename(libnode.get_path())
+
+ if Verbose:
+ print('_LibNameGenerator: return name=%r' % name)
+
+ return name
+
+
+ShLibNameGenerator = _LibNameGenerator('ShLib')
+LdModNameGenerator = _LibNameGenerator('LdMod')
+ImpLibNameGenerator = _LibNameGenerator('ImpLib')
+
+
+class _LibSonameGenerator(_LibInfoGeneratorBase):
+ """Library soname generator. Returns library soname (e.g. libfoo.so.0) for
+ a given node (e.g. /foo/bar/libfoo.so.0.1.2)"""
+
+ def __init__(self, libtype):
+ super(_LibSonameGenerator, self).__init__(libtype, 'Soname')
+
+ def __call__(self, env, libnode, **kw):
+ """Returns a SONAME based on a shared library's node path"""
+ Verbose = False
+
+ if libnode and 'target' not in kw:
+ kw2 = kw.copy()
+ kw2['target'] = libnode
+ else:
+ kw2 = kw
+
+ if Verbose:
+ print("_LibSonameGenerator: libnode=%r" % libnode.get_path())
+
+ soname = _call_env_subst(env, '$SONAME', **kw2)
+ if not soname:
+ version = self.get_lib_version(env, **kw2)
+ if Verbose:
+ print("_LibSonameGenerator: version=%r" % version)
+ if version:
+ prefix = self.get_lib_prefix(env, **kw2)
+ suffix = self.get_lib_suffix(env, **kw2)
+ soname = self.generate_versioned_lib_info(env, [libnode, version, prefix, suffix], **kw2)
+
+ if not soname:
+ # fallback to library name (as returned by appropriate _LibNameGenerator)
+ soname = _LibNameGenerator(self.libtype)(env, libnode)
+ if Verbose:
+ print("_LibSonameGenerator: FALLBACK: soname=%r" % soname)
+
+ if Verbose:
+ print("_LibSonameGenerator: return soname=%r" % soname)
+
+ return soname
+
+
+ShLibSonameGenerator = _LibSonameGenerator('ShLib')
+LdModSonameGenerator = _LibSonameGenerator('LdMod')
+
+
+def StringizeLibSymlinks(symlinks):
+ """Converts list with pairs of nodes to list with pairs of node paths
+ (strings). Used mainly for debugging."""
+ if is_List(symlinks):
+ try:
+ return [(k.get_path(), v.get_path()) for k, v in symlinks]
+ except (TypeError, ValueError):
+ return symlinks
+ else:
+ return symlinks
+
+
+def EmitLibSymlinks(env, symlinks, libnode, **kw):
+ """Used by emitters to handle (shared/versioned) library symlinks"""
+ Verbose = False
+
+ # nodes involved in process... all symlinks + library
+ nodes = list(set([x for x, y in symlinks] + [libnode]))
+
+ clean_targets = kw.get('clean_targets', [])
+ if not is_List(clean_targets):
+ clean_targets = [clean_targets]
+
+ for link, linktgt in symlinks:
+ env.SideEffect(link, linktgt)
+ if Verbose:
+ print("EmitLibSymlinks: SideEffect(%r,%r)" % (link.get_path(), linktgt.get_path()))
+ clean_list = [x for x in nodes if x != linktgt]
+ env.Clean(list(set([linktgt] + clean_targets)), clean_list)
+ if Verbose:
+ print("EmitLibSymlinks: Clean(%r,%r)" % (linktgt.get_path(), [x.get_path() for x in clean_list]))
+
+
+def CreateLibSymlinks(env, symlinks):
+ """Physically creates symlinks. The symlinks argument must be a list in
+ form [ (link, linktarget), ... ], where link and linktarget are SCons
+ nodes.
+ """
+
+ Verbose = False
+ for link, linktgt in symlinks:
+ linktgt = link.get_dir().rel_path(linktgt)
+ link = link.get_path()
+ if Verbose:
+ print("CreateLibSymlinks: preparing to add symlink %r -> %r" % (link, linktgt))
+ # Delete the (previously created) symlink if exists. Let only symlinks
+ # to be deleted to prevent accidental deletion of source files...
+ if env.fs.islink(link):
+ env.fs.unlink(link)
+ if Verbose:
+ print("CreateLibSymlinks: removed old symlink %r" % link)
+ # If a file or directory exists with the same name as link, an OSError
+ # will be thrown, which should be enough, I think.
+ env.fs.symlink(linktgt, link)
+ if Verbose:
+ print("CreateLibSymlinks: add symlink %r -> %r" % (link, linktgt))
+ return 0
+
+
+def LibSymlinksActionFunction(target, source, env):
+ for tgt in target:
+ symlinks = getattr(getattr(tgt, 'attributes', None), 'shliblinks', None)
+ if symlinks:
+ CreateLibSymlinks(env, symlinks)
+ return 0
+
+
+def LibSymlinksStrFun(target, source, env, *args):
+ cmd = None
+ for tgt in target:
+ symlinks = getattr(getattr(tgt, 'attributes', None), 'shliblinks', None)
+ if symlinks:
+ if cmd is None: cmd = ""
+ if cmd: cmd += "\n"
+ cmd += "Create symlinks for: %r" % tgt.get_path()
+ try:
+ linkstr = ', '.join(["%r->%r" % (k, v) for k, v in StringizeLibSymlinks(symlinks)])
+ except (KeyError, ValueError):
+ pass
+ else:
+ cmd += ": %s" % linkstr
+ return cmd
+
+
+def _call_env_subst(env, string, *args, **kw):
+ kw2 = {}
+ for k in ('raw', 'target', 'source', 'conv', 'executor'):
+ try:
+ kw2[k] = kw[k]
+ except KeyError:
+ pass
+ return env.subst(string, *args, **kw2) \ No newline at end of file
diff --git a/SCons/Tool/linkloc.py b/SCons/Tool/linkloc.py
index 0ca37b3..6ee5d61 100644
--- a/SCons/Tool/linkloc.py
+++ b/SCons/Tool/linkloc.py
@@ -34,7 +34,6 @@ selection method.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import os.path
import re
import SCons.Action
diff --git a/SCons/Tool/msginit.py b/SCons/Tool/msginit.py
index a94cb85..4b72c30 100644
--- a/SCons/Tool/msginit.py
+++ b/SCons/Tool/msginit.py
@@ -28,7 +28,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import SCons.Warnings
import SCons.Builder
-import re
#############################################################################
def _optional_no_translator_flag(env):
diff --git a/SCons/Tool/msvc.py b/SCons/Tool/msvc.py
index b9eb60a..a06a434 100644
--- a/SCons/Tool/msvc.py
+++ b/SCons/Tool/msvc.py
@@ -35,8 +35,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os.path
import os
-import re
-import sys
import SCons.Action
import SCons.Builder
diff --git a/SCons/Tool/packaging/rpm.py b/SCons/Tool/packaging/rpm.py
index a026e45..cdeabcf 100644
--- a/SCons/Tool/packaging/rpm.py
+++ b/SCons/Tool/packaging/rpm.py
@@ -27,7 +27,6 @@ The rpm packager.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-import os
import SCons.Builder
import SCons.Tool.rpmutils
diff --git a/SCons/Tool/qt.py b/SCons/Tool/qt.py
index fab1625..d8a51b2 100644
--- a/SCons/Tool/qt.py
+++ b/SCons/Tool/qt.py
@@ -35,7 +35,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import os.path
import re
-import glob
import SCons.Action
import SCons.Builder
diff --git a/SCons/Tool/textfile.py b/SCons/Tool/textfile.py
index bb8a0f9..c1b597f 100644
--- a/SCons/Tool/textfile.py
+++ b/SCons/Tool/textfile.py
@@ -48,8 +48,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import SCons
-import os
-import re
from SCons.Node import Node
from SCons.Node.Python import Value
@@ -76,8 +74,8 @@ def _do_subst(node, subs):
if 'b' in TEXTFILE_FILE_WRITE_MODE:
try:
contents = bytearray(contents, 'utf-8')
- except UnicodeDecodeError:
- # contents is already utf-8 encoded python 2 str i.e. a byte array
+ except TypeError:
+ # TODO: this should not happen, get_text_contents returns text
contents = bytearray(contents)
return contents
diff --git a/SCons/Tool/wixTests.py b/SCons/Tool/wixTests.py
index 6039115..5b255d9 100644
--- a/SCons/Tool/wixTests.py
+++ b/SCons/Tool/wixTests.py
@@ -26,7 +26,6 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import unittest
import os.path
import os
-import sys
import SCons.Errors
from SCons.Tool.wix import *
diff --git a/SCons/Tool/yacc.py b/SCons/Tool/yacc.py
index 0b62305..ab019b2 100644
--- a/SCons/Tool/yacc.py
+++ b/SCons/Tool/yacc.py
@@ -50,14 +50,14 @@ if sys.platform == 'win32':
else:
BINS = ["bison", "yacc"]
+
def _yaccEmitter(target, source, env, ysuf, hsuf):
yaccflags = env.subst("$YACCFLAGS", target=target, source=source)
flags = SCons.Util.CLVar(yaccflags)
targetBase, targetExt = os.path.splitext(SCons.Util.to_String(target[0]))
- if '.ym' in ysuf: # If using Objective-C
- target = [targetBase + ".m"] # the extension is ".m".
-
+ if '.ym' in ysuf: # If using Objective-C
+ target = [targetBase + ".m"] # the extension is ".m".
# If -d is specified on the command line, yacc will emit a .h
# or .hpp file with the same name as the .c or .cpp output file.
@@ -75,10 +75,8 @@ def _yaccEmitter(target, source, env, ysuf, hsuf):
# be noted and also be cleaned
# Bug #2558
if "-v" in flags:
- env.SideEffect(targetBase+'.output',target[0])
- env.Clean(target[0],targetBase+'.output')
-
-
+ env.SideEffect(targetBase + '.output', target[0])
+ env.Clean(target[0], targetBase + '.output')
# With --defines and --graph, the name of the file is totally defined
# in the options.
@@ -94,15 +92,19 @@ def _yaccEmitter(target, source, env, ysuf, hsuf):
return (target, source)
+
def yEmitter(target, source, env):
return _yaccEmitter(target, source, env, ['.y', '.yacc'], '$YACCHFILESUFFIX')
+
def ymEmitter(target, source, env):
return _yaccEmitter(target, source, env, ['.ym'], '$YACCHFILESUFFIX')
+
def yyEmitter(target, source, env):
return _yaccEmitter(target, source, env, ['.yy'], '$YACCHXXFILESUFFIX')
+
def get_yacc_path(env, append_paths=False):
"""
Find the path to the yacc tool, searching several possible names
@@ -118,7 +120,7 @@ def get_yacc_path(env, append_paths=False):
bin_path = SCons.Tool.find_program_path(
env,
prog,
- default_paths=CHOCO_DEFAULT_PATH + MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS )
+ default_paths=CHOCO_DEFAULT_PATH + MINGW_DEFAULT_PATHS + CYGWIN_DEFAULT_PATHS)
if bin_path:
if append_paths:
env.AppendENVPath('PATH', os.path.dirname(bin_path))
@@ -149,14 +151,20 @@ def generate(env):
# ignore the return, all we need is for the path to be added
_ = get_yacc_path(env, append_paths=True)
- env["YACC"] = env.Detect(BINS)
+ if 'YACC' not in env:
+ env["YACC"] = env.Detect(BINS)
+
env['YACCFLAGS'] = SCons.Util.CLVar('')
- env['YACCCOM'] = '$YACC $YACCFLAGS -o $TARGET $SOURCES'
+ env['YACCCOM'] = '$YACC $YACCFLAGS -o $TARGET $SOURCES'
env['YACCHFILESUFFIX'] = '.h'
env['YACCHXXFILESUFFIX'] = '.hpp'
env['YACCVCGFILESUFFIX'] = '.vcg'
+
def exists(env):
+ if 'YACC' in env:
+ return env.Detect(env['YACC'])
+
if sys.platform == 'win32':
return get_yacc_path(env)
else:
diff --git a/SCons/Tool/zip.py b/SCons/Tool/zip.py
index 23d540f..cbf2c16 100644
--- a/SCons/Tool/zip.py
+++ b/SCons/Tool/zip.py
@@ -42,7 +42,9 @@ import SCons.Util
import zipfile
-zipcompression = zipfile.ZIP_DEFLATED
+zip_compression = zipfile.ZIP_DEFLATED
+
+
def zip(target, source, env):
compression = env.get('ZIPCOMPRESSION', 0)
zf = zipfile.ZipFile(str(target[0]), 'w', compression)
@@ -52,19 +54,20 @@ def zip(target, source, env):
for fname in filenames:
path = os.path.join(dirpath, fname)
if os.path.isfile(path):
-
zf.write(path, os.path.relpath(path, str(env.get('ZIPROOT', ''))))
else:
zf.write(str(s), os.path.relpath(str(s), str(env.get('ZIPROOT', ''))))
zf.close()
-zipAction = SCons.Action.Action(zip, varlist=['ZIPCOMPRESSION'])
+# Fix PR #3569 - If you don't specify ZIPCOM and ZIPCOMSTR when creating
+# env, then it will ignore ZIPCOMSTR set afterwards.
+zipAction = SCons.Action.Action(zip, "$ZIPCOMSTR", varlist=['ZIPCOMPRESSION'])
-ZipBuilder = SCons.Builder.Builder(action = SCons.Action.Action('$ZIPCOM', '$ZIPCOMSTR'),
- source_factory = SCons.Node.FS.Entry,
- source_scanner = SCons.Defaults.DirScanner,
- suffix = '$ZIPSUFFIX',
- multi = 1)
+ZipBuilder = SCons.Builder.Builder(action=SCons.Action.Action('$ZIPCOM', '$ZIPCOMSTR'),
+ source_factory=SCons.Node.FS.Entry,
+ source_scanner=SCons.Defaults.DirScanner,
+ suffix='$ZIPSUFFIX',
+ multi=1)
def generate(env):
@@ -75,12 +78,13 @@ def generate(env):
bld = ZipBuilder
env['BUILDERS']['Zip'] = bld
- env['ZIP'] = 'zip'
- env['ZIPFLAGS'] = SCons.Util.CLVar('')
- env['ZIPCOM'] = zipAction
- env['ZIPCOMPRESSION'] = zipcompression
- env['ZIPSUFFIX'] = '.zip'
- env['ZIPROOT'] = SCons.Util.CLVar('')
+ env['ZIP'] = 'zip'
+ env['ZIPFLAGS'] = SCons.Util.CLVar('')
+ env['ZIPCOM'] = zipAction
+ env['ZIPCOMPRESSION'] = zip_compression
+ env['ZIPSUFFIX'] = '.zip'
+ env['ZIPROOT'] = SCons.Util.CLVar('')
+
def exists(env):
return True