cc1plus: avertissement: l'option de ligne de commande "- wstrict-prototypes" est valide pour Ada/C/ObjC mais pas pour C++
je construis une extension C++ pour une utilisation en Python. Je vois cet avertissement généré pendant le processus de compilation-quand un type:
python setup.py build_ext -i
Quelle est la cause et comment puis-je résoudre ce problème?
BTW, voici une copie de mon fichier de configuration:
#!/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"],
)
j'utilise gcc 4.4.3 sur Ubuntu
7 réponses
je peux répondre à une partie de la question, pourquoi vous recevez le message.
quelque chose dans votre processus de compilation invoque gcc sur un fichier source C++ avec l'option -Wstrict-prototypes
. Pour C et Objective-C, cela amène le compilateur à mettre en garde contre les déclarations de fonctions anciennes qui ne déclarent pas les types d'arguments.
pour C++, cette option n'a pas de sens; de telles déclarations ne sont même pas permises par le langage (les prototypes sont obligatoires).
(je n'ai pas sachez pourquoi le message mentionne Ada;-Wstrict-prototypes
fait encore moins de sens pour Ada que pour C++. Ce n'est pas une grosse affaire, mais j'ai soumis ce rapport de bogue, marquée comme résolue / corrigée en date du 2015-12-06.)
la solution doit être d'enlever le -Wstrict-prototypes
option de l'invocation de gcc. Mais puisque vous n'invoquez pas directement gcc, il est difficile de savoir comment le faire.
j'ai pu reproduire l'avertissement en utilisant votre setup.py
, après avoir créé manuellement un mannequin example_wrap.cxx
fichier:
% 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++
...
Donc, c'est probablement un bug mineur dans Python build_ext
.
mais puisque ce n'est qu'un avertissement, pas une erreur fatale, je dirais que vous pouvez l'ignorer sans risque. gcc met en garde contre l'option sans signification, mais il l'ignore.
EDIT:
en regardant à travers les sources Python-2.7.2, cette section de configure.in
peut-être le coupable:
case $GCC in
yes)
if test "$CC" != 'g++' ; then
STRICT_PROTO="-Wstrict-prototypes"
fi
(je suppose que c'est invoqué lors de l'utilisation de build_ext
.)
le -Wstrict-prototypes
option seulement si le compilateur est étant invoquée comme g++
-- mais dans votre cas, il utilise le gcc
commande de compilation du code source C++. Et dans Lib/distutils/command/build_ext.py
,build_extension()
ne fait pas attention au langage de fichier source lors de l'invocation self.compiler.compile()
, uniquement lors de l'appel de self.compiler.link_shared_object()
. (Ce qui semble étrange; pour les compilateurs autres que gcc, vous ne seriez pas nécessairement en mesure d'utiliser la même commande pour compiler C et C++ -- et il fait plus logique d'utiliser le g++
commande de toute façon, même si vous n'êtes pas la liaison.)
mise à jour: un rapport de bogue Python a été soumis:https://bugs.python.org/issue9031, and closed as a duplicate of this one:https://bugs.python.org/issue1222585, qui est encore ouverte au moment où j'écris ceci.
Mais comme je l'ai dit, c'est seulement un avertissement et vous pouvez probablement ignorer en toute sécurité. Peut-être que les responsables Python peuvent utiliser les informations ci-dessus pour corriger le problème dans un version future.
Supprimer-wstrict-prototypes de la variable D'environnement OPT n'a aucun effet. Ce qui fonctionne est à la sous-classe build_ext
comme suit:
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)
puis utiliser my_build_ext
à l'intérieur du setup
fonction:
setup(cmdclass = {'build_ext': my_build_ext})
-Wstrict-prototypes
l'option est lue par distutils de /usr/lib/pythonX.Y/config/Makefile
dans le cadre de la variable OPT. Il semble hackish, mais vous pouvez l'outrepasser en mettant os.environ['OPT']
dans votre setup.py.
Voici un code qui ne semble pas trop nocif:
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'
)
Le fragment de code suivant setup.py va supprimer toutes les occurrences de ce satanés drapeau:
# 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", "")
# ==================================
C'est un Python 3.solution de x avec des 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},
...
)
plus spécifiquement, distutils utilise les mêmes options que python a été construit avec, vous pouvez ajouter des options en utilisant extra_compile_args
en créant le distutils.core.Extension
mais il ne semble pas être un moyen de supprimer les arguments dans gcc ou distutils.
pour le bien de tous ceux qui sont arrivés ici après avoir essayé d'installer pydoop sous pypy, cette solution qui a été adoptée dans 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
casse l'installation sous pypy parce que PyPy sysconfig ne fournit pas du tout la variable 'OPT', ce qui la fait avorter quand elle essaie d'appliquer strip() à None. La Solution est juste de commenter tout le bloc.