问题:为什么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']
任何帮助将不胜感激。
回答 0
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
如果第一种形式为空(等于空字符串,或者根本不存在),则使用第二种形式,如果不是,则使用第二种形式。注意使用导出。
回答 1
确保您的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进行编译。如果您只是从其他系统复制了一些文件,则此方法将永远无法正常工作。如有疑问,请在要运行它们的系统上编译模块。
回答 2
最初编译pycurl时,还可以在用户环境中将LD_RUN_PATH设置为/ usr / local / lib。这会将/ usr / local / lib嵌入C扩展模块。的RPATH属性中,以便它在运行时自动知道在哪里可以找到该库,而不必在运行时设置LD_LIBRARY_PATH。
回答 3
有完全相同的问题。我将curl 7.19安装到/ opt / curl /中,以确保不会影响生产服务器上的当前curl。将libcurl.so.4链接到/ usr / lib之后:
须藤ln -s /opt/curl/lib/libcurl.so /usr/lib/libcurl.so.4
我仍然遇到相同的错误!杜尔夫
但是运行ldconfig可以使链接变得很有效。完全不需要设置LD_RUN_PATH或LD_LIBRARY_PATH。只需运行ldconfig。
回答 4
作为上述答案的补充-我只是遇到了类似的问题,并且完全使用默认安装的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
我使用的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的解释
回答 6
对我来说,这里的工作是使用版本管理器,例如pyenv,我强烈建议您对项目环境和程序包版本进行良好的管理,并使其与操作系统的版本分开。
操作系统更新后,我也遇到了同样的错误,但是很容易用pyenv install 3.7-dev
(我使用的版本)修复。