summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWilliam Deegan <bill@baddogconsulting.com>2018-12-04 22:33:28 (GMT)
committerWilliam Deegan <bill@baddogconsulting.com>2018-12-04 22:33:28 (GMT)
commit2b978d126393723def974e48fec0f7fffcd5743e (patch)
treeaa1f53e9b0e45491e0523e6c266902b9ed7b7e54 /src
parent666368d25da2c4339f5e7143eb0678b41ce95f87 (diff)
downloadSCons-2b978d126393723def974e48fec0f7fffcd5743e.zip
SCons-2b978d126393723def974e48fec0f7fffcd5743e.tar.gz
SCons-2b978d126393723def974e48fec0f7fffcd5743e.tar.bz2
Initial checkin of functional versioned shared libraries for applelink. Not loadable modules don't get versions embedded in the generated file
Diffstat (limited to 'src')
-rw-r--r--src/engine/SCons/Tool/applelink.py82
-rw-r--r--src/engine/SCons/Tool/link.py35
2 files changed, 97 insertions, 20 deletions
diff --git a/src/engine/SCons/Tool/applelink.py b/src/engine/SCons/Tool/applelink.py
index 5a06f9c..4a87a07 100644
--- a/src/engine/SCons/Tool/applelink.py
+++ b/src/engine/SCons/Tool/applelink.py
@@ -1,6 +1,6 @@
"""SCons.Tool.applelink
-Tool-specific initialization for the Apple gnu-like linker.
+Tool-specific initialization for the Apple's gnu-like linker.
There normally shouldn't be any need to import this module directly.
It will usually be imported through the generic SCons.Tool.Tool()
@@ -40,6 +40,73 @@ import SCons.Util
from . import link
+
+def _applelib_versioned_lib_suffix(env, suffix, version):
+ """For suffix='.dylib' and version='0.1.2' it returns '.0.1.2.dylib'"""
+ Verbose = False
+ if Verbose:
+ print("_applelib_versioned_lib_suffix: suffix={:r}".format(suffix))
+ print("_applelib_versioned_lib_suffix: version={:r}".format(version))
+ if not version in suffix:
+ suffix = "." + version + suffix
+ if Verbose:
+ print("_applelib_versioned_lib_suffix: return suffix={:r}".format(suffix))
+ return suffix
+
+
+def _applelib_versioned_lib_soname(env, libnode, version, prefix, suffix, name_func):
+ """For libnode='/optional/dir/libfoo.X.Y.Z.dylib' it returns 'libfoo.X.dylib'"""
+ Verbose = False
+ if Verbose:
+ print("_applelib_versioned_lib_soname: version={!r}".format(version))
+ name = name_func(env, libnode, version, prefix, suffix)
+ if Verbose:
+ print("_applelib_versioned_lib_soname: name={!r}".format(name))
+ major = version.split('.')[0]
+ (libname,_suffix) = name.split('.')
+ soname = '.'.join([libname, major, _suffix])
+ if Verbose:
+ 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.
+
+def _applelib_currentVersionFromSoVersion(source, target, env, for_signature):
+ """
+ -Wl,current_version=2.3
+ """
+
+ if env.get('APPLELINK_CURRENT_VERSION', False):
+ version_string = env['SHLIBVERSION']
+ elif env.get('SHLIBVERSION', False):
+ version_string = env['SHLIBVERSION']
+ else:
+ return ""
+
+ version_string = ".".join(version_string.split('.')[:3])
+
+ return "-Wl,-current_version,%s" % version_string
+
+
+def _applelib_compatVersionFromSoVersion(source, target, env, for_signature):
+ """
+ -Wl,compat_version=2.0
+ """
+
+ if env.get('APPLELINK_COMPAT_VERSION', False):
+ version_string = env['SHLIBVERSION']
+ elif env.get('SHLIBVERSION', False):
+ version_string = ".".join(env['SHLIBVERSION'].split('.')[:2] + ['0'])
+ else:
+ return ""
+
+ return "-Wl,-compatibility_version,%s" % version_string
+
+
def generate(env):
"""Add Builders and construction variables for applelink to an
Environment."""
@@ -57,9 +124,18 @@ def generate(env):
# TODO: Work needed to generate versioned shared libraries
# Leaving this commented out, and also going to disable versioned library checking for now
# see: http://docstore.mik.ua/orelly/unix3/mac/ch05_04.htm for proper naming
- #link._setup_versioned_lib_variables(env, tool = 'applelink')#, use_soname = use_soname)
- #env['LINKCALLBACKS'] = link._versioned_lib_callbacks()
+ link._setup_versioned_lib_variables(env, tool = 'applelink')#, use_soname = use_soname)
+ env['LINKCALLBACKS'] = link._versioned_lib_callbacks()
+
+ # 'VersionedShLibSuffix': _versioned_lib_suffix,
+ env['LINKCALLBACKS']['VersionedShLibSuffix'] = _applelib_versioned_lib_suffix
+ env['LINKCALLBACKS']['VersionedShLibSoname'] = _applelib_versioned_shlib_soname
+
+ env['APPLELINK_CURRENT_VERSION'] = _applelib_currentVersionFromSoVersion
+ env['APPLELINK_COMPATIBILITY_VERSION'] = _applelib_compatVersionFromSoVersion
+ env['_SHLIBVERSIONFLAGS'] = '$APPLELINK_CURRENT_VERSION $APPLELINK_COMPATIBILITY_VERSION '
+ env['_LDMODULEVERSIONFLAGS'] = '$APPLELINK_CURRENT_VERSION $APPLELINK_COMPATIBILITY_VERSION '
# override the default for loadable modules, which are different
# on OS X than dynamic shared libs. echoing what XCode does for
diff --git a/src/engine/SCons/Tool/link.py b/src/engine/SCons/Tool/link.py
index a55688c..5adc6ca 100644
--- a/src/engine/SCons/Tool/link.py
+++ b/src/engine/SCons/Tool/link.py
@@ -46,15 +46,13 @@ from SCons.Tool.FortranCommon import isfortran
from SCons.Tool.DCommon import isD
-import SCons.Tool.cxx
-
-cplusplus = SCons.Tool.cxx
+from SCons.Tool.cxx import iscplusplus
issued_mixed_link_warning = False
def smart_link(source, target, env, for_signature):
- has_cplusplus = cplusplus.iscplusplus(source)
+ has_cplusplus = iscplusplus(source)
has_fortran = isfortran(env, source)
has_d = isD(env, source)
if has_cplusplus and has_fortran and not has_d:
@@ -113,7 +111,7 @@ def ldmod_emitter(target, source, env):
# 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 = True
+ Verbose = False
if Verbose:
print("_versioned_lib_name: libnode={!r}".format(libnode.get_path()))
@@ -142,15 +140,15 @@ def _versioned_lib_name(env, libnode, version, prefix, suffix, prefix_generator,
def _versioned_shlib_name(env, libnode, version, prefix, suffix, **kw):
- pg = SCons.Tool.ShLibPrefixGenerator
- sg = SCons.Tool.ShLibSuffixGenerator
- return _versioned_lib_name(env, libnode, version, prefix, suffix, pg, sg, **kw)
+ prefix_generator = SCons.Tool.ShLibPrefixGenerator
+ suffix_generator = SCons.Tool.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):
- pg = SCons.Tool.LdModPrefixGenerator
- sg = SCons.Tool.LdModSuffixGenerator
- return _versioned_lib_name(env, libnode, version, prefix, suffix, pg, sg, **kw)
+ prefix_generator = SCons.Tool.LdModPrefixGenerator
+ suffix_generator = SCons.Tool.LdModSuffixGenerator
+ return _versioned_lib_name(env, libnode, version, prefix, suffix, prefix_generator, suffix_generator, **kw)
def _versioned_lib_suffix(env, suffix, version):
@@ -193,7 +191,7 @@ def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, so
"""Generate link names that should be created for a versioned shared library.
Returns a dictionary in the form { linkname : linktarget }
"""
- Verbose = True
+ Verbose = False
if Verbose:
print("_versioned_lib_symlinks: libnode={!r}".format(libnode.get_path()))
@@ -215,6 +213,8 @@ def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, so
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)
@@ -234,11 +234,8 @@ def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, so
def _versioned_shlib_symlinks(env, libnode, version, prefix, suffix):
- name_func = _versioned_shlib_name
- soname_func = _versioned_shlib_soname
-
- # nf = env['LINKCALLBACKS']['VersionedShLibName']
- # sf = env['LINKCALLBACKS']['VersionedShLibSoname']
+ name_func = env['LINKCALLBACKS']['VersionedShLibName']
+ soname_func = env['LINKCALLBACKS']['VersionedShLibSoname']
return _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, soname_func)
@@ -246,6 +243,10 @@ def _versioned_shlib_symlinks(env, libnode, version, prefix, suffix):
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)