您的位置:首页 > 编程语言 > Python开发

Python多版本共存导致动态库混乱的问题

2012-07-20 11:15 281 查看
转载自:寂寞是国,我是王。 作者:Soli 原文地址:Python多版本共存导致动态库混乱的问题

在已经存在Python的环境中再源码安装其他版本的Python时,或源码安装mod_python或mod_wsgi等模块时,经常会出现动态库混乱的问题。常见的错误信息如下:
/usr/bin/ld: .../lib/libpython2.7.a(abstract.o): relocation R_X86_64_32 against 'a local symbol' can not be used when making a shared object; recompile with -fPIC
.../lib/libpython2.7.a: could not read symbols: Bad value
collect2: ld returned 1 exit status


乍一看,错误信息非常明白,就是无法生成动态库,需要使用-fPIC参数来重新编译Python。其实,就是把Python编译成动态库。有这么几种方法:

直接修改Makefile:使用原来的./configure参数生成Makefile后,打开并在gcc命令后面添加”-fPIC”参数。

在./configure参数中设置CFLAGS变量:在原来的./configure参数后面追加”CFLAGS=-fPIC”。

在./configure参数中使用–enable-shared:在原来的./configure参数后面追加”–enable-shared”。

其中,最后一种方法是网上最推荐的。

但令人沮丧的是,在make的时候问题依在。我们明明看到每条gcc命令后面都跟了”-fPIC”参数。继续在网络上搜索会找到如下几个原因:

系统不支持位置相关代码(position-dependent code)。(参见)

在64位系统上使用了32位的Python库。也就是你的Python被编译成了32位的。(参见)

你的Python库没有被放置到正确的位置,或者系统找不到你的Python库。(参见)

系统使用了错误的Python库。这就是多版本Python共存的典型问题。(参见)

对上面的第一种情况我们不做讨论。

对第二种情况,你可以使用file命令查看一下你的Python到底被编译成了64位还是32位,如下:
$ file python
python: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), not stripped


对于第三种情况,你可以通过在./configure参数中设置LDFLAGS变量,或在make前设置LD_LIBRARY_PATH环境变量来指明你要使用的Python库的路径。如下:
$ ./configure --prefix=/bla/bla LDFLAGS=-L/path/to/your/python/lib


或在Bourne shell (/bin/sh or /bin/bash)中:
$ LD_LIBRARY_PATH=/usr/local/lib
$ export LD_LIBRARY_PATH
$ make


或在C-shell (/bin/csh or /bin/tcsh)中:
% setenv LD_LIBRARY_PATH /usr/local/lib
% make


下面是我遇到的第四种情况。上面给出的参见链接中,有人通过对比是否使用–enable-shared参数,以及是否使用–prefix参数,./configure的输出和make的输出,对该问题进行了仔细的研究。他发现,在使用–prefix参数后,编译命令中依然添加了系统中已经存在的python的include和lib路径。从而导致编译Python的附带模块时,链接的不是新生成的Python库,而是原来的系统中已经存在的Python库,而它恰巧并没有使用–enable-shared或-fPIC进行编译。

解决的办法就是,把系统原有的Python库的路径从编译参数中除去,或者把新的Python库所在的路径放到前面,让链接器先搜索该路径。对于Python自带的那些模块,这个路径应该就是当前路径”.”。可以通过设置LDFLAGS解决,如下:
$ ./configure --prefix=/bla/bla LDFLAGS=-L.


对于mod_python或mod_wsgi等模块可以使用–with-python解决,如下:
$ ./configure --prefix=/bla/bla --with-python=/path/to/your/python
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: