setup.py: add detection of supported compiler warning options

This allows us to get rid of the PYCAIRO_WARN env var and always
use warning options.
This is a copy of what I added on pygobject.
This commit is contained in:
Christoph Reiter 2018-03-16 19:16:53 +01:00
parent cd1a6a6d93
commit 8637672c8a
2 changed files with 112 additions and 45 deletions

View File

@ -4,45 +4,45 @@ matrix:
dist: trusty
language: python
python: "2.7"
env: PYCAIRO_WARN=1 CFLAGS="-Werror -coverage"
env: CFLAGS="-Werror -coverage"
- os: linux
dist: trusty
language: python
python: "3.3"
env: PYCAIRO_WARN=1 CFLAGS="-Werror -coverage"
env: CFLAGS="-Werror -coverage"
- os: linux
dist: trusty
language: python
python: "3.4"
env: PYCAIRO_WARN=1 CFLAGS="-Werror -coverage"
env: CFLAGS="-Werror -coverage"
- os: linux
dist: trusty
language: python
python: "3.5"
env: PYCAIRO_WARN=1 CFLAGS="-Werror -coverage"
env: CFLAGS="-Werror -coverage"
- os: linux
dist: trusty
language: python
python: "3.6"
env: PYCAIRO_WARN=1 CFLAGS="-Werror -coverage"
env: CFLAGS="-Werror -coverage"
- os: linux
dist: trusty
language: python
python: "pypy2.7-5.10.0"
env: PYCAIRO_WARN=1 CFLAGS="-Werror -coverage"
env: CFLAGS="-Werror -coverage"
- os: linux
dist: trusty
language: python
python: "pypy3.5-5.10.1"
env: PYCAIRO_WARN=1 CFLAGS="-coverage"
env: CFLAGS="-coverage"
- os: osx
osx_image: xcode7.3
language: generic
env: PYVER="3" PYCAIRO_WARN=1 CFLAGS="-Werror -coverage"
env: PYVER="3" CFLAGS="-Werror -coverage"
- os: osx
osx_image: xcode7.3
language: generic
env: PYVER="2" PYCAIRO_WARN=1 CFLAGS="-Werror -coverage"
env: PYVER="2" CFLAGS="-Werror -coverage"
install:

139
setup.py
View File

@ -13,6 +13,7 @@ if os.environ.get("PYCAIRO_SETUPTOOLS"):
from distutils.core import Extension, setup, Command, Distribution
from distutils.ccompiler import new_compiler
from distutils.sysconfig import customize_compiler
from distutils import log
from distutils import sysconfig
@ -58,6 +59,105 @@ def pkg_config_parse(opt, pkg):
return [x.lstrip(opt) for x in output.split()]
def filter_compiler_arguments(compiler, args):
"""Given a compiler instance and a list of compiler warning flags
returns the list of supported flags.
"""
if compiler.compiler_type == "msvc":
# TODO
return []
extra = []
def check_arguments(compiler, args):
p = subprocess.Popen(
[compiler.compiler[0]] + args + extra + ["-x", "c", "-E", "-"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = p.communicate(b"int i;\n")
if p.returncode != 0:
text = stderr.decode("ascii", "replace")
return False, [a for a in args if a in text]
else:
return True, []
def check_argument(compiler, arg):
return check_arguments(compiler, [arg])[0]
# clang doesn't error out for unknown options, force it to
if check_argument(compiler, '-Werror=unknown-warning-option'):
extra += ['-Werror=unknown-warning-option']
if check_argument(compiler, '-Werror=unused-command-line-argument'):
extra += ['-Werror=unused-command-line-argument']
# first try to remove all arguments contained in the error message
supported = list(args)
while 1:
ok, maybe_unknown = check_arguments(compiler, supported)
if ok:
return supported
elif not maybe_unknown:
break
for unknown in maybe_unknown:
if not check_argument(compiler, unknown):
supported.remove(unknown)
# hm, didn't work, try each argument one by one
supported = []
for arg in args:
if check_argument(compiler, arg):
supported.append(arg)
return supported
def add_ext_warn_flags(ext, compiler):
args = [
"-Wall",
"-Warray-bounds",
"-Wcast-align",
"-Wconversion",
"-Wdeclaration-after-statement",
"-Wextra",
"-Wformat=2",
"-Wformat-nonliteral",
"-Wformat-security",
"-Wimplicit-function-declaration",
"-Winit-self",
"-Winline",
"-Wmissing-format-attribute",
"-Wmissing-noreturn",
"-Wnested-externs",
"-Wold-style-definition",
"-Wpacked",
"-Wpointer-arith",
"-Wreturn-type",
"-Wshadow",
"-Wsign-compare",
"-Wstrict-aliasing",
"-Wundef",
"-Wunused-but-set-variable",
]
if sys.version_info[:2] not in [(3, 3), (3, 4)]:
args += [
"-Wswitch-default",
]
args += [
"-Wno-missing-field-initializers",
"-Wno-unused-parameter",
]
# silence clang for unused gcc CFLAGS added by Debian
args += [
"-Wno-unused-command-line-argument",
]
ext.extra_compile_args += filter_compiler_arguments(compiler, args)
class test_cmd(Command):
description = "run tests"
user_options = [
@ -291,42 +391,9 @@ class build_ext(du_build_ext):
# while MACROS like Py_RETURN_TRUE require it.
ext.extra_compile_args += ["-fno-strict-aliasing"]
if os.environ.get("PYCAIRO_WARN"):
ext.extra_compile_args += [
"-Wall",
"-Wundef",
"-Wextra",
"-Wno-missing-field-initializers",
"-Wno-unused-parameter",
"-Wnested-externs",
"-Wpointer-arith",
"-Wno-missing-field-initializers",
"-Wdeclaration-after-statement",
"-Wformat=2",
"-Wold-style-definition",
"-Wcast-align",
"-Wformat-nonliteral",
"-Wformat-security",
"-Wsign-compare",
"-Wstrict-aliasing",
"-Wshadow",
"-Winline",
"-Wpacked",
"-Wmissing-format-attribute",
"-Wmissing-noreturn",
"-Winit-self",
"-Wunused-but-set-variable",
"-Warray-bounds",
"-Wimplicit-function-declaration",
"-Wreturn-type",
"-Wconversion",
"-Wno-unknown-warning-option",
]
if sys.version_info[:2] not in [(3, 3), (3, 4)]:
ext.extra_compile_args += [
"-Wswitch-default",
]
compiler = new_compiler(compiler=self.compiler)
customize_compiler(compiler)
add_ext_warn_flags(ext, compiler)
if self.enable_xpyb:
if sys.version_info[0] != 2: