Python 扩展:对 C 部分和 C++ 部分使用不同的编译器标志
Python extension: using different compiler flags for a C parts and C++ parts
对于我的python扩展,我有C(来自嵌入式库)和C++文件,它们被编译并链接在一起。只有C++部分与Python接口(通过SWIG)。这适用于带有VS2015的Windows和Linux下的gcc。但是,对于 gcc,C++ 文件需要一组与 C 文件不同的编译器标志(例如 -std=c++11,-Wno-reorder),以避免有关 C 中不正确标志的警告。
在setuptools/distutils中是否有办法单独更改每个文件的编译器标志,例如基于文件扩展名?
我已经使用了 https://stackoverflow.com/a/36293331/3032680 中的自定义构建步骤。
更新:
主要问题是,distutils.ccompiler
不检查 C 或 C++ 的文件扩展名,并且使用 $CC 运行所有内容。即使定义 CXXFLAGS 也无济于事。我将忍受警告,既没有export
,也没有在 setup.py 文件中使用os.eniviron
的定义。
更新 2:
在装有CLang 8.0.0的macOS上,情况变得更糟:尝试使用-std=c ++ 11编译.c文件不是警告,而是错误。
还有另一种选择,包括重载distutils
编译器类(比如Unix C编译器):
import os
from distutils.unixccompiler import UnixCCompiler
cpp_flags = ['-std=c++11']
class C_CxxCompiler(UnixCCompiler):
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts):
_cc_args = cc_args
# add the C++ flags for source files with extensions listed below
if os.path.splitext(src)[-1] in ('.cpp', '.cxx', '.cc'):
_cc_args = cc_args + cpp_flags
UnixCCompiler._compile(self, obj, src, ext, _cc_args, extra_postargs, pp_opts)
然后重载distutils.build_ext
命令以截获扩展构建并在编译继续之前替换编译器:
class BuildC_CxxExtensions(build_ext):
def build_extensions(self, ext):
if self.compiler.compiler_type == 'unix':
# Replace the compiler
old_compiler = self.compiler
self.compiler = C_CxxCompiler()
# Copy its attributes
for attr, value in old_compiler.__dict__.items():
setattr(self.compiler, attr, value)
build_ext.build_extensions(self, ext)
根据您的平台,您可能需要重载其他编译器类MSVCCompiler
、CygwinCCompiler
、Mingw32CCompiler
或BCPPCompiler
。
由于 distutils 在确保所有文件使用相同的编译器标志进行编译方面有很长的路要走,无论其文件扩展名 .c 或 .cpp。因此,即使使用CFLAGS和CXXFLAGS也没有被考虑在内,但gcc和CLang仍然以不同的方式处理它们。Visual Studio只是将所有内容编译为C++。
我通过接受 C 在大多数情况下仍然是C++的子集并将 C-Source 文件重命名为 .cpp,即使文件包含 C,我解决了我的问题。这个解决方案很丑陋,但我摆脱了 gcc 中的警告和 CLang 的错误 - 特别是因为这个解决方案再次模糊了 C 和 C++ 之间的语言障碍。
我后来采用的第二个解决方案是从distutlis外部的C代码创建一个静态库,并将Python扩展链接到该静态库。
- 在 CMake 中为每个目标设置编译器/链接器标志
- Visual Studio 中是否有来自代码块的编译器标志的类似物?
- 如何将编译器标志限制为仅(我的)本地库?
- 为什么 gcc 编译器标志未知?
- 如何将编译器标志从 clang 传递给 nvcc
- 设置用于调试的 g++ 编译器标志
- 如何在 cmake 中设置编译器特定的标志
- 是否有任何编译器标志可以在下面的代码中用于报告有关 UB 的警告?
- std::function, Clang 6.0 & MSVC (10.0017134.12) - 可能的 ABI 错误或必需的编译器标志
- 是否可以使用 GCC 编译具有特定编译器标志的代码文件的一部分?
- CMAKE 如何在 C++ 中将编译器标志附加到末尾
- 为什么方法重载或枚举标志定义会触发 gcc7.2 编译器警告?
- 如何在 Visual Studio Code 中包含编译器标志
- 是否有编译器标志可以使较新的 gcc 版本像旧版本一样构建
- 使用 noexcept 和编译器标志来关闭异常
- 运行时附加编译器标志
- 链接QT5库会自动将额外的FPIC标志传递给NVCC编译器,并通过cmake Cause错误
- 不能在 Solaris 的最新编译器中使用带有新 c+11 标志的 xercesc
- 在每个平台上使用相同的模拟,具有正确的编译器标志
- 如何在 CMake 中添加"-l" (ell) 编译器标志