使用 setup.py 编译 Cython 扩展时,这些额外的编译器标志来自哪里?

Where are these extra compiler flags coming from when using setup.py to compile a Cython extension?

我正在尝试编译一个简单的 hello world 小示例来感受一下 Cython。它有效,但编译中到处都是我不想要的标志。按照示例 here,我能够清除大部分不需要的标志,但尽管我已尽最大努力控制环境变量,但仍有一些标志仍然存在。链接问题中的最后一条评论表明供应商可能会将额外的标志烘焙到编译器中,但我已经通过使用几种不同的编译器验证了这不太可能,所有这些编译器都默认为相同的额外标志。

我对 setup.py 的调用如下所示:

CC="gcc" CXX="g++" OPT="" CFLAGS="-O3 -D_GNU_SOURCE" BASECFLAGS="" LDFLAGS="" CCSHARED="" LDSHARED="gcc -shared" PY_CORE_FLAGS="" PY_CFLAGS="" AR="" ARFLAGS="" CPPFLAGS="" CPP="" SHLIB_SUFFIX="" python3 setup.py build_ext --inplace

setup.py很简单:

from setuptools import Extension, setup
from Cython.Build import cythonize

setup(
    ext_modules = cythonize([Extension("hellotest", ["hellotest.pyx"])], language_level="3")
)

最后,gcc 在编译过程中的输出,方括号中包含不需要的标志:

gcc [-DNDEBUG -g -fwrapv -O2 -Wall] -O3 -D_GNU_SOURCE -fPIC -I./ -I. -I/usr/include/python3.6m -c hellotest.c -o build/temp.linux-x86_64-3.6/hellotest.o
gcc [-DNDEBUG -g -fwrapv -O2 -Wall] -O3 -D_GNU_SOURCE -fPIC -I./ -I. -I/usr/include/python3.6m -c ./funcs.c -o build/temp.linux-x86_64-3.6/./funcs.o
gcc -shared -O3 -D_GNU_SOURCE build/temp.linux-x86_64-3.6/hellotest.o build/temp.linux-x86_64-3.6/./funcs.o -o build/lib.linux-x86_64-3.6/hellotest.cpython-36m-x86_64-linux-gnu.so

有没有人知道他们在哪里找到进入编译器选项的方式?

Setuptoolsdistutils 继承了很多功能,找出用于构建 c 扩展的 cflags 就是其中之一。

build_ext命令为运行时,调用distutils.sysconfig.customize_compiler(), which in its turn calls distutils.sysconfig.get_config_vars():

def customize_compiler(compiler):
    ...
        (cc, cxx, cflags, ccshared, ldshared, shlib_suffix, ar, ar_flags) = \
            get_config_vars('CC', 'CXX', 'CFLAGS',
                            'CCSHARED', 'LDSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS')
   ...

获取默认的 cflags,稍后将通过值 from the CFLAGS-environment variable and from setup-file and passed to the compiler.

进行扩展

get_config_vars() 解析(至少在 Linux 上)makefile 和 config-header,即 pyconfig.h,从而获得当前的 cflags(除其他外) Python-可执行文件已构建。然后使用完全相同的 cflags 来构建扩展。

如果需要,可以操纵这些内置标志,如我在此 中所展示的示例。这样做是否明智是另一个问题。


它在 Windows 上有点微妙,其中 get_config_vars() 没有提供那么多信息 - 因此使用其他技巧来构建正确的选项(例如,参见此 ).