cc1plus:警告:命令行选项"-Wstrict-prototypes"对Ada/C/ObjC有效但对C++无效

Hom*_*lli 36 c++ python swig gcc

我正在构建一个用于Python的C++扩展.我看到这个警告是在编译过程中生成的 - 当一个类型:

python setup.py build_ext -i
Run Code Online (Sandbox Code Playgroud)

是什么造成的,我该如何解决?

顺便说一句,这是我的安装文件的副本:

#!/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"],
           )
Run Code Online (Sandbox Code Playgroud)

我在Ubuntu上使用gcc 4.4.3

Kei*_*son 38

我可以回答部分问题,为什么你收到消息.

构建过程中的某些东西是使用该选项在C++源文件上调用gcc -Wstrict-prototypes.对于C和Objective-C,这会导致编译器警告没有声明参数类型的旧式函数声明.

对于C++,这个选项没有意义; 语言甚至不允许这样的声明(原型是强制性的).

(我不知道为什么这个消息提到了Ada; -Wstrict-prototypes对于Ada来说对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++
...
Run Code Online (Sandbox Code Playgroud)

所以它可能是Python中的一个小错误build_ext.

但是因为它只是一个警告,而不是一个致命的错误,我会说你可以放心地忽略它.gcc警告无意义的选择,但它只是忽略了它.

编辑:

浏览Python-2.7.2源代码,这一部分configure.in可能是罪魁祸首:

case $GCC in
yes)
    if test "$CC" != 'g++' ; then
        STRICT_PROTO="-Wstrict-prototypes"
    fi
Run Code Online (Sandbox Code Playgroud)

(我假设在使用时调用了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维护者可以使用上述信息来解决未来版本中的问题.

  • 现在,这是一些强大的精彩探险!谢谢你去嗅出那个问题.我将它提交给Python维护者. (2认同)

Thr*_*ule 23

从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)
Run Code Online (Sandbox Code Playgroud)

然后my_build_extsetup函数内部使用:

setup(cmdclass = {'build_ext': my_build_ext})
Run Code Online (Sandbox Code Playgroud)


小智 14

-Wstrict-prototypesdistutils /usr/lib/pythonX.Y/config/Makefile作为OPT变量的一部分读取选项.它似乎很hackish,但您可以通过设置os.environ['OPT']setup.py 来覆盖它.

这是一个似乎没有太大危害的代码:

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'
)
Run Code Online (Sandbox Code Playgroud)


Nim*_*mar 12

setup.py中的以下代码片段将删除此pesky标志的所有实例:

# 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", "")
# ==================================
Run Code Online (Sandbox Code Playgroud)


Yan*_*ong 8

这是一个带有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},
    ...
)
Run Code Online (Sandbox Code Playgroud)