使用distutils构建Python扩展模块

4 投票
2 回答
4373 浏览
提问于 2025-04-16 16:16

我正在使用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"]

你可以不写选项和库的部分。

撰写回答