Source code for soma.utils.find_library
# -*- coding: utf-8 -*-
''' replacement for :func:`ctypes.util.find_library`.
Provides a better version of :func:`find_library`, and allows to patch the
:mod:`ctypes` module to use our version: see :func:`patch_ctypes_find_library`.
'''
from __future__ import absolute_import
import os
import sys
import ctypes.util
import glob
ctypes_find_library = ctypes.util.find_library
[docs]def find_library(name):
''' :func:`ctypes.util.find_library` is broken on linux at least: it relies
on ``ldconfig``, which only searches system paths, not user paths nor
``LD_LIBRARY_PATH``, or alternatively uses ``gcc``, which is not always
installed nor configured.
Here we are looking in ``[[DY]LD_LIBRARY_]PATH`` (depending on the system)
'''
def sorted_match(filenames):
return sorted(filenames)[-1] # probably not the best
exts = ['.so']
patterns = [ext + '.*' for ext in exts]
fname = 'lib' + name
if sys.platform.startswith('linux'):
envar = 'LD_LIBRARY_PATH'
elif sys.platform == 'darwin':
envar = 'DYLD_LIBRARY_PATH'
exts = ['.dylib']
patterns = ['.*' + ext for ext in exts]
elif sys.platform.startswith('win'):
envar = 'PATH'
exts = ['.dll', '.DLL']
patterns = ['.*' + ext for ext in exts]
else:
# other undetermined system (bsd, othe unix...?), assume ELF
envar = 'LD_LIBRARY_PATH'
paths = os.environ.get(envar)
if paths is None:
# no path: fallback to ctypes
return ctypes_find_library(name)
paths = paths.split(os.pathsep)
names = [fname + ext for ext in exts] + [name + ext for ext in exts]
patterns = [fname + pattern for pattern in patterns] \
+ [name + pattern for pattern in patterns]
found = None
for path in paths:
for tname in names:
filename = os.path.join(path, tname)
if os.path.exists(filename):
found = filename
break
for tname in patterns:
filenames = glob.glob(os.path.join(path, tname))
if len(filenames) != 0:
found = sorted_match(filenames)
break
if found is not None:
return os.path.basename(os.path.realpath(found))
# not found: fallback to ctypes
return ctypes_find_library(name)
[docs]def patch_ctypes_find_library():
''' replace :func:`ctypes.util.find_library` by our version
'''
if ctypes.util.find_library is ctypes_find_library:
ctypes.util.find_library = find_library