From 5b317c5658f5865aea76b5a5afda2cdc8bd50959 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Fri, 1 Sep 2023 17:23:29 -0400 Subject: [PATCH] compilers: use correct version comparison for openbsd libraries It should *be* a version comparison. We are guaranteed to get a two-element version number, which also parses as a float but a float doesn't correctly handle version sorting when the second component differs in number of digits. The standard way to handle this is by comparing tuples such that each component is an integer. Do so here. Fixes #12195 Co-authored-by: George Koehler (for unittests) --- mesonbuild/compilers/mixins/clike.py | 9 ++++++--- unittests/internaltests.py | 5 ++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 61e671921e6a..38af08c42c26 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -1084,6 +1084,10 @@ def get_library_naming(self, env: 'Environment', libtype: LibType, strict: bool @staticmethod def _sort_shlibs_openbsd(libs: T.List[str]) -> T.List[str]: + def tuple_key(x: str) -> T.Tuple[int, ...]: + ver = x.rsplit('.so.', maxsplit=1)[1] + return tuple(int(i) for i in ver.split('.')) + filtered: T.List[str] = [] for lib in libs: # Validate file as a shared library of type libfoo.so.X.Y @@ -1091,12 +1095,11 @@ def _sort_shlibs_openbsd(libs: T.List[str]) -> T.List[str]: if len(ret) != 2: continue try: - float(ret[1]) + tuple(int(i) for i in ret[1].split('.')) except ValueError: continue filtered.append(lib) - float_cmp = lambda x: float(x.rsplit('.so.', maxsplit=1)[1]) - return sorted(filtered, key=float_cmp, reverse=True) + return sorted(filtered, key=tuple_key, reverse=True) @classmethod def _get_trials_from_pattern(cls, pattern: str, directory: str, libname: str) -> T.List[Path]: diff --git a/unittests/internaltests.py b/unittests/internaltests.py index 56d36117a454..eb3b1717a66b 100644 --- a/unittests/internaltests.py +++ b/unittests/internaltests.py @@ -549,11 +549,14 @@ def _test_all_naming(self, cc, env, patterns, platform): if platform != 'openbsd': return with tempfile.TemporaryDirectory() as tmpdir: - for i in ['libfoo.so.6.0', 'libfoo.so.5.0', 'libfoo.so.54.0', 'libfoo.so.66a.0b', 'libfoo.so.70.0.so.1']: + for i in ['libfoo.so.6.0', 'libfoo.so.5.0', 'libfoo.so.54.0', 'libfoo.so.66a.0b', 'libfoo.so.70.0.so.1', + 'libbar.so.7.10', 'libbar.so.7.9', 'libbar.so.7.9.3']: libpath = Path(tmpdir) / i libpath.write_text('', encoding='utf-8') found = cc._find_library_real('foo', env, [tmpdir], '', LibType.PREFER_SHARED, lib_prefix_warning=True) self.assertEqual(os.path.basename(found[0]), 'libfoo.so.54.0') + found = cc._find_library_real('bar', env, [tmpdir], '', LibType.PREFER_SHARED, lib_prefix_warning=True) + self.assertEqual(os.path.basename(found[0]), 'libbar.so.7.10') def test_find_library_patterns(self): '''