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