From 12be9a52ca6377df81ec742e065e1ec0db6ac06a Mon Sep 17 00:00:00 2001
From: Ray Donnelly <mingw.android@gmail.com>
Date: Tue, 5 Dec 2017 22:47:59 +0000
Subject: [PATCH 12/19] 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 c158e672f0..a4770ecf5c 100644
--- a/Lib/ctypes/macholib/dyld.py
+++ b/Lib/ctypes/macholib/dyld.py
@@ -88,6 +88,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 97973bce00..1340ad7c25 100644
--- a/Lib/ctypes/util.py
+++ b/Lib/ctypes/util.py
@@ -70,7 +70,8 @@ if os.name == "nt":
 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:
@@ -306,10 +307,30 @@ elif os.name == "posix":
                 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 _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 _findLib_ld(name))
+            else:
+                 return _findLib_prefix(name) or \
+                        _findSoname_ldconfig(name) or \
+                        _get_soname(_findLib_gcc(name) or _findLib_ld(name))
 
 ################################################################
 # test code
-- 
2.20.1

