Change with shared library compatibility version handling

For ELF binaries (e.g., Linux): default compatible version (SONAME =
`<library-name>.so.<MAJOR>`) can be specialized using additional `cnum`
parameter to `<library-name>.so.<MAJOR>.<MINOR>` or
`<library-name>.so.<MAJOR>.<MINOR>.<PATCH>`.

For Mach-O binaries (e.g., OS X):

- (bugfix) install-name points to compatible version (not absolute path
  to a non-versioned library)
- Default install-name `<install-path>/<library-name>.<MAJOR>.dylib` can
  be specialized using `cnum` parameter to
  `<install-path>/<library-name>.<MAJOR>.<MINOR>.dylib` or
  `<install-path>/<library-name>.<MAJOR>.<MINOR>.<PATCH>.dylib`
- `-Wl,-compatibility_version` and `-Wl,-current_version` flags use
  version from cnum/vnum (default cnum is vnum.split('.')[0])
This commit is contained in:
Alexander Afanasyev 2015-06-05 17:10:11 -07:00
parent 92f584fd8f
commit 728205fe3c
5 changed files with 27 additions and 9 deletions

View File

@ -19,6 +19,8 @@ def configure(conf):
def build(bld):
bld.shlib(source='a.cpp', target='mylib', vnum='9.8.7')
bld.shlib(source='a.cpp', target='mylib2', vnum='9.8.7', cnum='9.8')
bld.shlib(source='a.cpp', target='mylib3')
bld.program(source='main.cpp', target='app', use='mylib')
bld.stlib(target='foo', source='b.cpp')

View File

@ -489,10 +489,19 @@ def apply_vnum(self):
def build(bld):
bld.shlib(source='a.c', target='foo', vnum='14.15.16')
In this example, ``libfoo.so`` is installed as ``libfoo.so.1.2.3``, and the following symbolic links are created:
In this example on Linux platform, ``libfoo.so`` is installed as ``libfoo.so.14.15.16``, and the following symbolic links are created:
* ``libfoo.so libfoo.so.1.2.3``
* ``libfoo.so.1 libfoo.so.1.2.3``
* ``libfoo.so libfoo.so.14.15.16``
* ``libfoo.so.14 libfoo.so.14.15.16``
By default, the library will be assigned SONAME ``libfoo.so.14``, effectively declaring ABI compatibility between all minor and patch releases for the major version of the library. When necessary, the compatibility can be explicitly defined using `cnum` parameter:
def build(bld):
bld.shlib(source='a.c', target='foo', vnum='14.15.16', cnum='14.15')
In this case, the assigned SONAME will be ``libfoo.so.14.15`` with ABI compatibility only between path releases for a specific major and minor version of the library.
On OS X platform, install-name parameter will follow the above logic for SONAME with exception that it also specifies an absolute path (based on install_path) of the library.
"""
if not getattr(self, 'vnum', '') or os.name != 'posix' or self.env.DEST_BINFMT not in ('elf', 'mac-o'):
return
@ -503,13 +512,18 @@ def apply_vnum(self):
nums = self.vnum.split('.')
node = link.outputs[0]
cnum = getattr(self, 'cnum', str(nums[0]))
cnums = cnum.split('.')
if len(cnums)>len(nums) or nums[0:len(cnums)] != cnums:
raise Errors.WafError('invalid compatibility version %s' % cnum)
libname = node.name
if libname.endswith('.dylib'):
name3 = libname.replace('.dylib', '.%s.dylib' % self.vnum)
name2 = libname.replace('.dylib', '.%s.dylib' % nums[0])
name2 = libname.replace('.dylib', '.%s.dylib' % cnum)
else:
name3 = libname + '.' + self.vnum
name2 = libname + '.' + nums[0]
name2 = libname + '.' + cnum
# add the so name for the ld linker - to disable, just unset env.SONAME_ST
if self.env.SONAME_ST:
@ -548,8 +562,10 @@ def apply_vnum(self):
inst_to = self.link_task.__class__.inst_to
if inst_to:
p = Utils.subst_vars(inst_to, self.env)
path = os.path.join(p, self.link_task.outputs[0].name)
path = os.path.join(p, name2)
self.env.append_value('LINKFLAGS', ['-install_name', path])
self.env.append_value('LINKFLAGS', '-Wl,-compatibility_version,%s' % cnum)
self.env.append_value('LINKFLAGS', '-Wl,-current_version,%s' % self.vnum)
class vnum(Task.Task):
"""

View File

@ -93,7 +93,7 @@ def fortran_modifier_darwin(conf):
"""
v = conf.env
v['FCFLAGS_fcshlib'] = ['-fPIC']
v['LINKFLAGS_fcshlib'] = ['-dynamiclib', '-Wl,-compatibility_version,1', '-Wl,-current_version,1']
v['LINKFLAGS_fcshlib'] = ['-dynamiclib']
v['fcshlib_PATTERN'] = 'lib%s.dylib'
v['FRAMEWORKPATH_ST'] = '-F%s'
v['FRAMEWORK_ST'] = '-framework %s'

View File

@ -97,7 +97,7 @@ def gcc_modifier_darwin(conf):
"""Configuration flags for executing gcc on MacOS"""
v = conf.env
v['CFLAGS_cshlib'] = ['-fPIC']
v['LINKFLAGS_cshlib'] = ['-dynamiclib', '-Wl,-compatibility_version,1', '-Wl,-current_version,1']
v['LINKFLAGS_cshlib'] = ['-dynamiclib']
v['cshlib_PATTERN'] = 'lib%s.dylib'
v['FRAMEWORKPATH_ST'] = '-F%s'
v['FRAMEWORK_ST'] = ['-framework']

View File

@ -97,7 +97,7 @@ def gxx_modifier_darwin(conf):
"""Configuration flags for executing g++ on MacOS"""
v = conf.env
v['CXXFLAGS_cxxshlib'] = ['-fPIC']
v['LINKFLAGS_cxxshlib'] = ['-dynamiclib', '-Wl,-compatibility_version,1', '-Wl,-current_version,1']
v['LINKFLAGS_cxxshlib'] = ['-dynamiclib']
v['cxxshlib_PATTERN'] = 'lib%s.dylib'
v['FRAMEWORKPATH_ST'] = '-F%s'
v['FRAMEWORK_ST'] = ['-framework']