Issue #21042: Return full path in ctypes.util.find_library() on Linux

Patch by Tamás Bence Gedai.
This commit is contained in:
Martin Panter 2016-03-10 01:06:23 +00:00
parent aadaa3614e
commit b9f3114d42
5 changed files with 37 additions and 22 deletions

View file

@ -1252,15 +1252,15 @@ The exact functionality is system dependent.
On Linux, :func:`find_library` tries to run external programs On Linux, :func:`find_library` tries to run external programs
(``/sbin/ldconfig``, ``gcc``, and ``objdump``) to find the library file. It (``/sbin/ldconfig``, ``gcc``, and ``objdump``) to find the library file. It
returns the filename of the library file. Here are some examples:: returns the absolute path of the library file. Here are some examples::
>>> from ctypes.util import find_library >>> from ctypes.util import find_library
>>> find_library("m") >>> find_library("m")
'libm.so.6' '/lib/x86_64-linux-gnu/libm.so.6'
>>> find_library("c") >>> find_library("c")
'libc.so.6' '/lib/x86_64-linux-gnu/libc.so.6'
>>> find_library("bz2") >>> find_library("bz2")
'libbz2.so.1.0' '/lib/x86_64-linux-gnu/libbz2.so.1.0'
>>> >>>
On OS X, :func:`find_library` tries several predefined naming schemes and paths On OS X, :func:`find_library` tries several predefined naming schemes and paths
@ -1829,6 +1829,9 @@ Utility functions
The exact functionality is system dependent. The exact functionality is system dependent.
.. versionchanged:: 3.6
On Linux it returns an absolute path.
.. function:: find_msvcrt() .. function:: find_msvcrt()
:module: ctypes.util :module: ctypes.util

View file

@ -9,39 +9,39 @@
class Test_OpenGL_libs(unittest.TestCase): class Test_OpenGL_libs(unittest.TestCase):
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
lib_gl = lib_glu = lib_gle = None cls.lib_gl = cls.lib_glu = cls.lib_gle = None
if sys.platform == "win32": if sys.platform == "win32":
lib_gl = find_library("OpenGL32") cls.lib_gl = find_library("OpenGL32")
lib_glu = find_library("Glu32") cls.lib_glu = find_library("Glu32")
elif sys.platform == "darwin": elif sys.platform == "darwin":
lib_gl = lib_glu = find_library("OpenGL") cls.lib_gl = cls.lib_glu = find_library("OpenGL")
else: else:
lib_gl = find_library("GL") cls.lib_gl = find_library("GL")
lib_glu = find_library("GLU") cls.lib_glu = find_library("GLU")
lib_gle = find_library("gle") cls.lib_gle = find_library("gle")
## print, for debugging ## print, for debugging
if test.support.verbose: if test.support.verbose:
print("OpenGL libraries:") print("OpenGL libraries:")
for item in (("GL", lib_gl), for item in (("GL", cls.lib_gl),
("GLU", lib_glu), ("GLU", cls.lib_glu),
("gle", lib_gle)): ("gle", cls.lib_gle)):
print("\t", item) print("\t", item)
cls.gl = cls.glu = cls.gle = None cls.gl = cls.glu = cls.gle = None
if lib_gl: if cls.lib_gl:
try: try:
cls.gl = CDLL(lib_gl, mode=RTLD_GLOBAL) cls.gl = CDLL(cls.lib_gl, mode=RTLD_GLOBAL)
except OSError: except OSError:
pass pass
if lib_glu: if cls.lib_glu:
try: try:
cls.glu = CDLL(lib_glu, RTLD_GLOBAL) cls.glu = CDLL(cls.lib_glu, RTLD_GLOBAL)
except OSError: except OSError:
pass pass
if lib_gle: if cls.lib_gle:
try: try:
cls.gle = CDLL(lib_gle) cls.gle = CDLL(cls.lib_gle)
except OSError: except OSError:
pass pass
@ -64,6 +64,14 @@ def test_gle(self):
self.skipTest('lib_gle not available') self.skipTest('lib_gle not available')
self.gle.gleGetJoinStyle self.gle.gleGetJoinStyle
def test_abspath(self):
if self.lib_gl:
self.assertTrue(os.path.isabs(self.lib_gl))
if self.lib_glu:
self.assertTrue(os.path.isabs(self.lib_glu))
if self.lib_gle:
self.assertTrue(os.path.isabs(self.lib_gle))
# On platforms where the default shared library suffix is '.so', # On platforms where the default shared library suffix is '.so',
# at least some libraries can be loaded as attributes of the cdll # at least some libraries can be loaded as attributes of the cdll
# object, since ctypes now tries loading the lib again # object, since ctypes now tries loading the lib again

View file

@ -221,8 +221,8 @@ def _findSoname_ldconfig(name):
abi_type = mach_map.get(machine, 'libc6') abi_type = mach_map.get(machine, 'libc6')
# XXX assuming GLIBC's ldconfig (with option -p) # XXX assuming GLIBC's ldconfig (with option -p)
regex = os.fsencode( regex = r'lib%s\.[^\s]+\s\(%s(?:,\s.*)?\)\s=>\s(.*)'
'\s+(lib%s\.[^\s]+)\s+\(%s' % (re.escape(name), abi_type)) regex = os.fsencode(regex % (re.escape(name), abi_type))
try: try:
with subprocess.Popen(['/sbin/ldconfig', '-p'], with subprocess.Popen(['/sbin/ldconfig', '-p'],
stdin=subprocess.DEVNULL, stdin=subprocess.DEVNULL,

View file

@ -487,6 +487,7 @@ Matthieu Gautier
Stephen M. Gava Stephen M. Gava
Xavier de Gaye Xavier de Gaye
Harry Henry Gebel Harry Henry Gebel
Tamás Bence Gedai
Marius Gedminas Marius Gedminas
Jan-Philip Gehrcke Jan-Philip Gehrcke
Thomas Gellekum Thomas Gellekum

View file

@ -201,6 +201,9 @@ Core and Builtins
Library Library
------- -------
- Issue #21042: Make ctypes.util.find_library() return the full path on
Linux, similar to other platforms. Patch by Tamás Bence Gedai.
- Issue #15068: Got rid of excessive buffering in fileinput. - Issue #15068: Got rid of excessive buffering in fileinput.
The bufsize parameter is now deprecated and ignored. The bufsize parameter is now deprecated and ignored.