Подтвердить что ты не робот

Cc1plus: warning: опция командной строки "-Wstrict-prototypes" действительна для Ada/C/ObjC, но не для С++

Я создаю расширение С++ для использования в 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

4b9b3361

Ответ 1

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

Что-то в вашем процессе сборки вызывает gcc в исходном файле С++ с опцией -Wstrict-prototypes. Для C и Objective-C это заставляет компилятор предупреждать о объявлениях стиля старого стиля, которые не объявляют типы аргументов.

Для С++ этот параметр не имеет смысла; такие декларации даже не допускаются языком (прототипы являются обязательными).

(Я не знаю, почему сообщение упоминает Ada; -Wstrict-prototypes делает для Ada еще меньше смысла, чем для С++. Это не огромная сделка, но я представил этот отчет об ошибках, обозначенный как RESOLVED/FIXED с 2015 по 12 июня.)

Решение должно состоять в том, чтобы удалить опцию -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.)

Включает параметр -Wstrict-prototypes, только если компилятор не вызывается как g++ - но в вашем случае он использует команду gcc для компиляции исходного кода на С++. И в Lib/distutils/command/build_ext.py, build_extension() не обращает внимания на язык исходного файла при вызове self.compiler.compile(), только при вызове self.compiler.link_shared_object(). (Что кажется странным: для компиляторов, отличных от gcc, вы не обязательно сможете использовать одну и ту же команду для компиляции C и С++ - и имеет смысл использовать команду g++ в любом случае, даже если вы не сшивание.)

UPDATE: отчет об ошибке Python был отправлен: https://bugs.python.org/issue9031 и закрыт как дубликат этого: https://bugs.python.org/issue1222585, который все еще открыт, когда я пишу это.

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

Ответ 2

Удаление -Wstrict-прототипов из переменной среды 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})

Ответ 3

-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'
)

Ответ 4

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

Ответ 5

Это решение 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},
    ...
)

Ответ 6

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

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

Ответ 7

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