From 77ee4f3ce48e15bece3d36188ab7fec81a1a4f96 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Fri, 5 Aug 2016 17:13:48 +0900 Subject: [PATCH] Bug 1292463 - Move MOZ_C{,XX}_SUPPORTS_WARNING to python configure. r=chmanchester --- build/autoconf/compiler-opts.m4 | 186 ------------------ build/moz.configure/compile-checks.configure | 78 ++++++++ build/moz.configure/compilers-util.configure | 4 +- build/moz.configure/util.configure | 3 + build/moz.configure/warnings.configure | 98 +++++++++ js/src/old-configure.in | 9 - old-configure.in | 9 - .../test/configure/test_compile_checks.py | 143 +++++++++++++- 8 files changed, 322 insertions(+), 208 deletions(-) diff --git a/build/autoconf/compiler-opts.m4 b/build/autoconf/compiler-opts.m4 index 890c9c33f73d..c12d400cc94e 100644 --- a/build/autoconf/compiler-opts.m4 +++ b/build/autoconf/compiler-opts.m4 @@ -294,189 +294,3 @@ if test -n "$GCC_USE_GNU_LD"; then fi ]) - -dnl GCC and clang will fail if given an unknown warning option like -Wfoobar. -dnl But later versions won't fail if given an unknown negated warning option -dnl like -Wno-foobar. So when we are check for support of negated warning -dnl options, we actually test the positive form, but add the negated form to -dnl the flags variable. - -AC_DEFUN([MOZ_C_SUPPORTS_WARNING], -[ - AC_CACHE_CHECK(whether the C compiler supports $1$2, $3, - [ - AC_LANG_SAVE - AC_LANG_C - _SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Werror -W$2" - AC_TRY_COMPILE([], - [return(0);], - $3="yes", - $3="no") - CFLAGS="$_SAVE_CFLAGS" - AC_LANG_RESTORE - ]) - if test "${$3}" = "yes"; then - _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} $1$2" - fi -]) - -AC_DEFUN([MOZ_CXX_SUPPORTS_WARNING], -[ - AC_CACHE_CHECK(whether the C++ compiler supports $1$2, $3, - [ - AC_LANG_SAVE - AC_LANG_CPLUSPLUS - _SAVE_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS -Werror -W$2" - AC_TRY_COMPILE([], - [return(0);], - $3="yes", - $3="no") - CXXFLAGS="$_SAVE_CXXFLAGS" - AC_LANG_RESTORE - ]) - if test "${$3}" = "yes"; then - _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} $1$2" - fi -]) - -AC_DEFUN([MOZ_SET_WARNINGS_CFLAGS], -[ - # Turn on gcc/clang warnings: - # https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Warning-Options.html - - # -Wall - lots of useful warnings - # -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives - # -Wignored-qualifiers - catches return types with qualifiers like const - # -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void) - # -Wsign-compare - catches comparing signed/unsigned ints - # -Wtype-limits - catches overflow bugs, few false positives - # -Wunreachable-code - catches some dead code - _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall" - _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wempty-body" - _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wignored-qualifiers" - _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wpointer-arith" - _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wsign-compare" - _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wtype-limits" - _WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wunreachable-code" - - # -Wclass-varargs - catches objects passed by value to variadic functions. - # -Wloop-analysis - catches issues around loops - # -Wnon-literal-null-conversion - catches expressions used as a null pointer constant - # -Wstring-conversion - catches string literals used in boolean expressions - # -Wthread-safety - catches inconsistent use of mutexes - # - # XXX: at the time of writing, the version of clang used on the OS X test - # machines has a bug that causes it to reject some valid files if both - # -Wnon-literal-null-conversion and -Wsometimes-uninitialized are - # specified. We work around this by instead using - # -Werror=non-literal-null-conversion, but we only do that when - # --enable-warnings-as-errors is specified so that no unexpected fatal - # warnings are produced. - MOZ_C_SUPPORTS_WARNING(-W, class-varargs, ac_c_has_wclass_varargs) - MOZ_C_SUPPORTS_WARNING(-W, loop-analysis, ac_c_has_wloop_analysis) - - if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then - MOZ_C_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_c_has_non_literal_null_conversion) - fi - - MOZ_C_SUPPORTS_WARNING(-W, string-conversion, ac_c_has_wstring_conversion) - MOZ_C_SUPPORTS_WARNING(-W, thread-safety, ac_c_has_wthread_safety) - - # Turn off some non-useful warnings that -Wall turns on. - - # Prevent the following GCC warnings from being treated as errors: - # -Wmaybe-uninitialized - too many false positives - # -Wdeprecated-declarations - we don't want our builds held hostage when a - # platform-specific API becomes deprecated. - # -Wfree-nonheap-object - false positives during PGO - # -Warray-bounds - false positives depending on optimization - MOZ_C_SUPPORTS_WARNING(-W, no-error=maybe-uninitialized, ac_c_has_noerror_maybe_uninitialized) - MOZ_C_SUPPORTS_WARNING(-W, no-error=deprecated-declarations, ac_c_has_noerror_deprecated_declarations) - MOZ_C_SUPPORTS_WARNING(-W, no-error=array-bounds, ac_c_has_noerror_array_bounds) - - if test -n "$MOZ_PGO"; then - MOZ_C_SUPPORTS_WARNING(-W, no-error=coverage-mismatch, ac_c_has_noerror_coverage_mismatch) - MOZ_C_SUPPORTS_WARNING(-W, no-error=free-nonheap-object, ac_c_has_noerror_free_nonheap_object) - fi -]) - -AC_DEFUN([MOZ_SET_WARNINGS_CXXFLAGS], -[ - # Turn on gcc/clang warnings: - # https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Warning-Options.html - - # -Wall - lots of useful warnings - # -Wc++1[14z]-compat[-pedantic] - catches C++ version forward-compat issues - # -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives - # -Wignored-qualifiers - catches return types with qualifiers like const - # -Woverloaded-virtual - function declaration hides virtual function from base class - # -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void) - # -Wsign-compare - catches comparing signed/unsigned ints - # -Wtype-limits - catches overflow bugs, few false positives - # -Wunreachable-code - catches some dead code - # -Wwrite-strings - catches treating string literals as non-const - _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall" - _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wc++11-compat" - _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wempty-body" - _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wignored-qualifiers" - _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Woverloaded-virtual" - _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wpointer-arith" - _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wsign-compare" - _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wtype-limits" - _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wunreachable-code" - _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wwrite-strings" - - # -Wclass-varargs - catches objects passed by value to variadic functions. - # -Wimplicit-fallthrough - catches unintentional switch case fallthroughs - # -Wloop-analysis - catches issues around loops - # -Wnon-literal-null-conversion - catches expressions used as a null pointer constant - # -Wstring-conversion - catches string literals used in boolean expressions - # -Wthread-safety - catches inconsistent use of mutexes - # - # XXX: at the time of writing, the version of clang used on the OS X test - # machines has a bug that causes it to reject some valid files if both - # -Wnon-literal-null-conversion and -Wsometimes-uninitialized are - # specified. We work around this by instead using - # -Werror=non-literal-null-conversion, but we only do that when - # --enable-warnings-as-errors is specified so that no unexpected fatal - # warnings are produced. - MOZ_CXX_SUPPORTS_WARNING(-W, c++11-compat-pedantic, ac_cxx_has_wcxx11_compat_pedantic) - MOZ_CXX_SUPPORTS_WARNING(-W, c++14-compat, ac_cxx_has_wcxx14_compat) - MOZ_CXX_SUPPORTS_WARNING(-W, c++14-compat-pedantic, ac_cxx_has_wcxx14_compat_pedantic) - MOZ_CXX_SUPPORTS_WARNING(-W, c++1z-compat, ac_cxx_has_wcxx1z_compat) - MOZ_CXX_SUPPORTS_WARNING(-W, class-varargs, ac_cxx_has_wclass_varargs) - MOZ_CXX_SUPPORTS_WARNING(-W, implicit-fallthrough, ac_cxx_has_wimplicit_fallthrough) - MOZ_CXX_SUPPORTS_WARNING(-W, loop-analysis, ac_cxx_has_wloop_analysis) - - if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then - MOZ_CXX_SUPPORTS_WARNING(-Werror=, non-literal-null-conversion, ac_cxx_has_non_literal_null_conversion) - fi - - MOZ_CXX_SUPPORTS_WARNING(-W, string-conversion, ac_cxx_has_wstring_conversion) - MOZ_CXX_SUPPORTS_WARNING(-W, thread-safety, ac_cxx_has_wthread_safety) - - # Turn off some non-useful warnings that -Wall turns on. - - # -Wno-invalid-offsetof - we use offsetof on non-POD types frequently - _WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-invalid-offsetof" - - # -Wno-inline-new-delete - we inline 'new' and 'delete' in mozalloc - MOZ_CXX_SUPPORTS_WARNING(-Wno-, inline-new-delete, ac_cxx_has_wno_inline_new_delete) - - # Prevent the following GCC warnings from being treated as errors: - # -Wmaybe-uninitialized - too many false positives - # -Wdeprecated-declarations - we don't want our builds held hostage when a - # platform-specific API becomes deprecated. - # -Wfree-nonheap-object - false positives during PGO - # -Warray-bounds - false positives depending on optimization - MOZ_CXX_SUPPORTS_WARNING(-W, no-error=maybe-uninitialized, ac_cxx_has_noerror_maybe_uninitialized) - MOZ_CXX_SUPPORTS_WARNING(-W, no-error=deprecated-declarations, ac_cxx_has_noerror_deprecated_declarations) - MOZ_CXX_SUPPORTS_WARNING(-W, no-error=array-bounds, ac_cxx_has_noerror_array_bounds) - - if test -n "$MOZ_PGO"; then - MOZ_CXX_SUPPORTS_WARNING(-W, no-error=coverage-mismatch, ac_cxx_has_noerror_coverage_mismatch) - MOZ_CXX_SUPPORTS_WARNING(-W, no-error=free-nonheap-object, ac_cxx_has_noerror_free_nonheap_object) - fi -]) diff --git a/build/moz.configure/compile-checks.configure b/build/moz.configure/compile-checks.configure index fd771ef344c7..6013b5214eef 100644 --- a/build/moz.configure/compile-checks.configure +++ b/build/moz.configure/compile-checks.configure @@ -75,3 +75,81 @@ def check_headers(*headers, **kwargs): for header in headers: checks.append(check_header(header, **kwargs)) return checks + + +@depends(c_compiler) +def warnings_cflags(c_compiler): + return [] + +@depends(cxx_compiler) +def warnings_cxxflags(cxx_compiler): + return [] + + +# Tests whether GCC or clang support the given warning flag, and if it is, +# add it to the list of warning flags for the build. +# - `warning` is the warning flag (e.g. -Wfoo) +# - `compiler` (optional) is the compiler to test against (c_compiler or +# cxx_compiler, from toolchain.configure). When omitted, both compilers +# are tested. +# - `when` (optional) is a @depends function or option name conditioning +# when the warning flag is wanted. +# - `check`, when not set, skips checking whether the flag is supported and +# adds it to the list of warning flags unconditionally. This is only meant +# for add_gcc_warning(). +@template +def check_and_add_gcc_warning(warning, compiler=None, when=None, check=True): + if compiler: + compilers = (compiler,) + else: + compilers = (c_compiler, cxx_compiler) + + if not when: + when = depends('--help')(lambda _: True) + + for c in compilers: + assert c in (c_compiler, cxx_compiler) + lang, warnings_flags = { + c_compiler: ('C', warnings_cflags), + cxx_compiler: ('C++', warnings_cxxflags), + }[c] + + # GCC and clang will fail if given an unknown warning option like + # -Wfoobar. But later versions won't fail if given an unknown negated + # warning option like -Wno-foobar. So when we are checking for support + # of a negated warning option, we actually test the positive form, but + # add the negated form to the flags variable. + if (warning.startswith('-Wno-') and + not warning.startswith('-Wno-error=')): + flags = ['-Werror', '-W' + warning[5:]] + elif warning.startswith('-Werror='): + flags = [warning] + else: + flags = ['-Werror', warning] + + @depends(c, when) + def result(c, when): + if when and c.type in ('clang', 'gcc'): + return True + + if check: + result = c.try_compile( + flags=flags, when=result, + check_msg='whether the %s compiler supports %s' % (lang, + warning)) + + @depends(result, warnings_flags) + def maybe_add_flag(result, warnings_flags): + if result is not None: + warnings_flags.append(warning) + +# Add the given warning to the list of warning flags for the build. +# - `warning` is the warning flag (e.g. -Wfoo) +# - `compiler` (optional) is the compiler to add the flag for (c_compiler or +# cxx_compiler, from toolchain.configure). When omitted, the warning flag +# is added for both compilers. +# - `when` (optional) is a @depends function or option name conditioning +# when the warning flag is wanted. +@template +def add_gcc_warning(warning, compiler=None, when=None): + check_and_add_gcc_warning(warning, compiler, when, check=False) diff --git a/build/moz.configure/compilers-util.configure b/build/moz.configure/compilers-util.configure index 5a85df5e91da..9442e40adea1 100644 --- a/build/moz.configure/compilers-util.configure +++ b/build/moz.configure/compilers-util.configure @@ -22,7 +22,7 @@ def compiler_class(compiler): # - `check_msg` is the message to be printed to accompany compiling the # test program. def try_compile(self, includes=None, body='', flags=None, - check_msg=None, onerror=lambda: None): + check_msg=None, when=None, onerror=lambda: None): includes = includes or [] source_lines = ['#include <%s>' % f for f in includes] source = '\n'.join(source_lines) + '\n' @@ -48,7 +48,7 @@ def compiler_class(compiler): if flags: return flags[:] - @depends(self, extra_toolchain_flags) + @depends_when(self, extra_toolchain_flags, when=when) @checking_fn def func(compiler, extra_flags): flags = get_flags() or [] diff --git a/build/moz.configure/util.configure b/build/moz.configure/util.configure index 856a0476c508..c580d4d8302c 100644 --- a/build/moz.configure/util.configure +++ b/build/moz.configure/util.configure @@ -349,6 +349,9 @@ def depends_when(*args, **kwargs): if not len(kwargs) == 1 and kwargs.get('when'): die('depends_when requires a single keyword argument, "when"') when = kwargs['when'] + if not when: + return depends(*args) + def decorator(fn): @depends(when, *args) def wrapper(val, *args): diff --git a/build/moz.configure/warnings.configure b/build/moz.configure/warnings.configure index ad28ab589e95..273a41bd9136 100644 --- a/build/moz.configure/warnings.configure +++ b/build/moz.configure/warnings.configure @@ -11,3 +11,101 @@ js_option('--enable-warnings-as-errors', env='MOZ_ENABLE_WARNINGS_AS_ERRORS', add_old_configure_assignment( 'MOZ_ENABLE_WARNINGS_AS_ERRORS', depends('--enable-warnings-as-errors')(lambda x: bool(x))) + + +# GCC/Clang warnings: +# https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Warning-Options.html + +# lots of useful warnings +add_gcc_warning('-Wall') + +# catches C++ version forward-compat issues +add_gcc_warning('-Wc++11-compat', cxx_compiler) + +# catches bugs, e.g. "if (c); foo();", few false positives +add_gcc_warning('-Wempty-body') + +# catches return types with qualifiers like const +add_gcc_warning('-Wignored-qualifiers') + +# function declaration hides virtual function from base class +add_gcc_warning('-Woverloaded-virtual', cxx_compiler) + +# catches pointer arithmetic using NULL or sizeof(void) +add_gcc_warning('-Wpointer-arith') + +# catches comparing signed/unsigned ints +add_gcc_warning('-Wsign-compare') + +# catches overflow bugs, few false positives +add_gcc_warning('-Wtype-limits') + +# catches some dead code +add_gcc_warning('-Wunreachable-code') + +# catches treating string literals as non-const +add_gcc_warning('-Wwrite-strings', cxx_compiler) + +# turned on by -Wall, but we use offsetof on non-POD types frequently +add_gcc_warning('-Wno-invalid-offsetof', cxx_compiler) + +# catches objects passed by value to variadic functions. +check_and_add_gcc_warning('-Wclass-varargs') + +# catches issues around loops +check_and_add_gcc_warning('-Wloop-analysis') + +# catches C++ version forward-compat issues +check_and_add_gcc_warning('-Wc++11-compat-pedantic', cxx_compiler) +check_and_add_gcc_warning('-Wc++14-compat', cxx_compiler) +check_and_add_gcc_warning('-Wc++14-compat-pedantic', cxx_compiler) +check_and_add_gcc_warning('-Wc++1z-compat', cxx_compiler) + +# catches unintentional switch case fallthroughs +check_and_add_gcc_warning('-Wimplicit-fallthrough', cxx_compiler) + +# catches expressions used as a null pointer constant +# XXX: at the time of writing, the version of clang used on the OS X test +# machines has a bug that causes it to reject some valid files if both +# -Wnon-literal-null-conversion and -Wsometimes-uninitialized are +# specified. We work around this by instead using +# -Werror=non-literal-null-conversion, but we only do that when +# --enable-warnings-as-errors is specified so that no unexpected fatal +# warnings are produced. +check_and_add_gcc_warning('-Werror=non-literal-null-conversion', + when='--enable-warnings-as-errors') + +# catches string literals used in boolean expressions +check_and_add_gcc_warning('-Wstring-conversion') + +# catches inconsistent use of mutexes +check_and_add_gcc_warning('-Wthread-safety') + +# we inline 'new' and 'delete' in mozalloc +check_and_add_gcc_warning('-Wno-inline-new-delete', cxx_compiler) + +# Prevent the following GCC warnings from being treated as errors: +# too many false positives +check_and_add_gcc_warning('-Wno-error=maybe-uninitialized') + +# we don't want our builds held hostage when a platform-specific API +# becomes deprecated. +check_and_add_gcc_warning('-Wno-error=deprecated-declarations') + +# false positives depending on optimization +check_and_add_gcc_warning('-Wno-error=array-bounds') + +# can't get rid of those PGO warnings +check_and_add_gcc_warning('-Wno-error=coverage-mismatch', when='MOZ_PGO') + +# false positives during PGO +check_and_add_gcc_warning('-Wno-error=free-nonheap-object', when='MOZ_PGO') + +# We use mix of both POSIX and Win32 printf format across the tree, so format +# warnings are useless on mingw. +check_and_add_gcc_warning('-Wno-format', + when=depends(target)(lambda t: t.kernel == 'WINNT')) + +# Please keep these last in this file +add_old_configure_assignment('_WARNINGS_CFLAGS', warnings_cflags) +add_old_configure_assignment('_WARNINGS_CXXFLAGS', warnings_cxxflags) diff --git a/js/src/old-configure.in b/js/src/old-configure.in index 7d98b4f6d986..f8636350b728 100644 --- a/js/src/old-configure.in +++ b/js/src/old-configure.in @@ -562,8 +562,6 @@ if test "$GNU_CC"; then AC_MSG_RESULT([no]) LDFLAGS=$_SAVE_LDFLAGS) - MOZ_SET_WARNINGS_CFLAGS - _DEFINES_CFLAGS='-include $(topobjdir)/js/src/js-confdefs.h -DMOZILLA_CLIENT' _USE_CPP_INCLUDE_FLAG=1 @@ -583,8 +581,6 @@ else fi if test "$GNU_CXX"; then - MOZ_SET_WARNINGS_CXXFLAGS - _DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(topobjdir)/js/src/js-confdefs.h' _USE_CPP_INCLUDE_FLAG=1 @@ -770,11 +766,6 @@ case "$target" in WIN32_CONSOLE_EXE_LDFLAGS=-mconsole WIN32_GUI_EXE_LDFLAGS=-mwindows - - # We use mix of both POSIX and Win32 printf format across the tree, so format - # warnings are useless on mingw. - MOZ_C_SUPPORTS_WARNING(-Wno-, format, ac_c_has_wno_format) - MOZ_CXX_SUPPORTS_WARNING(-Wno-, format, ac_cxx_has_wno_format) else TARGET_COMPILER_ABI=msvc HOST_CC='$(CC)' diff --git a/old-configure.in b/old-configure.in index 6577ebf8c116..2b8e95a0c11e 100644 --- a/old-configure.in +++ b/old-configure.in @@ -785,8 +785,6 @@ if test "$GNU_CC"; then fi fi - MOZ_SET_WARNINGS_CFLAGS - _DEFINES_CFLAGS='-include $(topobjdir)/mozilla-config.h -DMOZILLA_CLIENT' _USE_CPP_INCLUDE_FLAG=1 @@ -811,8 +809,6 @@ if test "$GNU_CXX"; then # FIXME: Let us build with strict aliasing. bug 414641. CXXFLAGS="$CXXFLAGS -fno-exceptions -fno-strict-aliasing" - MOZ_SET_WARNINGS_CXXFLAGS - _DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(topobjdir)/mozilla-config.h' _USE_CPP_INCLUDE_FLAG=1 @@ -1116,11 +1112,6 @@ case "$target" in # and NSS with -mnop-fun-dllimport flag. The drawback of this solution is that # function thunks need to be generated for cross-DLL calls. MOZ_FOLD_LIBS_FLAGS=-mnop-fun-dllimport - - # We use mix of both POSIX and Win32 printf format across the tree, so format - # warnings are useless on mingw. - MOZ_C_SUPPORTS_WARNING(-Wno-, format, ac_c_has_wno_format) - MOZ_CXX_SUPPORTS_WARNING(-Wno-, format, ac_cxx_has_wno_format) else TARGET_COMPILER_ABI=msvc HOST_LD='$(LD)' diff --git a/python/mozbuild/mozbuild/test/configure/test_compile_checks.py b/python/mozbuild/mozbuild/test/configure/test_compile_checks.py index 61a0594a9b31..ad47c34d4480 100644 --- a/python/mozbuild/mozbuild/test/configure/test_compile_checks.py +++ b/python/mozbuild/mozbuild/test/configure/test_compile_checks.py @@ -18,8 +18,7 @@ from mozunit import main from test_toolchain_helpers import FakeCompiler -class TestHeaderChecks(unittest.TestCase): - +class BaseCompileChecks(unittest.TestCase): def get_mock_compiler(self, expected_test_content=None, expected_flags=None): expected_flags = expected_flags or [] def mock_compiler(stdin, args): @@ -59,6 +58,7 @@ class TestHeaderChecks(unittest.TestCase): def c_compiler(_): return namespace( flags=[], + type='gcc', compiler=os.path.abspath('/usr/bin/mockcc'), wrapper=[], language='C', @@ -69,6 +69,7 @@ class TestHeaderChecks(unittest.TestCase): def cxx_compiler(_): return namespace( flags=[], + type='gcc', compiler=os.path.abspath('/usr/bin/mockcc'), wrapper=[], language='C++', @@ -93,6 +94,8 @@ class TestHeaderChecks(unittest.TestCase): return config, out.getvalue(), status + +class TestHeaderChecks(BaseCompileChecks): def test_try_compile_include(self): expected_test_content = textwrap.dedent('''\ #include @@ -259,5 +262,141 @@ class TestHeaderChecks(unittest.TestCase): ''')) +class TestWarningChecks(BaseCompileChecks): + def get_warnings(self): + return textwrap.dedent('''\ + set_config('_WARNINGS_CFLAGS', warnings_cflags) + set_config('_WARNINGS_CXXFLAGS', warnings_cxxflags) + ''') + + def test_check_and_add_gcc_warning(self): + for flag, expected_flags in ( + ('-Wfoo', ['-Werror', '-Wfoo']), + ('-Wno-foo', ['-Werror', '-Wfoo']), + ('-Werror=foo', ['-Werror=foo']), + ('-Wno-error=foo', ['-Wno-error=foo']), + ): + cmd = textwrap.dedent('''\ + check_and_add_gcc_warning('%s') + ''' % flag) + self.get_warnings() + + config, out, status = self.do_compile_test( + cmd, expected_flags=expected_flags) + self.assertEqual(status, 0) + self.assertEqual(config, { + '_WARNINGS_CFLAGS': [flag], + '_WARNINGS_CXXFLAGS': [flag], + }) + self.assertEqual(out, textwrap.dedent('''\ + checking whether the C compiler supports {flag}... yes + checking whether the C++ compiler supports {flag}... yes + '''.format(flag=flag))) + + def test_check_and_add_gcc_warning_one(self): + cmd = textwrap.dedent('''\ + check_and_add_gcc_warning('-Wfoo', cxx_compiler) + ''') + self.get_warnings() + + config, out, status = self.do_compile_test(cmd) + self.assertEqual(status, 0) + self.assertEqual(config, { + '_WARNINGS_CFLAGS': [], + '_WARNINGS_CXXFLAGS': ['-Wfoo'], + }) + self.assertEqual(out, textwrap.dedent('''\ + checking whether the C++ compiler supports -Wfoo... yes + ''')) + + def test_check_and_add_gcc_warning_when(self): + cmd = textwrap.dedent('''\ + @depends('--help') + def never(_): + return False + check_and_add_gcc_warning('-Wfoo', cxx_compiler, when=never) + ''') + self.get_warnings() + + config, out, status = self.do_compile_test(cmd) + self.assertEqual(status, 0) + self.assertEqual(config, { + '_WARNINGS_CFLAGS': [], + '_WARNINGS_CXXFLAGS': [], + }) + self.assertEqual(out, '') + + cmd = textwrap.dedent('''\ + @depends('--help') + def always(_): + return True + check_and_add_gcc_warning('-Wfoo', cxx_compiler, when=always) + ''') + self.get_warnings() + + config, out, status = self.do_compile_test(cmd) + self.assertEqual(status, 0) + self.assertEqual(config, { + '_WARNINGS_CFLAGS': [], + '_WARNINGS_CXXFLAGS': ['-Wfoo'], + }) + self.assertEqual(out, textwrap.dedent('''\ + checking whether the C++ compiler supports -Wfoo... yes + ''')) + + def test_add_gcc_warning(self): + cmd = textwrap.dedent('''\ + add_gcc_warning('-Wfoo') + ''') + self.get_warnings() + + config, out, status = self.do_compile_test(cmd) + self.assertEqual(status, 0) + self.assertEqual(config, { + '_WARNINGS_CFLAGS': ['-Wfoo'], + '_WARNINGS_CXXFLAGS': ['-Wfoo'], + }) + self.assertEqual(out, '') + + def test_add_gcc_warning_one(self): + cmd = textwrap.dedent('''\ + add_gcc_warning('-Wfoo', c_compiler) + ''') + self.get_warnings() + + config, out, status = self.do_compile_test(cmd) + self.assertEqual(status, 0) + self.assertEqual(config, { + '_WARNINGS_CFLAGS': ['-Wfoo'], + '_WARNINGS_CXXFLAGS': [], + }) + self.assertEqual(out, '') + + def test_add_gcc_warning_when(self): + cmd = textwrap.dedent('''\ + @depends('--help') + def never(_): + return False + add_gcc_warning('-Wfoo', c_compiler, when=never) + ''') + self.get_warnings() + + config, out, status = self.do_compile_test(cmd) + self.assertEqual(status, 0) + self.assertEqual(config, { + '_WARNINGS_CFLAGS': [], + '_WARNINGS_CXXFLAGS': [], + }) + self.assertEqual(out, '') + + cmd = textwrap.dedent('''\ + @depends('--help') + def always(_): + return True + add_gcc_warning('-Wfoo', c_compiler, when=always) + ''') + self.get_warnings() + + config, out, status = self.do_compile_test(cmd) + self.assertEqual(status, 0) + self.assertEqual(config, { + '_WARNINGS_CFLAGS': ['-Wfoo'], + '_WARNINGS_CXXFLAGS': [], + }) + self.assertEqual(out, '') + + if __name__ == '__main__': main()