diff options
author | Martok <martok@martoks-place.de> | 2023-06-21 01:33:03 +0200 |
---|---|---|
committer | Martok <martok@martoks-place.de> | 2023-06-21 22:18:07 +0200 |
commit | 14836b0c1716038c21c0f1e4e52d42059f730745 (patch) | |
tree | 75dfecb51b4dcbbf9b5063edc7b694fb69f9ab05 /build | |
parent | 30829b7a07451ec67b48a22a28f64ab073a1970c (diff) | |
download | uxp-14836b0c1716038c21c0f1e4e52d42059f730745.tar.gz |
Issue #2262 - Build with C++14 by default
Including infrastructure changes to ensure correct opts for future changes.
Based-on: m-c 1325632, 1418047, 1418573
Diffstat (limited to 'build')
-rw-r--r-- | build/moz.configure/compile-checks.configure | 148 | ||||
-rw-r--r-- | build/moz.configure/flags.configure | 13 | ||||
-rw-r--r-- | build/moz.configure/toolchain.configure | 47 | ||||
-rw-r--r-- | build/moz.configure/warnings.configure | 6 |
4 files changed, 154 insertions, 60 deletions
diff --git a/build/moz.configure/compile-checks.configure b/build/moz.configure/compile-checks.configure index 9ef9496db5..7f45b2d4b1 100644 --- a/build/moz.configure/compile-checks.configure +++ b/build/moz.configure/compile-checks.configure @@ -74,55 +74,45 @@ def check_headers(*headers, **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) +# Determine whether to add a given flag to the given lists of flags for C or +# C++ compilation. +# - `flag` is the flag to test +# - `cflags` is a @depends function for the list of C compiler flags to add to +# - `cxxflags` is a @depends function for the list of C++ compiler flags to +# add to +# - `test_flags` is a list of flags to pass to the compiler instead of merely +# passing `flag`. This is especially useful for checking warning flags. If +# this list is empty, `flag` will be passed on its own. # - `compiler` (optional) is the compiler to test against (c_compiler or # cxx_compiler, from toolchain.configure). When omitted, both compilers -# are tested. +# are tested; the list of flags added to is dependent on the compiler 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(). +# adds it to the list of flags unconditionally. @template -def check_and_add_gcc_warning(warning, compiler=None, when=None, check=True): - if compiler: +def check_and_add_flags(flag, cflags, cxxflags, test_flags, + compiler=None, when=None, check=True): + if compiler is not None: compilers = (compiler,) else: compilers = (c_compiler, cxx_compiler) - when = when or always + if when is None: + when = always + + if test_flags: + flags = test_flags + else: + flags = [flag] for c in compilers: assert c in (c_compiler, cxx_compiler) - lang, warnings_flags = { - c_compiler: ('C', warnings_cflags), - cxx_compiler: ('C++', warnings_cxxflags), + lang, list_of_flags = { + c_compiler: ('C', cflags), + cxx_compiler: ('C++', 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'): @@ -131,13 +121,51 @@ def check_and_add_gcc_warning(warning, compiler=None, when=None, check=True): if check: result = c.try_compile( flags=flags, when=result, - check_msg='whether the %s compiler supports %s' % (lang, - warning)) + check_msg='whether the %s compiler supports %s' % (lang, flag)) - @depends(result, warnings_flags) - def maybe_add_flag(result, warnings_flags): + @depends(result, list_of_flags) + def maybe_add_flag(result, list_of_flags): if result: - warnings_flags.append(warning) + list_of_flags.append(flag) + + +@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): + # 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] + + check_and_add_flags(warning, warnings_cflags, warnings_cxxflags, + flags, compiler=compiler, when=when, check=check) + # Add the given warning to the list of warning flags for the build. # - `warning` is the warning flag (e.g. -Wfoo) @@ -149,3 +177,45 @@ def check_and_add_gcc_warning(warning, compiler=None, when=None, check=True): @template def add_gcc_warning(warning, compiler=None, when=None): check_and_add_gcc_warning(warning, compiler, when, check=False) + + +# Like the warning checks above, but for general compilation flags. +@dependable +def compilation_cflags(): + return [] + + +@dependable +def compilation_cxxflags(): + return [] + + +# Tests whether GCC or clang support the given compilation flag; if the flag +# is supported, add it to the list of compilation flags for the build. +# - `flag` is the flag to test +# - `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 flags unconditionally. This is only meant for +# add_gcc_flag(). +@template +def check_and_add_gcc_flag(flag, compiler=None, when=None, check=True): + flags = ['-Werror', flag] + + check_and_add_flags(flag, compilation_cflags, compilation_cxxflags, + flags, compiler=compiler, when=when, check=check) + + +# Add the given flag to the list of flags for the build. +# - `flag` is the flag (e.g. -fno-sized-deallocation) +# - `compiler` (optional) is the compiler to add the flag for (c_compiler or +# cxx_compiler, from toolchain.configure). When omitted, the flag is added +# for both compilers. +# - `when` (optional) is a @depends function or option name conditioning +# when the flag is wanted. +@template +def add_gcc_flag(warning, compiler=None, when=None): + check_and_add_gcc_flag(warning, compiler, when, check=False) diff --git a/build/moz.configure/flags.configure b/build/moz.configure/flags.configure new file mode 100644 index 0000000000..c98f5088db --- /dev/null +++ b/build/moz.configure/flags.configure @@ -0,0 +1,13 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# We support C++14, but we don't want to enable the sized deallocation +# facilities in C++14 yet. +check_and_add_gcc_flag('-fno-sized-deallocation', compiler=cxx_compiler) + +# Please keep these last in this file. +add_old_configure_assignment('_COMPILATION_CFLAGS', compilation_cflags) +add_old_configure_assignment('_COMPILATION_CXXFLAGS', compilation_cxxflags) diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure index 5f03cb2b74..cc0540ea1c 100644 --- a/build/moz.configure/toolchain.configure +++ b/build/moz.configure/toolchain.configure @@ -171,6 +171,9 @@ include('compilers-util.configure') def try_preprocess(compiler, language, source): return try_invoke_compiler(compiler, language, source, ['-E']) +def msvc_std14(): return '-std:c++14' +def msvc_std17(): return '-std:c++17' + @imports(_from='mozbuild.configure.constants', _import='CompilerType') @imports(_from='mozbuild.configure.constants', _import='CPU_preprocessor_checks') @@ -279,6 +282,13 @@ def get_compiler_info(compiler, language): 'Unknown compiler or compiler not supported.') cplusplus = int(data.get('cplusplus', '0L').rstrip('L')) + if language == 'C++' and type=='msvc' and cplusplus == 199711: + # Note: MSVC still reports 199711L for __cplusplus. Fix the report by + # assuming it does what we asked it to do. + if msvc_std14() in compiler: + cplusplus = 201402 + elif msvc_std17() in compiler: + cplusplus = 201703 stdc_version = int(data.get('STDC_VERSION', '0L').rstrip('L')) version = data.get('VERSION') @@ -330,16 +340,17 @@ def check_compiler(compiler, language, target): if info.type in ('clang-cl', 'clang', 'gcc'): append_flag('-std=gnu99') - # Note: MSVC, while supporting C++11, still reports 199711L for __cplusplus. # Note: this is a strict version check because we used to always add - # -std=gnu++11. + # -std=gnu++14. + cxx14_version = 201402 if info.language == 'C++': - if info.type in ('clang', 'gcc') and info.language_version != 201103: - append_flag('-std=gnu++11') + if info.type in ('clang', 'gcc') and info.language_version != cxx14_version: + append_flag('-std=gnu++14') # MSVC 2015 headers include C++14 features, but don't guard them # with appropriate checks. - if info.type == 'clang-cl' and info.language_version != 201402: + if info.type == 'clang-cl' and info.language_version != cxx14_version: append_flag('-std=c++14') + # MSVC from 2015 on defaults to C++14. # We force clang-cl to emulate Visual C++ 2015 Update 3 with fallback to # cl.exe. @@ -644,11 +655,17 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None, host_or_target) # Check that the additional flags we got are enough to not require any - # more flags. - if info.flags: - flags += info.flags - info = check_compiler(wrapper + [compiler] + flags, language, - host_or_target) + # more flags. If we get an exception, just ignore it; it's liable to be + # invalid command-line flags, which means the compiler we're checking + # doesn't support those command-line flags and will fail one or more of + # the checks below. + try: + if info.flags: + flags += info.flags + info = check_compiler(wrapper + [compiler] + flags, language, + host_or_target) + except FatalCheckError: + pass if not info.target_cpu or info.target_cpu != host_or_target.cpu: raise FatalCheckError( @@ -674,10 +691,6 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None, info.target_endianness or 'unknown', host_or_target_str, host_or_target.endianness)) - if info.flags: - raise FatalCheckError( - 'Unknown compiler or compiler not supported.') - # Compiler version checks # =================================================== # Check the compiler version here instead of in `compiler_version` so @@ -689,7 +702,7 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None, % info.version) # If you want to bump the version check here search for - # __cpp_static_assert above, and see the associated comment. + # cxx_alignof above, and see the associated comment. if info.type == 'clang' and not info.version: raise FatalCheckError( 'Only clang/llvm 3.6 or newer is supported.') @@ -704,6 +717,10 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None, 'See https://developer.mozilla.org/en/' 'Windows_Build_Prerequisites' % info.version) + if info.flags: + raise FatalCheckError( + 'Unknown compiler or compiler not supported.') + return namespace( wrapper=wrapper, compiler=compiler, diff --git a/build/moz.configure/warnings.configure b/build/moz.configure/warnings.configure index b2c3758047..2edf1748ad 100644 --- a/build/moz.configure/warnings.configure +++ b/build/moz.configure/warnings.configure @@ -18,9 +18,6 @@ add_old_configure_assignment( # 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') @@ -55,9 +52,6 @@ check_and_add_gcc_warning('-Wclass-varargs') 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 |