OSError: cannot open shared object file: No such file or directory even though file is in the folder
OSError: cannot open shared object file: No such file or directory even though file is in the folder
我已经和这个问题斗争了很长一段时间了。我正在尝试安装 Yaafe 以提取音频特征。我按照此处的说明进行操作:https://github.com/Yaafe/Yaafe
一切都安装得很好,但是当我尝试 运行 测试文件 "frames.py" 时,出现以下错误:
File "frames.py", line 6, in <module>
from yaafelib import FeaturePlan, Engine, AudioFileProcessor
File "/usr/local/lib/python2.7/dist-packages/yaafelib/__init__.py", line 36, in <module>
from yaafelib.core import (loadComponentLibrary,
File "/usr/local/lib/python2.7/dist-packages/yaafelib/core.py", line 35, in <module>
yaafecore = cdll.LoadLibrary('libyaafe-python.so')
File "/usr/lib/python2.7/ctypes/__init__.py", line 443, in LoadLibrary
return self._dlltype(name)
File "/usr/lib/python2.7/ctypes/__init__.py", line 365, in __init__
self._handle = _dlopen(self._name, mode)
OSError: libyaafe-python.so: cannot open shared object file: No such file or directory
我已使用以下命令将 lib 目录包含到 LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=/usr/local/lib
确实,当我回显 LIBRARY_PATH 时,它就在那里。此外,当我检查 /usr/local/lib 时,它包含以下内容:
libyaafe-components.so libyaafe-io.so python2.7
libyaafe-components.so.0 libyaafe-io.so.0 python3.4
libyaafe-components.so.0.70.0 libyaafe-io.so.0.70.0 site_ruby
libyaafe-core.so libyaafe-python.so yaafe
libyaafe-core.so.0 libyaafe-python.so.0
libyaafe-core.so.0.70.0 libyaafe-python.so.0.70.0
所以不应该一切都好吗?我不明白这是什么问题。我已按照说明进行操作。
更改您的代码,以便在异常发生之前打印 os.environ
。这样你就会看到 Python 进程是否设置了正确的环境。另一个明显要检查的事情是您的 Python 进程是否有足够的权限打开和读取 libyaafe-python.so
。请注意,出于安全原因,sudo
默认情况下会限制调用命令的环境(例如,请参阅 here)。
我知道这个post是旧的,但是如果你不能修改(或不想修改)LD_LIBRARY_PATH
并且你仍然需要一种方法来将共享对象加载到[=中的内存中36=],那么就可以用这个通用的方法了。
import ctypes
ctypes.CDLL('/usr/local/lib/library.version.so', mode=ctypes.RTLD_GLOBAL)
对你来说,电话可能是这样的:
import ctypes
ctypes.CDLL('/usr/local/lib/libyaafe-python.so', mode=ctypes.RTLD_GLOBAL)
如果您事先不知道路径,我已经整理了以下函数,可以递归搜索一组库路径以查找指定的库名称(和版本)。希望这对您有所帮助!
# Given a library name, try to locate the library and load it in
# global mode as a CDLL so that it is accessible to all code.
def load_library(libname, version=None, paths=("/usr/lib","/usr/local/lib",),
extensions=(".so",), prefixes=("","lib",),
recursive=True):
import os, ctypes
# This code will find all possible matches for the library,
# and pick the first lexicographically.
versions = set()
for directory in paths:
# Enumerate all files at that path (depending on "resursive" option).
if recursive:
file_paths = sum((
[os.path.join(dirpath, f) for f in filenames]
for (dirpath, dirnames, filenames) in os.walk(directory)
), [])
else:
file_paths = [
os.path.join(directory,f) for f in os.listdir(directory)
if not os.path.isdir(f)
]
# Iterate over the files looking for the specified library.
for path in file_paths:
filename = os.path.basename(path)
# Verify the file extension is allowed.
ext = filename[len(filename)-filename[::-1].find('.')-1:]
# Examples of the value for 'ext' given a 'filename':
# "foo.bar" -> ".bar", "foobar" -> ""
if (ext not in extensions): continue
# Check that the library name is in file name.
if (libname not in filename): continue
# Check that the version is in the name (if it is specified).
file_version = ".".join(filename.split('.')[1:-1])
if ((version is not None) and (version != file_version)): continue
# Extract the file name and check for matches against prefixes.
name = filename[:(filename+'.').find('.')]
for p in prefixes:
if (p+libname == name): break
else: continue
# Now this filename matches the required:
# name preceding the first ".",
# file extension including last ".",
# version between first and last "." if that was specified,
# and it exists in one of the provided paths.
versions.add(path)
# Uncomment the following line to see the considered libraries.
# print([path, filename, name, file_version, ext, os.path.islink(path)])
# Raise an error if no versions could be found.
if (len(versions) == 0):
raise(FileNotFoundError(f"No library file found for '{libname}'{'' if version is None else ' version '+version}."))
# Get the library path as the first element of the set of discovered versions.
library_path = sorted(versions)[0]
# Load the library globally (so it is accessible to later codes) and return its path.
ctypes.CDLL(library_path, mode=ctypes.RTLD_GLOBAL)
return library_path
对于您的特定示例,对该函数的调用如下所示:
load_library("yaafe-python")
只要您在 之前调用这个 导入任何无法加载的模块,一切都应该有效。
WARNINGS
- 这是为 POSIX 系统(Ubuntu、macOS、...)编写的
- 这会将库加载到全局 C 命名空间中,因此我不确定如果某些内容已经存在,它将如何处理重复声明,并且如果加载的库被覆盖,它可能会导致意外的下游后果。
我已经和这个问题斗争了很长一段时间了。我正在尝试安装 Yaafe 以提取音频特征。我按照此处的说明进行操作:https://github.com/Yaafe/Yaafe
一切都安装得很好,但是当我尝试 运行 测试文件 "frames.py" 时,出现以下错误:
File "frames.py", line 6, in <module>
from yaafelib import FeaturePlan, Engine, AudioFileProcessor
File "/usr/local/lib/python2.7/dist-packages/yaafelib/__init__.py", line 36, in <module>
from yaafelib.core import (loadComponentLibrary,
File "/usr/local/lib/python2.7/dist-packages/yaafelib/core.py", line 35, in <module>
yaafecore = cdll.LoadLibrary('libyaafe-python.so')
File "/usr/lib/python2.7/ctypes/__init__.py", line 443, in LoadLibrary
return self._dlltype(name)
File "/usr/lib/python2.7/ctypes/__init__.py", line 365, in __init__
self._handle = _dlopen(self._name, mode)
OSError: libyaafe-python.so: cannot open shared object file: No such file or directory
我已使用以下命令将 lib 目录包含到 LD_LIBRARY_PATH:
export LD_LIBRARY_PATH=/usr/local/lib
确实,当我回显 LIBRARY_PATH 时,它就在那里。此外,当我检查 /usr/local/lib 时,它包含以下内容:
libyaafe-components.so libyaafe-io.so python2.7
libyaafe-components.so.0 libyaafe-io.so.0 python3.4
libyaafe-components.so.0.70.0 libyaafe-io.so.0.70.0 site_ruby
libyaafe-core.so libyaafe-python.so yaafe
libyaafe-core.so.0 libyaafe-python.so.0
libyaafe-core.so.0.70.0 libyaafe-python.so.0.70.0
所以不应该一切都好吗?我不明白这是什么问题。我已按照说明进行操作。
更改您的代码,以便在异常发生之前打印 os.environ
。这样你就会看到 Python 进程是否设置了正确的环境。另一个明显要检查的事情是您的 Python 进程是否有足够的权限打开和读取 libyaafe-python.so
。请注意,出于安全原因,sudo
默认情况下会限制调用命令的环境(例如,请参阅 here)。
我知道这个post是旧的,但是如果你不能修改(或不想修改)LD_LIBRARY_PATH
并且你仍然需要一种方法来将共享对象加载到[=中的内存中36=],那么就可以用这个通用的方法了。
import ctypes
ctypes.CDLL('/usr/local/lib/library.version.so', mode=ctypes.RTLD_GLOBAL)
对你来说,电话可能是这样的:
import ctypes
ctypes.CDLL('/usr/local/lib/libyaafe-python.so', mode=ctypes.RTLD_GLOBAL)
如果您事先不知道路径,我已经整理了以下函数,可以递归搜索一组库路径以查找指定的库名称(和版本)。希望这对您有所帮助!
# Given a library name, try to locate the library and load it in
# global mode as a CDLL so that it is accessible to all code.
def load_library(libname, version=None, paths=("/usr/lib","/usr/local/lib",),
extensions=(".so",), prefixes=("","lib",),
recursive=True):
import os, ctypes
# This code will find all possible matches for the library,
# and pick the first lexicographically.
versions = set()
for directory in paths:
# Enumerate all files at that path (depending on "resursive" option).
if recursive:
file_paths = sum((
[os.path.join(dirpath, f) for f in filenames]
for (dirpath, dirnames, filenames) in os.walk(directory)
), [])
else:
file_paths = [
os.path.join(directory,f) for f in os.listdir(directory)
if not os.path.isdir(f)
]
# Iterate over the files looking for the specified library.
for path in file_paths:
filename = os.path.basename(path)
# Verify the file extension is allowed.
ext = filename[len(filename)-filename[::-1].find('.')-1:]
# Examples of the value for 'ext' given a 'filename':
# "foo.bar" -> ".bar", "foobar" -> ""
if (ext not in extensions): continue
# Check that the library name is in file name.
if (libname not in filename): continue
# Check that the version is in the name (if it is specified).
file_version = ".".join(filename.split('.')[1:-1])
if ((version is not None) and (version != file_version)): continue
# Extract the file name and check for matches against prefixes.
name = filename[:(filename+'.').find('.')]
for p in prefixes:
if (p+libname == name): break
else: continue
# Now this filename matches the required:
# name preceding the first ".",
# file extension including last ".",
# version between first and last "." if that was specified,
# and it exists in one of the provided paths.
versions.add(path)
# Uncomment the following line to see the considered libraries.
# print([path, filename, name, file_version, ext, os.path.islink(path)])
# Raise an error if no versions could be found.
if (len(versions) == 0):
raise(FileNotFoundError(f"No library file found for '{libname}'{'' if version is None else ' version '+version}."))
# Get the library path as the first element of the set of discovered versions.
library_path = sorted(versions)[0]
# Load the library globally (so it is accessible to later codes) and return its path.
ctypes.CDLL(library_path, mode=ctypes.RTLD_GLOBAL)
return library_path
对于您的特定示例,对该函数的调用如下所示:
load_library("yaafe-python")
只要您在 之前调用这个 导入任何无法加载的模块,一切都应该有效。
WARNINGS
- 这是为 POSIX 系统(Ubuntu、macOS、...)编写的
- 这会将库加载到全局 C 命名空间中,因此我不确定如果某些内容已经存在,它将如何处理重复声明,并且如果加载的库被覆盖,它可能会导致意外的下游后果。