使用distutils构建Python扩展模块
我正在使用distutils来构建一个用C++写的Python扩展模块。我的问题是,为了编译这个扩展模块,我需要链接一个特定的共享库。这就需要设置一个额外的编译器标志。所以,我查阅了Python的文档,发现了Extension
对象的extra_compile_args
属性。于是我尝试了以下代码:
from distutils.core import setup, Extension
module = Extension('test', sources = ['test.cpp'])
module.extra_compile_args = ['--std=c++0x', '-l mylib'];
setup(name = 'test', version = '1.0', ext_modules = [module])
这段代码似乎可以编译,但当我在Python中导入我的模块时,它抛出了一个ImportError
异常,原因是有一个未定义的符号。所以,显然这个库没有正确链接。于是我尝试写了一个临时的C++程序,链接了这个共享库,结果运行得很好。然后我意识到distutils
似乎有点奇怪,因为如果我添加一个链接到一个虚假的库名的编译参数,distutils却能毫无问题地编译所有内容:
module.extra_compile_args = ['--std=c++0x', '-l some_fake_library'];
当我运行setup.py build
时,构建过程没有任何错误!
那么,这到底是怎么回事呢?我该如何编译一个需要链接到共享库的扩展模块呢?
2 个回答
3
distutils的一个目的就是让你的代码不依赖于某一个特定的编译器。你写的“-l somelib”看起来是想和GCC编译器一起用的(其实应该是“-lsomelib”,中间不能有空格)。这就是为什么你要在Extension
类中使用libraries
这个选项。distutils会把合适的链接命令传给它正在使用的编译器。
你还可以查看distutils实际使用的构建命令,然后自己执行这些命令,看看哪里出错了。
6
其实有一个特别的选项可以做到这一点。
比如说:
libraries=["rt"]
你可以不写选项和库的部分。