From d0fbf86bbb4292032eb2f8c8a0f47579619f51d5 Mon Sep 17 00:00:00 2001 From: Ray Donnelly Date: Tue, 5 Dec 2017 22:47:59 +0000 Subject: [PATCH 07/25] Fix find_library so that it looks in sys.prefix/lib first --- Lib/ctypes/macholib/dyld.py | 4 ++++ Lib/ctypes/util.py | 27 ++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Lib/ctypes/macholib/dyld.py b/Lib/ctypes/macholib/dyld.py index 1c3f8fd38b..82a4b4fd58 100644 --- a/Lib/ctypes/macholib/dyld.py +++ b/Lib/ctypes/macholib/dyld.py @@ -93,6 +93,10 @@ def dyld_executable_path_search(name, executable_path=None): # If we haven't done any searching and found a library and the # dylib_name starts with "@executable_path/" then construct the # library name. + if not executable_path: + import sys + if sys.prefix: + executable_path = os.path.join(sys.prefix, 'bin') if name.startswith('@executable_path/') and executable_path is not None: yield os.path.join(executable_path, name[len('@executable_path/'):]) diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 0c2510e161..72b46cc481 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -70,7 +70,8 @@ def find_library(name): elif os.name == "posix" and sys.platform == "darwin": from ctypes.macholib.dyld import dyld_find as _dyld_find def find_library(name): - possible = ['lib%s.dylib' % name, + possible = ['@executable_path/../lib/lib%s.dylib' % name, + 'lib%s.dylib' % name, '%s.dylib' % name, '%s.framework/%s' % (name, name)] for name in possible: @@ -324,10 +325,30 @@ def _findLib_ld(name): pass # result will be None return result + def _findLib_prefix(name): + if not name: + return None + for fullname in (name, "lib%s.so" % (name)): + path = os.path.join(sys.prefix, 'lib', fullname) + if os.path.exists(path): + return path + return None + def find_library(name): # See issue #9998 - return _findSoname_ldconfig(name) or \ - _get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name)) + # Yes calling _findLib_prefix twice is deliberate, because _get_soname ditches + # the full path. + # When objdump is unavailable this returns None + so_name = _get_soname(_findLib_prefix(name)) or name + if so_name != name: + return _findLib_prefix(so_name) or \ + _findLib_prefix(name) or \ + _findSoname_ldconfig(name) or \ + _get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name)) + else: + return _findLib_prefix(name) or \ + _findSoname_ldconfig(name) or \ + _get_soname(_findLib_gcc(name)) or _get_soname(_findLib_ld(name)) ################################################################ # test code