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

时间:2009-07-08 19:06:18

标签: python shared-libraries libcurl pycurl

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

非常感谢任何帮助。

7 个答案:

答案 0 :(得分:143)

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

答案 1 :(得分:53)

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

“快速修复”是将此路径添加到LD_LIBRARY_PATH变量。但是,设置该系统范围(甚至帐户范围)是一个不好的想法,因为可以设置它,使某些程序找到一个它不应该的库,或者更糟糕的是,打开安全漏洞。 / p>

如果您的“本地安装的库”安装在例如/ 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编译的。如果你刚刚从另一个系统复制了一些文件,这不会一直有效。如果有疑问,请在要运行它们的系统上编译模块。

答案 2 :(得分:24)

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

答案 3 :(得分:10)

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

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

我仍然遇到同样的错误! Durf。

但是运行ldconfig会为我建立链接并且这样做有效。根本不需要设置LD_RUN_PATH或LD_LIBRARY_PATH。只需要运行ldconfig。

答案 4 :(得分:8)

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

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

以为我会在这里记下这一点 - 干杯!

答案 5 :(得分:1)

对我来说,这里有效的方法是使用版本管理器,例如pyenv,我强烈建议您对项目环境和程序包版本进行良好的管理,并将其与操作系统分开。

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

答案 6 :(得分:0)

我使用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

的说明