为什么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']
任何帮助都将非常感谢。
8 个回答
你可以在用户环境中把 LD_RUN_PATH 设置为 /usr/local/lib,这样在你第一次编译 pycurl 的时候,它会把 /usr/local/lib 嵌入到 C 扩展模块 .so 的 RPATH 属性里。这样一来,运行时它就知道去哪里找这个库了,而不需要在运行时再设置 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 编译的。如果你只是把一些文件从其他系统复制过来,这并不总是有效。如果不确定,最好在你打算运行它们的系统上编译你的模块。
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
如果 LD_LIBRARY_PATH
是空的(也就是没有设置),就用第一种方式;如果已经有值了,就用第二种方式。注意要使用 export。