cc1plus: предупреждение: опция командной строки «-Wstrict-prototypes» действительна для Ada / C / ObjC, но не для C ++ - PullRequest
33 голосов
/ 12 ноября 2011

Я строю расширение C ++ для использования в Python.Я вижу, как это предупреждение генерируется во время процесса компиляции - когда тип:

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"],
           )

Я использую gcc 4.4.3 в Ubuntu

Ответы [ 7 ]

38 голосов
/ 12 ноября 2011

Я могу ответить на часть вопроса, почему вы получаете сообщение.

Что-то в процессе сборки вызывает gcc для исходного файла C ++ с параметром -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++
...

Так что это, вероятно, небольшая ошибка в build_ext.

Python

Но так как это всего лишь предупреждение, а не фатальная ошибка, я бы сказал, что вы можете спокойно ее игнорировать. gcc предупреждает о бессмысленном параметре, но затем игнорирует его.

EDIT

Просматривая источники 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 могут использовать вышеуказанную информацию для исправления проблемы в будущем выпуске.

20 голосов
/ 29 марта 2016

Удаление -Wstrict-prototypes из переменной среды OPT не имеет никакого эффекта.То, что работает, это подкласс 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})
15 голосов
/ 16 марта 2012
Параметр

-Wstrict-prototypes считывается distutils из /usr/lib/pythonX.Y/config/Makefile как часть переменной OPT. Это кажется хакерским, но вы можете переопределить его, установив 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'
)
12 голосов
/ 14 апреля 2015

Следующий фрагмент кода в 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", "")
# ==================================
7 голосов
/ 01 марта 2018

Это решение Python 3.x с setuptools.

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},
    ...
)
2 голосов
/ 20 января 2012

В частности, distutils использует те же параметры, что и Python, с помощью которых вы можете добавить параметры, используя extra_compile_args при создании distutils.core.Extension, но не существует способа удалить существующие аргументы в gcc или distutils.

См. http://bugs.python.org/issue9031 для деталей, он был закрыт как дубликат http://bugs.python.org/issue1222585,, но 9031 детализирует этот аспект проблемы

1 голос
/ 17 мая 2015

Для тех, кто прибывает сюда после попытки установить pydoop под pypy, это решение, которое было принято в 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. Решение - просто закомментировать весь блок.

...