1# This Source Code Form is subject to the terms of the Mozilla Public 2# License, v. 2.0. If a copy of the MPL was not distributed with this 3# file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5from __future__ import absolute_import, print_function, unicode_literals 6 7import logging 8import os 9import six 10from six import StringIO 11 12from mozunit import main 13 14from common import BaseConfigureTest 15from mozbuild.configure.util import Version 16from mozbuild.util import ( 17 memoize, 18 ReadOnlyNamespace, 19) 20from mozpack import path as mozpath 21from test_toolchain_helpers import ( 22 FakeCompiler, 23 CompilerResult, 24 PrependFlags, 25) 26 27 28DEFAULT_C99 = { 29 '__STDC_VERSION__': '199901L', 30} 31 32DEFAULT_C11 = { 33 '__STDC_VERSION__': '201112L', 34} 35 36DEFAULT_CXX_97 = { 37 '__cplusplus': '199711L', 38} 39 40DEFAULT_CXX_11 = { 41 '__cplusplus': '201103L', 42} 43 44DRAFT_CXX_14 = { 45 '__cplusplus': '201300L', 46} 47 48DEFAULT_CXX_14 = { 49 '__cplusplus': '201402L', 50} 51 52DRAFT_CXX17_201500 = { 53 '__cplusplus': '201500L', 54} 55 56DRAFT_CXX17_201406 = { 57 '__cplusplus': '201406L', 58} 59 60DEFAULT_CXX_17 = { 61 '__cplusplus': '201703L', 62} 63 64SUPPORTS_GNU99 = { 65 '-std=gnu99': DEFAULT_C99, 66} 67 68SUPPORTS_GNUXX11 = { 69 '-std=gnu++11': DEFAULT_CXX_11, 70} 71 72SUPPORTS_GNUXX14 = { 73 '-std=gnu++14': DEFAULT_CXX_14, 74} 75 76SUPPORTS_CXX14 = { 77 '-std=c++14': DEFAULT_CXX_14, 78} 79 80SUPPORTS_GNUXX17 = { 81 '-std=gnu++17': DEFAULT_CXX_17, 82} 83 84SUPPORTS_CXX17 = { 85 '-std=c++17': DEFAULT_CXX_17, 86} 87 88 89@memoize 90def GCC_BASE(version): 91 version = Version(version) 92 return FakeCompiler({ 93 '__GNUC__': version.major, 94 '__GNUC_MINOR__': version.minor, 95 '__GNUC_PATCHLEVEL__': version.patch, 96 '__STDC__': 1, 97 }) 98 99 100@memoize 101def GCC(version): 102 return GCC_BASE(version) + SUPPORTS_GNU99 103 104 105@memoize 106def GXX(version): 107 return GCC_BASE(version) + DEFAULT_CXX_97 + SUPPORTS_GNUXX11 108 109 110SUPPORTS_DRAFT_CXX14_VERSION = { 111 '-std=gnu++14': DRAFT_CXX_14, 112} 113 114SUPPORTS_GNUXX1Z = { 115 '-std=gnu++1z': DRAFT_CXX17_201406, 116} 117 118SUPPORTS_DRAFT_CXX17_201500_VERSION = { 119 '-std=gnu++17': DRAFT_CXX17_201500, 120} 121 122GCC_4_9 = GCC('4.9.3') 123GXX_4_9 = GXX('4.9.3') + SUPPORTS_DRAFT_CXX14_VERSION 124GCC_5 = GCC('5.2.1') + DEFAULT_C11 125GXX_5 = GXX('5.2.1') + SUPPORTS_GNUXX14 126GCC_6 = GCC('6.4.0') + DEFAULT_C11 127GXX_6 = GXX('6.4.0') + DEFAULT_CXX_14 + SUPPORTS_GNUXX17 + SUPPORTS_DRAFT_CXX17_201500_VERSION 128GCC_7 = GCC('7.3.0') + DEFAULT_C11 129GXX_7 = GXX('7.3.0') + DEFAULT_CXX_14 + SUPPORTS_GNUXX17 + SUPPORTS_CXX17 130GCC_8 = GCC('8.3.0') + DEFAULT_C11 131GXX_8 = GXX('8.3.0') + DEFAULT_CXX_14 + SUPPORTS_GNUXX17 + SUPPORTS_CXX17 132 133DEFAULT_GCC = GCC_7 134DEFAULT_GXX = GXX_7 135 136GCC_PLATFORM_LITTLE_ENDIAN = { 137 '__ORDER_LITTLE_ENDIAN__': 1234, 138 '__ORDER_BIG_ENDIAN__': 4321, 139 '__BYTE_ORDER__': 1234, 140} 141 142GCC_PLATFORM_BIG_ENDIAN = { 143 '__ORDER_LITTLE_ENDIAN__': 1234, 144 '__ORDER_BIG_ENDIAN__': 4321, 145 '__BYTE_ORDER__': 4321, 146} 147 148GCC_PLATFORM_X86 = FakeCompiler(GCC_PLATFORM_LITTLE_ENDIAN) + { 149 None: { 150 '__i386__': 1, 151 }, 152 '-m64': { 153 '__i386__': False, 154 '__x86_64__': 1, 155 }, 156} 157 158GCC_PLATFORM_X86_64 = FakeCompiler(GCC_PLATFORM_LITTLE_ENDIAN) + { 159 None: { 160 '__x86_64__': 1, 161 }, 162 '-m32': { 163 '__x86_64__': False, 164 '__i386__': 1, 165 }, 166} 167 168GCC_PLATFORM_ARM = FakeCompiler(GCC_PLATFORM_LITTLE_ENDIAN) + { 169 '__arm__': 1, 170} 171 172GCC_PLATFORM_LINUX = { 173 '__linux__': 1, 174} 175 176GCC_PLATFORM_DARWIN = { 177 '__APPLE__': 1, 178} 179 180GCC_PLATFORM_WIN = { 181 '_WIN32': 1, 182 'WINNT': 1, 183} 184 185GCC_PLATFORM_OPENBSD = { 186 '__OpenBSD__': 1, 187} 188 189GCC_PLATFORM_X86_LINUX = FakeCompiler(GCC_PLATFORM_X86, GCC_PLATFORM_LINUX) 190GCC_PLATFORM_X86_64_LINUX = FakeCompiler(GCC_PLATFORM_X86_64, 191 GCC_PLATFORM_LINUX) 192GCC_PLATFORM_ARM_LINUX = FakeCompiler(GCC_PLATFORM_ARM, GCC_PLATFORM_LINUX) 193GCC_PLATFORM_X86_OSX = FakeCompiler(GCC_PLATFORM_X86, GCC_PLATFORM_DARWIN) 194GCC_PLATFORM_X86_64_OSX = FakeCompiler(GCC_PLATFORM_X86_64, 195 GCC_PLATFORM_DARWIN) 196GCC_PLATFORM_X86_WIN = FakeCompiler(GCC_PLATFORM_X86, GCC_PLATFORM_WIN) 197GCC_PLATFORM_X86_64_WIN = FakeCompiler(GCC_PLATFORM_X86_64, GCC_PLATFORM_WIN) 198 199 200@memoize 201def CLANG_BASE(version): 202 version = Version(version) 203 return FakeCompiler({ 204 '__clang__': 1, 205 '__clang_major__': version.major, 206 '__clang_minor__': version.minor, 207 '__clang_patchlevel__': version.patch, 208 }) 209 210 211@memoize 212def CLANG(version): 213 return GCC_BASE('4.2.1') + CLANG_BASE(version) + SUPPORTS_GNU99 214 215 216@memoize 217def CLANGXX(version): 218 return (GCC_BASE('4.2.1') + CLANG_BASE(version) + DEFAULT_CXX_97 + 219 SUPPORTS_GNUXX11 + SUPPORTS_GNUXX14) 220 221 222CLANG_3_3 = CLANG('3.3.0') + DEFAULT_C99 223CLANGXX_3_3 = CLANGXX('3.3.0') 224CLANG_4_0 = CLANG('4.0.2') + DEFAULT_C11 + { 225 '__has_attribute(diagnose_if)': 1, 226} 227CLANGXX_4_0 = CLANGXX('4.0.2') + SUPPORTS_GNUXX1Z + { 228 '__has_attribute(diagnose_if)': 1, 229} 230CLANG_5_0 = CLANG('5.0.1') + DEFAULT_C11 + { 231 '__has_attribute(diagnose_if)': 1, 232 '__has_warning("-Wunguarded-availability")': 1, 233} 234CLANGXX_5_0 = CLANGXX('5.0.1') + SUPPORTS_GNUXX17 + { 235 '__has_attribute(diagnose_if)': 1, 236 '__has_warning("-Wunguarded-availability")': 1, 237} 238DEFAULT_CLANG = CLANG_5_0 239DEFAULT_CLANGXX = CLANGXX_5_0 240 241 242def CLANG_PLATFORM(gcc_platform): 243 base = { 244 '--target=x86_64-linux-gnu': GCC_PLATFORM_X86_64_LINUX[None], 245 '--target=x86_64-apple-darwin11.2.0': GCC_PLATFORM_X86_64_OSX[None], 246 '--target=i686-linux-gnu': GCC_PLATFORM_X86_LINUX[None], 247 '--target=i686-apple-darwin11.2.0': GCC_PLATFORM_X86_OSX[None], 248 '--target=arm-linux-gnu': GCC_PLATFORM_ARM_LINUX[None], 249 } 250 undo_gcc_platform = { 251 k: {symbol: False for symbol in gcc_platform[None]} 252 for k in base 253 } 254 return FakeCompiler(gcc_platform, undo_gcc_platform, base) 255 256 257CLANG_PLATFORM_X86_LINUX = CLANG_PLATFORM(GCC_PLATFORM_X86_LINUX) 258CLANG_PLATFORM_X86_64_LINUX = CLANG_PLATFORM(GCC_PLATFORM_X86_64_LINUX) 259CLANG_PLATFORM_X86_OSX = CLANG_PLATFORM(GCC_PLATFORM_X86_OSX) 260CLANG_PLATFORM_X86_64_OSX = CLANG_PLATFORM(GCC_PLATFORM_X86_64_OSX) 261CLANG_PLATFORM_X86_WIN = CLANG_PLATFORM(GCC_PLATFORM_X86_WIN) 262CLANG_PLATFORM_X86_64_WIN = CLANG_PLATFORM(GCC_PLATFORM_X86_64_WIN) 263 264 265@memoize 266def VS(version): 267 version = Version(version) 268 return FakeCompiler({ 269 None: { 270 '_MSC_VER': '%02d%02d' % (version.major, version.minor), 271 '_MSC_FULL_VER': '%02d%02d%05d' % (version.major, version.minor, 272 version.patch), 273 '_MT': '1', 274 }, 275 '*.cpp': DEFAULT_CXX_97, 276 }) 277 278 279VS_2017u8 = VS('19.15.26726') 280 281VS_PLATFORM_X86 = { 282 '_M_IX86': 600, 283 '_WIN32': 1, 284} 285 286VS_PLATFORM_X86_64 = { 287 '_M_X64': 100, 288 '_WIN32': 1, 289 '_WIN64': 1, 290} 291 292# Note: In reality, the -std=gnu* options are only supported when preceded by 293# -Xclang. 294CLANG_CL_3_9 = (CLANG_BASE('3.9.0') + VS('18.00.00000') + DEFAULT_C11 + 295 SUPPORTS_GNU99 + SUPPORTS_GNUXX11 + SUPPORTS_CXX14) + { 296 '*.cpp': { 297 '__STDC_VERSION__': False, 298 '__cplusplus': '201103L', 299 }, 300} 301CLANG_CL_8_0 = (CLANG_BASE('8.0.0') + VS('18.00.00000') + DEFAULT_C11 + 302 SUPPORTS_GNU99 + SUPPORTS_GNUXX11 + SUPPORTS_CXX14 + 303 SUPPORTS_CXX17) + { 304 '*.cpp': { 305 '__STDC_VERSION__': False, 306 '__cplusplus': '201103L', 307 }, 308} 309 310CLANG_CL_PLATFORM_X86 = FakeCompiler( 311 VS_PLATFORM_X86, GCC_PLATFORM_X86[None], GCC_PLATFORM_LITTLE_ENDIAN) 312CLANG_CL_PLATFORM_X86_64 = FakeCompiler( 313 VS_PLATFORM_X86_64, GCC_PLATFORM_X86_64[None], GCC_PLATFORM_LITTLE_ENDIAN) 314 315LIBRARY_NAME_INFOS = { 316 'linux-gnu': { 317 'DLL_PREFIX': 'lib', 318 'DLL_SUFFIX': '.so', 319 'LIB_PREFIX': 'lib', 320 'LIB_SUFFIX': 'a', 321 'IMPORT_LIB_SUFFIX': '', 322 'RUST_LIB_PREFIX': 'lib', 323 'RUST_LIB_SUFFIX': 'a', 324 'OBJ_SUFFIX': 'o', 325 }, 326 'darwin11.2.0': { 327 'DLL_PREFIX': 'lib', 328 'DLL_SUFFIX': '.dylib', 329 'LIB_PREFIX': 'lib', 330 'LIB_SUFFIX': 'a', 331 'IMPORT_LIB_SUFFIX': '', 332 'RUST_LIB_PREFIX': 'lib', 333 'RUST_LIB_SUFFIX': 'a', 334 'OBJ_SUFFIX': 'o', 335 }, 336 'mingw32': { 337 'DLL_PREFIX': '', 338 'DLL_SUFFIX': '.dll', 339 'LIB_PREFIX': 'lib', 340 'LIB_SUFFIX': 'a', 341 'IMPORT_LIB_SUFFIX': 'a', 342 'RUST_LIB_PREFIX': '', 343 'RUST_LIB_SUFFIX': 'lib', 344 'OBJ_SUFFIX': 'o', 345 }, 346 'msvc': { 347 'DLL_PREFIX': '', 348 'DLL_SUFFIX': '.dll', 349 'LIB_PREFIX': '', 350 'LIB_SUFFIX': 'lib', 351 'IMPORT_LIB_SUFFIX': 'lib', 352 'RUST_LIB_PREFIX': '', 353 'RUST_LIB_SUFFIX': 'lib', 354 'OBJ_SUFFIX': 'obj', 355 }, 356 'openbsd6.1': { 357 'DLL_PREFIX': 'lib', 358 'DLL_SUFFIX': '.so.1.0', 359 'LIB_PREFIX': 'lib', 360 'LIB_SUFFIX': 'a', 361 'IMPORT_LIB_SUFFIX': '', 362 'RUST_LIB_PREFIX': 'lib', 363 'RUST_LIB_SUFFIX': 'a', 364 'OBJ_SUFFIX': 'o', 365 }, 366} 367 368 369class BaseToolchainTest(BaseConfigureTest): 370 def setUp(self): 371 super(BaseToolchainTest, self).setUp() 372 self.out = StringIO() 373 self.logger = logging.getLogger('BaseToolchainTest') 374 self.logger.setLevel(logging.ERROR) 375 self.handler = logging.StreamHandler(self.out) 376 self.logger.addHandler(self.handler) 377 378 def tearDown(self): 379 self.logger.removeHandler(self.handler) 380 del self.handler 381 del self.out 382 super(BaseToolchainTest, self).tearDown() 383 384 def do_toolchain_test(self, paths, results, args=[], environ={}): 385 '''Helper to test the toolchain checks from toolchain.configure. 386 387 - `paths` is a dict associating compiler paths to FakeCompiler 388 definitions from above. 389 - `results` is a dict associating result variable names from 390 toolchain.configure (c_compiler, cxx_compiler, host_c_compiler, 391 host_cxx_compiler) with a result. 392 The result can either be an error string, or a CompilerResult 393 corresponding to the object returned by toolchain.configure checks. 394 When the results for host_c_compiler are identical to c_compiler, 395 they can be omitted. Likewise for host_cxx_compiler vs. 396 cxx_compiler. 397 ''' 398 environ = dict(environ) 399 if 'PATH' not in environ: 400 environ['PATH'] = os.pathsep.join( 401 mozpath.abspath(p) for p in ('/bin', '/usr/bin')) 402 403 args = args + ['--enable-release'] 404 405 sandbox = self.get_sandbox(paths, {}, args, environ, 406 logger=self.logger) 407 408 for var in ('c_compiler', 'cxx_compiler', 'host_c_compiler', 409 'host_cxx_compiler'): 410 if var in results: 411 result = results[var] 412 elif var.startswith('host_'): 413 result = results.get(var[5:], {}) 414 else: 415 result = {} 416 try: 417 self.out.truncate(0) 418 self.out.seek(0) 419 compiler = sandbox._value_for(sandbox[var]) 420 # Add var on both ends to make it clear which of the 421 # variables is failing the test when that happens. 422 self.assertEquals((var, compiler), (var, result)) 423 except SystemExit: 424 self.assertEquals((var, result), 425 (var, self.out.getvalue().strip())) 426 return 427 428 # Normalize the target os to match what we have as keys in 429 # LIBRARY_NAME_INFOS. 430 target_os = getattr(self, 'TARGET', self.HOST).split('-', 2)[2] 431 if target_os == 'mingw32': 432 compiler_type = sandbox._value_for(sandbox['c_compiler']).type 433 if compiler_type == 'clang-cl': 434 target_os = 'msvc' 435 elif target_os == 'linux-gnuabi64': 436 target_os = 'linux-gnu' 437 438 self.do_library_name_info_test(target_os, sandbox) 439 440 # Try again on artifact builds. In that case, we always get library 441 # name info for msvc on Windows 442 if target_os == 'mingw32': 443 target_os = 'msvc' 444 445 sandbox = self.get_sandbox( 446 paths, {}, args + ['--enable-artifact-builds'], environ, 447 logger=self.logger) 448 449 self.do_library_name_info_test(target_os, sandbox) 450 451 def do_library_name_info_test(self, target_os, sandbox): 452 library_name_info = LIBRARY_NAME_INFOS[target_os] 453 for k in ( 454 'DLL_PREFIX', 455 'DLL_SUFFIX', 456 'LIB_PREFIX', 457 'LIB_SUFFIX', 458 'IMPORT_LIB_SUFFIX', 459 'RUST_LIB_PREFIX', 460 'RUST_LIB_SUFFIX', 461 'OBJ_SUFFIX', 462 ): 463 self.assertEquals('%s=%s' % (k, sandbox.get_config(k)), 464 '%s=%s' % (k, library_name_info[k])) 465 466 467def old_gcc_message(old_ver): 468 return 'Only GCC 7.1 or newer is supported (found version {}).'.format(old_ver) 469 470 471class LinuxToolchainTest(BaseToolchainTest): 472 PATHS = { 473 '/usr/bin/gcc': DEFAULT_GCC + GCC_PLATFORM_X86_64_LINUX, 474 '/usr/bin/g++': DEFAULT_GXX + GCC_PLATFORM_X86_64_LINUX, 475 '/usr/bin/gcc-4.9': GCC_4_9 + GCC_PLATFORM_X86_64_LINUX, 476 '/usr/bin/g++-4.9': GXX_4_9 + GCC_PLATFORM_X86_64_LINUX, 477 '/usr/bin/gcc-5': GCC_5 + GCC_PLATFORM_X86_64_LINUX, 478 '/usr/bin/g++-5': GXX_5 + GCC_PLATFORM_X86_64_LINUX, 479 '/usr/bin/gcc-6': GCC_6 + GCC_PLATFORM_X86_64_LINUX, 480 '/usr/bin/g++-6': GXX_6 + GCC_PLATFORM_X86_64_LINUX, 481 '/usr/bin/gcc-7': GCC_7 + GCC_PLATFORM_X86_64_LINUX, 482 '/usr/bin/g++-7': GXX_7 + GCC_PLATFORM_X86_64_LINUX, 483 '/usr/bin/gcc-8': GCC_8 + GCC_PLATFORM_X86_64_LINUX, 484 '/usr/bin/g++-8': GXX_8 + GCC_PLATFORM_X86_64_LINUX, 485 '/usr/bin/clang': DEFAULT_CLANG + CLANG_PLATFORM_X86_64_LINUX, 486 '/usr/bin/clang++': DEFAULT_CLANGXX + CLANG_PLATFORM_X86_64_LINUX, 487 '/usr/bin/clang-5.0': CLANG_5_0 + CLANG_PLATFORM_X86_64_LINUX, 488 '/usr/bin/clang++-5.0': CLANGXX_5_0 + CLANG_PLATFORM_X86_64_LINUX, 489 '/usr/bin/clang-4.0': CLANG_4_0 + CLANG_PLATFORM_X86_64_LINUX, 490 '/usr/bin/clang++-4.0': CLANGXX_4_0 + CLANG_PLATFORM_X86_64_LINUX, 491 '/usr/bin/clang-3.3': CLANG_3_3 + CLANG_PLATFORM_X86_64_LINUX, 492 '/usr/bin/clang++-3.3': CLANGXX_3_3 + CLANG_PLATFORM_X86_64_LINUX, 493 } 494 495 GCC_4_7_RESULT = old_gcc_message('4.7.3') 496 GXX_4_7_RESULT = GCC_4_7_RESULT 497 GCC_4_9_RESULT = old_gcc_message('4.9.3') 498 GXX_4_9_RESULT = GCC_4_9_RESULT 499 GCC_5_RESULT = old_gcc_message('5.2.1') 500 GXX_5_RESULT = GCC_5_RESULT 501 GCC_6_RESULT = old_gcc_message('6.4.0') 502 GXX_6_RESULT = GCC_6_RESULT 503 GCC_7_RESULT = CompilerResult( 504 flags=['-std=gnu99'], 505 version='7.3.0', 506 type='gcc', 507 compiler='/usr/bin/gcc-7', 508 language='C', 509 ) 510 GXX_7_RESULT = CompilerResult( 511 flags=['-std=gnu++17'], 512 version='7.3.0', 513 type='gcc', 514 compiler='/usr/bin/g++-7', 515 language='C++', 516 ) 517 GCC_8_RESULT = CompilerResult( 518 flags=['-std=gnu99'], 519 version='8.3.0', 520 type='gcc', 521 compiler='/usr/bin/gcc-8', 522 language='C', 523 ) 524 GXX_8_RESULT = CompilerResult( 525 flags=['-std=gnu++17'], 526 version='8.3.0', 527 type='gcc', 528 compiler='/usr/bin/g++-8', 529 language='C++', 530 ) 531 DEFAULT_GCC_RESULT = GCC_7_RESULT + {'compiler': '/usr/bin/gcc'} 532 DEFAULT_GXX_RESULT = GXX_7_RESULT + {'compiler': '/usr/bin/g++'} 533 534 CLANG_3_3_RESULT = 'Only clang/llvm 5.0 or newer is supported.' 535 CLANGXX_3_3_RESULT = 'Only clang/llvm 5.0 or newer is supported.' 536 CLANG_4_0_RESULT = 'Only clang/llvm 5.0 or newer is supported.' 537 CLANGXX_4_0_RESULT = 'Only clang/llvm 5.0 or newer is supported.' 538 CLANG_5_0_RESULT = CompilerResult( 539 flags=['-std=gnu99'], 540 version='5.0.1', 541 type='clang', 542 compiler='/usr/bin/clang-5.0', 543 language='C', 544 ) 545 CLANGXX_5_0_RESULT = CompilerResult( 546 flags=['-std=gnu++17'], 547 version='5.0.1', 548 type='clang', 549 compiler='/usr/bin/clang++-5.0', 550 language='C++', 551 ) 552 DEFAULT_CLANG_RESULT = CLANG_5_0_RESULT + {'compiler': '/usr/bin/clang'} 553 DEFAULT_CLANGXX_RESULT = CLANGXX_5_0_RESULT + {'compiler': '/usr/bin/clang++'} 554 555 def test_default(self): 556 # We'll try clang and gcc, and find clang first. 557 self.do_toolchain_test(self.PATHS, { 558 'c_compiler': self.DEFAULT_CLANG_RESULT, 559 'cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 560 }) 561 562 def test_gcc(self): 563 self.do_toolchain_test(self.PATHS, { 564 'c_compiler': self.DEFAULT_GCC_RESULT, 565 'cxx_compiler': self.DEFAULT_GXX_RESULT, 566 }, environ={ 567 'CC': 'gcc', 568 'CXX': 'g++', 569 }) 570 571 def test_unsupported_gcc(self): 572 self.do_toolchain_test(self.PATHS, { 573 'c_compiler': self.GCC_4_9_RESULT, 574 }, environ={ 575 'CC': 'gcc-4.9', 576 'CXX': 'g++-4.9', 577 }) 578 579 # Maybe this should be reporting the mismatched version instead. 580 self.do_toolchain_test(self.PATHS, { 581 'c_compiler': self.DEFAULT_GCC_RESULT, 582 'cxx_compiler': self.GXX_4_9_RESULT, 583 }, environ={ 584 'CC': 'gcc', 585 'CXX': 'g++-4.9', 586 }) 587 588 def test_overridden_gcc(self): 589 self.do_toolchain_test(self.PATHS, { 590 'c_compiler': self.GCC_7_RESULT, 591 'cxx_compiler': self.GXX_7_RESULT, 592 }, environ={ 593 'CC': 'gcc-7', 594 'CXX': 'g++-7', 595 }) 596 597 def test_guess_cxx(self): 598 # When CXX is not set, we guess it from CC. 599 self.do_toolchain_test(self.PATHS, { 600 'c_compiler': self.GCC_7_RESULT, 601 'cxx_compiler': self.GXX_7_RESULT, 602 }, environ={ 603 'CC': 'gcc-7', 604 }) 605 606 def test_mismatched_gcc(self): 607 self.do_toolchain_test(self.PATHS, { 608 'c_compiler': self.DEFAULT_GCC_RESULT, 609 'cxx_compiler': ( 610 'The target C compiler is version 7.3.0, while the target ' 611 'C++ compiler is version 8.3.0. Need to use the same compiler ' 612 'version.'), 613 }, environ={ 614 'CC': 'gcc', 615 'CXX': 'g++-8', 616 }) 617 618 self.do_toolchain_test(self.PATHS, { 619 'c_compiler': self.DEFAULT_GCC_RESULT, 620 'cxx_compiler': self.DEFAULT_GXX_RESULT, 621 'host_c_compiler': self.DEFAULT_GCC_RESULT, 622 'host_cxx_compiler': ( 623 'The host C compiler is version 7.3.0, while the host ' 624 'C++ compiler is version 8.3.0. Need to use the same compiler ' 625 'version.'), 626 }, environ={ 627 'CC': 'gcc', 628 'HOST_CXX': 'g++-8', 629 }) 630 631 def test_mismatched_compiler(self): 632 self.do_toolchain_test(self.PATHS, { 633 'c_compiler': self.DEFAULT_CLANG_RESULT, 634 'cxx_compiler': ( 635 'The target C compiler is clang, while the target C++ compiler ' 636 'is gcc. Need to use the same compiler suite.'), 637 }, environ={ 638 'CXX': 'g++', 639 }) 640 641 self.do_toolchain_test(self.PATHS, { 642 'c_compiler': self.DEFAULT_CLANG_RESULT, 643 'cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 644 'host_c_compiler': self.DEFAULT_CLANG_RESULT, 645 'host_cxx_compiler': ( 646 'The host C compiler is clang, while the host C++ compiler ' 647 'is gcc. Need to use the same compiler suite.'), 648 }, environ={ 649 'HOST_CXX': 'g++', 650 }) 651 652 self.do_toolchain_test(self.PATHS, { 653 'c_compiler': '`%s` is not a C compiler.' 654 % mozpath.abspath('/usr/bin/g++'), 655 }, environ={ 656 'CC': 'g++', 657 }) 658 659 self.do_toolchain_test(self.PATHS, { 660 'c_compiler': self.DEFAULT_CLANG_RESULT, 661 'cxx_compiler': '`%s` is not a C++ compiler.' 662 % mozpath.abspath('/usr/bin/clang'), 663 }, environ={ 664 'CXX': 'clang', 665 }) 666 667 def test_clang(self): 668 # We'll try gcc and clang, but since there is no gcc (gcc-x.y doesn't 669 # count), find clang. 670 paths = { 671 k: v for k, v in six.iteritems(self.PATHS) 672 if os.path.basename(k) not in ('gcc', 'g++') 673 } 674 self.do_toolchain_test(paths, { 675 'c_compiler': self.DEFAULT_CLANG_RESULT, 676 'cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 677 }) 678 679 def test_guess_cxx_clang(self): 680 # When CXX is not set, we guess it from CC. 681 self.do_toolchain_test(self.PATHS, { 682 'c_compiler': self.CLANG_5_0_RESULT, 683 'cxx_compiler': self.CLANGXX_5_0_RESULT, 684 }, environ={ 685 'CC': 'clang-5.0', 686 }) 687 688 def test_unsupported_clang(self): 689 self.do_toolchain_test(self.PATHS, { 690 'c_compiler': self.CLANG_3_3_RESULT, 691 'cxx_compiler': self.CLANGXX_3_3_RESULT, 692 }, environ={ 693 'CC': 'clang-3.3', 694 'CXX': 'clang++-3.3', 695 }) 696 self.do_toolchain_test(self.PATHS, { 697 'c_compiler': self.CLANG_4_0_RESULT, 698 'cxx_compiler': self.CLANGXX_4_0_RESULT, 699 }, environ={ 700 'CC': 'clang-4.0', 701 'CXX': 'clang++-4.0', 702 }) 703 704 def test_no_supported_compiler(self): 705 # Even if there are gcc-x.y or clang-x.y compilers available, we 706 # don't try them. This could be considered something to improve. 707 paths = { 708 k: v for k, v in six.iteritems(self.PATHS) 709 if os.path.basename(k) not in ('gcc', 'g++', 'clang', 'clang++') 710 } 711 self.do_toolchain_test(paths, { 712 'c_compiler': 'Cannot find the target C compiler', 713 }) 714 715 def test_absolute_path(self): 716 paths = dict(self.PATHS) 717 paths.update({ 718 '/opt/clang/bin/clang': paths['/usr/bin/clang'], 719 '/opt/clang/bin/clang++': paths['/usr/bin/clang++'], 720 }) 721 result = { 722 'c_compiler': self.DEFAULT_CLANG_RESULT + { 723 'compiler': '/opt/clang/bin/clang', 724 }, 725 'cxx_compiler': self.DEFAULT_CLANGXX_RESULT + { 726 'compiler': '/opt/clang/bin/clang++', 727 }, 728 } 729 self.do_toolchain_test(paths, result, environ={ 730 'CC': '/opt/clang/bin/clang', 731 'CXX': '/opt/clang/bin/clang++', 732 }) 733 # With CXX guess too. 734 self.do_toolchain_test(paths, result, environ={ 735 'CC': '/opt/clang/bin/clang', 736 }) 737 738 def test_atypical_name(self): 739 paths = dict(self.PATHS) 740 paths.update({ 741 '/usr/bin/afl-clang-fast': paths['/usr/bin/clang'], 742 '/usr/bin/afl-clang-fast++': paths['/usr/bin/clang++'], 743 }) 744 self.do_toolchain_test(paths, { 745 'c_compiler': self.DEFAULT_CLANG_RESULT + { 746 'compiler': '/usr/bin/afl-clang-fast', 747 }, 748 'cxx_compiler': self.DEFAULT_CLANGXX_RESULT + { 749 'compiler': '/usr/bin/afl-clang-fast++', 750 }, 751 }, environ={ 752 'CC': 'afl-clang-fast', 753 'CXX': 'afl-clang-fast++', 754 }) 755 756 def test_mixed_compilers(self): 757 self.do_toolchain_test(self.PATHS, { 758 'c_compiler': self.DEFAULT_CLANG_RESULT, 759 'cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 760 'host_c_compiler': self.DEFAULT_GCC_RESULT, 761 'host_cxx_compiler': self.DEFAULT_GXX_RESULT, 762 }, environ={ 763 'CC': 'clang', 764 'HOST_CC': 'gcc', 765 }) 766 767 self.do_toolchain_test(self.PATHS, { 768 'c_compiler': self.DEFAULT_CLANG_RESULT, 769 'cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 770 'host_c_compiler': self.DEFAULT_GCC_RESULT, 771 'host_cxx_compiler': self.DEFAULT_GXX_RESULT, 772 }, environ={ 773 'CC': 'clang', 774 'CXX': 'clang++', 775 'HOST_CC': 'gcc', 776 }) 777 778 779class LinuxSimpleCrossToolchainTest(BaseToolchainTest): 780 TARGET = 'i686-pc-linux-gnu' 781 PATHS = LinuxToolchainTest.PATHS 782 DEFAULT_GCC_RESULT = LinuxToolchainTest.DEFAULT_GCC_RESULT 783 DEFAULT_GXX_RESULT = LinuxToolchainTest.DEFAULT_GXX_RESULT 784 DEFAULT_CLANG_RESULT = LinuxToolchainTest.DEFAULT_CLANG_RESULT 785 DEFAULT_CLANGXX_RESULT = LinuxToolchainTest.DEFAULT_CLANGXX_RESULT 786 787 def test_cross_gcc(self): 788 self.do_toolchain_test(self.PATHS, { 789 'c_compiler': self.DEFAULT_GCC_RESULT + { 790 'flags': ['-m32'] 791 }, 792 'cxx_compiler': self.DEFAULT_GXX_RESULT + { 793 'flags': ['-m32'] 794 }, 795 'host_c_compiler': self.DEFAULT_GCC_RESULT, 796 'host_cxx_compiler': self.DEFAULT_GXX_RESULT, 797 }, environ={ 798 'CC': 'gcc' 799 }) 800 801 def test_cross_clang(self): 802 self.do_toolchain_test(self.PATHS, { 803 'c_compiler': self.DEFAULT_CLANG_RESULT + { 804 'flags': ['-m32'] 805 }, 806 'cxx_compiler': self.DEFAULT_CLANGXX_RESULT + { 807 'flags': ['-m32'] 808 }, 809 'host_c_compiler': self.DEFAULT_CLANG_RESULT, 810 'host_cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 811 }) 812 813 814class LinuxX86_64CrossToolchainTest(BaseToolchainTest): 815 HOST = 'i686-pc-linux-gnu' 816 TARGET = 'x86_64-pc-linux-gnu' 817 PATHS = { 818 '/usr/bin/gcc': DEFAULT_GCC + GCC_PLATFORM_X86_LINUX, 819 '/usr/bin/g++': DEFAULT_GXX + GCC_PLATFORM_X86_LINUX, 820 '/usr/bin/clang': DEFAULT_CLANG + CLANG_PLATFORM_X86_LINUX, 821 '/usr/bin/clang++': DEFAULT_CLANGXX + CLANG_PLATFORM_X86_LINUX, 822 } 823 DEFAULT_GCC_RESULT = LinuxToolchainTest.DEFAULT_GCC_RESULT 824 DEFAULT_GXX_RESULT = LinuxToolchainTest.DEFAULT_GXX_RESULT 825 DEFAULT_CLANG_RESULT = LinuxToolchainTest.DEFAULT_CLANG_RESULT 826 DEFAULT_CLANGXX_RESULT = LinuxToolchainTest.DEFAULT_CLANGXX_RESULT 827 828 def test_cross_gcc(self): 829 self.do_toolchain_test(self.PATHS, { 830 'c_compiler': self.DEFAULT_GCC_RESULT + { 831 'flags': ['-m64'] 832 }, 833 'cxx_compiler': self.DEFAULT_GXX_RESULT + { 834 'flags': ['-m64'] 835 }, 836 'host_c_compiler': self.DEFAULT_GCC_RESULT, 837 'host_cxx_compiler': self.DEFAULT_GXX_RESULT, 838 }, environ={ 839 'CC': 'gcc', 840 }) 841 842 def test_cross_clang(self): 843 self.do_toolchain_test(self.PATHS, { 844 'c_compiler': self.DEFAULT_CLANG_RESULT + { 845 'flags': ['-m64'] 846 }, 847 'cxx_compiler': self.DEFAULT_CLANGXX_RESULT + { 848 'flags': ['-m64'] 849 }, 850 'host_c_compiler': self.DEFAULT_CLANG_RESULT, 851 'host_cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 852 }) 853 854 855def xcrun(stdin, args): 856 if args == ('--show-sdk-path',): 857 return 0, os.path.join(os.path.abspath(os.path.dirname(__file__)), 858 'fake_macos_sdk'), '' 859 raise NotImplementedError() 860 861 862class OSXToolchainTest(BaseToolchainTest): 863 HOST = 'x86_64-apple-darwin11.2.0' 864 PATHS = { 865 '/usr/bin/gcc-5': GCC_5 + GCC_PLATFORM_X86_64_OSX, 866 '/usr/bin/g++-5': GXX_5 + GCC_PLATFORM_X86_64_OSX, 867 '/usr/bin/gcc-7': GCC_7 + GCC_PLATFORM_X86_64_OSX, 868 '/usr/bin/g++-7': GXX_7 + GCC_PLATFORM_X86_64_OSX, 869 '/usr/bin/clang': CLANG_5_0 + CLANG_PLATFORM_X86_64_OSX, 870 '/usr/bin/clang++': CLANGXX_5_0 + CLANG_PLATFORM_X86_64_OSX, 871 '/usr/bin/clang-4.0': CLANG_4_0 + CLANG_PLATFORM_X86_64_OSX, 872 '/usr/bin/clang++-4.0': CLANGXX_4_0 + CLANG_PLATFORM_X86_64_OSX, 873 '/usr/bin/clang-3.3': CLANG_3_3 + CLANG_PLATFORM_X86_64_OSX, 874 '/usr/bin/clang++-3.3': CLANGXX_3_3 + CLANG_PLATFORM_X86_64_OSX, 875 '/usr/bin/xcrun': xcrun, 876 } 877 CLANG_3_3_RESULT = 'Only clang/llvm 5.0 or newer is supported.' 878 CLANGXX_3_3_RESULT = 'Only clang/llvm 5.0 or newer is supported.' 879 CLANG_4_0_RESULT = 'Only clang/llvm 5.0 or newer is supported.' 880 CLANGXX_4_0_RESULT = 'Only clang/llvm 5.0 or newer is supported.' 881 DEFAULT_CLANG_RESULT = CompilerResult( 882 flags=['-std=gnu99'], 883 version='5.0.1', 884 type='clang', 885 compiler='/usr/bin/clang', 886 language='C', 887 ) 888 DEFAULT_CLANGXX_RESULT = CompilerResult( 889 flags=['-std=gnu++17'], 890 version='5.0.1', 891 type='clang', 892 compiler='/usr/bin/clang++', 893 language='C++', 894 ) 895 GCC_5_RESULT = LinuxToolchainTest.GCC_5_RESULT 896 GXX_5_RESULT = LinuxToolchainTest.GXX_5_RESULT 897 GCC_7_RESULT = LinuxToolchainTest.GCC_7_RESULT 898 GXX_7_RESULT = LinuxToolchainTest.GXX_7_RESULT 899 SYSROOT_FLAGS = { 900 'flags': PrependFlags(['-isysroot', xcrun('', ('--show-sdk-path',))[1]]), 901 } 902 903 def test_clang(self): 904 # We only try clang because gcc is known not to work. 905 self.do_toolchain_test(self.PATHS, { 906 'c_compiler': self.DEFAULT_CLANG_RESULT + self.SYSROOT_FLAGS, 907 'cxx_compiler': self.DEFAULT_CLANGXX_RESULT + self.SYSROOT_FLAGS, 908 }) 909 910 def test_not_gcc(self): 911 # We won't pick GCC if it's the only thing available. 912 paths = { 913 k: v for k, v in six.iteritems(self.PATHS) 914 if os.path.basename(k) not in ('clang', 'clang++') 915 } 916 self.do_toolchain_test(paths, { 917 'c_compiler': 'Cannot find the target C compiler', 918 }) 919 920 def test_unsupported_clang(self): 921 self.do_toolchain_test(self.PATHS, { 922 'c_compiler': self.CLANG_3_3_RESULT, 923 'cxx_compiler': self.CLANGXX_3_3_RESULT, 924 }, environ={ 925 'CC': 'clang-3.3', 926 'CXX': 'clang++-3.3', 927 }) 928 # When targeting mac, we require at least version 5. 929 self.do_toolchain_test(self.PATHS, { 930 'c_compiler': self.CLANG_4_0_RESULT, 931 'cxx_compiler': self.CLANGXX_4_0_RESULT, 932 }, environ={ 933 'CC': 'clang-4.0', 934 'CXX': 'clang++-4.0', 935 }) 936 937 def test_forced_gcc(self): 938 # GCC can still be forced if the user really wants it. 939 self.do_toolchain_test(self.PATHS, { 940 'c_compiler': self.GCC_7_RESULT + self.SYSROOT_FLAGS, 941 'cxx_compiler': self.GXX_7_RESULT + self.SYSROOT_FLAGS, 942 }, environ={ 943 'CC': 'gcc-7', 944 'CXX': 'g++-7', 945 }) 946 947 def test_forced_unsupported_gcc(self): 948 self.do_toolchain_test(self.PATHS, { 949 'c_compiler': self.GCC_5_RESULT, 950 }, environ={ 951 'CC': 'gcc-5', 952 'CXX': 'g++-5', 953 }) 954 955 956class WindowsToolchainTest(BaseToolchainTest): 957 HOST = 'i686-pc-mingw32' 958 959 # For the purpose of this test, it doesn't matter that the paths are not 960 # real Windows paths. 961 PATHS = { 962 '/usr/bin/cl': VS_2017u8 + VS_PLATFORM_X86, 963 '/usr/bin/clang-cl-3.9': CLANG_CL_3_9 + CLANG_CL_PLATFORM_X86, 964 '/usr/bin/clang-cl': CLANG_CL_8_0 + CLANG_CL_PLATFORM_X86, 965 '/usr/bin/gcc': DEFAULT_GCC + GCC_PLATFORM_X86_WIN, 966 '/usr/bin/g++': DEFAULT_GXX + GCC_PLATFORM_X86_WIN, 967 '/usr/bin/gcc-4.9': GCC_4_9 + GCC_PLATFORM_X86_WIN, 968 '/usr/bin/g++-4.9': GXX_4_9 + GCC_PLATFORM_X86_WIN, 969 '/usr/bin/gcc-5': GCC_5 + GCC_PLATFORM_X86_WIN, 970 '/usr/bin/g++-5': GXX_5 + GCC_PLATFORM_X86_WIN, 971 '/usr/bin/gcc-6': GCC_6 + GCC_PLATFORM_X86_WIN, 972 '/usr/bin/g++-6': GXX_6 + GCC_PLATFORM_X86_WIN, 973 '/usr/bin/gcc-7': GCC_7 + GCC_PLATFORM_X86_WIN, 974 '/usr/bin/g++-7': GXX_7 + GCC_PLATFORM_X86_WIN, 975 '/usr/bin/clang': DEFAULT_CLANG + CLANG_PLATFORM_X86_WIN, 976 '/usr/bin/clang++': DEFAULT_CLANGXX + CLANG_PLATFORM_X86_WIN, 977 '/usr/bin/clang-5.0': CLANG_5_0 + CLANG_PLATFORM_X86_WIN, 978 '/usr/bin/clang++-5.0': CLANGXX_5_0 + CLANG_PLATFORM_X86_WIN, 979 '/usr/bin/clang-4.0': CLANG_4_0 + CLANG_PLATFORM_X86_WIN, 980 '/usr/bin/clang++-4.0': CLANGXX_4_0 + CLANG_PLATFORM_X86_WIN, 981 '/usr/bin/clang-3.3': CLANG_3_3 + CLANG_PLATFORM_X86_WIN, 982 '/usr/bin/clang++-3.3': CLANGXX_3_3 + CLANG_PLATFORM_X86_WIN, 983 } 984 985 CLANG_CL_3_9_RESULT = 'Only clang-cl 8.0 or newer is supported (found version 3.9.0)' 986 CLANG_CL_8_0_RESULT = CompilerResult( 987 version='8.0.0', 988 flags=['-Xclang', '-std=gnu99'], 989 type='clang-cl', 990 compiler='/usr/bin/clang-cl', 991 language='C', 992 ) 993 CLANGXX_CL_3_9_RESULT = 'Only clang-cl 8.0 or newer is supported (found version 3.9.0)' 994 CLANGXX_CL_8_0_RESULT = CompilerResult( 995 version='8.0.0', 996 flags=['-Xclang', '-std=c++17'], 997 type='clang-cl', 998 compiler='/usr/bin/clang-cl', 999 language='C++', 1000 ) 1001 CLANG_3_3_RESULT = LinuxToolchainTest.CLANG_3_3_RESULT 1002 CLANGXX_3_3_RESULT = LinuxToolchainTest.CLANGXX_3_3_RESULT 1003 CLANG_4_0_RESULT = LinuxToolchainTest.CLANG_4_0_RESULT 1004 CLANGXX_4_0_RESULT = LinuxToolchainTest.CLANGXX_4_0_RESULT 1005 DEFAULT_CLANG_RESULT = LinuxToolchainTest.DEFAULT_CLANG_RESULT 1006 DEFAULT_CLANGXX_RESULT = LinuxToolchainTest.DEFAULT_CLANGXX_RESULT 1007 GCC_4_9_RESULT = LinuxToolchainTest.GCC_4_9_RESULT 1008 GXX_4_9_RESULT = LinuxToolchainTest.GXX_4_9_RESULT 1009 GCC_5_RESULT = LinuxToolchainTest.GCC_5_RESULT 1010 GXX_5_RESULT = LinuxToolchainTest.GXX_5_RESULT 1011 GCC_6_RESULT = LinuxToolchainTest.GCC_6_RESULT 1012 GXX_6_RESULT = LinuxToolchainTest.GXX_6_RESULT 1013 GCC_7_RESULT = LinuxToolchainTest.GCC_7_RESULT 1014 GXX_7_RESULT = LinuxToolchainTest.GXX_7_RESULT 1015 DEFAULT_GCC_RESULT = LinuxToolchainTest.DEFAULT_GCC_RESULT 1016 DEFAULT_GXX_RESULT = LinuxToolchainTest.DEFAULT_GXX_RESULT 1017 1018 def test_unsupported_msvc(self): 1019 self.do_toolchain_test(self.PATHS, { 1020 'c_compiler': 'Unknown compiler or compiler not supported.' 1021 }, environ={ 1022 'CC': '/usr/bin/cl', 1023 }) 1024 1025 def test_unsupported_clang_cl(self): 1026 self.do_toolchain_test(self.PATHS, { 1027 'c_compiler': self.CLANG_CL_3_9_RESULT, 1028 }, environ={ 1029 'CC': '/usr/bin/clang-cl-3.9', 1030 }) 1031 1032 def test_clang_cl(self): 1033 self.do_toolchain_test(self.PATHS, { 1034 'c_compiler': self.CLANG_CL_8_0_RESULT, 1035 'cxx_compiler': self.CLANGXX_CL_8_0_RESULT, 1036 }) 1037 1038 def test_gcc(self): 1039 # We'll pick GCC if msvc and clang-cl can't be found. 1040 paths = { 1041 k: v for k, v in six.iteritems(self.PATHS) 1042 if os.path.basename(k) not in ('cl', 'clang-cl') 1043 } 1044 self.do_toolchain_test(paths, { 1045 'c_compiler': self.DEFAULT_GCC_RESULT, 1046 'cxx_compiler': self.DEFAULT_GXX_RESULT, 1047 }) 1048 1049 def test_overridden_unsupported_gcc(self): 1050 self.do_toolchain_test(self.PATHS, { 1051 'c_compiler': self.GCC_5_RESULT, 1052 }, environ={ 1053 'CC': 'gcc-5', 1054 'CXX': 'g++-5', 1055 }) 1056 1057 def test_clang(self): 1058 # We'll pick clang if nothing else is found. 1059 paths = { 1060 k: v for k, v in six.iteritems(self.PATHS) 1061 if os.path.basename(k) not in ('cl', 'clang-cl', 'gcc') 1062 } 1063 self.do_toolchain_test(paths, { 1064 'c_compiler': self.DEFAULT_CLANG_RESULT, 1065 'cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 1066 }) 1067 1068 def test_overridden_unsupported_clang(self): 1069 # clang 3.3 C compiler is perfectly fine, but we need more for C++. 1070 self.do_toolchain_test(self.PATHS, { 1071 'c_compiler': self.CLANG_3_3_RESULT, 1072 'cxx_compiler': self.CLANGXX_3_3_RESULT, 1073 }, environ={ 1074 'CC': 'clang-3.3', 1075 'CXX': 'clang++-3.3', 1076 }) 1077 1078 1079class Windows64ToolchainTest(WindowsToolchainTest): 1080 HOST = 'x86_64-pc-mingw32' 1081 1082 # For the purpose of this test, it doesn't matter that the paths are not 1083 # real Windows paths. 1084 PATHS = { 1085 '/usr/bin/cl': VS_2017u8 + VS_PLATFORM_X86_64, 1086 '/usr/bin/clang-cl': CLANG_CL_8_0 + CLANG_CL_PLATFORM_X86_64, 1087 '/usr/bin/clang-cl-3.9': CLANG_CL_3_9 + CLANG_CL_PLATFORM_X86_64, 1088 '/usr/bin/gcc': DEFAULT_GCC + GCC_PLATFORM_X86_64_WIN, 1089 '/usr/bin/g++': DEFAULT_GXX + GCC_PLATFORM_X86_64_WIN, 1090 '/usr/bin/gcc-4.9': GCC_4_9 + GCC_PLATFORM_X86_64_WIN, 1091 '/usr/bin/g++-4.9': GXX_4_9 + GCC_PLATFORM_X86_64_WIN, 1092 '/usr/bin/gcc-5': GCC_5 + GCC_PLATFORM_X86_64_WIN, 1093 '/usr/bin/g++-5': GXX_5 + GCC_PLATFORM_X86_64_WIN, 1094 '/usr/bin/gcc-6': GCC_6 + GCC_PLATFORM_X86_64_WIN, 1095 '/usr/bin/g++-6': GXX_6 + GCC_PLATFORM_X86_64_WIN, 1096 '/usr/bin/gcc-7': GCC_7 + GCC_PLATFORM_X86_64_WIN, 1097 '/usr/bin/g++-7': GXX_7 + GCC_PLATFORM_X86_64_WIN, 1098 '/usr/bin/clang': DEFAULT_CLANG + CLANG_PLATFORM_X86_64_WIN, 1099 '/usr/bin/clang++': DEFAULT_CLANGXX + CLANG_PLATFORM_X86_64_WIN, 1100 '/usr/bin/clang-5.0': CLANG_5_0 + CLANG_PLATFORM_X86_64_WIN, 1101 '/usr/bin/clang++-5.0': CLANGXX_5_0 + CLANG_PLATFORM_X86_64_WIN, 1102 '/usr/bin/clang-4.0': CLANG_4_0 + CLANG_PLATFORM_X86_64_WIN, 1103 '/usr/bin/clang++-4.0': CLANGXX_4_0 + CLANG_PLATFORM_X86_64_WIN, 1104 '/usr/bin/clang-3.3': CLANG_3_3 + CLANG_PLATFORM_X86_64_WIN, 1105 '/usr/bin/clang++-3.3': CLANGXX_3_3 + CLANG_PLATFORM_X86_64_WIN, 1106 } 1107 1108 1109class LinuxCrossCompileToolchainTest(BaseToolchainTest): 1110 TARGET = 'arm-unknown-linux-gnu' 1111 PATHS = { 1112 '/usr/bin/arm-linux-gnu-gcc-4.9': GCC_4_9 + GCC_PLATFORM_ARM_LINUX, 1113 '/usr/bin/arm-linux-gnu-g++-4.9': GXX_4_9 + GCC_PLATFORM_ARM_LINUX, 1114 '/usr/bin/arm-linux-gnu-gcc-5': GCC_5 + GCC_PLATFORM_ARM_LINUX, 1115 '/usr/bin/arm-linux-gnu-g++-5': GXX_5 + GCC_PLATFORM_ARM_LINUX, 1116 '/usr/bin/arm-linux-gnu-gcc': DEFAULT_GCC + GCC_PLATFORM_ARM_LINUX, 1117 '/usr/bin/arm-linux-gnu-g++': DEFAULT_GXX + GCC_PLATFORM_ARM_LINUX, 1118 '/usr/bin/arm-linux-gnu-gcc-7': GCC_7 + GCC_PLATFORM_ARM_LINUX, 1119 '/usr/bin/arm-linux-gnu-g++-7': GXX_7 + GCC_PLATFORM_ARM_LINUX, 1120 } 1121 PATHS.update(LinuxToolchainTest.PATHS) 1122 ARM_GCC_4_9_RESULT = LinuxToolchainTest.GCC_4_9_RESULT 1123 ARM_GXX_4_9_RESULT = LinuxToolchainTest.GXX_4_9_RESULT 1124 ARM_GCC_5_RESULT = LinuxToolchainTest.GCC_5_RESULT 1125 ARM_GXX_5_RESULT = LinuxToolchainTest.GXX_5_RESULT 1126 ARM_DEFAULT_GCC_RESULT = LinuxToolchainTest.DEFAULT_GCC_RESULT + { 1127 'compiler': '/usr/bin/arm-linux-gnu-gcc', 1128 } 1129 ARM_DEFAULT_GXX_RESULT = LinuxToolchainTest.DEFAULT_GXX_RESULT + { 1130 'compiler': '/usr/bin/arm-linux-gnu-g++', 1131 } 1132 ARM_GCC_7_RESULT = LinuxToolchainTest.GCC_7_RESULT + { 1133 'compiler': '/usr/bin/arm-linux-gnu-gcc-7', 1134 } 1135 ARM_GXX_7_RESULT = LinuxToolchainTest.GXX_7_RESULT + { 1136 'compiler': '/usr/bin/arm-linux-gnu-g++-7', 1137 } 1138 DEFAULT_CLANG_RESULT = LinuxToolchainTest.DEFAULT_CLANG_RESULT 1139 DEFAULT_CLANGXX_RESULT = LinuxToolchainTest.DEFAULT_CLANGXX_RESULT 1140 DEFAULT_GCC_RESULT = LinuxToolchainTest.DEFAULT_GCC_RESULT 1141 DEFAULT_GXX_RESULT = LinuxToolchainTest.DEFAULT_GXX_RESULT 1142 1143 little_endian = FakeCompiler(GCC_PLATFORM_LINUX, 1144 GCC_PLATFORM_LITTLE_ENDIAN) 1145 big_endian = FakeCompiler(GCC_PLATFORM_LINUX, GCC_PLATFORM_BIG_ENDIAN) 1146 1147 PLATFORMS = { 1148 'i686-pc-linux-gnu': GCC_PLATFORM_X86_LINUX, 1149 'x86_64-pc-linux-gnu': GCC_PLATFORM_X86_64_LINUX, 1150 'arm-unknown-linux-gnu': GCC_PLATFORM_ARM_LINUX, 1151 'aarch64-unknown-linux-gnu': little_endian + { 1152 '__aarch64__': 1, 1153 }, 1154 'ia64-unknown-linux-gnu': little_endian + { 1155 '__ia64__': 1, 1156 }, 1157 's390x-unknown-linux-gnu': big_endian + { 1158 '__s390x__': 1, 1159 '__s390__': 1, 1160 }, 1161 's390-unknown-linux-gnu': big_endian + { 1162 '__s390__': 1, 1163 }, 1164 'powerpc64-unknown-linux-gnu': big_endian + { 1165 None: { 1166 '__powerpc64__': 1, 1167 '__powerpc__': 1, 1168 }, 1169 '-m32': { 1170 '__powerpc64__': False, 1171 }, 1172 }, 1173 'powerpc-unknown-linux-gnu': big_endian + { 1174 None: { 1175 '__powerpc__': 1, 1176 }, 1177 '-m64': { 1178 '__powerpc64__': 1, 1179 }, 1180 }, 1181 'alpha-unknown-linux-gnu': little_endian + { 1182 '__alpha__': 1, 1183 }, 1184 'hppa-unknown-linux-gnu': big_endian + { 1185 '__hppa__': 1, 1186 }, 1187 'sparc64-unknown-linux-gnu': big_endian + { 1188 None: { 1189 '__arch64__': 1, 1190 '__sparc__': 1, 1191 }, 1192 '-m32': { 1193 '__arch64__': False, 1194 }, 1195 }, 1196 'sparc-unknown-linux-gnu': big_endian + { 1197 None: { 1198 '__sparc__': 1, 1199 }, 1200 '-m64': { 1201 '__arch64__': 1, 1202 }, 1203 }, 1204 'mips64-unknown-linux-gnuabi64': big_endian + { 1205 '__mips64': 1, 1206 '__mips__': 1, 1207 }, 1208 'mips-unknown-linux-gnu': big_endian + { 1209 '__mips__': 1, 1210 }, 1211 'sh4-unknown-linux-gnu': little_endian + { 1212 '__sh__': 1, 1213 }, 1214 } 1215 1216 PLATFORMS['powerpc64le-unknown-linux-gnu'] = \ 1217 PLATFORMS['powerpc64-unknown-linux-gnu'] + GCC_PLATFORM_LITTLE_ENDIAN 1218 PLATFORMS['mips64el-unknown-linux-gnuabi64'] = \ 1219 PLATFORMS['mips64-unknown-linux-gnuabi64'] + GCC_PLATFORM_LITTLE_ENDIAN 1220 PLATFORMS['mipsel-unknown-linux-gnu'] = \ 1221 PLATFORMS['mips-unknown-linux-gnu'] + GCC_PLATFORM_LITTLE_ENDIAN 1222 1223 def do_test_cross_gcc_32_64(self, host, target): 1224 self.HOST = host 1225 self.TARGET = target 1226 paths = { 1227 '/usr/bin/gcc': DEFAULT_GCC + self.PLATFORMS[host], 1228 '/usr/bin/g++': DEFAULT_GXX + self.PLATFORMS[host], 1229 } 1230 cross_flags = { 1231 'flags': ['-m64' if '64' in target else '-m32'] 1232 } 1233 self.do_toolchain_test(paths, { 1234 'c_compiler': self.DEFAULT_GCC_RESULT + cross_flags, 1235 'cxx_compiler': self.DEFAULT_GXX_RESULT + cross_flags, 1236 'host_c_compiler': self.DEFAULT_GCC_RESULT, 1237 'host_cxx_compiler': self.DEFAULT_GXX_RESULT, 1238 }) 1239 self.HOST = LinuxCrossCompileToolchainTest.HOST 1240 self.TARGET = LinuxCrossCompileToolchainTest.TARGET 1241 1242 def test_cross_x86_x64(self): 1243 self.do_test_cross_gcc_32_64( 1244 'i686-pc-linux-gnu', 'x86_64-pc-linux-gnu') 1245 self.do_test_cross_gcc_32_64( 1246 'x86_64-pc-linux-gnu', 'i686-pc-linux-gnu') 1247 1248 def test_cross_sparc_sparc64(self): 1249 self.do_test_cross_gcc_32_64( 1250 'sparc-unknown-linux-gnu', 'sparc64-unknown-linux-gnu') 1251 self.do_test_cross_gcc_32_64( 1252 'sparc64-unknown-linux-gnu', 'sparc-unknown-linux-gnu') 1253 1254 def test_cross_ppc_ppc64(self): 1255 self.do_test_cross_gcc_32_64( 1256 'powerpc-unknown-linux-gnu', 'powerpc64-unknown-linux-gnu') 1257 self.do_test_cross_gcc_32_64( 1258 'powerpc64-unknown-linux-gnu', 'powerpc-unknown-linux-gnu') 1259 1260 def do_test_cross_gcc(self, host, target): 1261 self.HOST = host 1262 self.TARGET = target 1263 host_cpu = host.split('-')[0] 1264 cpu, manufacturer, os = target.split('-', 2) 1265 toolchain_prefix = '/usr/bin/%s-%s' % (cpu, os) 1266 paths = { 1267 '/usr/bin/gcc': DEFAULT_GCC + self.PLATFORMS[host], 1268 '/usr/bin/g++': DEFAULT_GXX + self.PLATFORMS[host], 1269 } 1270 self.do_toolchain_test(paths, { 1271 'c_compiler': ('Target C compiler target CPU (%s) ' 1272 'does not match --target CPU (%s)' 1273 % (host_cpu, cpu)), 1274 }) 1275 1276 paths.update({ 1277 '%s-gcc' % toolchain_prefix: DEFAULT_GCC + self.PLATFORMS[target], 1278 '%s-g++' % toolchain_prefix: DEFAULT_GXX + self.PLATFORMS[target], 1279 }) 1280 self.do_toolchain_test(paths, { 1281 'c_compiler': self.DEFAULT_GCC_RESULT + { 1282 'compiler': '%s-gcc' % toolchain_prefix, 1283 }, 1284 'cxx_compiler': self.DEFAULT_GXX_RESULT + { 1285 'compiler': '%s-g++' % toolchain_prefix, 1286 }, 1287 'host_c_compiler': self.DEFAULT_GCC_RESULT, 1288 'host_cxx_compiler': self.DEFAULT_GXX_RESULT, 1289 }) 1290 self.HOST = LinuxCrossCompileToolchainTest.HOST 1291 self.TARGET = LinuxCrossCompileToolchainTest.TARGET 1292 1293 def test_cross_gcc_misc(self): 1294 for target in self.PLATFORMS: 1295 if not target.endswith('-pc-linux-gnu'): 1296 self.do_test_cross_gcc('x86_64-pc-linux-gnu', target) 1297 1298 def test_cannot_cross(self): 1299 self.TARGET = 'mipsel-unknown-linux-gnu' 1300 1301 paths = { 1302 '/usr/bin/gcc': DEFAULT_GCC + self.PLATFORMS['mips-unknown-linux-gnu'], 1303 '/usr/bin/g++': DEFAULT_GXX + self.PLATFORMS['mips-unknown-linux-gnu'], 1304 } 1305 self.do_toolchain_test(paths, { 1306 'c_compiler': ('Target C compiler target endianness (big) ' 1307 'does not match --target endianness (little)'), 1308 }) 1309 self.TARGET = LinuxCrossCompileToolchainTest.TARGET 1310 1311 def test_overridden_cross_gcc(self): 1312 self.do_toolchain_test(self.PATHS, { 1313 'c_compiler': self.ARM_GCC_7_RESULT, 1314 'cxx_compiler': self.ARM_GXX_7_RESULT, 1315 'host_c_compiler': self.DEFAULT_GCC_RESULT, 1316 'host_cxx_compiler': self.DEFAULT_GXX_RESULT, 1317 }, environ={ 1318 'CC': 'arm-linux-gnu-gcc-7', 1319 'CXX': 'arm-linux-gnu-g++-7', 1320 }) 1321 1322 def test_overridden_unsupported_cross_gcc(self): 1323 self.do_toolchain_test(self.PATHS, { 1324 'c_compiler': self.ARM_GCC_4_9_RESULT, 1325 }, environ={ 1326 'CC': 'arm-linux-gnu-gcc-4.9', 1327 'CXX': 'arm-linux-gnu-g++-4.9', 1328 }) 1329 1330 def test_guess_cross_cxx(self): 1331 # When CXX is not set, we guess it from CC. 1332 self.do_toolchain_test(self.PATHS, { 1333 'c_compiler': self.ARM_GCC_7_RESULT, 1334 'cxx_compiler': self.ARM_GXX_7_RESULT, 1335 'host_c_compiler': self.DEFAULT_GCC_RESULT, 1336 'host_cxx_compiler': self.DEFAULT_GXX_RESULT, 1337 }, environ={ 1338 'CC': 'arm-linux-gnu-gcc-7', 1339 }) 1340 1341 self.do_toolchain_test(self.PATHS, { 1342 'c_compiler': self.ARM_DEFAULT_GCC_RESULT, 1343 'cxx_compiler': self.ARM_DEFAULT_GXX_RESULT, 1344 'host_c_compiler': self.DEFAULT_CLANG_RESULT, 1345 'host_cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 1346 }, environ={ 1347 'CC': 'arm-linux-gnu-gcc', 1348 'HOST_CC': 'clang', 1349 }) 1350 1351 self.do_toolchain_test(self.PATHS, { 1352 'c_compiler': self.ARM_DEFAULT_GCC_RESULT, 1353 'cxx_compiler': self.ARM_DEFAULT_GXX_RESULT, 1354 'host_c_compiler': self.DEFAULT_CLANG_RESULT, 1355 'host_cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 1356 }, environ={ 1357 'CC': 'arm-linux-gnu-gcc', 1358 'CXX': 'arm-linux-gnu-g++', 1359 'HOST_CC': 'clang', 1360 }) 1361 1362 def test_cross_clang(self): 1363 cross_clang_result = self.DEFAULT_CLANG_RESULT + { 1364 'flags': ['--target=arm-linux-gnu'], 1365 } 1366 cross_clangxx_result = self.DEFAULT_CLANGXX_RESULT + { 1367 'flags': ['--target=arm-linux-gnu'], 1368 } 1369 self.do_toolchain_test(self.PATHS, { 1370 'c_compiler': cross_clang_result, 1371 'cxx_compiler': cross_clangxx_result, 1372 'host_c_compiler': self.DEFAULT_CLANG_RESULT, 1373 'host_cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 1374 }, environ={ 1375 'CC': 'clang', 1376 'HOST_CC': 'clang', 1377 }) 1378 1379 self.do_toolchain_test(self.PATHS, { 1380 'c_compiler': cross_clang_result, 1381 'cxx_compiler': cross_clangxx_result, 1382 'host_c_compiler': self.DEFAULT_CLANG_RESULT, 1383 'host_cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 1384 }, environ={ 1385 'CC': 'clang', 1386 }) 1387 1388 def test_cross_atypical_clang(self): 1389 paths = dict(self.PATHS) 1390 paths.update({ 1391 '/usr/bin/afl-clang-fast': paths['/usr/bin/clang'], 1392 '/usr/bin/afl-clang-fast++': paths['/usr/bin/clang++'], 1393 }) 1394 afl_clang_result = self.DEFAULT_CLANG_RESULT + { 1395 'compiler': '/usr/bin/afl-clang-fast', 1396 } 1397 afl_clangxx_result = self.DEFAULT_CLANGXX_RESULT + { 1398 'compiler': '/usr/bin/afl-clang-fast++', 1399 } 1400 self.do_toolchain_test(paths, { 1401 'c_compiler': afl_clang_result + { 1402 'flags': ['--target=arm-linux-gnu'], 1403 }, 1404 'cxx_compiler': afl_clangxx_result + { 1405 'flags': ['--target=arm-linux-gnu'], 1406 }, 1407 'host_c_compiler': afl_clang_result, 1408 'host_cxx_compiler': afl_clangxx_result, 1409 }, environ={ 1410 'CC': 'afl-clang-fast', 1411 'CXX': 'afl-clang-fast++', 1412 }) 1413 1414 1415class OSXCrossToolchainTest(BaseToolchainTest): 1416 TARGET = 'i686-apple-darwin11.2.0' 1417 PATHS = dict(LinuxToolchainTest.PATHS) 1418 PATHS.update({ 1419 '/usr/bin/clang': CLANG_5_0 + CLANG_PLATFORM_X86_64_LINUX, 1420 '/usr/bin/clang++': CLANGXX_5_0 + CLANG_PLATFORM_X86_64_LINUX, 1421 }) 1422 DEFAULT_CLANG_RESULT = OSXToolchainTest.DEFAULT_CLANG_RESULT 1423 DEFAULT_CLANGXX_RESULT = OSXToolchainTest.DEFAULT_CLANGXX_RESULT 1424 1425 def test_osx_cross(self): 1426 self.do_toolchain_test(self.PATHS, { 1427 'c_compiler': self.DEFAULT_CLANG_RESULT + OSXToolchainTest.SYSROOT_FLAGS + { 1428 'flags': ['--target=i686-apple-darwin11.2.0'], 1429 }, 1430 'cxx_compiler': self.DEFAULT_CLANGXX_RESULT + OSXToolchainTest.SYSROOT_FLAGS + { 1431 'flags': ['--target=i686-apple-darwin11.2.0'], 1432 }, 1433 'host_c_compiler': self.DEFAULT_CLANG_RESULT, 1434 'host_cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 1435 }, environ={ 1436 'CC': 'clang', 1437 }, args=['--with-macos-sdk=%s' % OSXToolchainTest.SYSROOT_FLAGS['flags'][1]]) 1438 1439 def test_cannot_osx_cross(self): 1440 self.do_toolchain_test(self.PATHS, { 1441 'c_compiler': 'Target C compiler target kernel (Linux) does not ' 1442 'match --target kernel (Darwin)', 1443 }, environ={ 1444 'CC': 'gcc', 1445 }, args=['--with-macos-sdk=%s' % OSXToolchainTest.SYSROOT_FLAGS['flags'][1]]) 1446 1447 1448class WindowsCrossToolchainTest(BaseToolchainTest): 1449 TARGET = 'x86_64-pc-mingw32' 1450 DEFAULT_CLANG_RESULT = LinuxToolchainTest.DEFAULT_CLANG_RESULT 1451 DEFAULT_CLANGXX_RESULT = LinuxToolchainTest.DEFAULT_CLANGXX_RESULT 1452 1453 def test_clang_cl_cross(self): 1454 paths = { 1455 '/usr/bin/clang-cl': CLANG_CL_8_0 + CLANG_CL_PLATFORM_X86_64, 1456 } 1457 paths.update(LinuxToolchainTest.PATHS) 1458 self.do_toolchain_test(paths, { 1459 'c_compiler': WindowsToolchainTest.CLANG_CL_8_0_RESULT, 1460 'cxx_compiler': WindowsToolchainTest.CLANGXX_CL_8_0_RESULT, 1461 'host_c_compiler': self.DEFAULT_CLANG_RESULT, 1462 'host_cxx_compiler': self.DEFAULT_CLANGXX_RESULT, 1463 }) 1464 1465 1466class OpenBSDToolchainTest(BaseToolchainTest): 1467 HOST = 'x86_64-unknown-openbsd6.1' 1468 TARGET = 'x86_64-unknown-openbsd6.1' 1469 PATHS = { 1470 '/usr/bin/gcc': DEFAULT_GCC + GCC_PLATFORM_X86_64 + GCC_PLATFORM_OPENBSD, 1471 '/usr/bin/g++': DEFAULT_GXX + GCC_PLATFORM_X86_64 + GCC_PLATFORM_OPENBSD, 1472 } 1473 DEFAULT_GCC_RESULT = LinuxToolchainTest.DEFAULT_GCC_RESULT 1474 DEFAULT_GXX_RESULT = LinuxToolchainTest.DEFAULT_GXX_RESULT 1475 1476 def test_gcc(self): 1477 self.do_toolchain_test(self.PATHS, { 1478 'c_compiler': self.DEFAULT_GCC_RESULT, 1479 'cxx_compiler': self.DEFAULT_GXX_RESULT, 1480 }) 1481 1482 1483@memoize 1484def gen_invoke_cargo(version, rustup_wrapper=False): 1485 def invoke_cargo(stdin, args): 1486 args = tuple(args) 1487 if not rustup_wrapper and args == ('+stable',): 1488 return (101, '', 'we are the real thing') 1489 if args == ('--version', '--verbose'): 1490 return 0, 'cargo %s\nrelease: %s' % (version, version), '' 1491 raise NotImplementedError('unsupported arguments') 1492 return invoke_cargo 1493 1494 1495@memoize 1496def gen_invoke_rustc(version, rustup_wrapper=False): 1497 def invoke_rustc(stdin, args): 1498 args = tuple(args) 1499 # TODO: we don't have enough machinery set up to test the `rustup which` 1500 # fallback yet. 1501 if not rustup_wrapper and args == ('+stable',): 1502 return (1, '', 'error: couldn\'t read +stable: No such file or directory') 1503 if args == ('--version', '--verbose'): 1504 return (0, 'rustc %s\nrelease: %s\nhost: x86_64-unknown-linux-gnu' 1505 % (version, version), '') 1506 if args == ('--print', 'target-list'): 1507 # Raw list returned by rustc version 1.32, + ios, which somehow 1508 # don't appear in the default list. 1509 # https://github.com/rust-lang/rust/issues/36156 1510 rust_targets = [ 1511 'aarch64-apple-ios', 1512 'aarch64-fuchsia', 1513 'aarch64-linux-android', 1514 'aarch64-pc-windows-msvc', 1515 'aarch64-unknown-cloudabi', 1516 'aarch64-unknown-freebsd', 1517 'aarch64-unknown-hermit', 1518 'aarch64-unknown-linux-gnu', 1519 'aarch64-unknown-linux-musl', 1520 'aarch64-unknown-netbsd', 1521 'aarch64-unknown-none', 1522 'aarch64-unknown-openbsd', 1523 'arm-linux-androideabi', 1524 'arm-unknown-linux-gnueabi', 1525 'arm-unknown-linux-gnueabihf', 1526 'arm-unknown-linux-musleabi', 1527 'arm-unknown-linux-musleabihf', 1528 'armebv7r-none-eabi', 1529 'armebv7r-none-eabihf', 1530 'armv4t-unknown-linux-gnueabi', 1531 'armv5te-unknown-linux-gnueabi', 1532 'armv5te-unknown-linux-musleabi', 1533 'armv6-unknown-netbsd-eabihf', 1534 'armv7-linux-androideabi', 1535 'armv7-unknown-cloudabi-eabihf', 1536 'armv7-unknown-linux-gnueabihf', 1537 'armv7-unknown-linux-musleabihf', 1538 'armv7-unknown-netbsd-eabihf', 1539 'armv7r-none-eabi', 1540 'armv7r-none-eabihf', 1541 'armv7s-apple-ios', 1542 'asmjs-unknown-emscripten', 1543 'i386-apple-ios', 1544 'i586-pc-windows-msvc', 1545 'i586-unknown-linux-gnu', 1546 'i586-unknown-linux-musl', 1547 'i686-apple-darwin', 1548 'i686-linux-android', 1549 'i686-pc-windows-gnu', 1550 'i686-pc-windows-msvc', 1551 'i686-unknown-cloudabi', 1552 'i686-unknown-dragonfly', 1553 'i686-unknown-freebsd', 1554 'i686-unknown-haiku', 1555 'i686-unknown-linux-gnu', 1556 'i686-unknown-linux-musl', 1557 'i686-unknown-netbsd', 1558 'i686-unknown-openbsd', 1559 'mips-unknown-linux-gnu', 1560 'mips-unknown-linux-musl', 1561 'mips-unknown-linux-uclibc', 1562 'mips64-unknown-linux-gnuabi64', 1563 'mips64el-unknown-linux-gnuabi64', 1564 'mipsel-unknown-linux-gnu', 1565 'mipsel-unknown-linux-musl', 1566 'mipsel-unknown-linux-uclibc', 1567 'msp430-none-elf', 1568 'powerpc-unknown-linux-gnu', 1569 'powerpc-unknown-linux-gnuspe', 1570 'powerpc-unknown-linux-musl', 1571 'powerpc-unknown-netbsd', 1572 'powerpc64-unknown-linux-gnu', 1573 'powerpc64-unknown-linux-musl', 1574 'powerpc64le-unknown-linux-gnu', 1575 'powerpc64le-unknown-linux-musl', 1576 'riscv32imac-unknown-none-elf', 1577 'riscv32imc-unknown-none-elf', 1578 's390x-unknown-linux-gnu', 1579 'sparc-unknown-linux-gnu', 1580 'sparc64-unknown-linux-gnu', 1581 'sparc64-unknown-netbsd', 1582 'sparcv9-sun-solaris', 1583 'thumbv6m-none-eabi', 1584 'thumbv7a-pc-windows-msvc', 1585 'thumbv7em-none-eabi', 1586 'thumbv7em-none-eabihf', 1587 'thumbv7m-none-eabi', 1588 'thumbv8m.base-none-eabi', 1589 'wasm32-experimental-emscripten', 1590 'wasm32-unknown-emscripten', 1591 'wasm32-unknown-unknown', 1592 'x86_64-apple-darwin', 1593 'x86_64-apple-ios', 1594 'x86_64-fortanix-unknown-sgx', 1595 'x86_64-fuchsia', 1596 'x86_64-linux-android', 1597 'x86_64-pc-windows-gnu', 1598 'x86_64-pc-windows-msvc', 1599 'x86_64-rumprun-netbsd', 1600 'x86_64-sun-solaris', 1601 'x86_64-unknown-bitrig', 1602 'x86_64-unknown-cloudabi', 1603 'x86_64-unknown-dragonfly', 1604 'x86_64-unknown-freebsd', 1605 'x86_64-unknown-haiku', 1606 'x86_64-unknown-hermit', 1607 'x86_64-unknown-l4re-uclibc', 1608 'x86_64-unknown-linux-gnu', 1609 'x86_64-unknown-linux-gnux32', 1610 'x86_64-unknown-linux-musl', 1611 'x86_64-unknown-netbsd', 1612 'x86_64-unknown-openbsd', 1613 'x86_64-unknown-redox', 1614 ] 1615 # Additional targets from 1.33 1616 if Version(version) >= '1.33.0': 1617 rust_targets += [ 1618 'thumbv7neon-linux-androideabi', 1619 'thumbv7neon-unknown-linux-gnueabihf', 1620 'x86_64-unknown-uefi', 1621 'thumbv8m.main-none-eabi', 1622 'thumbv8m.main-none-eabihf', 1623 ] 1624 # Additional targets from 1.34 1625 if Version(version) >= '1.34.0': 1626 rust_targets += [ 1627 'nvptx64-nvidia-cuda', 1628 'powerpc64-unknown-freebsd', 1629 'riscv64gc-unknown-none-elf', 1630 'riscv64imac-unknown-none-elf', 1631 ] 1632 # Additional targets from 1.35 1633 if Version(version) >= '1.35.0': 1634 rust_targets += [ 1635 'armv6-unknown-freebsd', 1636 'armv7-unknown-freebsd', 1637 'mipsisa32r6-unknown-linux-gnu', 1638 'mipsisa32r6el-unknown-linux-gnu', 1639 'mipsisa64r6-unknown-linux-gnuabi64', 1640 'mipsisa64r6el-unknown-linux-gnuabi64', 1641 'wasm32-unknown-wasi', 1642 ] 1643 # Additional targets from 1.36 1644 if Version(version) >= '1.36.0': 1645 rust_targets += [ 1646 'wasm32-wasi', 1647 ] 1648 rust_targets.remove('wasm32-unknown-wasi') 1649 rust_targets.remove('x86_64-unknown-bitrig') 1650 # Additional targets from 1.37 1651 if Version(version) >= '1.37.0': 1652 rust_targets += [ 1653 'x86_64-pc-solaris', 1654 ] 1655 # Additional targets from 1.38 1656 if Version(version) >= '1.38.0': 1657 rust_targets += [ 1658 'aarch64-unknown-redox', 1659 'aarch64-wrs-vxworks', 1660 'armv7-unknown-linux-gnueabi', 1661 'armv7-unknown-linux-musleabi', 1662 'armv7-wrs-vxworks', 1663 'hexagon-unknown-linux-musl', 1664 'i586-wrs-vxworks', 1665 'i686-uwp-windows-gnu', 1666 'i686-wrs-vxworks', 1667 'powerpc-wrs-vxworks', 1668 'powerpc-wrs-vxworks-spe', 1669 'powerpc64-wrs-vxworks', 1670 'riscv32i-unknown-none-elf', 1671 'x86_64-uwp-windows-gnu', 1672 'x86_64-wrs-vxworks', 1673 ] 1674 # Additional targets from 1.38 1675 if Version(version) >= '1.39.0': 1676 rust_targets += [ 1677 'aarch64-uwp-windows-msvc', 1678 'armv7-wrs-vxworks-eabihf', 1679 'i686-unknown-uefi', 1680 'i686-uwp-windows-msvc', 1681 'mips64-unknown-linux-muslabi64', 1682 'mips64el-unknown-linux-muslabi64', 1683 'sparc64-unknown-openbsd', 1684 'x86_64-linux-kernel', 1685 'x86_64-uwp-windows-msvc', 1686 ] 1687 rust_targets.remove('armv7-wrs-vxworks') 1688 rust_targets.remove('i586-wrs-vxworks') 1689 1690 return 0, '\n'.join(sorted(rust_targets)), '' 1691 if (len(args) == 6 and args[:2] == ('--crate-type', 'staticlib') and 1692 args[2].startswith('--target=') and args[3] == '-o'): 1693 with open(args[4], 'w') as fh: 1694 fh.write('foo') 1695 return 0, '', '' 1696 raise NotImplementedError('unsupported arguments') 1697 return invoke_rustc 1698 1699 1700class RustTest(BaseConfigureTest): 1701 def get_rust_target(self, target, compiler_type='gcc', version='1.39.0', 1702 arm_target=None): 1703 environ = { 1704 'PATH': os.pathsep.join( 1705 mozpath.abspath(p) for p in ('/bin', '/usr/bin')), 1706 } 1707 1708 paths = { 1709 mozpath.abspath('/usr/bin/cargo'): gen_invoke_cargo(version), 1710 mozpath.abspath('/usr/bin/rustc'): gen_invoke_rustc(version), 1711 } 1712 1713 self.TARGET = target 1714 # --enable-project=tools/crashreporter for more relaxed rust 1715 # dependency. 1716 sandbox = self.get_sandbox( 1717 paths, {}, ['--enable-project=tools/crashreporter'], environ) 1718 1719 # Trick the sandbox into not running the target compiler check 1720 dep = sandbox._depends[sandbox['c_compiler']] 1721 getattr(sandbox, '__value_for_depends')[(dep,)] = \ 1722 CompilerResult(type=compiler_type) 1723 # Same for the arm_target checks. 1724 dep = sandbox._depends[sandbox['arm_target']] 1725 getattr(sandbox, '__value_for_depends')[(dep,)] = \ 1726 arm_target or ReadOnlyNamespace(arm_arch=7, thumb2=False, 1727 fpu='vfpv2', float_abi='softfp') 1728 return sandbox._value_for(sandbox['rust_target_triple']) 1729 1730 def test_rust_target(self): 1731 # Cases where the output of config.sub matches a rust target 1732 for straightforward in ( 1733 'x86_64-unknown-dragonfly', 1734 'aarch64-unknown-freebsd', 1735 'i686-unknown-freebsd', 1736 'x86_64-unknown-freebsd', 1737 'sparc64-unknown-netbsd', 1738 'i686-unknown-netbsd', 1739 'x86_64-unknown-netbsd', 1740 'i686-unknown-openbsd', 1741 'x86_64-unknown-openbsd', 1742 'aarch64-unknown-linux-gnu', 1743 'sparc64-unknown-linux-gnu', 1744 'i686-unknown-linux-gnu', 1745 'i686-apple-darwin', 1746 'x86_64-apple-darwin', 1747 'mips-unknown-linux-gnu', 1748 'mipsel-unknown-linux-gnu', 1749 'mips64-unknown-linux-gnuabi64', 1750 'mips64el-unknown-linux-gnuabi64', 1751 'powerpc64-unknown-linux-gnu', 1752 'powerpc64le-unknown-linux-gnu', 1753 ): 1754 self.assertEqual(self.get_rust_target(straightforward), straightforward) 1755 1756 # Cases where the output of config.sub is different 1757 for autoconf, rust in ( 1758 ('aarch64-unknown-linux-android', 'aarch64-linux-android'), 1759 ('arm-unknown-linux-androideabi', 'armv7-linux-androideabi'), 1760 ('armv7-unknown-linux-androideabi', 'armv7-linux-androideabi'), 1761 ('i386-unknown-linux-android', 'i686-linux-android'), 1762 ('i686-unknown-linux-android', 'i686-linux-android'), 1763 ('i686-pc-linux-gnu', 'i686-unknown-linux-gnu'), 1764 ('x86_64-unknown-linux-android', 'x86_64-linux-android'), 1765 ('x86_64-pc-linux-gnu', 'x86_64-unknown-linux-gnu'), 1766 ('sparcv9-sun-solaris2', 'sparcv9-sun-solaris'), 1767 ('x86_64-sun-solaris2', 'x86_64-sun-solaris'), 1768 ): 1769 self.assertEqual(self.get_rust_target(autoconf), rust) 1770 1771 # Windows 1772 for autoconf, building_with_gcc, rust in ( 1773 ('i686-pc-mingw32', 'cl', 'i686-pc-windows-msvc'), 1774 ('x86_64-pc-mingw32', 'cl', 'x86_64-pc-windows-msvc'), 1775 ('i686-pc-mingw32', 'gcc', 'i686-pc-windows-gnu'), 1776 ('x86_64-pc-mingw32', 'gcc', 'x86_64-pc-windows-gnu'), 1777 ('i686-pc-mingw32', 'clang', 'i686-pc-windows-gnu'), 1778 ('x86_64-pc-mingw32', 'clang', 'x86_64-pc-windows-gnu'), 1779 ('i686-w64-mingw32', 'clang', 'i686-pc-windows-gnu'), 1780 ('x86_64-w64-mingw32', 'clang', 'x86_64-pc-windows-gnu'), 1781 ('aarch64-windows-mingw32', 'clang-cl', 'aarch64-pc-windows-msvc'), 1782 ): 1783 self.assertEqual(self.get_rust_target(autoconf, building_with_gcc), rust) 1784 1785 # Arm special cases 1786 self.assertEqual( 1787 self.get_rust_target('arm-unknown-linux-androideabi', 1788 arm_target=ReadOnlyNamespace( 1789 arm_arch=7, fpu='neon', thumb2=True, float_abi='softfp')), 1790 'thumbv7neon-linux-androideabi') 1791 1792 self.assertEqual( 1793 self.get_rust_target('arm-unknown-linux-androideabi', 1794 arm_target=ReadOnlyNamespace( 1795 arm_arch=7, fpu='neon', thumb2=False, float_abi='softfp')), 1796 'armv7-linux-androideabi') 1797 1798 self.assertEqual( 1799 self.get_rust_target('arm-unknown-linux-androideabi', 1800 arm_target=ReadOnlyNamespace( 1801 arm_arch=7, fpu='vfpv2', thumb2=True, float_abi='softfp')), 1802 'armv7-linux-androideabi') 1803 1804 self.assertEqual( 1805 self.get_rust_target('armv7-unknown-linux-gnueabihf', 1806 arm_target=ReadOnlyNamespace( 1807 arm_arch=7, fpu='neon', thumb2=True, float_abi='hard')), 1808 'thumbv7neon-unknown-linux-gnueabihf') 1809 1810 self.assertEqual( 1811 self.get_rust_target('armv7-unknown-linux-gnueabihf', 1812 arm_target=ReadOnlyNamespace( 1813 arm_arch=7, fpu='neon', thumb2=False, float_abi='hard')), 1814 'armv7-unknown-linux-gnueabihf') 1815 1816 self.assertEqual( 1817 self.get_rust_target('armv7-unknown-linux-gnueabihf', 1818 arm_target=ReadOnlyNamespace( 1819 arm_arch=7, fpu='vfpv2', thumb2=True, float_abi='hard')), 1820 'armv7-unknown-linux-gnueabihf') 1821 1822 self.assertEqual( 1823 self.get_rust_target('arm-unknown-freebsd13.0-gnueabihf', 1824 arm_target=ReadOnlyNamespace( 1825 arm_arch=7, fpu='vfpv2', thumb2=True, float_abi='hard')), 1826 'armv7-unknown-freebsd') 1827 1828 self.assertEqual( 1829 self.get_rust_target('arm-unknown-freebsd13.0-gnueabihf', 1830 arm_target=ReadOnlyNamespace( 1831 arm_arch=6, fpu=None, thumb2=False, float_abi='hard')), 1832 'armv6-unknown-freebsd') 1833 1834 self.assertEqual( 1835 self.get_rust_target('arm-unknown-linux-gnueabi', 1836 arm_target=ReadOnlyNamespace( 1837 arm_arch=4, fpu=None, thumb2=False, float_abi='softfp')), 1838 'armv4t-unknown-linux-gnueabi') 1839 1840 1841if __name__ == '__main__': 1842 main() 1843