cc1plus: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
Question:
I am building a C++ extension for use in Python. I am seeing this warning being generated during the compilation process – when a type:
python setup.py build_ext -i
What is causing it, and how do I fix it?
BTW, here is a copy of my setup file:
#!/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"],
)
I am using gcc 4.4.3 on Ubuntu
Answers:
I can answer part of the question, why you’re getting the message.
Something in your build process is invoking gcc on a C++ source file with the option -Wstrict-prototypes
. For C and Objective-C, this causes the compiler to warn about old-style function declarations that don’t declare the types of arguments.
For C++, this option doesn’t make sense; such declarations aren’t even allowed by the language (prototypes are mandatory).
(I don’t know why the message mentions Ada; -Wstrict-prototypes
makes even less sense for Ada than for C++. It’s not a huge deal, but I’ve submitted this bug report, marked as RESOLVED/FIXED as of 2015-12-06.)
The solution should be to remove the -Wstrict-prototypes
option from the invocation of gcc. But since you’re not invoking gcc directly, it’s difficult to know how to do that.
I was able to reproduce the warning using your setup.py
, after manually creating a dummy example_wrap.cxx
file:
% 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++
...
So it’s probably a minor bug in Python’s build_ext
.
But since it’s only a warning, not a fatal error, I’d say you can safely ignore it. gcc warns about the meaningless option, but then it just ignores it.
EDIT:
Looking through the Python-2.7.2 sources, this section of configure.in
might be the culprit:
case $GCC in
yes)
if test "$CC" != 'g++' ; then
STRICT_PROTO="-Wstrict-prototypes"
fi
(I’m assuming that’s invoked when using build_ext
.)
It turns on the -Wstrict-prototypes
option only if the compiler is not being invoked as g++
— but in your case it’s using the gcc
command to compile C++ source code. And in Lib/distutils/command/build_ext.py
, build_extension()
doesn’t pay attention to the source file language when invoking self.compiler.compile()
, only when invoking self.compiler.link_shared_object()
. (Which seems odd; for compilers other than gcc, you wouldn’t necessarily be able to use the same command to compile C and C++ — and it makes more sense to use the g++
command anyway, even if you’re not linking.)
UPDATE: A Python bug report was submitted: https://bugs.python.org/issue9031, and closed as a duplicate of this one: https://bugs.python.org/issue1222585, which is still open as I write this.
But as I said, it’s only a warning and you can probably safely ignore it. Perhaps the Python maintainers can use the above information to fix the problem in a future release.
More specifically, distutils uses the same options that python was built with, you can add options using extra_compile_args
in creating the distutils.core.Extension
but there does not appear to be a way to remove existing arguments in gcc or distutils.
See http://bugs.python.org/issue9031 for details, it has been closed as a duplicate of http://bugs.python.org/issue1222585, but 9031 details this aspect of the problem
-Wstrict-prototypes
option is read by distutils from /usr/lib/pythonX.Y/config/Makefile
as part of OPT variable. It seems hackish, but you can override it by setting os.environ['OPT']
in your setup.py.
Here is a code that seems not too harmful:
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'
)
The following code fragment in setup.py will remove all instances of this pesky flag:
# 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", "")
# ==================================
For the sake of anyone arriving here after trying to install pydoop under pypy, this solution which was adopted in 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
breaks the installation under pypy because pypy sysconfig does not supply the ‘OPT’ variable at all, causing it to abort when it tries to apply strip() to None. Solution is just to comment out the whole block.
Removing -Wstrict-prototypes from the OPT environment variable has no effect. What works is to subclass build_ext
as follows:
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)
and then use my_build_ext
inside the setup
function:
setup(cmdclass = {'build_ext': my_build_ext})
This is a Python 3.x solution with 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},
...
)
I am building a C++ extension for use in Python. I am seeing this warning being generated during the compilation process – when a type:
python setup.py build_ext -i
What is causing it, and how do I fix it?
BTW, here is a copy of my setup file:
#!/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"],
)
I am using gcc 4.4.3 on Ubuntu
I can answer part of the question, why you’re getting the message.
Something in your build process is invoking gcc on a C++ source file with the option -Wstrict-prototypes
. For C and Objective-C, this causes the compiler to warn about old-style function declarations that don’t declare the types of arguments.
For C++, this option doesn’t make sense; such declarations aren’t even allowed by the language (prototypes are mandatory).
(I don’t know why the message mentions Ada; -Wstrict-prototypes
makes even less sense for Ada than for C++. It’s not a huge deal, but I’ve submitted this bug report, marked as RESOLVED/FIXED as of 2015-12-06.)
The solution should be to remove the -Wstrict-prototypes
option from the invocation of gcc. But since you’re not invoking gcc directly, it’s difficult to know how to do that.
I was able to reproduce the warning using your setup.py
, after manually creating a dummy example_wrap.cxx
file:
% 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++
...
So it’s probably a minor bug in Python’s build_ext
.
But since it’s only a warning, not a fatal error, I’d say you can safely ignore it. gcc warns about the meaningless option, but then it just ignores it.
EDIT:
Looking through the Python-2.7.2 sources, this section of configure.in
might be the culprit:
case $GCC in
yes)
if test "$CC" != 'g++' ; then
STRICT_PROTO="-Wstrict-prototypes"
fi
(I’m assuming that’s invoked when using build_ext
.)
It turns on the -Wstrict-prototypes
option only if the compiler is not being invoked as g++
— but in your case it’s using the gcc
command to compile C++ source code. And in Lib/distutils/command/build_ext.py
, build_extension()
doesn’t pay attention to the source file language when invoking self.compiler.compile()
, only when invoking self.compiler.link_shared_object()
. (Which seems odd; for compilers other than gcc, you wouldn’t necessarily be able to use the same command to compile C and C++ — and it makes more sense to use the g++
command anyway, even if you’re not linking.)
UPDATE: A Python bug report was submitted: https://bugs.python.org/issue9031, and closed as a duplicate of this one: https://bugs.python.org/issue1222585, which is still open as I write this.
But as I said, it’s only a warning and you can probably safely ignore it. Perhaps the Python maintainers can use the above information to fix the problem in a future release.
More specifically, distutils uses the same options that python was built with, you can add options using extra_compile_args
in creating the distutils.core.Extension
but there does not appear to be a way to remove existing arguments in gcc or distutils.
See http://bugs.python.org/issue9031 for details, it has been closed as a duplicate of http://bugs.python.org/issue1222585, but 9031 details this aspect of the problem
-Wstrict-prototypes
option is read by distutils from /usr/lib/pythonX.Y/config/Makefile
as part of OPT variable. It seems hackish, but you can override it by setting os.environ['OPT']
in your setup.py.
Here is a code that seems not too harmful:
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'
)
The following code fragment in setup.py will remove all instances of this pesky flag:
# 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", "")
# ==================================
For the sake of anyone arriving here after trying to install pydoop under pypy, this solution which was adopted in 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
breaks the installation under pypy because pypy sysconfig does not supply the ‘OPT’ variable at all, causing it to abort when it tries to apply strip() to None. Solution is just to comment out the whole block.
Removing -Wstrict-prototypes from the OPT environment variable has no effect. What works is to subclass build_ext
as follows:
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)
and then use my_build_ext
inside the setup
function:
setup(cmdclass = {'build_ext': my_build_ext})
This is a Python 3.x solution with 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},
...
)