3

解决setup.py编译C++代码的-Wstrict-prototypes警告

 3 years ago
source link: https://note.qidong.name/2018/03/setup-warning-strict-prototypes/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

解决setup.py编译C++代码的-Wstrict-prototypes警告

2018-03-01 10:52:14 +08  字数:845  标签: Python C

在利用setuptoolsExtension来编译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伴生。 虽然忍忍也就过了,但为了零警告的目标,还是需要解决一下。

原因

setuptoolsExtension,源于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.pybuild_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方案


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK