diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2016-12-02 23:57:19 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-02 23:57:19 +0200 |
commit | 3276bdd23d0479eb343b95e80ac0d87475bb3a7e (patch) | |
tree | aec07111dda4960f3db83ba4eef06531ac941277 | |
parent | e933bdd87229f13766705274a8815e9f10d4fe8d (diff) | |
parent | 07d7e87411ca411682344c945c006fd61fa7ab98 (diff) | |
download | meson-3276bdd23d0479eb343b95e80ac0d87475bb3a7e.zip meson-3276bdd23d0479eb343b95e80ac0d87475bb3a7e.tar.gz meson-3276bdd23d0479eb343b95e80ac0d87475bb3a7e.tar.bz2 |
Merge pull request #1102 from mesonbuild/soname
Fix soname symlink generation
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 11 | ||||
-rw-r--r-- | mesonbuild/build.py | 6 | ||||
-rwxr-xr-x | run_unittests.py | 51 | ||||
-rw-r--r-- | test cases/unit/1 soname/CMakeLists.txt | 26 | ||||
-rw-r--r-- | test cases/unit/1 soname/meson.build | 18 | ||||
-rw-r--r-- | test cases/unit/1 soname/versioned.c | 3 |
6 files changed, 109 insertions, 6 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 659a53d..bd65cbe 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2004,14 +2004,21 @@ rule FORTRAN_DEP_HACK def generate_shlib_aliases(self, target, outdir): basename = target.get_filename() aliases = target.get_aliaslist() - for alias in aliases: + for i, alias in enumerate(aliases): aliasfile = os.path.join(self.environment.get_build_dir(), outdir, alias) try: os.remove(aliasfile) except Exception: pass + # If both soversion and version are set and to different values, + # the .so symlink must point to the soversion symlink rather than the + # original file. + if i == 0 and len(aliases) > 1: + pointed_to_filename = aliases[1] + else: + pointed_to_filename = basename try: - os.symlink(basename, aliasfile) + os.symlink(pointed_to_filename, aliasfile) except NotImplementedError: mlog.debug("Library versioning disabled because symlinks are not supported.") except OSError: diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 39e215f..462a55b 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1069,12 +1069,10 @@ class SharedLibrary(BuildTarget): self.soversion = str(self.soversion) if not isinstance(self.soversion, str): raise InvalidArguments('Shared library soversion is not a string or integer.') - try: - int(self.soversion) - except ValueError: - raise InvalidArguments('Shared library soversion must be a valid integer') elif self.ltversion: # library version is defined, get the soversion from that + # We replicate what Autotools does here and take the first + # number of the version by default. self.soversion = self.ltversion.split('.')[0] # Visual Studio module-definitions file if 'vs_module_defs' in kwargs: diff --git a/run_unittests.py b/run_unittests.py index 39e93c9..8b1f13f 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -17,6 +17,7 @@ import unittest, os, sys, shutil, time import subprocess import re, json import tempfile +from glob import glob import mesonbuild.environment from mesonbuild.environment import detect_ninja from mesonbuild.dependencies import PkgConfigDependency, Qt5Dependency @@ -52,6 +53,7 @@ class LinuxlikeTests(unittest.TestCase): def setUp(self): super().setUp() src_root = os.path.dirname(__file__) + src_root = os.path.join(os.getcwd(), src_root) self.builddir = tempfile.mkdtemp() self.meson_command = [sys.executable, os.path.join(src_root, 'meson.py')] self.mconf_command = [sys.executable, os.path.join(src_root, 'mesonconf.py')] @@ -60,6 +62,7 @@ class LinuxlikeTests(unittest.TestCase): self.common_test_dir = os.path.join(src_root, 'test cases/common') self.vala_test_dir = os.path.join(src_root, 'test cases/vala') self.framework_test_dir = os.path.join(src_root, 'test cases/frameworks') + self.unit_test_dir = os.path.join(src_root, 'test cases/unit') self.output = b'' self.orig_env = os.environ.copy() @@ -211,5 +214,53 @@ class LinuxlikeTests(unittest.TestCase): mesonlog = self.get_meson_log() self.assertTrue(msg in mesonlog or msg2 in mesonlog) + def get_soname(self, fname): + output = subprocess.check_output(['readelf', '-a', fname]) + for line in output.decode('utf-8', errors='ignore').split('\n'): + if 'SONAME' in line: + return line.split('[')[1].split(']')[0] + raise RuntimeError('Readelf gave no SONAME.') + + def test_soname(self): + testdir = os.path.join(self.unit_test_dir, '1 soname') + self.init(testdir) + self.build() + + # File without aliases set. + nover = os.path.join(self.builddir, 'libnover.so') + self.assertTrue(os.path.exists(nover)) + self.assertFalse(os.path.islink(nover)) + self.assertEqual(self.get_soname(nover), 'libnover.so') + self.assertEqual(len(glob(nover[:-3] + '*')), 1) + + # File with version set + verset = os.path.join(self.builddir, 'libverset.so') + self.assertTrue(os.path.exists(verset + '.4.5.6')) + self.assertEqual(os.readlink(verset), 'libverset.so.4') + self.assertEqual(self.get_soname(verset), 'libverset.so.4') + self.assertEqual(len(glob(verset[:-3] + '*')), 3) + + # File with soversion set + soverset = os.path.join(self.builddir, 'libsoverset.so') + self.assertTrue(os.path.exists(soverset + '.1.2.3')) + self.assertEqual(os.readlink(soverset), 'libsoverset.so.1.2.3') + self.assertEqual(self.get_soname(soverset), 'libsoverset.so.1.2.3') + self.assertEqual(len(glob(soverset[:-3] + '*')), 2) + + # File with version and soversion set to same values + settosame = os.path.join(self.builddir, 'libsettosame.so') + self.assertTrue(os.path.exists(settosame + '.7.8.9')) + self.assertEqual(os.readlink(settosame), 'libsettosame.so.7.8.9') + self.assertEqual(self.get_soname(settosame), 'libsettosame.so.7.8.9') + self.assertEqual(len(glob(settosame[:-3] + '*')), 2) + + # File with version and soversion set to different values + bothset = os.path.join(self.builddir, 'libbothset.so') + self.assertTrue(os.path.exists(bothset + '.1.2.3')) + self.assertEqual(os.readlink(bothset), 'libbothset.so.1.2.3') + self.assertEqual(os.readlink(bothset + '.1.2.3'), 'libbothset.so.4.5.6') + self.assertEqual(self.get_soname(bothset), 'libbothset.so.1.2.3') + self.assertEqual(len(glob(bothset[:-3] + '*')), 3) + if __name__ == '__main__': unittest.main() diff --git a/test cases/unit/1 soname/CMakeLists.txt b/test cases/unit/1 soname/CMakeLists.txt new file mode 100644 index 0000000..c4f2e3e --- /dev/null +++ b/test cases/unit/1 soname/CMakeLists.txt @@ -0,0 +1,26 @@ +# This is a CMake version of this test. It behaves slightly differently +# so in case you ever need to debug this, here it is. +# +# The biggest difference is that if SOVERSION is not set, it +# is set to VERSION. Autotools sets it to the first number +# of VERSION. That is, for version number 1.2.3 CMake sets +# soname to 1.2.3 but Autotools sets it to 1. + +project(vertest C) +cmake_minimum_required(VERSION 3.5) + +add_library(nover SHARED versioned.c) + +add_library(verset SHARED versioned.c) +set_target_properties(verset PROPERTIES VERSION 4.5.6) + +add_library(soverset SHARED versioned.c) +set_target_properties(soverset PROPERTIES SOVERSION 1.2.3) + +add_library(bothset SHARED versioned.c) +set_target_properties(bothset PROPERTIES SOVERSION 1.2.3) +set_target_properties(bothset PROPERTIES VERSION 4.5.6) + +add_library(settosame SHARED versioned.c) +set_target_properties(settosame PROPERTIES SOVERSION 7.8.9) +set_target_properties(settosame PROPERTIES VERSION 7.8.9) diff --git a/test cases/unit/1 soname/meson.build b/test cases/unit/1 soname/meson.build new file mode 100644 index 0000000..d956afe --- /dev/null +++ b/test cases/unit/1 soname/meson.build @@ -0,0 +1,18 @@ +project('vertest', 'c') + +shared_library('nover', 'versioned.c') + +shared_library('verset', 'versioned.c', + version : '4.5.6') + +shared_library('soverset', 'versioned.c', + soversion : '1.2.3') + +shared_library('bothset', 'versioned.c', + soversion : '1.2.3', + version : '4.5.6') + +shared_library('settosame', 'versioned.c', + soversion : '7.8.9', + version : '7.8.9') + diff --git a/test cases/unit/1 soname/versioned.c b/test cases/unit/1 soname/versioned.c new file mode 100644 index 0000000..f48d2b0 --- /dev/null +++ b/test cases/unit/1 soname/versioned.c @@ -0,0 +1,3 @@ +int versioned_func() { + return 0; +} |