через cc1plus: warning: опция командной строки «-Wstrict-prototypes» действительна для Ada/C/ObjC, но не для C++




парсер командной строки c++ (6)

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

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

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


Удаление -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})

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

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


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

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

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

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

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

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

Решение должно состоять в том, чтобы удалить -Wstrict-prototypes из вызова gcc. Но так как вы не вызываете gcc напрямую, трудно понять, как это сделать.

Я смог воспроизвести предупреждение, используя ваш setup.py , после создания вручную файла dummy 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++ , даже если вы не связываетесь. )

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

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


Это решение 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):
        self.compiler.compiler_so.remove('-Wstrict-prototypes')
        super(BuildExt, self).build_extensions()

setup(
    ...
    cmdclass={'build_ext': BuildExt},
    ...
)




swig