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 <xkernigh@netscape.net>
(for unittests)
pull/12210/head
Eli Schwartz 1 year ago
parent fb6fd5aa17
commit 5b317c5658
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
  1. 9
      mesonbuild/compilers/mixins/clike.py
  2. 5
      unittests/internaltests.py

@ -1084,6 +1084,10 @@ class CLikeCompiler(Compiler):
@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 @@ class CLikeCompiler(Compiler):
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]:

@ -549,11 +549,14 @@ class InternalTests(unittest.TestCase):
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):
'''

Loading…
Cancel
Save