为什么 Python 不能在 sys.path 的目录中找到共享对象?

我想导入 pycurl:

$ python -c "import pycurl"
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: libcurl.so.4: cannot open shared object file: No such file or directory

现在,libcurl.so.4/usr/local/lib。正如你所看到的,这是在 sys.path:

$ python -c "import sys; print(sys.path)"
['', '/usr/local/lib/python2.5/site-packages/setuptools-0.6c9-py2.5.egg',
'/usr/local/lib/python25.zip', '/usr/local/lib/python2.5',
'/usr/local/lib/python2.5/plat-linux2', '/usr/local/lib/python2.5/lib-tk',
'/usr/local/lib/python2.5/lib-dynload',
'/usr/local/lib/python2.5/sitepackages', '/usr/local/lib',
'/usr/local/lib/python2.5/site-packages']

任何帮助都将不胜感激。

240463 次浏览

sys.path只搜索 Python 模块。对于动态链接库,搜索的路径必须在 LD_LIBRARY_PATH中。检查你的 LD_LIBRARY_PATH是否包含 /usr/local/lib,如果没有,添加它,然后再试一次。

更多资料(来源) :

在 Linux 中,环境变量 LD _ LIBRARY _ PATH 是冒号分隔的 库的目录集 应该首先搜索,然后 标准的目录集; 这个 在调试新库时是有用的 或使用非标准库 特殊目的,环境 变量 LD _ PRELOAD 列表共享 具有重写函数的库 标准的一套,就像 /etc/ld.so.preload 执行 由装载机执行 /lib/ld-linux.so, 而 LD _ LIBRARY _ PATH 在许多 像 Unix 一样的系统,它不能工作 例如,这个功能 可以在 HP-UX 上使用,但是 环境变量 SHLIB _ PATH,以及 在 AIX,这个功能是通过 变量 LIBPATH (使用相同的 使用冒号分隔的列表)。

更新: 设置 LD_LIBRARY_PATH,使用以下方法之一,最好在您的 ~/.bashrc中使用 或同等档案:

export LD_LIBRARY_PATH=/usr/local/lib

或者

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

如果第一个表单为空,则使用它(相当于空字符串,或根本不存在) ; 如果不为空,则使用第二个表单。请注意 出口的使用。

确保您的 libcurl.so模块位于系统库路径中,该路径与 python 库路径是独立的。

“快速修复”是将此路径添加到 LD_LIBRARY_PATH变量。然而,设置系统范围(甚至帐户范围)是一个糟糕的想法,因为它可能设置成某些程序会发现一个不应该,甚至更糟糕的是,打开安全漏洞的库。

如果您的“本地安装的库”安装在,例如,/usr/local/lib中,将此目录添加到 /etc/ld.so.conf(它是一个文本文件)并运行 ldconfig

该命令将运行一个缓存实用程序,但也将创建加载程序系统运行所需的所有必要的“符号链接”。令人惊讶的是,用于 libcurl 的 make install并没有这样做,但是如果 /usr/local/lib不在 /etc/ld.so.conf中,那么它可能不会这样做。

附注: 有可能你的 /etc/ld.so.conf只包含 include ld.so.conf.d/*.conf。您仍然可以在它之后添加一个目录路径,或者只是在包含它的目录中创建一个新文件。不要忘记运行 ldconfig之后。

小心点,弄错了可能会毁了你的系统。

另外: 确保您的 python 模块是根据 libcurl 的那个版本编译的。如果您只是从另一个系统复制了一些文件,那么这种方法不会一直有效。如果有疑问,请在打算运行模块的系统上编译模块。

还可以在编译 pycurl 时将用户环境中的 LD _ RUN _ PATH 设置为/usr/local/lib。这将在 C 扩展模块的 RPATH 属性中嵌入/usr/local/lib。这样它就可以自动知道在运行时在哪里找到库,而不必在运行时设置 LD _ LIBRARY _ PATH。

也有同样的问题。我将 curl 7.19安装到/opt/curl/,以确保不会影响生产服务器上的当前 curl。 一旦我将 libcurl.so.4链接到/usr/lib:

Sudo ln-s/opt/curl/lib/libcurl.so/usr/lib/libcurl.so. 4

我还是犯同样的错误,德夫。

但是运行 ldconfig 为我创建了这个链接,并且成功了。根本不需要设置 LD _ RUN _ PATH 或 LD _ LIBRARY _ PATH。只需要运行 ldconfig。

作为上述答案的补充——我只是碰到了一个类似的问题,并且完全使用了默认安装的 python。

当我调用我在 LD_LIBRARY_PATH中寻找的共享对象库的例子时,我得到了这样的结果:

$ LD_LIBRARY_PATH=/path/to/mysodir:$LD_LIBRARY_PATH python example-so-user.py
python: can't open file 'example-so-user.py': [Errno 2] No such file or directory

值得注意的是,它甚至没有抱怨导入——而是抱怨源文件!

但如果我用 LD_PRELOAD强制加载物体:

$ LD_PRELOAD=/path/to/mysodir/mypyobj.so python example-so-user.py
python: error while loading shared libraries: libtiff.so.5: cannot open shared object file: No such file or directory

... 我立即得到一个更有意义的错误消息-关于缺少依赖关系!

我只是想把这个记下来,干杯!

我使用的是 python setup.py build_ext -R/usr/local/lib -I/usr/local/include/libcalg-1.0,编译后的.so 文件位于构建文件夹下。 您可以键入 python setup.py --help build_ext查看-R 和-I 的解释

对我来说,这里的工作方式是使用版本管理器,比如 Penenv,我强烈建议使用它来管理好项目环境和包版本,并将其与操作系统的版本管理器分离开来。

在一次操作系统更新之后,我也出现了同样的错误,但是用 pyenv install 3.7-dev(我使用的版本)很容易就修复了。