Python多版本共存导致动态库混乱的问题
2012-07-20 11:15
281 查看
转载自:寂寞是国,我是王。 作者:Soli 原文地址:Python多版本共存导致动态库混乱的问题
在已经存在Python的环境中再源码安装其他版本的Python时,或源码安装mod_python或mod_wsgi等模块时,经常会出现动态库混乱的问题。常见的错误信息如下:
乍一看,错误信息非常明白,就是无法生成动态库,需要使用-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位,如下:
对于第三种情况,你可以通过在./configure参数中设置LDFLAGS变量,或在make前设置LD_LIBRARY_PATH环境变量来指明你要使用的Python库的路径。如下:
或在Bourne shell (/bin/sh or /bin/bash)中:
或在C-shell (/bin/csh or /bin/tcsh)中:
下面是我遇到的第四种情况。上面给出的参见链接中,有人通过对比是否使用–enable-shared参数,以及是否使用–prefix参数,./configure的输出和make的输出,对该问题进行了仔细的研究。他发现,在使用–prefix参数后,编译命令中依然添加了系统中已经存在的python的include和lib路径。从而导致编译Python的附带模块时,链接的不是新生成的Python库,而是原来的系统中已经存在的Python库,而它恰巧并没有使用–enable-shared或-fPIC进行编译。
解决的办法就是,把系统原有的Python库的路径从编译参数中除去,或者把新的Python库所在的路径放到前面,让链接器先搜索该路径。对于Python自带的那些模块,这个路径应该就是当前路径”.”。可以通过设置LDFLAGS解决,如下:
对于mod_python或mod_wsgi等模块可以使用–with-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
相关文章推荐
- 在Centos7上安装python3.5,以及与旧版本python2.7.5的共存问题
- python多版本的pip共存问题解决办法
- python多版本的pip共存问题解决办法
- python版本冲突问题——多版本共存配置
- Python 多版本共存问题
- Linux下载安装高版本python与系统自带低版本共存问题
- python多版本共存问题
- 解决多个版本的python共存时的问题 => 持续更新
- CentOS7上安装Python3.X及其与旧版本Python2.7.5的共存问题
- Win10下python3和python2同时安装并解决pip共存问题 特别说明,本文是在Windows64位系统下进行的,32位系统请下载相应版本的安装包,安装方法类似。 使用python开
- 强制IE使用最高版本引擎渲染页面,避免默认使用IE7引擎导致的页面布局混乱及其它问题
- Linux系统之路——python多版本共存问题(ps:自行切换python版本,pip安装遇到的一些问题)
- python 版本问题,导致ansible提示报错
- python多个版本的共存问题
- python多版本的pip共存问题解决办法
- Windows中多个python版本共存的问题
- Python 多版本共存问题 2
- python多版本的pip共存问题解决办法
- 在CentOS7上安装Python3.5.0,及其与旧版本Python2.7.5的共存问题笔记
- Mac python版本混乱的问题