Bug 1288313 - Ensure the host and target compilers build for the right CPU. r=chmanchester

And for GCC and clang, try to see if adding -m32, -m64 or --target
works if they don't.

--HG--
extra : rebase_source : 874bc2404a5ccc48e938bc7d9b2fe67ba625cb3e
This commit is contained in:
Mike Hommey 2016-04-22 15:08:55 +09:00
Родитель 2578400d7b
Коммит ae1ab9803b
4 изменённых файлов: 504 добавлений и 40 удалений

Просмотреть файл

@ -195,6 +195,8 @@ def try_preprocess(compiler, language, source):
@imports(_from='mozbuild.configure.constants', _import='CompilerType')
@imports(_from='mozbuild.configure.constants',
_import='CPU_preprocessor_checks')
@imports(_from='textwrap', _import='dedent')
def get_compiler_info(compiler, language):
'''Returns information about the given `compiler` (command line in the
@ -245,6 +247,20 @@ def get_compiler_info(compiler, language):
#endif
''')
# While we're doing some preprocessing, we might as well do some more
# preprocessor-based tests at the same time, to check the toolchain
# matches what we want.
for n, (value, condition) in enumerate(CPU_preprocessor_checks.iteritems()):
check += dedent('''\
#%(if)s %(condition)s
%%CPU %(value)s
''' % {
'if': 'elif' if n else 'if',
'condition': condition,
'value': value,
})
check += '#endif\n'
result = try_preprocess(compiler, language, check)
if not result:
@ -283,13 +299,14 @@ def get_compiler_info(compiler, language):
return namespace(
type=type,
version=version,
cpu=data.get('CPU'),
language='C++' if cplusplus else 'C',
language_version=cplusplus if cplusplus else stdc_version,
)
@imports(_from='mozbuild.shellutil', _import='quote')
def check_compiler(compiler, language):
def check_compiler(compiler, language, target):
info = get_compiler_info(compiler, language)
flags = []
@ -329,9 +346,26 @@ def check_compiler(compiler, language):
flags.append('-fms-compatibility-version=18.00.30723')
flags.append('-fallback')
# Check compiler target
# --------------------------------------------------------------------
if not info.cpu or info.cpu != target.cpu:
if info.type == 'clang':
append_flag('--target=%s' % target.toolchain)
elif info.type == 'gcc':
same_arch_different_bits = (
('x86', 'x86_64'),
('ppc', 'ppc64'),
('sparc', 'sparc64'),
)
if (target.cpu, info.cpu) in same_arch_different_bits:
append_flag('-m32')
elif (info.cpu, target.cpu) in same_arch_different_bits:
append_flag('-m64')
return namespace(
type=info.type,
version=info.version,
target_cpu=info.cpu,
flags=flags,
)
@ -453,6 +487,9 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
# 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.
# As a special case, since clang supports all kinds of targets in the same
# executable, when cross compiling with clang, default to the same compiler
# as the target compiler, resetting flags.
if host_or_target == host:
args = (c_compiler, other_c_compiler) if other_c_compiler else ()
@ -463,6 +500,11 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
c_compiler, other_c_compiler = args if args else (None, None)
if not cross_compiling and c_compiler == other_c_compiler:
return other_compiler
if cross_compiling and other_compiler.type == 'clang':
return namespace(**{
k: [] if k == 'flags' else v
for k, v in other_compiler.__dict__.iteritems()
})
# 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
@ -471,10 +513,11 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
compiler = check_prog('_%s' % var, what=what, progs=default_compilers,
input=delayed_getattr(provided_compiler, 'compiler'))
@depends(compiler, provided_compiler, compiler_wrapper)
@depends(compiler, provided_compiler, compiler_wrapper, host_or_target)
@checking('whether %s can be used' % what, lambda x: bool(x))
@imports(_from='mozbuild.shellutil', _import='quote')
def valid_compiler(compiler, provided_compiler, compiler_wrapper):
def valid_compiler(compiler, provided_compiler, compiler_wrapper,
host_or_target):
wrapper = list(compiler_wrapper or ())
if provided_compiler:
provided_wrapper = list(provided_compiler.wrapper)
@ -508,13 +551,22 @@ def compiler(language, host_or_target, c_compiler=None, other_compiler=None,
quote(os.path.dirname(found_compiler)),
quote(os.path.dirname(full_path)))
info = check_compiler(wrapper + [compiler] + flags, language)
info = check_compiler(wrapper + [compiler] + flags, language,
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)
info = check_compiler(wrapper + [compiler] + flags, language,
host_or_target)
if not info.target_cpu or info.target_cpu != host_or_target.cpu:
raise FatalCheckError(
'%s %s compiler target CPU (%s) does not match --%s CPU (%s)'
% (host_or_target_str.capitalize(), language,
info.target_cpu or 'unknown', host_or_target_str,
host_or_target.raw_cpu))
if info.flags:
raise FatalCheckError(

Просмотреть файл

@ -5,6 +5,7 @@
from __future__ import absolute_import, print_function, unicode_literals
from mozbuild.util import EnumString
from collections import OrderedDict
CompilerType = EnumString.subclass(
@ -59,3 +60,24 @@ Endianness = EnumString.subclass(
'big',
'little',
)
# The order of those checks matter
CPU_preprocessor_checks = OrderedDict((
('x86', '__i386__ || _M_IX86'),
('x86_64', '__x86_64__ || _M_X64'),
('arm', '__arm__ || _M_ARM'),
('aarch64', '__aarch64__'),
('ia64', '__ia64__'),
('s390x', '__s390x__'),
('s390', '__s390__'),
('ppc64', '__powerpc64__'),
('ppc', '__powerpc__'),
('Alpha', '__alpha__'),
('hppa', '__hppa__'),
('sparc64', '__sparc__ && __arch64__'),
('sparc', '__sparc__'),
('mips64', '__mips64'),
('mips32', '__mips__'),
))
assert sorted(CPU_preprocessor_checks.keys()) == sorted(CPU.POSSIBLE_VALUES)

Просмотреть файл

@ -74,6 +74,30 @@ GXX_4_9 = GXX('4.9.3')
GCC_5 = GCC('5.2.1') + DEFAULT_C11
GXX_5 = GXX('5.2.1')
GCC_PLATFORM_X86 = {
None: {
'__i386__': 1,
},
'-m64': {
'__i386__': False,
'__x86_64__': 1,
},
}
GCC_PLATFORM_X86_64 = {
None: {
'__x86_64__': 1,
},
'-m32': {
'__x86_64__': False,
'__i386__': 1,
},
}
GCC_PLATFORM_ARM = {
'__arm__': 1,
}
@memoize
def CLANG_BASE(version):
@ -107,6 +131,26 @@ CLANGXX_3_6 = CLANGXX('3.6.2') + {
}
def CLANG_PLATFORM(gcc_platform):
base = {
'--target=x86_64-linux-gnu': GCC_PLATFORM_X86_64[None],
'--target=x86_64-darwin11.2.0': GCC_PLATFORM_X86_64[None],
'--target=i686-linux-gnu': GCC_PLATFORM_X86[None],
'--target=i686-darwin11.2.0': GCC_PLATFORM_X86[None],
'--target=arm-linux-gnu': GCC_PLATFORM_ARM,
}
undo_gcc_platform = {
k: {symbol: False for symbol in gcc_platform[None]}
for k in base
}
return FakeCompiler(gcc_platform, undo_gcc_platform, base)
CLANG_PLATFORM_X86 = CLANG_PLATFORM(GCC_PLATFORM_X86)
CLANG_PLATFORM_X86_64 = CLANG_PLATFORM(GCC_PLATFORM_X86_64)
@memoize
def VS(version):
version = Version(version)
@ -126,6 +170,14 @@ VS_2015 = VS('19.00.23026')
VS_2015u1 = VS('19.00.23506')
VS_2015u2 = VS('19.00.23918')
VS_PLATFORM_X86 = {
'_M_IX86': 600,
}
VS_PLATFORM_X86_64 = {
'_M_X64': 100,
}
# Note: In reality, the -std=gnu* options are only supported when preceded by
# -Xclang.
CLANG_CL_3_9 = (CLANG_BASE('3.9.0') + VS('18.00.00000') + DEFAULT_C11 +
@ -137,6 +189,9 @@ CLANG_CL_3_9 = (CLANG_BASE('3.9.0') + VS('18.00.00000') + DEFAULT_C11 +
'-fms-compatibility-version=18.00.30723': VS('18.00.30723')[None],
}
CLANG_CL_PLATFORM_X86 = FakeCompiler(VS_PLATFORM_X86, GCC_PLATFORM_X86[None])
CLANG_CL_PLATFORM_X86_64 = FakeCompiler(VS_PLATFORM_X86_64, GCC_PLATFORM_X86_64[None])
class BaseToolchainTest(BaseConfigureTest):
def setUp(self):
@ -197,18 +252,18 @@ class BaseToolchainTest(BaseConfigureTest):
class LinuxToolchainTest(BaseToolchainTest):
PATHS = {
'/usr/bin/gcc': GCC_4_9,
'/usr/bin/g++': GXX_4_9,
'/usr/bin/gcc-4.7': GCC_4_7,
'/usr/bin/g++-4.7': GXX_4_7,
'/usr/bin/gcc-5': GCC_5,
'/usr/bin/g++-5': GXX_5,
'/usr/bin/clang': CLANG_3_6,
'/usr/bin/clang++': CLANGXX_3_6,
'/usr/bin/clang-3.6': CLANG_3_6,
'/usr/bin/clang++-3.6': CLANGXX_3_6,
'/usr/bin/clang-3.3': CLANG_3_3,
'/usr/bin/clang++-3.3': CLANGXX_3_3,
'/usr/bin/gcc': GCC_4_9 + GCC_PLATFORM_X86_64,
'/usr/bin/g++': GXX_4_9 + GCC_PLATFORM_X86_64,
'/usr/bin/gcc-4.7': GCC_4_7 + GCC_PLATFORM_X86_64,
'/usr/bin/g++-4.7': GXX_4_7 + GCC_PLATFORM_X86_64,
'/usr/bin/gcc-5': GCC_5 + GCC_PLATFORM_X86_64,
'/usr/bin/g++-5': GXX_5 + GCC_PLATFORM_X86_64,
'/usr/bin/clang': CLANG_3_6 + CLANG_PLATFORM_X86_64,
'/usr/bin/clang++': CLANGXX_3_6 + CLANG_PLATFORM_X86_64,
'/usr/bin/clang-3.6': CLANG_3_6 + CLANG_PLATFORM_X86_64,
'/usr/bin/clang++-3.6': CLANGXX_3_6 + CLANG_PLATFORM_X86_64,
'/usr/bin/clang-3.3': CLANG_3_3 + CLANG_PLATFORM_X86_64,
'/usr/bin/clang++-3.3': CLANGXX_3_3 + CLANG_PLATFORM_X86_64,
}
GCC_4_7_RESULT = ('Only GCC 4.8 or newer is supported '
'(found version 4.7.3).')
@ -406,8 +461,8 @@ class LinuxToolchainTest(BaseToolchainTest):
def test_absolute_path(self):
paths = dict(self.PATHS)
paths.update({
'/opt/clang/bin/clang': CLANG_3_6,
'/opt/clang/bin/clang++': CLANGXX_3_6,
'/opt/clang/bin/clang': paths['/usr/bin/clang'],
'/opt/clang/bin/clang++': paths['/usr/bin/clang++'],
})
result = {
'c_compiler': self.CLANG_3_6_RESULT + {
@ -429,8 +484,8 @@ class LinuxToolchainTest(BaseToolchainTest):
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,
'/usr/bin/afl-clang-fast': paths['/usr/bin/clang'],
'/usr/bin/afl-clang-fast++': paths['/usr/bin/clang++'],
})
self.do_toolchain_test(paths, {
'c_compiler': self.CLANG_3_6_RESULT + {
@ -467,6 +522,82 @@ class LinuxToolchainTest(BaseToolchainTest):
})
class LinuxSimpleCrossToolchainTest(BaseToolchainTest):
TARGET = 'i686-pc-linux-gnu'
PATHS = LinuxToolchainTest.PATHS
GCC_4_9_RESULT = LinuxToolchainTest.GCC_4_9_RESULT
GXX_4_9_RESULT = LinuxToolchainTest.GXX_4_9_RESULT
CLANG_3_6_RESULT = LinuxToolchainTest.CLANG_3_6_RESULT
CLANGXX_3_6_RESULT = LinuxToolchainTest.CLANGXX_3_6_RESULT
def test_cross_gcc(self):
self.do_toolchain_test(self.PATHS, {
'c_compiler': self.GCC_4_9_RESULT + {
'flags': ['-m32']
},
'cxx_compiler': self.GXX_4_9_RESULT + {
'flags': ['-m32']
},
'host_c_compiler': self.GCC_4_9_RESULT,
'host_cxx_compiler': self.GXX_4_9_RESULT,
})
def test_cross_clang(self):
self.do_toolchain_test(self.PATHS, {
'c_compiler': self.CLANG_3_6_RESULT + {
'flags': ['--target=i686-linux-gnu'],
},
'cxx_compiler': self.CLANGXX_3_6_RESULT + {
'flags': ['--target=i686-linux-gnu'],
},
'host_c_compiler': self.CLANG_3_6_RESULT,
'host_cxx_compiler': self.CLANGXX_3_6_RESULT,
}, environ={
'CC': 'clang',
})
class LinuxX86_64CrossToolchainTest(BaseToolchainTest):
HOST = 'i686-pc-linux-gnu'
TARGET = 'x86_64-pc-linux-gnu'
PATHS = {
'/usr/bin/gcc': GCC_4_9 + GCC_PLATFORM_X86,
'/usr/bin/g++': GXX_4_9 + GCC_PLATFORM_X86,
'/usr/bin/clang': CLANG_3_6 + CLANG_PLATFORM_X86,
'/usr/bin/clang++': CLANGXX_3_6 + CLANG_PLATFORM_X86,
}
GCC_4_9_RESULT = LinuxToolchainTest.GCC_4_9_RESULT
GXX_4_9_RESULT = LinuxToolchainTest.GXX_4_9_RESULT
CLANG_3_6_RESULT = LinuxToolchainTest.CLANG_3_6_RESULT
CLANGXX_3_6_RESULT = LinuxToolchainTest.CLANGXX_3_6_RESULT
def test_cross_gcc(self):
self.do_toolchain_test(self.PATHS, {
'c_compiler': self.GCC_4_9_RESULT + {
'flags': ['-m64']
},
'cxx_compiler': self.GXX_4_9_RESULT + {
'flags': ['-m64']
},
'host_c_compiler': self.GCC_4_9_RESULT,
'host_cxx_compiler': self.GXX_4_9_RESULT,
})
def test_cross_clang(self):
self.do_toolchain_test(self.PATHS, {
'c_compiler': self.CLANG_3_6_RESULT + {
'flags': ['--target=x86_64-linux-gnu'],
},
'cxx_compiler': self.CLANGXX_3_6_RESULT + {
'flags': ['--target=x86_64-linux-gnu'],
},
'host_c_compiler': self.CLANG_3_6_RESULT,
'host_cxx_compiler': self.CLANGXX_3_6_RESULT,
}, environ={
'CC': 'clang',
})
class OSXToolchainTest(BaseToolchainTest):
HOST = 'x86_64-apple-darwin11.2.0'
PATHS = LinuxToolchainTest.PATHS
@ -530,14 +661,25 @@ class WindowsToolchainTest(BaseToolchainTest):
# For the purpose of this test, it doesn't matter that the paths are not
# real Windows paths.
PATHS = {
'/opt/VS_2013u2/bin/cl': VS_2013u2,
'/opt/VS_2013u3/bin/cl': VS_2013u3,
'/opt/VS_2015/bin/cl': VS_2015,
'/opt/VS_2015u1/bin/cl': VS_2015u1,
'/usr/bin/cl': VS_2015u2,
'/usr/bin/clang-cl': CLANG_CL_3_9,
'/opt/VS_2013u2/bin/cl': VS_2013u2 + VS_PLATFORM_X86,
'/opt/VS_2013u3/bin/cl': VS_2013u3 + VS_PLATFORM_X86,
'/opt/VS_2015/bin/cl': VS_2015 + VS_PLATFORM_X86,
'/opt/VS_2015u1/bin/cl': VS_2015u1 + VS_PLATFORM_X86,
'/usr/bin/cl': VS_2015u2 + VS_PLATFORM_X86,
'/usr/bin/clang-cl': CLANG_CL_3_9 + CLANG_CL_PLATFORM_X86,
'/usr/bin/gcc': GCC_4_9 + GCC_PLATFORM_X86,
'/usr/bin/g++': GXX_4_9 + GCC_PLATFORM_X86,
'/usr/bin/gcc-4.7': GCC_4_7 + GCC_PLATFORM_X86,
'/usr/bin/g++-4.7': GXX_4_7 + GCC_PLATFORM_X86,
'/usr/bin/gcc-5': GCC_5 + GCC_PLATFORM_X86,
'/usr/bin/g++-5': GXX_5 + GCC_PLATFORM_X86,
'/usr/bin/clang': CLANG_3_6 + CLANG_PLATFORM_X86,
'/usr/bin/clang++': CLANGXX_3_6 + CLANG_PLATFORM_X86,
'/usr/bin/clang-3.6': CLANG_3_6 + CLANG_PLATFORM_X86,
'/usr/bin/clang++-3.6': CLANGXX_3_6 + CLANG_PLATFORM_X86,
'/usr/bin/clang-3.3': CLANG_3_3 + CLANG_PLATFORM_X86,
'/usr/bin/clang++-3.3': CLANGXX_3_3 + CLANG_PLATFORM_X86,
}
PATHS.update(LinuxToolchainTest.PATHS)
VS_2013u2_RESULT = (
'This version (18.00.30501) of the MSVC compiler is not supported.\n'
@ -667,16 +809,61 @@ class WindowsToolchainTest(BaseToolchainTest):
'CXX': 'clang++-3.3',
})
def test_cannot_cross(self):
paths = {
'/usr/bin/cl': VS_2015u2 + VS_PLATFORM_X86_64,
}
self.do_toolchain_test(paths, {
'c_compiler': ('Target C compiler target CPU (x86_64) '
'does not match --target CPU (i686)'),
})
class CrossCompileToolchainTest(BaseToolchainTest):
class Windows64ToolchainTest(WindowsToolchainTest):
HOST = 'x86_64-pc-mingw32'
# For the purpose of this test, it doesn't matter that the paths are not
# real Windows paths.
PATHS = {
'/opt/VS_2013u2/bin/cl': VS_2013u2 + VS_PLATFORM_X86_64,
'/opt/VS_2013u3/bin/cl': VS_2013u3 + VS_PLATFORM_X86_64,
'/opt/VS_2015/bin/cl': VS_2015 + VS_PLATFORM_X86_64,
'/opt/VS_2015u1/bin/cl': VS_2015u1 + VS_PLATFORM_X86_64,
'/usr/bin/cl': VS_2015u2 + VS_PLATFORM_X86_64,
'/usr/bin/clang-cl': CLANG_CL_3_9 + CLANG_CL_PLATFORM_X86_64,
'/usr/bin/gcc': GCC_4_9 + GCC_PLATFORM_X86_64,
'/usr/bin/g++': GXX_4_9 + GCC_PLATFORM_X86_64,
'/usr/bin/gcc-4.7': GCC_4_7 + GCC_PLATFORM_X86_64,
'/usr/bin/g++-4.7': GXX_4_7 + GCC_PLATFORM_X86_64,
'/usr/bin/gcc-5': GCC_5 + GCC_PLATFORM_X86_64,
'/usr/bin/g++-5': GXX_5 + GCC_PLATFORM_X86_64,
'/usr/bin/clang': CLANG_3_6 + CLANG_PLATFORM_X86_64,
'/usr/bin/clang++': CLANGXX_3_6 + CLANG_PLATFORM_X86_64,
'/usr/bin/clang-3.6': CLANG_3_6 + CLANG_PLATFORM_X86_64,
'/usr/bin/clang++-3.6': CLANGXX_3_6 + CLANG_PLATFORM_X86_64,
'/usr/bin/clang-3.3': CLANG_3_3 + CLANG_PLATFORM_X86_64,
'/usr/bin/clang++-3.3': CLANGXX_3_3 + CLANG_PLATFORM_X86_64,
}
def test_cannot_cross(self):
paths = {
'/usr/bin/cl': VS_2015u2 + VS_PLATFORM_X86,
}
self.do_toolchain_test(paths, {
'c_compiler': ('Target C compiler target CPU (x86) '
'does not match --target CPU (x86_64)'),
})
class LinuxCrossCompileToolchainTest(BaseToolchainTest):
TARGET = 'arm-unknown-linux-gnu'
PATHS = {
'/usr/bin/arm-linux-gnu-gcc': GCC_4_9,
'/usr/bin/arm-linux-gnu-g++': GXX_4_9,
'/usr/bin/arm-linux-gnu-gcc-4.7': GCC_4_7,
'/usr/bin/arm-linux-gnu-g++-4.7': GXX_4_7,
'/usr/bin/arm-linux-gnu-gcc-5': GCC_5,
'/usr/bin/arm-linux-gnu-g++-5': GXX_5,
'/usr/bin/arm-linux-gnu-gcc': GCC_4_9 + GCC_PLATFORM_ARM,
'/usr/bin/arm-linux-gnu-g++': GXX_4_9 + GCC_PLATFORM_ARM,
'/usr/bin/arm-linux-gnu-gcc-4.7': GCC_4_7 + GCC_PLATFORM_ARM,
'/usr/bin/arm-linux-gnu-g++-4.7': GXX_4_7 + GCC_PLATFORM_ARM,
'/usr/bin/arm-linux-gnu-gcc-5': GCC_5 + GCC_PLATFORM_ARM,
'/usr/bin/arm-linux-gnu-g++-5': GXX_5 + GCC_PLATFORM_ARM,
}
PATHS.update(LinuxToolchainTest.PATHS)
ARM_GCC_4_7_RESULT = LinuxToolchainTest.GXX_4_7_RESULT
@ -691,17 +878,146 @@ class CrossCompileToolchainTest(BaseToolchainTest):
GCC_4_9_RESULT = LinuxToolchainTest.GCC_4_9_RESULT
GXX_4_9_RESULT = LinuxToolchainTest.GXX_4_9_RESULT
def test_cross_gcc(self):
self.do_toolchain_test(self.PATHS, {
PLATFORMS = {
'i686-pc-linux-gnu': GCC_PLATFORM_X86,
'x86_64-pc-linux-gnu': GCC_PLATFORM_X86_64,
'arm-unknown-linux-gnu': GCC_PLATFORM_ARM,
'aarch64-unknown-linux-gnu': {
'__aarch64__': 1,
},
'ia64-unknown-linux-gnu': {
'__ia64__': 1,
},
's390x-unknown-linux-gnu': {
'__s390x__': 1,
'__s390__': 1,
},
's390-unknown-linux-gnu': {
'__s390__': 1,
},
'powerpc64-unknown-linux-gnu': {
None: {
'__powerpc64__': 1,
'__powerpc__': 1,
},
'-m32': {
'__powerpc64__': False,
},
},
'powerpc-unknown-linux-gnu': {
None: {
'__powerpc__': 1,
},
'-m64': {
'__powerpc64__': 1,
},
},
'alpha-unknown-linux-gnu': {
'__alpha__': 1,
},
'hppa-unknown-linux-gnu': {
'__hppa__': 1,
},
'sparc64-unknown-linux-gnu': {
None: {
'__arch64__': 1,
'__sparc__': 1,
},
'-m32': {
'__arch64__': False,
},
},
'sparc-unknown-linux-gnu': {
None: {
'__sparc__': 1,
},
'-m64': {
'__arch64__': 1,
},
},
'mips64-unknown-linux-gnuabi64': {
'__mips64': 1,
'__mips__': 1,
},
'mips-unknown-linux-gnu': {
'__mips__': 1,
},
}
def do_test_cross_gcc_32_64(self, host, target):
self.HOST = host
self.TARGET = target
paths = {
'/usr/bin/gcc': GCC_4_9 + self.PLATFORMS[host],
'/usr/bin/g++': GXX_4_9 + self.PLATFORMS[host],
}
cross_flags = {
'flags': ['-m64' if '64' in target else '-m32']
}
self.do_toolchain_test(paths, {
'c_compiler': self.GCC_4_9_RESULT + cross_flags,
'cxx_compiler': self.GXX_4_9_RESULT + cross_flags,
'host_c_compiler': self.GCC_4_9_RESULT,
'host_cxx_compiler': self.GXX_4_9_RESULT,
})
self.HOST = LinuxCrossCompileToolchainTest.HOST
self.TARGET = LinuxCrossCompileToolchainTest.TARGET
def test_cross_x86_x64(self):
self.do_test_cross_gcc_32_64(
'i686-pc-linux-gnu', 'x86_64-pc-linux-gnu')
self.do_test_cross_gcc_32_64(
'x86_64-pc-linux-gnu', 'i686-pc-linux-gnu')
def test_cross_sparc_sparc64(self):
self.do_test_cross_gcc_32_64(
'sparc-unknown-linux-gnu', 'sparc64-unknown-linux-gnu')
self.do_test_cross_gcc_32_64(
'sparc64-unknown-linux-gnu', 'sparc-unknown-linux-gnu')
def test_cross_ppc_ppc64(self):
self.do_test_cross_gcc_32_64(
'powerpc-unknown-linux-gnu', 'powerpc64-unknown-linux-gnu')
self.do_test_cross_gcc_32_64(
'powerpc64-unknown-linux-gnu', 'powerpc-unknown-linux-gnu')
def do_test_cross_gcc(self, host, target):
self.HOST = host
self.TARGET = target
host_cpu = host.split('-')[0]
cpu, manufacturer, os = target.split('-', 2)
toolchain_prefix = '/usr/bin/%s-%s' % (cpu, os)
paths = {
'/usr/bin/gcc': GCC_4_9 + self.PLATFORMS[host],
'/usr/bin/g++': GXX_4_9 + self.PLATFORMS[host],
}
self.do_toolchain_test(paths, {
'c_compiler': ('Target C compiler target CPU (%s) '
'does not match --target CPU (%s)'
% (host_cpu, cpu)),
})
paths.update({
'%s-gcc' % toolchain_prefix: GCC_4_9 + self.PLATFORMS[target],
'%s-g++' % toolchain_prefix: GXX_4_9 + self.PLATFORMS[target],
})
self.do_toolchain_test(paths, {
'c_compiler': self.GCC_4_9_RESULT + {
'compiler': '/usr/bin/arm-linux-gnu-gcc',
'compiler': '%s-gcc' % toolchain_prefix,
},
'cxx_compiler': self.GXX_4_9_RESULT + {
'compiler': '/usr/bin/arm-linux-gnu-g++',
'compiler': '%s-g++' % toolchain_prefix,
},
'host_c_compiler': self.GCC_4_9_RESULT,
'host_cxx_compiler': self.GXX_4_9_RESULT,
})
self.HOST = LinuxCrossCompileToolchainTest.HOST
self.TARGET = LinuxCrossCompileToolchainTest.TARGET
def test_cross_gcc_misc(self):
for target in self.PLATFORMS:
if not target.endswith('-pc-linux-gnu'):
self.do_test_cross_gcc('x86_64-pc-linux-gnu', target)
def test_overridden_cross_gcc(self):
self.do_toolchain_test(self.PATHS, {
@ -754,6 +1070,79 @@ class CrossCompileToolchainTest(BaseToolchainTest):
'HOST_CC': 'clang',
})
def test_cross_clang(self):
cross_clang_result = self.CLANG_3_6_RESULT + {
'flags': ['--target=arm-linux-gnu'],
}
cross_clangxx_result = self.CLANGXX_3_6_RESULT + {
'flags': ['--target=arm-linux-gnu'],
}
self.do_toolchain_test(self.PATHS, {
'c_compiler': cross_clang_result,
'cxx_compiler': cross_clangxx_result,
'host_c_compiler': self.CLANG_3_6_RESULT,
'host_cxx_compiler': self.CLANGXX_3_6_RESULT,
}, environ={
'CC': 'clang',
'HOST_CC': 'clang',
})
self.do_toolchain_test(self.PATHS, {
'c_compiler': cross_clang_result,
'cxx_compiler': cross_clangxx_result,
'host_c_compiler': self.CLANG_3_6_RESULT,
'host_cxx_compiler': self.CLANGXX_3_6_RESULT,
}, environ={
'CC': 'clang',
})
def test_cross_atypical_clang(self):
paths = dict(self.PATHS)
paths.update({
'/usr/bin/afl-clang-fast': paths['/usr/bin/clang'],
'/usr/bin/afl-clang-fast++': paths['/usr/bin/clang++'],
})
afl_clang_result = self.CLANG_3_6_RESULT + {
'compiler': '/usr/bin/afl-clang-fast',
}
afl_clangxx_result = self.CLANGXX_3_6_RESULT + {
'compiler': '/usr/bin/afl-clang-fast++',
}
self.do_toolchain_test(paths, {
'c_compiler': afl_clang_result + {
'flags': ['--target=arm-linux-gnu'],
},
'cxx_compiler': afl_clangxx_result + {
'flags': ['--target=arm-linux-gnu'],
},
'host_c_compiler': afl_clang_result,
'host_cxx_compiler': afl_clangxx_result,
}, environ={
'CC': 'afl-clang-fast',
'CXX': 'afl-clang-fast++',
})
class OSXCrossToolchainTest(BaseToolchainTest):
TARGET = 'i686-apple-darwin11.2.0'
PATHS = LinuxToolchainTest.PATHS
CLANG_3_6_RESULT = LinuxToolchainTest.CLANG_3_6_RESULT
CLANGXX_3_6_RESULT = LinuxToolchainTest.CLANGXX_3_6_RESULT
def test_osx_cross(self):
self.do_toolchain_test(self.PATHS, {
'c_compiler': self.CLANG_3_6_RESULT + {
'flags': ['--target=i686-darwin11.2.0'],
},
'cxx_compiler': self.CLANGXX_3_6_RESULT + {
'flags': ['--target=i686-darwin11.2.0'],
},
'host_c_compiler': self.CLANG_3_6_RESULT,
'host_cxx_compiler': self.CLANGXX_3_6_RESULT,
}, environ={
'CC': 'clang',
})
if __name__ == '__main__':
main()

Просмотреть файл

@ -104,7 +104,8 @@ class ReadOnlyNamespace(object):
return not (self == other)
def __eq__(self, other):
return self is other or self.__dict__ == other.__dict__
return self is other or (
hasattr(other, '__dict__') and self.__dict__ == other.__dict__)
def __repr__(self):
return '<%s %r>' % (self.__class__.__name__, self.__dict__)