Python distutils未使用正确版本的gcc
我在Mac OSX 10.6.5上尝试编译一个软件包。这个软件包的安装脚本依赖于distutils。问题是,电脑默认的gcc版本是4.2(我在终端窗口运行gcc --version确认的),但是当我运行'python setup.py build'时,输出显示distutils选择了gcc-4.0而不是4.2。这对我来说是个大问题,因为我使用的代码需要gcc版本大于等于4.2。我在这台机器上没有管理员权限,所以作为解决办法,我创建了一些符号链接,把gcc-4.0指向gcc-4.2。结果是代码可以编译了,但生成的.so文件无法使用(当我尝试在python中导入它们时,出现错误,提示共享对象缺少初始化函数)。
我尝试在另一台Mac(10.6.6)上编译这段代码,结果非常顺利:distutils自动选择了4.2,我可以毫无问题地导入生成的共享对象。所以,我想在我的电脑上编译代码,而不需要使用这种符号链接的技巧……我只希望distutils能自动选择4.2,就像应该的那样。我也尝试把编译成功的.so文件转移到我的电脑上,但由于一些原因失败了(它们链接的库在我的机器上不存在,或者版本不同)。
有没有人能给点建议?
谢谢,
Josh
4 个回答
你没有说明你使用的是哪个版本的Python,但很可能你电脑上的默认Python并不是苹果提供的2.6.1版本,而是从python.org安装的版本。你可以试着用 /usr/bin/python2.6
来运行构建脚本,这个路径应该是苹果提供的Python 2.6,它是用 gcc-4.2
编译的。
当你使用Python的Distutils(通常是通过运行 setup.py
脚本或使用 easy_install
)时,Distutils会确保你安装的包中的任何C扩展模块都是用与构建Python时相同的编译器版本和兼容的编译选项(比如CPU架构、ABI等)来编译的。一般来说,python.org为OS X提供的安装包都是通用的Python,能在多个版本的OS X和不同的CPU架构上运行。这就是为什么它们是用gcc-4.0编译的。如果你需要使用gcc-4.2来支持其他库,最安全的做法是使用一个用gcc-4.2编译的Python。苹果在OS X 10.6上提供的系统Python就是这样编译的。此外,对于最新版本的Python(2.7.1和3.2),python.org还提供了一个针对OS X 10.6的第二种安装包变体,也是用gcc-4.2编译的。不过,如果你没有管理员权限,这种选择就不适用了。
你可以通过以下方式查看默认使用的是哪个Python:
which python
你有没有试过设置一个自定义的CC环境变量呢?
CC=gcc-4.2 python setup.py build
为了强制distutils使用一个单独的编译器,你可以通过环境变量重新定义几个变量。首先,找出distutils默认使用的编译器是什么:
>>> from distutils import sysconfig
>>> sysconfig.get_config_var('LDSHARED')
'gcc-4.0 -Wl,-F. -bundle -undefined dynamic_lookup'
>>> sysconfig.get_config_var('CC')
'gcc-4.0'
接下来,你需要重新定义这些变量,把你想用的gcc版本替换进去:
% LDSHARED="gcc-4.2 -Wl,-F. -bundle -undefined dynamic_lookup" CC=gcc-4.2 \
/usr/bin/python setup.py build_ext
请记住,sysconfig的默认值是从最初用来编译Python的Makefile中提取的,所以随意修改这些值可能会产生意想不到的结果:
>>> path = sysconfig.get_python_lib(plat_specific=1, standard_lib=1)
>>> os.path.join(path, 'config', 'Makefile')
'/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/config/Makefile'