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, } GCC_4_7_RESULT = ('Only GCC 4.8 or newer is supported ' '(found version 4.7.3).') GXX_4_7_RESULT = GCC_4_7_RESULT GCC_4_9_RESULT = CompilerResult( flags=['-std=gnu99'], version='4.9.3', type='gcc', compiler='/usr/bin/gcc', ) GXX_4_9_RESULT = CompilerResult( flags=['-std=gnu++11'], version='4.9.3', type='gcc', compiler='/usr/bin/g++', ) GCC_5_RESULT = CompilerResult( flags=['-std=gnu99'], version='5.2.1', type='gcc', compiler='/usr/bin/gcc-5', ) GXX_5_RESULT = CompilerResult( flags=['-std=gnu++11'], version='5.2.1', type='gcc', compiler='/usr/bin/g++-5', ) CLANG_3_3_RESULT = CompilerResult( flags=[], version='3.3.0', type='clang', compiler='/usr/bin/clang-3.3', ) CLANGXX_3_3_RESULT = 'Only clang/llvm 3.4 or newer is supported.' CLANG_3_6_RESULT = CompilerResult( flags=['-std=gnu99'], version='3.6.2', type='clang', compiler='/usr/bin/clang', ) CLANGXX_3_6_RESULT = CompilerResult( flags=['-std=gnu++11'], version='3.6.2', type='clang', compiler='/usr/bin/clang++', ) def test_gcc(self): # We'll try gcc and clang, and find gcc first. self.do_toolchain_test( self.PATHS, { 'c_compiler': self.GCC_4_9_RESULT, 'cxx_compiler': self.GXX_4_9_RESULT, }) def test_unsupported_gcc(self): self.do_toolchain_test(self.PATHS, { 'c_compiler': self.GCC_4_7_RESULT, }, environ={ 'CC': 'gcc-4.7', 'CXX': 'g++-4.7', }) # Maybe this should be reporting the mismatched version instead. self.do_toolchain_test(self.PATHS, { 'c_compiler': self.GCC_4_9_RESULT, 'cxx_compiler': self.GXX_4_7_RESULT, }, environ={ 'CXX': 'g++-4.7', }) def test_overridden_gcc(self): self.do_toolchain_test(self.PATHS, { 'c_compiler': self.GCC_5_RESULT, 'cxx_compiler': self.GXX_5_RESULT, }, environ={ 'CC': 'gcc-5', 'CXX': 'g++-5', }) def test_guess_cxx(self): # When CXX is not set, we guess it from CC. self.do_toolchain_test(self.PATHS, { 'c_compiler': self.GCC_5_RESULT, 'cxx_compiler': self.GXX_5_RESULT, }, environ={ 'CC': 'gcc-5', }) def test_mismatched_gcc(self): self.do_toolchain_test(self.PATHS, { 'c_compiler': self.GCC_4_9_RESULT, 'cxx_compiler': ('The target C compiler is version 4.9.3, while the target ' 'C++ compiler is version 5.2.1. Need to use the same compiler ' 'version.'), }, environ={ 'CXX': 'g++-5', }) self.do_toolchain_test(self.PATHS, { 'c_compiler': self.GCC_4_9_RESULT, 'cxx_compiler': self.GXX_4_9_RESULT, 'host_c_compiler': self.GCC_4_9_RESULT, 'host_cxx_compiler': ('The host C compiler is version 4.9.3, while the host ' 'C++ compiler is version 5.2.1. Need to use the same compiler ' 'version.'), }, environ={ 'HOST_CXX': 'g++-5', }) def test_mismatched_compiler(self): self.do_toolchain_test(self.PATHS, { 'c_compiler': self.GCC_4_9_RESULT, 'cxx_compiler': ('The target C compiler is gcc, while the target C++ compiler ' 'is clang. Need to use the same compiler suite.'), }, environ={ 'CXX': 'clang++', }) self.do_toolchain_test(self.PATHS, { 'c_compiler': self.GCC_4_9_RESULT, 'cxx_compiler': self.GXX_4_9_RESULT, 'host_c_compiler': self.GCC_4_9_RESULT, 'host_cxx_compiler': ('The host C compiler is gcc, while the host C++ compiler ' 'is clang. Need to use the same compiler suite.'), }, environ={ 'HOST_CXX': 'clang++', }) self.do_toolchain_test(self.PATHS, { 'c_compiler': '`%s` is not a C compiler.' % mozpath.abspath('/usr/bin/g++'), }, environ={ 'CC': 'g++', }) self.do_toolchain_test(self.PATHS, { 'c_compiler': self.GCC_4_9_RESULT, 'cxx_compiler': '`%s` is not a C++ compiler.' % mozpath.abspath('/usr/bin/gcc'), }, environ={ 'CXX': 'gcc', }) def test_clang(self): # We'll try gcc and clang, but since there is no gcc (gcc-x.y doesn't # count), find clang. paths = { k: v for k, v in self.PATHS.iteritems() if os.path.basename(k) not in ('gcc', 'g++') } self.do_toolchain_test( paths, { 'c_compiler': self.CLANG_3_6_RESULT, 'cxx_compiler': self.CLANGXX_3_6_RESULT, }) def test_guess_cxx_clang(self): # When CXX is not set, we guess it from CC. self.do_toolchain_test(self.PATHS, { 'c_compiler': self.CLANG_3_6_RESULT + { 'compiler': '/usr/bin/clang-3.6', }, 'cxx_compiler': self.CLANGXX_3_6_RESULT + { 'compiler': '/usr/bin/clang++-3.6', }, }, environ={ 'CC': 'clang-3.6', }) def test_unsupported_clang(self): # clang 3.3 C compiler is perfectly fine, but we need more for C++. self.do_toolchain_test(self.PATHS, { 'c_compiler': self.CLANG_3_3_RESULT, 'cxx_compiler': self.CLANGXX_3_3_RESULT, }, environ={ 'CC': 'clang-3.3', 'CXX': 'clang++-3.3', }) def test_no_supported_compiler(self): # Even if there are gcc-x.y or clang-x.y compilers available, we # don't try them. This could be considered something to improve. paths = { k: v for k, v in self.PATHS.iteritems() if os.path.basename(k) not in ('gcc', 'g++', 'clang', 'clang++') } self.do_toolchain_test( paths, { 'c_compiler': 'Cannot find the target C compiler', }) 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, }) result = { 'c_compiler': self.CLANG_3_6_RESULT + { 'compiler': '/opt/clang/bin/clang', }, 'cxx_compiler': self.CLANGXX_3_6_RESULT + { 'compiler': '/opt/clang/bin/clang++' }, } self.do_toolchain_test(paths, result, environ={ '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', }) 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, }) self.do_toolchain_test(paths, { 'c_compiler': self.CLANG_3_6_RESULT + { 'compiler': '/usr/bin/afl-clang-fast', }, 'cxx_compiler': self.CLANGXX_3_6_RESULT + { 'compiler': '/usr/bin/afl-clang-fast++', }, }, 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 WindowsToolchainTest(BaseToolchainTest): HOST = 'i686-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, '/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, } PATHS.update(LinuxToolchainTest.PATHS) VS_2013u2_RESULT = ( 'This version (18.00.30501) of the MSVC compiler is not supported.\n' 'You must install Visual C++ 2015 Update 2 or newer in order to build.\n' 'See https://developer.mozilla.org/en/Windows_Build_Prerequisites') VS_2013u3_RESULT = ( 'This version (18.00.30723) of the MSVC compiler is not supported.\n' 'You must install Visual C++ 2015 Update 2 or newer in order to build.\n' 'See https://developer.mozilla.org/en/Windows_Build_Prerequisites') VS_2015_RESULT = ( 'This version (19.00.23026) of the MSVC compiler is not supported.\n' 'You must install Visual C++ 2015 Update 2 or newer in order to build.\n' 'See https://developer.mozilla.org/en/Windows_Build_Prerequisites') VS_2015u1_RESULT = ( 'This version (19.00.23506) of the MSVC compiler is not supported.\n' 'You must install Visual C++ 2015 Update 2 or newer in order to build.\n' 'See https://developer.mozilla.org/en/Windows_Build_Prerequisites') VS_2015u2_RESULT = CompilerResult( flags=[], version='19.00.23918', type='msvc', compiler='/usr/bin/cl', ) CLANG_CL_3_9_RESULT = CompilerResult( flags=[ '-Xclang', '-std=gnu99', '-fms-compatibility-version=18.00.30723', '-fallback' ], version='18.00.30723', type='clang-cl', compiler='/usr/bin/clang-cl', ) CLANGXX_CL_3_9_RESULT = CompilerResult( flags=['-fms-compatibility-version=18.00.30723', '-fallback'], version='18.00.30723', type='clang-cl', compiler='/usr/bin/clang-cl', ) 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 GCC_4_7_RESULT = LinuxToolchainTest.GCC_4_7_RESULT GCC_4_9_RESULT = LinuxToolchainTest.GCC_4_9_RESULT GXX_4_9_RESULT = LinuxToolchainTest.GXX_4_9_RESULT GCC_5_RESULT = LinuxToolchainTest.GCC_5_RESULT GXX_5_RESULT = LinuxToolchainTest.GXX_5_RESULT # VS2015u2 or greater is required. def test_msvc(self): self.do_toolchain_test( self.PATHS, { 'c_compiler': self.VS_2015u2_RESULT, 'cxx_compiler': self.VS_2015u2_RESULT, }) def test_unsupported_msvc(self): self.do_toolchain_test(self.PATHS, { 'c_compiler': self.VS_2015u1_RESULT, }, environ={ 'CC': '/opt/VS_2015u1/bin/cl', }) self.do_toolchain_test(self.PATHS, { 'c_compiler': self.VS_2015_RESULT, }, environ={ 'CC': '/opt/VS_2015/bin/cl', }) self.do_toolchain_test(self.PATHS, { 'c_compiler': self.VS_2013u3_RESULT, }, environ={ 'CC': '/opt/VS_2013u3/bin/cl', }) self.do_toolchain_test(self.PATHS, { 'c_compiler': self.VS_2013u2_RESULT, }, environ={ 'CC': '/opt/VS_2013u2/bin/cl', }) def test_clang_cl(self): # We'll pick clang-cl if msvc can't be found. paths = { k: v for k, v in self.PATHS.iteritems() if os.path.basename(k) != 'cl' } self.do_toolchain_test( paths, { 'c_compiler': self.CLANG_CL_3_9_RESULT, 'cxx_compiler': self.CLANGXX_CL_3_9_RESULT, }) def test_gcc(self): # We'll pick GCC if msvc and clang-cl can't be found. paths = { k: v for k, v in self.PATHS.iteritems() if os.path.basename(k) not in ('cl', 'clang-cl') } self.do_toolchain_test( paths, { 'c_compiler': self.GCC_4_9_RESULT, 'cxx_compiler': self.GXX_4_9_RESULT, }) def test_overridden_unsupported_gcc(self): self.do_toolchain_test(self.PATHS, { 'c_compiler': self.GCC_4_7_RESULT, }, environ={ 'CC': 'gcc-4.7', 'CXX': 'g++-4.7', }) def test_clang(self): # We'll pick clang if nothing else is found. paths = { k: v for k, v in self.PATHS.iteritems() if os.path.basename(k) not in ('cl', 'clang-cl', 'gcc') } self.do_toolchain_test( paths, { 'c_compiler': self.CLANG_3_6_RESULT, 'cxx_compiler': self.CLANGXX_3_6_RESULT, }) def test_overridden_unsupported_clang(self): # clang 3.3 C compiler is perfectly fine, but we need more for C++. self.do_toolchain_test(self.PATHS, { 'c_compiler': self.CLANG_3_3_RESULT, 'cxx_compiler': self.CLANGXX_3_3_RESULT, }, environ={ 'CC': 'clang-3.3', 'CXX': 'clang++-3.3', })
class WindowsToolchainTest(BaseToolchainTest): HOST = 'i686-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, '/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, '/opt/VS_2015u2/bin/cl': VS_2015u2 + VS_PLATFORM_X86, '/usr/bin/cl': VS_2015u3 + VS_PLATFORM_X86, '/usr/bin/clang-cl': CLANG_CL_3_9 + CLANG_CL_PLATFORM_X86, '/usr/bin/gcc': GCC_4_9 + GCC_PLATFORM_X86_WIN, '/usr/bin/g++': GXX_4_9 + GCC_PLATFORM_X86_WIN, '/usr/bin/gcc-4.7': GCC_4_7 + GCC_PLATFORM_X86_WIN, '/usr/bin/g++-4.7': GXX_4_7 + GCC_PLATFORM_X86_WIN, '/usr/bin/gcc-5': GCC_5 + GCC_PLATFORM_X86_WIN, '/usr/bin/g++-5': GXX_5 + GCC_PLATFORM_X86_WIN, '/usr/bin/clang': CLANG_3_6 + CLANG_PLATFORM_X86_WIN, '/usr/bin/clang++': CLANGXX_3_6 + CLANG_PLATFORM_X86_WIN, '/usr/bin/clang-3.6': CLANG_3_6 + CLANG_PLATFORM_X86_WIN, '/usr/bin/clang++-3.6': CLANGXX_3_6 + CLANG_PLATFORM_X86_WIN, '/usr/bin/clang-3.3': CLANG_3_3 + CLANG_PLATFORM_X86_WIN, '/usr/bin/clang++-3.3': CLANGXX_3_3 + CLANG_PLATFORM_X86_WIN, } VS_2013u2_RESULT = ( 'This version (18.00.30501) of the MSVC compiler is not supported.\n' 'You must install Visual C++ 2015 Update 3 or newer in order to build.\n' 'See https://developer.mozilla.org/en/Windows_Build_Prerequisites') VS_2013u3_RESULT = ( 'This version (18.00.30723) of the MSVC compiler is not supported.\n' 'You must install Visual C++ 2015 Update 3 or newer in order to build.\n' 'See https://developer.mozilla.org/en/Windows_Build_Prerequisites') VS_2015_RESULT = ( 'This version (19.00.23026) of the MSVC compiler is not supported.\n' 'You must install Visual C++ 2015 Update 3 or newer in order to build.\n' 'See https://developer.mozilla.org/en/Windows_Build_Prerequisites') VS_2015u1_RESULT = ( 'This version (19.00.23506) of the MSVC compiler is not supported.\n' 'You must install Visual C++ 2015 Update 3 or newer in order to build.\n' 'See https://developer.mozilla.org/en/Windows_Build_Prerequisites') VS_2015u2_RESULT = ( 'This version (19.00.23918) of the MSVC compiler is not supported.\n' 'You must install Visual C++ 2015 Update 3 or newer in order to build.\n' 'See https://developer.mozilla.org/en/Windows_Build_Prerequisites') VS_2015u3_RESULT = CompilerResult( flags=[], version='19.00.24210', type='msvc', compiler='/usr/bin/cl', language='C', ) VSXX_2015u3_RESULT = CompilerResult( flags=[], version='19.00.24210', type='msvc', compiler='/usr/bin/cl', language='C++', ) CLANG_CL_3_9_RESULT = CompilerResult( flags=['-Xclang', '-std=gnu99', '-fms-compatibility-version=19.11.25547'], version='19.11.25547', type='clang-cl', compiler='/usr/bin/clang-cl', language='C', ) CLANGXX_CL_3_9_RESULT = CompilerResult( flags=['-Xclang', '-std=c++14', '-fms-compatibility-version=19.11.25547'], version='19.11.25547', type='clang-cl', compiler='/usr/bin/clang-cl', language='C++', ) 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 GCC_4_7_RESULT = LinuxToolchainTest.GCC_4_7_RESULT GCC_4_9_RESULT = LinuxToolchainTest.GCC_4_9_RESULT GXX_4_9_RESULT = LinuxToolchainTest.GXX_4_9_RESULT GCC_5_RESULT = LinuxToolchainTest.GCC_5_RESULT GXX_5_RESULT = LinuxToolchainTest.GXX_5_RESULT # VS2015u3 or greater is required. def test_msvc(self): self.do_toolchain_test(self.PATHS, { 'c_compiler': self.VS_2015u3_RESULT, 'cxx_compiler': self.VSXX_2015u3_RESULT, }) def test_unsupported_msvc(self): self.do_toolchain_test(self.PATHS, { 'c_compiler': self.VS_2015u2_RESULT, }, environ={ 'CC': '/opt/VS_2015u2/bin/cl', }) self.do_toolchain_test(self.PATHS, { 'c_compiler': self.VS_2015u1_RESULT, }, environ={ 'CC': '/opt/VS_2015u1/bin/cl', }) self.do_toolchain_test(self.PATHS, { 'c_compiler': self.VS_2015_RESULT, }, environ={ 'CC': '/opt/VS_2015/bin/cl', }) self.do_toolchain_test(self.PATHS, { 'c_compiler': self.VS_2013u3_RESULT, }, environ={ 'CC': '/opt/VS_2013u3/bin/cl', }) self.do_toolchain_test(self.PATHS, { 'c_compiler': self.VS_2013u2_RESULT, }, environ={ 'CC': '/opt/VS_2013u2/bin/cl', }) def test_clang_cl(self): # We'll pick clang-cl if msvc can't be found. paths = { k: v for k, v in self.PATHS.iteritems() if os.path.basename(k) != 'cl' } self.do_toolchain_test(paths, { 'c_compiler': self.CLANG_CL_3_9_RESULT, 'cxx_compiler': self.CLANGXX_CL_3_9_RESULT, }) def test_gcc(self): # We'll pick GCC if msvc and clang-cl can't be found. paths = { k: v for k, v in self.PATHS.iteritems() if os.path.basename(k) not in ('cl', 'clang-cl') } self.do_toolchain_test(paths, { 'c_compiler': self.GCC_4_9_RESULT, 'cxx_compiler': self.GXX_4_9_RESULT, }) def test_overridden_unsupported_gcc(self): self.do_toolchain_test(self.PATHS, { 'c_compiler': self.GCC_4_7_RESULT, }, environ={ 'CC': 'gcc-4.7', 'CXX': 'g++-4.7', }) def test_clang(self): # We'll pick clang if nothing else is found. paths = { k: v for k, v in self.PATHS.iteritems() if os.path.basename(k) not in ('cl', 'clang-cl', 'gcc') } self.do_toolchain_test(paths, { 'c_compiler': self.CLANG_3_6_RESULT, 'cxx_compiler': self.CLANGXX_3_6_RESULT, }) def test_overridden_unsupported_clang(self): # clang 3.3 C compiler is perfectly fine, but we need more for C++. self.do_toolchain_test(self.PATHS, { 'c_compiler': self.CLANG_3_3_RESULT, 'cxx_compiler': self.CLANGXX_3_3_RESULT, }, environ={ 'CC': 'clang-3.3', 'CXX': 'clang++-3.3', }) def test_cannot_cross(self): paths = { '/usr/bin/cl': VS_2015u3 + VS_PLATFORM_X86_64, } self.do_toolchain_test(paths, { 'c_compiler': ('Target C compiler target CPU (x86_64) ' 'does not match --target CPU (i686)'), })