为什么 distutils.core.setup 在 2 次编译器调用中构建共享扩展?

Why does distutils.core.setup build shared extensions in 2 compiler invocations?

distutils.core.setup,当被告知从单个 C 源文件构建共享扩展模块时,分两步完成:

首先,它调用编译器并使用 -fPIC 构建目标文件。 此步骤的缩短命令行看起来像这样(至少在 unix 系统上):

gcc -pthread -I/usr/include/python3.8 -O3 -fPIC -c ./SOURCE.c -o build/.../ext.o

第二,它再次将上述目标文件提供给编译器,这次传递一个额外的 -shared 编译器标志,并生成一个共享 .so 库文件。

gcc -pthread -O1 -shared ./build/.../ext.o -o ./build/.../ext.so


这肯定可以通过一个单独的步骤实现(我设法使用一次编译器调用手动重现了一个有效的扩展)那么为什么要分两步完成呢?这是一个非常小众的实现细节,但我很好奇。

第一个运行是编译,将SOURCE.c编译成ext.o。第二个 运行 正在链接,它将 ext.o 与标准库链接并生成最终的 ext.so.

为什么有 2 个独立的 运行 很难说。也许是因为 distutils/setuptools 被设计成通用的并且使用不同的编译器,而不仅仅是 gcc。查看支持的编译器列表 in the source code;看看 *compiler.py.