Bug 1264609 - Derive HOST_CXX from CXX when it makes sense. r?ted
--- 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