diff options
author | William Deegan <bill@baddogconsulting.com> | 2018-12-04 22:33:28 (GMT) |
---|---|---|
committer | William Deegan <bill@baddogconsulting.com> | 2018-12-04 22:33:28 (GMT) |
commit | 2b978d126393723def974e48fec0f7fffcd5743e (patch) | |
tree | aa1f53e9b0e45491e0523e6c266902b9ed7b7e54 /src | |
parent | 666368d25da2c4339f5e7143eb0678b41ce95f87 (diff) | |
download | SCons-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.py | 82 | ||||
-rw-r--r-- | src/engine/SCons/Tool/link.py | 35 |
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) |