解决setup.py编译C++代码的-Wstrict-prototypes警告
2018-03-01 10:52:14 +08 字数:845 标签: Python C在利用setuptools的Extension
来编译C++代码时,会出现以下警告:
$ python setup.py bdist_wheel
running bdist_wheel
running build
running build_py
creating build
...
running build_ext
building '_example' extension
...
gcc -pthread -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC ...
cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid for C/ObjC but not for C++
g++ -pthread -shared ...
...
这个cc1plus: warning:
的警告在用g++
时不会出现,只有在使用gcc
时出现,通常与带--c++
参数的SWIG伴生。
虽然忍忍也就过了,但为了零警告的目标,还是需要解决一下。
原因 ¶
setuptools的Extension
,源于distutils,是标准库里就有的问题。
在Python的相关配置文件(以Python 3.5为例)/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu/Makefile
中,有以下配置:
# Compiler options
OPT= -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes
这里就给gcc
默认加上了-Wstrict-prototypes
参数,而它在编译C++代码时是多余的。
解决方案 ¶
直接用root权限修改配置文件,当然是一个办法,也当然不推荐。
而Extension
仅仅是一个指定参数的类,只能添加额外参数,无法修改既有的编译参数。
因此,需要对build_ext
进行封装修改,并且替换setup.py
的build_ext
子命令。
from setuptools import setup
from setuptools.command.build_ext import build_ext
# Avoid a gcc warning below:
# cc1plus: warning: command line option ‘-Wstrict-prototypes’ is valid
# for C/ObjC but not for C++
class BuildExt(build_ext):
def build_extensions(self):
self.compiler.compiler_so.remove('-Wstrict-prototypes')
super(BuildExt, self).build_extensions()
setup(
...
cmdclass={'build_ext': BuildExt},
...
)
参考 ¶
这个问题目前的有效参考,基本上只有stackoverflow.com/questions/8106258。
其中还提到了修改环境变量OPT
的方法,经测试无效。
在distutils.sysconfig.customize_compiler
中有以下代码,应该预示着这个方案只有在设置了CFLAGS
才生效吧。
def customize_compiler(compiler):
if compiler.compiler_type == "unix":
...
(cc, cxx, opt, cflags, ccshared, ldshared, shlib_suffix, ar, ar_flags) = \
get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
'CCSHARED', 'LDSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS')
...
if 'CFLAGS' in os.environ:
cflags = opt + ' ' + os.environ['CFLAGS']
ldshared = ldshared + ' ' + os.environ['CFLAGS']
虽然已经有了一个distutils的方案, 但我还是添加了自己基于Python3的setuptools方案。