Bug 1264609 - Derive HOST_CXX from CXX when it makes sense. r?ted draft
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 22 Apr 2016 08:00:11 +0900
changeset 355258 fb63a77c99455a8813e95fe91481270a0298d2cd
parent 355167 98ac8c1e7fed89d704025fe8337a4f3c68546586
child 519157 1df29c8861bb989d66781f5828d6b70d6113c8fd
push id16246
push userbmo:mh+mozilla@glandium.org
push dateFri, 22 Apr 2016 06:54:03 +0000
reviewersted
bugs1264609
milestone48.0a1
Bug 1264609 - Derive HOST_CXX from CXX when it makes sense. r?ted
build/moz.configure/toolchain.configure
python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
--- a/build/moz.configure/toolchain.configure
+++ b/build/moz.configure/toolchain.configure
@@ -377,30 +377,35 @@ def default_cxx_compilers(c_compiler):
             return (os.path.join(dir, file.replace('clang', 'clang++')),)
 
         return (c_compiler.compiler,)
 
     return default_cxx_compilers
 
 
 @template
-def compiler(language, host_or_target, c_compiler=None, other_compiler=None):
+def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
+             other_c_compiler=None):
     '''Template handling the generic base checks for the compiler for the
     given `language` on the given platform (`host_or_target`).
     `host_or_target` is either `host` or `target` (the @depends functions
     from init.configure.
-    When the language in 'C++', `c_compiler` is the result of the `compiler`
+    When the language is 'C++', `c_compiler` is the result of the `compiler`
     template for the language 'C' for the same `host_or_target`.
     When `host_or_target` is `host`, `other_compiler` is the result of the
     `compiler` template for the same `language` for `target`.
+    When `host_or_target` is `host` and the language is 'C++',
+    `other_c_compiler` is the result of the `compiler` template for the
+    language 'C' for `target`.
     '''
     assert host_or_target in (host, target)
     assert language in ('C', 'C++')
     assert language == 'C' or c_compiler
     assert host_or_target == target or other_compiler
+    assert language == 'C' or host_or_target == target or other_c_compiler
 
     host_or_target_str = {
         host: 'host',
         target: 'target',
     }[host_or_target]
 
     var = {
         ('C', target): 'CC',
@@ -434,24 +439,29 @@ def compiler(language, host_or_target, c
         without_flags = list(takewhile(lambda x: not x.startswith('-'), cmd))
 
         return namespace(
             wrapper=without_flags[:-1],
             compiler=without_flags[-1],
             flags=cmd[len(without_flags):],
         )
 
-    # Derive the host C compiler from the target C compiler when no explicit
-    # compiler was given and we're not cross compiling.
-    if language == 'C' and host_or_target == host:
-        @depends(provided_compiler, other_compiler, cross_compiling)
-        def provided_compiler(value, other_compiler, cross_compiling):
+    # Derive the host compiler from the corresponding target compiler when no
+    # explicit compiler was given and we're not cross compiling. For the C++
+    # compiler, though, prefer to derive from the host C compiler when it
+    # doesn't match the target C compiler.
+    if host_or_target == host:
+        args = (c_compiler, other_c_compiler) if other_c_compiler else ()
+
+        @depends(provided_compiler, other_compiler, cross_compiling, *args)
+        def provided_compiler(value, other_compiler, cross_compiling, *args):
             if value:
                 return value
-            if not cross_compiling:
+            c_compiler, other_c_compiler = args if args else (None, None)
+            if not cross_compiling and c_compiler == other_c_compiler:
                 return other_compiler
 
     # Normally, we'd use `var` instead of `_var`, but the interaction with
     # old-configure complicates things, and for now, we a) can't take the plain
     # result from check_prog as CC/CXX/HOST_CC/HOST_CXX and b) have to let
     # old-configure AC_SUBST it (because it's autoconf doing it, not us)
     compiler = check_prog('_%s' % var, what=what, progs=default_compilers,
                           input=delayed_getattr(provided_compiler, 'compiler'))
@@ -579,9 +589,10 @@ def compiler(language, host_or_target, c
 
     return valid_compiler
 
 
 c_compiler = compiler('C', target)
 cxx_compiler = compiler('C++', target, c_compiler=c_compiler)
 host_c_compiler = compiler('C', host, other_compiler=c_compiler)
 host_cxx_compiler = compiler('C++', host, c_compiler=host_c_compiler,
-                             other_compiler=cxx_compiler)
+                             other_compiler=cxx_compiler,
+                             other_c_compiler=c_compiler)
--- a/python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
+++ b/python/mozbuild/mozbuild/test/configure/test_toolchain_configure.py
@@ -727,17 +727,16 @@ class LinuxToolchainTest(BaseToolchainTe
             'CC': '/opt/clang/bin/clang',
             'CXX': '/opt/clang/bin/clang++',
         })
         # With CXX guess too.
         self.do_toolchain_test(paths, result, environ={
             'CC': '/opt/clang/bin/clang',
         })
 
-    @unittest.expectedFailure  # Bug 1264609
     def test_atypical_name(self):
         paths = dict(self.PATHS)
         paths.update({
             '/usr/bin/afl-clang-fast': CLANG_3_6,
             '/usr/bin/afl-clang-fast++': CLANGXX_3_6,
         })
         afl_clang_result = dict(self.CLANG_3_6_RESULT)
         afl_clang_result['compiler'] = '/usr/bin/afl-clang-fast'
@@ -746,16 +745,38 @@ class LinuxToolchainTest(BaseToolchainTe
         self.do_toolchain_test(paths, {
             'c_compiler': afl_clang_result,
             'cxx_compiler': afl_clangxx_result,
         }, environ={
             'CC': 'afl-clang-fast',
             'CXX': 'afl-clang-fast++',
         })
 
+    def test_mixed_compilers(self):
+        self.do_toolchain_test(self.PATHS, {
+            'c_compiler': self.CLANG_3_6_RESULT,
+            'cxx_compiler': self.CLANGXX_3_6_RESULT,
+            'host_c_compiler': self.GCC_4_9_RESULT,
+            'host_cxx_compiler': self.GXX_4_9_RESULT,
+        }, environ={
+            'CC': 'clang',
+            'HOST_CC': 'gcc',
+        })
+
+        self.do_toolchain_test(self.PATHS, {
+            'c_compiler': self.CLANG_3_6_RESULT,
+            'cxx_compiler': self.CLANGXX_3_6_RESULT,
+            'host_c_compiler': self.GCC_4_9_RESULT,
+            'host_cxx_compiler': self.GXX_4_9_RESULT,
+        }, environ={
+            'CC': 'clang',
+            'CXX': 'clang++',
+            'HOST_CC': 'gcc',
+        })
+
 
 class OSXToolchainTest(BaseToolchainTest):
     HOST = 'x86_64-apple-darwin11.2.0'
     PATHS = LinuxToolchainTest.PATHS
     CLANG_3_3_RESULT = LinuxToolchainTest.CLANG_3_3_RESULT
     CLANGXX_3_3_RESULT = LinuxToolchainTest.CLANGXX_3_3_RESULT
     CLANG_3_6_RESULT = LinuxToolchainTest.CLANG_3_6_RESULT
     CLANGXX_3_6_RESULT = LinuxToolchainTest.CLANGXX_3_6_RESULT