【问题标题】:Why can't Python find shared objects that are in directories in sys.path?为什么 Python 找不到 sys.path 目录中的共享对象?
【发布时间】:2010-11-09 03:45:11
【问题描述】:

我正在尝试导入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']

任何帮助将不胜感激。

【问题讨论】:

  • 查看我的更新答案,以防您没有正确设置LD_LIBRARY_PATH(我认为您的评论缺少冒号)。
  • 是否有一个名为 libcurl.so.4 的符号链接损坏?在我看来,它正在查找文件但无法打开它。如果一切都失败了,strace 解释器并寻找失败的调用。

标签: python shared-libraries libcurl pycurl


【解决方案1】:

sys.path 仅搜索 Python 模块。对于动态链接库,搜索的路径必须在LD_LIBRARY_PATH 中。检查您的LD_LIBRARY_PATH 是否包含/usr/local/lib,如果没有,请添加并重试。

更多信息 (source):

在 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

如果第一种形式为空(相当于空字符串,或根本不存在),则使用第一种形式,否则使用第二种形式。注意export的使用。

【讨论】:

  • 谢谢。我的 LD_LIBRARY_PATH 没有设置,所以: $ LD_LIBRARY_PATH=/usr/local/lib $LD_LIBRARY_PATH /usr/local/lib 但我仍然得到同样的错误: $ python -c "import pycurl" Traceback (最近一次调用最后一次): File "", line 1, in ImportError: libcurl.so.4: cannot open shared object file: No such file or directory
  • 在设置 LD_LIBRARY_PATH 变量后,我还必须授予我的用户读取库的权限。现在终于奏效了。
【解决方案2】:

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

“快速修复”是将此路径添加到 LD_LIBRARY_PATH 变量。但是,设置系统范围(甚至帐户范围)是一个坏主意,因为它可能会以这样一种方式设置,即某些程序会找到它不应该的库,或者更糟糕的是,会打开安全漏洞。

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

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

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

小心。弄错这个可能会搞砸你的系统。

另外:确保你的 python 模块是针对那个版本的 libcurl 编译的。如果您只是从另一个系统复制了一些文件,这将不会总是有效。如果有疑问,请在您打算运行它们的系统上编译您的模块。

【讨论】:

  • 谢谢 - 这工作。我想知道为什么我之前尝试的“快速修复”更改 LD_LIBRARY_PATH 变量没有。
  • 取决于很多因素。这是一种可能性:您的代码是从 apache 或 cron 运行的。这些程序通常会“清理”环境,因此您必须做一些额外的事情来获取环境变量。例如,apache 中的“SetEnv”,或者在 crontab 文件中为 cron 设置变量。犯错的可能性是无穷无尽的!
【解决方案3】:

当你首先编译 pycurl 时,你也可以在你的用户环境中将 LD_RUN_PATH 设置为 /usr/local/lib。这会将 /usr/local/lib 嵌入到 C 扩展模块的 RPATH 属性中。这样它就可以在运行时自动知道在哪里可以找到库,而不必在运行时设置 LD_LIBRARY_PATH。

【讨论】:

  • 或者,在构建扩展模块时使用 python setup.py build_ext --rpath=/usr/local/librpath 中烘焙
【解决方案4】:

遇到了完全相同的问题。我将 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。

【讨论】:

  • 如果我没有 sudo 权限怎么办?我无法运行 ldconfig?那么有什么办法可以清除上面的错误呢?
  • @SPRajagopal:如果您没有权限修改系统属性,则必须使用上述LD_LIBRARY_PATH 环境变量方法。如果您不想在 ~/.bashrc 中设置它(添加该设置不是一个好主意 IMO),您可以编写一个设置此变量的 shell 脚本,然后运行 ​​python,然后调用该脚本。
【解决方案5】:

作为上述答案的补充 - 我只是遇到了一个类似的问题,并且完全使用默认安装的 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

...我立即收到一条更有意义的错误消息 - 关于缺少依赖项!

我只是想把这个记在这里 - 干杯!

【讨论】:

  • 你确定这不是 OP 错误之前发生的新错误吗?
【解决方案6】:

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

【讨论】:

    【解决方案7】:

    对我来说,这里的工作是使用版本管理器,例如 pyenv,我强烈建议您妥善管理您的项目环境和包版本,并将其与操作系统分开。

    我在更新操作系统后遇到了同样的错误,但使用pyenv install 3.7-dev(我使用的版本)很容易修复。

    【讨论】:

      猜你喜欢
      • 2018-12-26
      • 2012-06-22
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      • 2019-05-01
      • 1970-01-01
      • 2020-10-31
      • 2016-07-19
      相关资源
      最近更新 更多