cc1plus: 警告:命令行选项 "-Wstrict-prototypes" 对Ada/C/ObjC有效,但对C++无效
我正在为Python开发一个C++扩展。在编译的过程中,我看到出现了一个警告,警告是关于某个类型的:
python setup.py build_ext -i
这个警告是怎么产生的,我该怎么解决呢?
顺便说一下,这是我的设置文件的内容:
#!/usr/bin/env python
"""
setup.py file for SWIG example
"""
from distutils.core import setup, Extension
example_module = Extension('_foolib',
sources=['example_wrap.cxx',
'../wrapper++/src/Foo.cpp'
],
libraries=["foopp"]
)
setup (name = 'foolib',
version = '0.1',
author = "Me, Myself and I",
description = """Example""",
ext_modules = [example_module],
py_modules = ["example"],
)
我在Ubuntu上使用的是gcc 4.4.3版本。
7 个回答
-Wstrict-prototypes
这个选项是从 /usr/lib/pythonX.Y/config/Makefile
文件中被 distutils 读取的,它是 OPT 变量的一部分。虽然这看起来有点不太正规,但你可以通过在你的 setup.py 文件中设置 os.environ['OPT']
来覆盖它。
下面是一段看起来没什么害处的代码:
import os
from distutils.sysconfig import get_config_vars
(opt,) = get_config_vars('OPT')
os.environ['OPT'] = " ".join(
flag for flag in opt.split() if flag != '-Wstrict-prototypes'
)
从OPT环境变量中去掉-Wstrict-prototypes这个选项没有任何效果。有效的方法是像下面这样对build_ext
进行子类化:
from distutils.command.build_ext import build_ext
from distutils.sysconfig import customize_compiler
class my_build_ext(build_ext):
def build_extensions(self):
customize_compiler(self.compiler)
try:
self.compiler.compiler_so.remove("-Wstrict-prototypes")
except (AttributeError, ValueError):
pass
build_ext.build_extensions(self)
然后在setup
函数里面使用my_build_ext
:
setup(cmdclass = {'build_ext': my_build_ext})
我可以回答你问题的一部分,告诉你为什么会收到这个消息。
在你的构建过程中,有某个地方在用 gcc 编译一个 C++ 源文件,并且加上了 -Wstrict-prototypes
这个选项。对于 C 和 Objective-C,这个选项会让编译器警告你使用了旧式的函数声明,因为这些声明没有说明参数的类型。
但是对于 C++ 来说,这个选项就没有意义了;因为这种声明在语言中根本是不允许的(函数原型是必须的)。
(我不知道为什么消息中提到 Ada;对 Ada 来说,-Wstrict-prototypes
的意义比对 C++ 还要小。这不是大问题,但我已经提交了一个错误报告,在 2015-12-06 标记为已解决/修复。)
解决办法应该是把 -Wstrict-prototypes
这个选项从 gcc 的调用中去掉。但是因为你并不是直接调用 gcc,所以很难知道该怎么做。
我用你的 setup.py
复现了这个警告,手动创建了一个虚拟的 example_wrap.cxx
文件:
% python setup.py build_ext -i
running build_ext
building '_foolib' extension
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/include/python2.7 -c example_wrap.cxx -o build/temp.linux-i686-2.7/example_wrap.o
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
...
所以这可能是 Python 的 build_ext
中的一个小错误。
不过因为这只是一个警告,而不是致命错误,我觉得你可以安全地忽略它。gcc 会警告这个没意义的选项,但之后它会直接忽略它。
编辑:
查看 Python-2.7.2 的源代码,这部分 configure.in
可能是罪魁祸首:
case $GCC in
yes)
if test "$CC" != 'g++' ; then
STRICT_PROTO="-Wstrict-prototypes"
fi
(我假设这是在使用 build_ext
时调用的。)
它只有在编译器不是以 g++
的方式调用时,才会开启 -Wstrict-prototypes
这个选项——但在你的情况下,它是用 gcc
命令来编译 C++ 源代码的。而在 Lib/distutils/command/build_ext.py
中,build_extension()
在调用 self.compiler.compile()
时并没有关注源文件的语言,只有在调用 self.compiler.link_shared_object()
时才会关注。(这听起来有点奇怪;对于除了 gcc 以外的编译器,你可能不能用同一个命令来编译 C 和 C++——而且即使不链接,使用 g++
命令也更合理。)
更新:已经提交了一个 Python 的错误报告:https://bugs.python.org/issue9031,并且被关闭为这个报告的重复:https://bugs.python.org/issue1222585,在我写这段话的时候这个报告仍然是开放状态。
但正如我所说,这只是一个警告,你可能可以安全地忽略它。也许 Python 的维护者可以利用以上信息在未来的版本中修复这个问题。