我正在构建一个用于Python的C ++扩展。我看到这个警告是在编译过程中生成的 - 当一个类型:
python setup.py build_ext -i
是什么造成的,我该如何解决?
BTW,这是我的安装文件的副本:
#!/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
答案 0 :(得分:38)
我可以回答部分问题,为什么要收到信息。
构建过程中的某些内容是使用选项-Wstrict-prototypes
在C ++源文件上调用gcc。对于C和Objective-C,这会导致编译器警告没有声明参数类型的旧式函数声明。
对于C ++,这个选项没有意义;语言甚至不允许这样的声明(原型是强制性的)。
(我不知道为什么这条消息提到了Ada; -Wstrict-prototypes
对于Ada而言比对C ++更不重要。这不是一个大问题,但我提交了this bug report,标记为已解决/自2015-12-06起固定。)
解决方案应该是从gcc的调用中删除-Wstrict-prototypes
选项。但由于你没有直接调用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
时调用了它。)
仅当编译器不被调用为-Wstrict-prototypes
时才会打开g++
选项 - 但在您的情况下,它使用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维护者可以使用上述信息来解决未来版本中的问题。
答案 1 :(得分:20)
从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)
然后在my_build_ext
函数中使用setup
:
setup(cmdclass = {'build_ext': my_build_ext})
答案 2 :(得分:14)
-Wstrict-prototypes
的distutils读取 /usr/lib/pythonX.Y/config/Makefile
选项。它似乎很乱,但您可以通过在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'
)
答案 3 :(得分:12)
setup.py中的以下代码片段将删除此讨厌标志的所有实例:
# Remove the "-Wstrict-prototypes" compiler option, which isn't valid for C++.
import distutils.sysconfig
cfg_vars = distutils.sysconfig.get_config_vars()
for key, value in cfg_vars.items():
if type(value) == str:
cfg_vars[key] = value.replace("-Wstrict-prototypes", "")
# ==================================
答案 4 :(得分:7)
这是一个带有setuptools的Python 3.x解决方案。
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):
if '-Wstrict-prototypes' in self.compiler.compiler_so:
self.compiler.compiler_so.remove('-Wstrict-prototypes')
super().build_extensions()
setup(
...
cmdclass={'build_ext': BuildExt},
...
)
答案 5 :(得分:2)
更具体地说,distutils使用与构建python相同的选项,您可以在创建extra_compile_args
时使用distutils.core.Extension
添加选项,但似乎没有办法删除gcc中的现有参数或者是distutils。
有关详细信息,请参阅http://bugs.python.org/issue9031,它已作为http://bugs.python.org/issue1222585的副本关闭,但9031详细说明了问题的这一方面
答案 6 :(得分:1)
为了在尝试在pypy下安装pydoop之后到达这里的人,这个解决方案在pydoop 1.0.0中采用:
from distutils.sysconfig import get_config_var
_UNWANTED_OPTS = frozenset(['-Wstrict-prototypes'])
os.environ['OPT'] = ' '.join(
_ for _ in get_config_var('OPT').strip().split() if _ not in _UNWANTED_OPTS
在pypy下中断安装,因为pypy sysconfig根本不提供'OPT'变量,导致它在尝试将strip()应用于None时中止。解决方案只是评论整个块。