summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--SCons/Builder.py1
-rw-r--r--SCons/Defaults.py11
-rw-r--r--SCons/Environment.py2
-rw-r--r--SCons/Platform/aix.py1
-rw-r--r--SCons/Platform/hpux.py2
-rw-r--r--SCons/Tool/FortranCommon.py6
-rw-r--r--SCons/Tool/aixlink.py9
-rw-r--r--SCons/Tool/applelink.py12
-rw-r--r--SCons/Tool/cxx.py5
-rw-r--r--SCons/Tool/cyglink.py31
-rw-r--r--SCons/Tool/gnulink.py12
-rw-r--r--SCons/Tool/hplink.py5
-rw-r--r--SCons/Tool/ilink.py4
-rw-r--r--SCons/Tool/link.py303
-rw-r--r--SCons/Tool/linkCommon/README.md103
-rw-r--r--SCons/Tool/linkCommon/__init__.py283
-rw-r--r--SCons/Tool/mslink.py3
-rw-r--r--SCons/Tool/sgilink.py3
-rw-r--r--SCons/Tool/sunlink.py14
-rw-r--r--test/LINK/SHLIBVERSIONFLAGS.py27
20 files changed, 469 insertions, 368 deletions
diff --git a/SCons/Builder.py b/SCons/Builder.py
index a0df272..035196d 100644
--- a/SCons/Builder.py
+++ b/SCons/Builder.py
@@ -503,6 +503,7 @@ class BuilderBase:
splitext = lambda S: self.splitext(S,env)
tlist = [ t_from_s(pre, suf, splitext) ]
else:
+ orig_target = target
target = self._adjustixes(target, pre, suf, self.ensure_suffix)
tlist = env.arg2nodes(target, target_factory, target=target, source=source)
diff --git a/SCons/Defaults.py b/SCons/Defaults.py
index 06d938c..c59fbcf 100644
--- a/SCons/Defaults.py
+++ b/SCons/Defaults.py
@@ -20,6 +20,7 @@
# 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.
+#
"""Builders and other things for the local site.
@@ -542,8 +543,14 @@ class Variable_Method_Caller:
frame = frame.f_back
return None
-# if $version_var is not empty, returns env[flags_var], otherwise returns None
def __libversionflags(env, version_var, flags_var):
+ """
+ if $version_var is not empty, returns env[flags_var], otherwise returns None
+ :param env:
+ :param version_var:
+ :param flags_var:
+ :return:
+ """
try:
if env.subst('$'+version_var):
return env[flags_var]
@@ -551,6 +558,8 @@ def __libversionflags(env, version_var, flags_var):
pass
return None
+
+
ConstructionEnvironment = {
'BUILDERS' : {},
'SCANNERS' : [ SCons.Tool.SourceFileScanner ],
diff --git a/SCons/Environment.py b/SCons/Environment.py
index 4ebd515..55a5003 100644
--- a/SCons/Environment.py
+++ b/SCons/Environment.py
@@ -1613,7 +1613,7 @@ class Base(SubstitutionEnvironment):
prefix = self.subst('$'+prefix)
for path in paths:
- dir,name = os.path.split(str(path))
+ name = os.path.basename(str(path))
if name[:len(prefix)] == prefix and name[-len(suffix):] == suffix:
return path
diff --git a/SCons/Platform/aix.py b/SCons/Platform/aix.py
index bee3eb8..db1ccdb 100644
--- a/SCons/Platform/aix.py
+++ b/SCons/Platform/aix.py
@@ -71,6 +71,7 @@ def generate(env):
posix.generate(env)
#Based on AIX 5.2: ARG_MAX=24576 - 3000 for environment expansion
env['MAXLINELENGTH'] = 21576
+ env['SHLIBSUFFIX'] = '.a'
# Local Variables:
# tab-width:4
diff --git a/SCons/Platform/hpux.py b/SCons/Platform/hpux.py
index 551468e..53c7b67 100644
--- a/SCons/Platform/hpux.py
+++ b/SCons/Platform/hpux.py
@@ -35,6 +35,8 @@ def generate(env):
#Based on HP-UX11i: ARG_MAX=2048000 - 3000 for environment expansion
env['MAXLINELENGTH'] = 2045000
+ env['SHLIBSUFFIX'] = '.sl'
+
# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
diff --git a/SCons/Tool/FortranCommon.py b/SCons/Tool/FortranCommon.py
index bfa1c1c..f8d9fdc 100644
--- a/SCons/Tool/FortranCommon.py
+++ b/SCons/Tool/FortranCommon.py
@@ -5,8 +5,6 @@ Stuff for processing Fortran, common to all fortran dialects.
"""
#
-# __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
@@ -26,13 +24,11 @@ Stuff for processing Fortran, common to all fortran dialects.
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import re
import os.path
import SCons.Action
-import SCons.Defaults
import SCons.Scanner.Fortran
import SCons.Tool
import SCons.Util
@@ -78,10 +74,12 @@ def _fortranEmitter(target, source, env):
return (target, source)
def FortranEmitter(target, source, env):
+ import SCons.Defaults
target, source = _fortranEmitter(target, source, env)
return SCons.Defaults.StaticObjectEmitter(target, source, env)
def ShFortranEmitter(target, source, env):
+ import SCons.Defaults
target, source = _fortranEmitter(target, source, env)
return SCons.Defaults.SharedObjectEmitter(target, source, env)
diff --git a/SCons/Tool/aixlink.py b/SCons/Tool/aixlink.py
index fed4342..dc0de2a 100644
--- a/SCons/Tool/aixlink.py
+++ b/SCons/Tool/aixlink.py
@@ -8,8 +8,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,8 +28,6 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
import os
import os.path
@@ -42,7 +38,6 @@ from . import link
import SCons.Tool.cxx
cplusplus = SCons.Tool.cxx
-#cplusplus = __import__('cxx', globals(), locals(), [])
def smart_linkflags(source, target, env, for_signature):
@@ -52,6 +47,7 @@ def smart_linkflags(source, target, env, for_signature):
return '-qtempinc=' + os.path.join(build_dir, 'tempinc')
return ''
+
def generate(env):
"""
Add Builders and construction variables for Visual Age linker to
@@ -64,12 +60,13 @@ def generate(env):
env['SHLINKFLAGS'] = SCons.Util.CLVar('$LINKFLAGS -qmkshrobj -qsuppress=1501-218')
env['SHLIBSUFFIX'] = '.a'
+
def exists(env):
# TODO: sync with link.smart_link() to choose a linker
linkers = { 'CXX': ['aixc++'], 'CC': ['aixcc'] }
alltools = []
for langvar, linktools in linkers.items():
- if langvar in env: # use CC over CXX when user specified CC but not CXX
+ if langvar in env: # use CC over CXX when user specified CC but not CXX
return SCons.Tool.FindTool(linktools, env)
alltools.extend(linktools)
return SCons.Tool.FindTool(alltools, env)
diff --git a/SCons/Tool/applelink.py b/SCons/Tool/applelink.py
index aec8b93..f51a6af 100644
--- a/SCons/Tool/applelink.py
+++ b/SCons/Tool/applelink.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
@@ -31,8 +29,7 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
+import SCons.Tool.linkCommon
import SCons.Util
# Even though the Mac is based on the GNU toolchain, it doesn't understand
@@ -85,7 +82,8 @@ def _applelib_versioned_lib_soname(env, libnode, version, prefix, suffix, name_f
def _applelib_versioned_shlib_soname(env, libnode, version, prefix, suffix):
- return _applelib_versioned_lib_soname(env, libnode, version, prefix, suffix, link._versioned_shlib_name)
+ return _applelib_versioned_lib_soname(env, libnode, version, prefix, suffix,
+ SCons.Tool.linkCommon._versioned_shlib_name)
# User programmatically describes how SHLIBVERSION maps to values for compat/current.
@@ -197,8 +195,8 @@ def generate(env):
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=True)
- env['LINKCALLBACKS'] = link._versioned_lib_callbacks()
+ SCons.Tool.linkCommon._setup_versioned_lib_variables(env, tool='applelink', use_soname=True)
+ env['LINKCALLBACKS'] = SCons.Tool.linkCommon._versioned_lib_callbacks()
env['LINKCALLBACKS']['VersionedShLibSuffix'] = _applelib_versioned_lib_suffix
env['LINKCALLBACKS']['VersionedShLibSoname'] = _applelib_versioned_shlib_soname
diff --git a/SCons/Tool/cxx.py b/SCons/Tool/cxx.py
index 430851c..128cdc4 100644
--- a/SCons/Tool/cxx.py
+++ b/SCons/Tool/cxx.py
@@ -8,8 +8,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,11 +28,8 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
import os.path
-import SCons.Tool
import SCons.Defaults
import SCons.Util
diff --git a/SCons/Tool/cyglink.py b/SCons/Tool/cyglink.py
index 08b8a98..595cc2e 100644
--- a/SCons/Tool/cyglink.py
+++ b/SCons/Tool/cyglink.py
@@ -12,13 +12,13 @@ import re
import os
import SCons.Action
+import SCons.Tool.linkCommon as linkCommon
from SCons.Tool.linkCommon import ImpLibSymlinkGenerator, StringizeLibSymlinks, EmitLibSymlinks, ImpLibPrefixGenerator, \
ImpLibSuffixGenerator, ImpLibNameGenerator
import SCons.Util
import SCons.Tool
from . import gnulink
-from . import link
def _lib_generator(target, source, env, for_signature, **kw):
@@ -120,14 +120,15 @@ def _lib_emitter(target, source, env, **kw):
implib_target.attributes.shared = 1
target.append(implib_target)
- symlinks = ImpLibSymlinkGenerator(env, implib_target,
- implib_libtype=libtype,
- generator_libtype=libtype + 'ImpLib')
- if Verbose:
- print("_lib_emitter: implib symlinks=%r" % StringizeLibSymlinks(symlinks))
- if symlinks:
- EmitLibSymlinks(env, symlinks, implib_target, clean_targets=target[0])
- implib_target.attributes.shliblinks = symlinks
+ # Only create the symlinks if there is actually an import library
+ symlinks = ImpLibSymlinkGenerator(env, implib_target,
+ implib_libtype=libtype,
+ generator_libtype=libtype + 'ImpLib')
+ if Verbose:
+ print("_lib_emitter: implib symlinks=%r" % StringizeLibSymlinks(symlinks))
+ if symlinks:
+ EmitLibSymlinks(env, symlinks, implib_target, clean_targets=target[0])
+ implib_target.attributes.shliblinks = symlinks
return (target, source)
@@ -156,10 +157,10 @@ def _versioned_lib_suffix(env, suffix, version):
def _versioned_implib_name(env, libnode, version, prefix, suffix, **kw):
- return link._versioned_lib_name(env, libnode, version, prefix, suffix,
- ImpLibPrefixGenerator,
- ImpLibSuffixGenerator,
- implib_libtype=kw['libtype'])
+ return linkCommon._versioned_lib_name(env, libnode, version, prefix, suffix,
+ ImpLibPrefixGenerator,
+ ImpLibSuffixGenerator,
+ implib_libtype=kw['libtype'])
def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw):
@@ -230,8 +231,8 @@ def generate(env):
'VersionedShLibSuffix': _versioned_lib_suffix,
'VersionedLdModSuffix': _versioned_lib_suffix,
'VersionedImpLibSuffix': _versioned_lib_suffix,
- 'VersionedShLibName': link._versioned_shlib_name,
- 'VersionedLdModName': link._versioned_ldmod_name,
+ 'VersionedShLibName': linkCommon._versioned_shlib_name,
+ 'VersionedLdModName': linkCommon._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'),
diff --git a/SCons/Tool/gnulink.py b/SCons/Tool/gnulink.py
index 5372322..2b09549 100644
--- a/SCons/Tool/gnulink.py
+++ b/SCons/Tool/gnulink.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
@@ -31,13 +29,14 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+import SCons.Tool.linkCommon
import SCons.Util
import SCons.Tool
import sys
from . import link
+import SCons.Tool.linkCommon as linkCommon
def generate(env):
@@ -55,11 +54,8 @@ def generate(env):
# OpenBSD doesn't usually use SONAME for libraries
use_soname = not sys.platform.startswith('openbsd')
- link._setup_versioned_lib_variables(env, tool='gnulink', use_soname=use_soname)
- env['LINKCALLBACKS'] = link._versioned_lib_callbacks()
-
- # # For backward-compatibility with older SCons versions
- # env['SHLIBVERSIONFLAGS'] = SCons.Util.CLVar('')
+ linkCommon._setup_versioned_lib_variables(env, tool='gnulink', use_soname=use_soname)
+ env['LINKCALLBACKS'] = linkCommon._versioned_lib_callbacks()
def exists(env):
diff --git a/SCons/Tool/hplink.py b/SCons/Tool/hplink.py
index 10ef30b..ba182f1 100644
--- a/SCons/Tool/hplink.py
+++ b/SCons/Tool/hplink.py
@@ -8,8 +8,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,9 +28,6 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-import os
import os.path
import SCons.Util
diff --git a/SCons/Tool/ilink.py b/SCons/Tool/ilink.py
index aa6bcaa..4112825 100644
--- a/SCons/Tool/ilink.py
+++ b/SCons/Tool/ilink.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
@@ -31,8 +29,6 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
import SCons.Defaults
import SCons.Tool
import SCons.Util
diff --git a/SCons/Tool/link.py b/SCons/Tool/link.py
index de377ac..c552273 100644
--- a/SCons/Tool/link.py
+++ b/SCons/Tool/link.py
@@ -1,13 +1,7 @@
-"""SCons.Tool.link
-
-Tool-specific initialization for the generic Posix linker.
-
-There normally shouldn't be any need to import this module directly.
-It will usually be imported through the generic SCons.Tool.Tool()
-selection method.
-
-"""
-
+#
+# MIT License
+#
+# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -28,287 +22,21 @@ 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.
#
+"""
+Tool-specific initialization for the generic Posix linker.
+
+There normally shouldn't be any need to import this module directly.
+It will usually be imported through the generic SCons.Tool.Tool()
+selection method.
+
+"""
-import sys
-import re
-import os
import SCons.Tool
import SCons.Util
import SCons.Warnings
-from SCons.Tool.FortranCommon import isfortran
-
-from SCons.Tool.DCommon import isD
-
-from SCons.Tool.cxx import iscplusplus
-
-from SCons.Tool.linkCommon import StringizeLibSymlinks, ShLibSonameGenerator, EmitLibSymlinks, ShLibSymlinkGenerator, \
- LdModSymlinkGenerator, ShLibPrefixGenerator, ShLibSuffixGenerator, LdModPrefixGenerator, LdModSuffixGenerator, \
- LdModSonameGenerator
-
-issued_mixed_link_warning = False
-
-
-def smart_link(source, target, env, for_signature):
- has_cplusplus = iscplusplus(source)
- has_fortran = isfortran(env, source)
- has_d = isD(env, source)
- if has_cplusplus and has_fortran and not has_d:
- global issued_mixed_link_warning
- if not issued_mixed_link_warning:
- msg = "Using $CXX to link Fortran and C++ code together.\n\t" + \
- "This may generate a buggy executable if the '%s'\n\t" + \
- "compiler does not know how to deal with Fortran runtimes."
- SCons.Warnings.warn(SCons.Warnings.FortranCxxMixWarning,
- msg % env.subst('$CXX'))
- issued_mixed_link_warning = True
- return '$CXX'
- elif has_d:
- env['LINKCOM'] = env['DLINKCOM']
- env['SHLINKCOM'] = env['SHDLINKCOM']
- return '$DC'
- elif has_fortran:
- return '$FORTRAN'
- elif has_cplusplus:
- return '$CXX'
- return '$CC'
-
-
-def _lib_emitter(target, source, env, **kw):
- Verbose = False
- if Verbose:
- print("_lib_emitter: target[0]={!r}".format(target[0].get_path()))
- for tgt in target:
- if SCons.Util.is_String(tgt):
- tgt = env.File(tgt)
- tgt.attributes.shared = 1
-
- try:
- symlink_generator = kw['symlink_generator']
- except KeyError:
- pass
- else:
- if Verbose:
- print("_lib_emitter: symlink_generator={!r}".format(symlink_generator))
- symlinks = symlink_generator(env, target[0])
- if Verbose:
- print("_lib_emitter: symlinks={!r}".format(symlinks))
-
- if symlinks:
- 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=ShLibSymlinkGenerator)
-
-
-def ldmod_emitter(target, source, env):
- return _lib_emitter(target, source, env, symlink_generator=LdModSymlinkGenerator)
-
-
-# This is generic enough to be included here...
-def _versioned_lib_name(env, libnode, version, prefix, suffix, prefix_generator, suffix_generator, **kw):
- """For libnode='/optional/dir/libfoo.so.X.Y.Z' it returns 'libfoo.so'"""
- Verbose = False
-
- if Verbose:
- print("_versioned_lib_name: libnode={!r}".format(libnode.get_path()))
- print("_versioned_lib_name: version={!r}".format(version))
- print("_versioned_lib_name: prefix={!r}".format(prefix))
- print("_versioned_lib_name: suffix={!r}".format(suffix))
- print("_versioned_lib_name: suffix_generator={!r}".format(suffix_generator))
-
- versioned_name = os.path.basename(libnode.get_path())
- if Verbose:
- print("_versioned_lib_name: versioned_name={!r}".format(versioned_name))
-
- versioned_prefix = prefix_generator(env, **kw)
- versioned_suffix = suffix_generator(env, **kw)
- if Verbose:
- print("_versioned_lib_name: versioned_prefix={!r}".format(versioned_prefix))
- print("_versioned_lib_name: versioned_suffix={!r}".format(versioned_suffix))
-
- versioned_prefix_re = '^' + re.escape(versioned_prefix)
- versioned_suffix_re = re.escape(versioned_suffix) + '$'
- name = re.sub(versioned_prefix_re, prefix, versioned_name)
- name = re.sub(versioned_suffix_re, suffix, name)
- if Verbose:
- print("_versioned_lib_name: name={!r}".format(name))
- return name
-
-
-def _versioned_shlib_name(env, libnode, version, prefix, suffix, **kw):
- 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 = LdModPrefixGenerator
- suffix_generator = LdModSuffixGenerator
- return _versioned_lib_name(env, libnode, version, prefix, suffix, prefix_generator, suffix_generator, **kw)
-
-
-def _versioned_lib_suffix(env, suffix, version):
- """For suffix='.so' and version='0.1.2' it returns '.so.0.1.2'"""
- Verbose = False
- if Verbose:
- print("_versioned_lib_suffix: suffix={!r}".format(suffix))
- print("_versioned_lib_suffix: version={!r}".format(version))
- if not suffix.endswith(version):
- suffix = suffix + '.' + version
- if Verbose:
- print("_versioned_lib_suffix: return suffix={!r}".format(suffix))
- return suffix
-
-
-def _versioned_lib_soname(env, libnode, version, prefix, suffix, name_func):
- """For libnode='/optional/dir/libfoo.so.X.Y.Z' it returns 'libfoo.so.X'"""
- Verbose = False
- if Verbose:
- print("_versioned_lib_soname: version={!r}".format(version))
- name = name_func(env, libnode, version, prefix, suffix)
- if Verbose:
- print("_versioned_lib_soname: name={!r}".format(name))
- major = version.split('.')[0]
-
- # if a desired SONAME was supplied, use that, otherwise create
- # a default from the major version
- if env.get('SONAME'):
- soname = ShLibSonameGenerator(env, libnode)
- else:
- soname = name + '.' + major
- if Verbose:
- print("_versioned_lib_soname: soname={!r}".format(soname))
- return soname
-
-
-def _versioned_shlib_soname(env, libnode, version, prefix, suffix):
- return _versioned_lib_soname(env, libnode, version, prefix, suffix, _versioned_shlib_name)
-
-
-def _versioned_ldmod_soname(env, libnode, version, prefix, suffix):
- return _versioned_lib_soname(env, libnode, version, prefix, suffix, _versioned_ldmod_name)
-
-
-def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, soname_func):
- """Generate link names that should be created for a versioned shared library.
- Returns a dictionary in the form { linkname : linktarget }
- """
- Verbose = False
-
- if Verbose:
- print("_versioned_lib_symlinks: libnode={!r}".format(libnode.get_path()))
- print("_versioned_lib_symlinks: version={!r}".format(version))
-
- if sys.platform.startswith('openbsd'):
- # OpenBSD uses x.y shared library versioning numbering convention
- # and doesn't use symlinks to backwards-compatible libraries
- if Verbose:
- print("_versioned_lib_symlinks: return symlinks={!r}".format(None))
- return None
-
- linkdir = libnode.get_dir()
- if Verbose:
- print("_versioned_lib_symlinks: linkdir={!r}".format(linkdir.get_path()))
-
- name = name_func(env, libnode, version, prefix, suffix)
- if Verbose:
- print("_versioned_lib_symlinks: name={!r}".format(name))
-
- soname = soname_func(env, libnode, version, prefix, suffix)
- if Verbose:
- print("_versioned_lib_symlinks: soname={!r}".format(soname))
-
- link0 = env.fs.File(soname, linkdir)
- link1 = env.fs.File(name, linkdir)
-
- # We create direct symlinks, not daisy-chained.
- if link0 == libnode:
- # This enables SHLIBVERSION without periods (e.g. SHLIBVERSION=1)
- symlinks = [(link1, libnode)]
- else:
- # This handles usual SHLIBVERSION, i.e. '1.2', '1.2.3', etc.
- symlinks = [(link0, libnode), (link1, libnode)]
-
- if Verbose:
- print("_versioned_lib_symlinks: return symlinks={!r}".format(
- StringizeLibSymlinks(symlinks)))
-
- return symlinks
-
-
-def _versioned_shlib_symlinks(env, libnode, version, prefix, suffix):
- name_func = env['LINKCALLBACKS']['VersionedShLibName']
- soname_func = env['LINKCALLBACKS']['VersionedShLibSoname']
-
- return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, soname_func)
-
-
-def _versioned_ldmod_symlinks(env, libnode, version, prefix, suffix):
- name_func = _versioned_ldmod_name
- soname_func = _versioned_ldmod_soname
-
- name_func = env['LINKCALLBACKS']['VersionedLdModName']
- soname_func = env['LINKCALLBACKS']['VersionedLdModSoname']
-
- return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, soname_func)
-
-
-def _versioned_lib_callbacks():
- return {
- 'VersionedShLibSuffix': _versioned_lib_suffix,
- 'VersionedLdModSuffix': _versioned_lib_suffix,
- 'VersionedShLibSymlinks': _versioned_shlib_symlinks,
- 'VersionedLdModSymlinks': _versioned_ldmod_symlinks,
- 'VersionedShLibName': _versioned_shlib_name,
- 'VersionedLdModName': _versioned_ldmod_name,
- 'VersionedShLibSoname': _versioned_shlib_soname,
- 'VersionedLdModSoname': _versioned_ldmod_soname,
- }.copy()
-
-
-def _setup_versioned_lib_variables(env, **kw):
- """
- Setup all variables required by the versioning machinery
- """
-
- tool = None
- try:
- tool = kw['tool']
- except KeyError:
- pass
-
- use_soname = False
- try:
- use_soname = kw['use_soname']
- except KeyError:
- pass
-
- # The $_SHLIBVERSIONFLAGS define extra commandline flags used when
- # building VERSIONED shared libraries. It's always set, but used only
- # when VERSIONED library is built (see __SHLIBVERSIONFLAGS in SCons/Defaults.py).
- if use_soname:
- # If the linker uses SONAME, then we need this little automata
- if tool == 'sunlink':
- env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -h $_SHLIBSONAME'
- env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -h $_LDMODULESONAME'
- else:
- env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -Wl,-soname=$_SHLIBSONAME'
- env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -Wl,-soname=$_LDMODULESONAME'
- env['_SHLIBSONAME'] = '${ShLibSonameGenerator(__env__,TARGET)}'
- env['_LDMODULESONAME'] = '${LdModSonameGenerator(__env__,TARGET)}'
- env['ShLibSonameGenerator'] = ShLibSonameGenerator
- env['LdModSonameGenerator'] = LdModSonameGenerator
- else:
- env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS'
- env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS'
-
- # LDOMDULVERSIONFLAGS should always default to $SHLIBVERSIONFLAGS
- env['LDMODULEVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS'
+from SCons.Tool.linkCommon import smart_link, shlib_emitter, ldmod_emitter
def generate(env):
@@ -336,11 +64,6 @@ def generate(env):
env['LIBLINKPREFIX'] = '-l'
env['LIBLINKSUFFIX'] = ''
- if env['PLATFORM'] == 'hpux':
- env['SHLIBSUFFIX'] = '.sl'
- elif env['PLATFORM'] == 'aix':
- env['SHLIBSUFFIX'] = '.a'
-
# For most platforms, a loadable module is the same as a shared
# library. Platforms which are different can override these, but
# setting them the same means that LoadableModule works everywhere.
diff --git a/SCons/Tool/linkCommon/README.md b/SCons/Tool/linkCommon/README.md
new file mode 100644
index 0000000..add1246
--- /dev/null
+++ b/SCons/Tool/linkCommon/README.md
@@ -0,0 +1,103 @@
+
+
+# Versioned Shared Library and Loadable modules requirements
+
+The following env variables can affect the command line and created files for these
+
+* `SHLIBVERSION` - If this is not set, the all of the following will be ignored?
+* `SONAME`
+* `SOVERSION`
+* `APPLELINK_NO_CURRENT_VERSION` (applelink only)
+* `APPLELINK_CURRENT_VERSION` (applelink only)
+* `APPLELINK_COMPATIBILITY_VERSION` (applelink only)
+
+In most cases the linker will create a file named as
+
+`${SHLIBPREFIX}lib_name${SHLIBVERSION}${SHLIBSUFFIX}`
+
+Which will have a soname baked into it as one of the
+
+* `${SONAME}`
+* `${SHLIBPREFIX}lib_name${SOVERSION}${SHLIBSUFFIX}`
+* `-Wl,-soname=$_SHLIBSONAME` (for gnulink as similar)
+* (for applelink only)
+ * `${SHLIBPREFIX}lib_name${major version only from SHLIBVERSION}${SHLIBSUFFIX}`
+ * `-Wl,-compatibility_version,%s`
+ * `-Wl,-current_version,%s`
+
+For **applelink** the version has to follow these rules to verify that the version # is valid.
+
+* For version # = X[.Y[.Z]]
+* where X 0-65535
+* where Y either not specified or 0-255
+* where Z either not specified or 0-255
+
+
+For most platforms this will lead to a series of symlinks eventually pointing to the actual shared library (or loadable module file).
+1. `${SHLIBPREFIX}lib_name${SHLIBSUFFIX} -> ${SHLIBPREFIX}lib_name${SHLIBVERSION}${SHLIBSUFFIX}`
+1. `${SHLIBPREFIX}lib_name${SOVERSION}${SHLIBSUFFIX} -> ${SHLIBPREFIX}lib_name${SHLIBVERSION}${SHLIBSUFFIX}`
+
+These symlinks are stored by the emitter in the following
+`target[0].attributes.shliblinks = symlinks`
+This means that those values are fixed a the time SharedLibrary() is called (generally)
+
+For **openbsd** the following rules for symlinks apply
+
+ * OpenBSD uses x.y shared library versioning numbering convention and doesn't use symlinks to backwards-compatible libraries
+
+
+The current code provides the following hooks a compiler can use to customize:
+
+```
+ 'VersionedShLibSuffix': _versioned_lib_suffix,
+ 'VersionedLdModSuffix': _versioned_lib_suffix,
+ 'VersionedShLibSymlinks': _versioned_shlib_symlinks,
+ 'VersionedLdModSymlinks': _versioned_ldmod_symlinks,
+ 'VersionedShLibName': _versioned_shlib_name,
+ 'VersionedLdModName': _versioned_ldmod_name,
+ 'VersionedShLibSoname': _versioned_shlib_soname,
+ 'VersionedLdModSoname': _versioned_ldmod_soname,
+```
+
+
+User can request:
+env.SharedLibrary('a',sources, SHLIBVERSION)
+env.SharedLibrary('liba.so',sources, SHLIBVERSION)
+Ideally we'll keep the 'a' for use in constructing all follow on. To do this we have to do it in the Builder() or at
+least prevent BuilderBase._create_nodes() from discarding this info if it's available.
+
+
+Firstly check if [SH|LD]LIBNOVERSIONSYMLINKS defined or if [SH|LD]LIBVERSION is not defined, if so we do nothing special
+
+The emitter can calculate the filename stem 'a' above and store it on the target node. Then also create the symlinks
+and store those on the node. We should have all the information needed by the time the emitter is called.
+Same should apply for loadable modules..
+This should be vastly simpler.
+Unfortunately we cannot depend on the target having an OverrideEnvironment() which we could populate all the related
+env variables in the emitter...
+Maybe we can force one at that point?
+
+
+SOVERSION can be specified, if not, then defaults to major portion of SHLIBVERSION
+SONAME can be specified, if not defaults to ${SHLIBPREFIX}lib_name${SOVERSION}
+
+NOTE: mongodb uses Append(SHLIBEMITTER=.. ) for their libdeps stuff. (So test
+with that once you have new logic working)
+
+
+TODO:
+1. Generate proper naming for:
+ * shared library (altered by emitter if SHLIBVERSION is set)
+ * soname'd library (for symlink) - SHLIB_SONAME_SYMLINK
+ * non versioned shared library (for symlink) - SHLIB_NOVERSION_SYMLINK
+2. in emitter also, actually create the symlinks (if SHLIBVERSION is set) and
+ add to node.attributes.symlinks. (note bsd doesn't do this so skip if on bsd)
+3. We need to check somewhere if SONAME and SOVERSION are both set and thrown an error.
+ Probably in the emitter to it will traceback to where the SharedLibrary() which
+ yielded the issue is located.
+4. Generate proper linker soname compiler construct (-Wl,soname=libxyz.1.so for example)
+
+hrm.. tricky.
+SHLIBSUFFIX needs to have .${SHLIBVERSION}${SHLIBSUFFIX} as it's value when
+fixing a sharedlibrary()'s target file name (from a -> liba.1.2.3.so)
+But when creating the symlinks for the rest, we need to drop the versioned SHLIBSUFFIX \ No newline at end of file
diff --git a/SCons/Tool/linkCommon/__init__.py b/SCons/Tool/linkCommon/__init__.py
index f66ad6d..c49bc23 100644
--- a/SCons/Tool/linkCommon/__init__.py
+++ b/SCons/Tool/linkCommon/__init__.py
@@ -1,8 +1,6 @@
-"""SCons.Tool.linkCommon
-
-Common link/shared library logic
-"""
-
+# MIT License
+#
+# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -22,8 +20,19 @@ Common link/shared library logic
# 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.
+
+"""
+Common link/shared library logic
+"""
+
import os
+import re
+import sys
from typing import Callable
+
+import SCons.Util
+import SCons.Warnings
+from SCons.Tool.DCommon import isD
from SCons.Util import is_List
@@ -499,4 +508,266 @@ def _call_env_subst(env, string, *args, **kw):
kw2[k] = kw[k]
except KeyError:
pass
- return env.subst(string, *args, **kw2) \ No newline at end of file
+ return env.subst(string, *args, **kw2)
+
+
+def smart_link(source, target, env, for_signature):
+ import SCons.Tool.cxx
+ import SCons.Tool.FortranCommon
+
+ has_cplusplus = SCons.Tool.cxx.iscplusplus(source)
+ has_fortran = SCons.Tool.FortranCommon.isfortran(env, source)
+ has_d = isD(env, source)
+ if has_cplusplus and has_fortran and not has_d:
+ global issued_mixed_link_warning
+ if not issued_mixed_link_warning:
+ msg = "Using $CXX to link Fortran and C++ code together.\n\t" + \
+ "This may generate a buggy executable if the '%s'\n\t" + \
+ "compiler does not know how to deal with Fortran runtimes."
+ SCons.Warnings.warn(SCons.Warnings.FortranCxxMixWarning,
+ msg % env.subst('$CXX'))
+ issued_mixed_link_warning = True
+ return '$CXX'
+ elif has_d:
+ env['LINKCOM'] = env['DLINKCOM']
+ env['SHLINKCOM'] = env['SHDLINKCOM']
+ return '$DC'
+ elif has_fortran:
+ return '$FORTRAN'
+ elif has_cplusplus:
+ return '$CXX'
+ return '$CC'
+
+
+def _lib_emitter(target, source, env, **kw):
+ Verbose = False
+ if Verbose:
+ print("_lib_emitter: target[0]={!r}".format(target[0].get_path()))
+ for tgt in target:
+ if SCons.Util.is_String(tgt):
+ tgt = env.File(tgt)
+ tgt.attributes.shared = 1
+
+ try:
+ symlink_generator = kw['symlink_generator']
+ except KeyError:
+ pass
+ else:
+ if Verbose:
+ print("_lib_emitter: symlink_generator={!r}".format(symlink_generator))
+ symlinks = symlink_generator(env, target[0])
+ if Verbose:
+ print("_lib_emitter: symlinks={!r}".format(symlinks))
+
+ if symlinks:
+ 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=ShLibSymlinkGenerator)
+
+
+def ldmod_emitter(target, source, env):
+ return _lib_emitter(target, source, env, symlink_generator=LdModSymlinkGenerator)
+
+
+def _versioned_lib_name(env, libnode, version, prefix, suffix, prefix_generator, suffix_generator, **kw):
+ """For libnode='/optional/dir/libfoo.so.X.Y.Z' it returns 'libfoo.so'"""
+ Verbose = False
+
+ if Verbose:
+ print("_versioned_lib_name: libnode={!r}".format(libnode.get_path()))
+ print("_versioned_lib_name: version={!r}".format(version))
+ print("_versioned_lib_name: prefix={!r}".format(prefix))
+ print("_versioned_lib_name: suffix={!r}".format(suffix))
+ print("_versioned_lib_name: suffix_generator={!r}".format(suffix_generator))
+
+ versioned_name = os.path.basename(libnode.get_path())
+ if Verbose:
+ print("_versioned_lib_name: versioned_name={!r}".format(versioned_name))
+
+ versioned_prefix = prefix_generator(env, **kw)
+ versioned_suffix = suffix_generator(env, **kw)
+ if Verbose:
+ print("_versioned_lib_name: versioned_prefix={!r}".format(versioned_prefix))
+ print("_versioned_lib_name: versioned_suffix={!r}".format(versioned_suffix))
+
+ versioned_prefix_re = '^' + re.escape(versioned_prefix)
+ versioned_suffix_re = re.escape(versioned_suffix) + '$'
+ name = re.sub(versioned_prefix_re, prefix, versioned_name)
+ name = re.sub(versioned_suffix_re, suffix, name)
+ if Verbose:
+ print("_versioned_lib_name: name={!r}".format(name))
+ return name
+
+
+def _versioned_shlib_name(env, libnode, version, prefix, suffix, **kw):
+ 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 = LdModPrefixGenerator
+ suffix_generator = LdModSuffixGenerator
+ return _versioned_lib_name(env, libnode, version, prefix, suffix, prefix_generator, suffix_generator, **kw)
+
+
+def _versioned_lib_suffix(env, suffix, version):
+ """For suffix='.so' and version='0.1.2' it returns '.so.0.1.2'"""
+ Verbose = False
+ if Verbose:
+ print("_versioned_lib_suffix: suffix={!r}".format(suffix))
+ print("_versioned_lib_suffix: version={!r}".format(version))
+ if not suffix.endswith(version):
+ suffix = suffix + '.' + version
+ if Verbose:
+ print("_versioned_lib_suffix: return suffix={!r}".format(suffix))
+ return suffix
+
+
+def _versioned_lib_soname(env, libnode, version, prefix, suffix, name_func):
+ """For libnode='/optional/dir/libfoo.so.X.Y.Z' it returns 'libfoo.so.X'"""
+ Verbose = False
+ if Verbose:
+ print("_versioned_lib_soname: version={!r}".format(version))
+ name = name_func(env, libnode, version, prefix, suffix)
+ if Verbose:
+ print("_versioned_lib_soname: name={!r}".format(name))
+ major = version.split('.')[0]
+
+ # if a desired SONAME was supplied, use that, otherwise create
+ # a default from the major version
+ if env.get('SONAME'):
+ soname = ShLibSonameGenerator(env, libnode)
+ else:
+ soname = name + '.' + major
+ if Verbose:
+ print("_versioned_lib_soname: soname={!r}".format(soname))
+ return soname
+
+
+def _versioned_shlib_soname(env, libnode, version, prefix, suffix):
+ return _versioned_lib_soname(env, libnode, version, prefix, suffix, _versioned_shlib_name)
+
+
+def _versioned_ldmod_soname(env, libnode, version, prefix, suffix):
+ return _versioned_lib_soname(env, libnode, version, prefix, suffix, _versioned_ldmod_name)
+
+
+def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, soname_func):
+ """Generate link names that should be created for a versioned shared library.
+ Returns a dictionary in the form { linkname : linktarget }
+ """
+ Verbose = False
+
+ if Verbose:
+ print("_versioned_lib_symlinks: libnode={!r}".format(libnode.get_path()))
+ print("_versioned_lib_symlinks: version={!r}".format(version))
+
+ if sys.platform.startswith('openbsd'):
+ # OpenBSD uses x.y shared library versioning numbering convention
+ # and doesn't use symlinks to backwards-compatible libraries
+ if Verbose:
+ print("_versioned_lib_symlinks: return symlinks={!r}".format(None))
+ return None
+
+ linkdir = libnode.get_dir()
+ if Verbose:
+ print("_versioned_lib_symlinks: linkdir={!r}".format(linkdir.get_path()))
+
+ name = name_func(env, libnode, version, prefix, suffix)
+ if Verbose:
+ print("_versioned_lib_symlinks: name={!r}".format(name))
+
+ soname = soname_func(env, libnode, version, prefix, suffix)
+ if Verbose:
+ print("_versioned_lib_symlinks: soname={!r}".format(soname))
+
+ link0 = env.fs.File(soname, linkdir)
+ link1 = env.fs.File(name, linkdir)
+
+ # We create direct symlinks, not daisy-chained.
+ if link0 == libnode:
+ # This enables SHLIBVERSION without periods (e.g. SHLIBVERSION=1)
+ symlinks = [(link1, libnode)]
+ else:
+ # This handles usual SHLIBVERSION, i.e. '1.2', '1.2.3', etc.
+ symlinks = [(link0, libnode), (link1, libnode)]
+
+ if Verbose:
+ print("_versioned_lib_symlinks: return symlinks={!r}".format(
+ StringizeLibSymlinks(symlinks)))
+
+ return symlinks
+
+
+def _versioned_shlib_symlinks(env, libnode, version, prefix, suffix):
+ name_func = env['LINKCALLBACKS']['VersionedShLibName']
+ soname_func = env['LINKCALLBACKS']['VersionedShLibSoname']
+
+ return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, soname_func)
+
+
+def _versioned_ldmod_symlinks(env, libnode, version, prefix, suffix):
+ name_func = _versioned_ldmod_name
+ soname_func = _versioned_ldmod_soname
+
+ name_func = env['LINKCALLBACKS']['VersionedLdModName']
+ soname_func = env['LINKCALLBACKS']['VersionedLdModSoname']
+
+ return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, soname_func)
+
+
+def _versioned_lib_callbacks():
+ return {
+ 'VersionedShLibSuffix': _versioned_lib_suffix,
+ 'VersionedLdModSuffix': _versioned_lib_suffix,
+ 'VersionedShLibSymlinks': _versioned_shlib_symlinks,
+ 'VersionedLdModSymlinks': _versioned_ldmod_symlinks,
+ 'VersionedShLibName': _versioned_shlib_name,
+ 'VersionedLdModName': _versioned_ldmod_name,
+ 'VersionedShLibSoname': _versioned_shlib_soname,
+ 'VersionedLdModSoname': _versioned_ldmod_soname,
+ }.copy()
+
+
+issued_mixed_link_warning = False
+
+
+def _setup_versioned_lib_variables(env, **kw):
+ """
+ Setup all variables required by the versioning machinery
+ """
+
+ tool = None
+ try:
+ tool = kw['tool']
+ except KeyError:
+ pass
+
+ use_soname = False
+ try:
+ use_soname = kw['use_soname']
+ except KeyError:
+ pass
+
+ # The $_SHLIBVERSIONFLAGS define extra commandline flags used when
+ # building VERSIONED shared libraries. It's always set, but used only
+ # when VERSIONED library is built (see __SHLIBVERSIONFLAGS in SCons/Defaults.py).
+ if use_soname:
+ # If the linker uses SONAME, then we need this little automata
+ env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -Wl,-soname=$_SHLIBSONAME'
+ env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -Wl,-soname=$_LDMODULESONAME'
+ env['_SHLIBSONAME'] = '${ShLibSonameGenerator(__env__,TARGET)}'
+ env['_LDMODULESONAME'] = '${LdModSonameGenerator(__env__,TARGET)}'
+ env['ShLibSonameGenerator'] = ShLibSonameGenerator
+ env['LdModSonameGenerator'] = LdModSonameGenerator
+ else:
+ env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS'
+ env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS'
+
+ # LDOMDULVERSIONFLAGS should always default to $SHLIBVERSIONFLAGS
+ env['LDMODULEVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS' \ No newline at end of file
diff --git a/SCons/Tool/mslink.py b/SCons/Tool/mslink.py
index bab78d8..8fd7922 100644
--- a/SCons/Tool/mslink.py
+++ b/SCons/Tool/mslink.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 os
import os.path
diff --git a/SCons/Tool/sgilink.py b/SCons/Tool/sgilink.py
index b1e7921..e92c7b9 100644
--- a/SCons/Tool/sgilink.py
+++ b/SCons/Tool/sgilink.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
@@ -31,7 +29,6 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import SCons.Util
diff --git a/SCons/Tool/sunlink.py b/SCons/Tool/sunlink.py
index 39d9ec2..f668903 100644
--- a/SCons/Tool/sunlink.py
+++ b/SCons/Tool/sunlink.py
@@ -8,8 +8,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,11 +28,9 @@ selection method.
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
-
-import os
import os.path
+import SCons.Tool.linkCommon as linkCommon
import SCons.Util
from . import link
@@ -67,8 +63,12 @@ def generate(env):
env['_RPATH'] = '${_concat(RPATHPREFIX, RPATH, RPATHSUFFIX, __env__)}'
# Support for versioned libraries
- link._setup_versioned_lib_variables(env, tool = 'sunlink', use_soname = True)
- env['LINKCALLBACKS'] = link._versioned_lib_callbacks()
+ linkCommon._setup_versioned_lib_variables(env, tool='sunlink', use_soname=True)
+
+ env['_SHLIBVERSIONFLAGS'] = '$SHLIBVERSIONFLAGS -h $_SHLIBSONAME'
+ env['_LDMODULEVERSIONFLAGS'] = '$LDMODULEVERSIONFLAGS -h $_LDMODULESONAME'
+
+ env['LINKCALLBACKS'] = linkCommon._versioned_lib_callbacks()
def exists(env):
return ccLinker
diff --git a/test/LINK/SHLIBVERSIONFLAGS.py b/test/LINK/SHLIBVERSIONFLAGS.py
index d2e271c..7bcabf0 100644
--- a/test/LINK/SHLIBVERSIONFLAGS.py
+++ b/test/LINK/SHLIBVERSIONFLAGS.py
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
-# __COPYRIGHT__
+# MIT License
+#
+# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -22,7 +24,6 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
-__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import TestSCons
@@ -67,15 +68,35 @@ test.write('SConstruct', "SharedLibrary('foo','foo.c',SHLIBVERSION='1.2.3')\n")
test.run(stdout = versionflags, match = TestSCons.match_re_dotall)
test.run(arguments = ['-c'])
-# stdout must contain SHLIBVERSIONFLAGS if there is SHLIBVERSION provided
+# stdout must contain SONAME if there is SONAME provided
test = TestSCons.TestSCons()
test.write('foo.c', foo_c_src)
test.write('SConstruct', """
SharedLibrary('foo','foo.c',SHLIBVERSION='1.2.3',SONAME='%s')
""" % soname)
test.run(stdout = sonameVersionFlags, match = TestSCons.match_re_dotall)
+test.must_exist(test.workpath(soname))
test.run(arguments = ['-c'])
+# stdout must contain SOVERSION if there is SOVERSION provided
+test = TestSCons.TestSCons()
+test.write('foo.c', foo_c_src)
+test.write('SConstruct', """
+SharedLibrary('foo','foo.c',SHLIBVERSION='1.2.3',SOVERSION='4')
+""")
+test.run(stdout = sonameVersionFlags, match = TestSCons.match_re_dotall)
+test.must_exist(test.workpath(soname))
+test.run(arguments = ['-c'])
+
+# test if both SONAME and SOVERSION are used
+test = TestSCons.TestSCons()
+test.write('foo.c', foo_c_src)
+test.write('SConstruct', """
+SharedLibrary('foo','foo.c',SHLIBVERSION='1.2.3',SONAME='%s',SOVERSION='4')
+""" % soname)
+test.run(status=2,stderr=None)
+test.must_contain_all_lines(test.stderr(), ['Ambiguous library .so naming'])
+
test.pass_test()
# Local Variables: