Bug 1325632 - part 4 - split out framework for testing flags; r=chmanchester
authorNathan Froyd <froydnj@mozilla.com>
Wed, 15 Nov 2017 13:53:16 -0500
changeset 392045 aeaf5db9a9e276ddb59b512926d95b858c4e1ccf
parent 392044 c7756d08443dfc817b2d8894e7259c6d6d4726b8
child 392046 402cad93aa6ece010f3c834b9d20e431c4ee8f8b
push id32909
push usercbrindusan@mozilla.com
push dateWed, 15 Nov 2017 22:25:14 +0000
treeherdermozilla-central@f41930a869a8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerschmanchester
bugs1325632
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1325632 - part 4 - split out framework for testing flags; r=chmanchester We have code to test whether particular flags are supported for the compiler we're using. Unfortunately, that code is tied up with checking for warning flags. We're about to add a separate facility for generic compilation flags, and we'd like to avoid cutting and pasting code if possible. Let's split the core code out into a separate, reusable function.
build/moz.configure/compile-checks.configure
--- a/build/moz.configure/compile-checks.configure
+++ b/build/moz.configure/compile-checks.configure
@@ -73,16 +73,71 @@ def check_header(header, language='C++',
 @template
 def check_headers(*headers, **kwargs):
     checks = []
     for header in headers:
         checks.append(check_header(header, **kwargs))
     return checks
 
 
+# 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; 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 flags unconditionally.
+@template
+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)
+
+    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, list_of_flags = {
+            c_compiler: ('C', cflags),
+            cxx_compiler: ('C++', cxxflags),
+        }[c]
+
+        @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, flag))
+
+        @depends(result, list_of_flags)
+        def maybe_add_flag(result, list_of_flags):
+            if result:
+                list_of_flags.append(flag)
+
+
 @dependable
 def warnings_cflags():
     return []
 
 
 @dependable
 def warnings_cxxflags():
     return []
@@ -96,59 +151,31 @@ def warnings_cxxflags():
 #   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 is not None:
-        compilers = (compiler,)
+    # 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:
-        compilers = (c_compiler, cxx_compiler)
-
-    if when is None:
-        when = always
-
-    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]
+        flags = ['-Werror', warning]
 
-        # 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)
 
-        @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:
-                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.