1# Copyright 2012-2017 The Meson development team 2 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6 7# http://www.apache.org/licenses/LICENSE-2.0 8 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15import copy 16import functools 17import os.path 18import typing as T 19 20from .. import coredata 21from .. import mlog 22from ..mesonlib import MesonException, MachineChoice, version_compare 23 24from ..linkers import LinkerEnvVarsMixin 25from .compilers import ( 26 gnu_winlibs, 27 msvc_winlibs, 28 Compiler, 29) 30from .c_function_attributes import CXX_FUNC_ATTRIBUTES, C_FUNC_ATTRIBUTES 31from .mixins.clike import CLikeCompiler 32from .mixins.ccrx import CcrxCompiler 33from .mixins.c2000 import C2000Compiler 34from .mixins.arm import ArmCompiler, ArmclangCompiler 35from .mixins.visualstudio import MSVCCompiler, ClangClCompiler 36from .mixins.gnu import GnuCompiler 37from .mixins.intel import IntelGnuLikeCompiler, IntelVisualStudioLikeCompiler 38from .mixins.clang import ClangCompiler 39from .mixins.elbrus import ElbrusCompiler 40from .mixins.pgi import PGICompiler 41from .mixins.emscripten import EmscriptenMixin 42 43if T.TYPE_CHECKING: 44 from ..envconfig import MachineInfo 45 46 47def non_msvc_eh_options(eh, args): 48 if eh == 'none': 49 args.append('-fno-exceptions') 50 elif eh == 's' or eh == 'c': 51 mlog.warning('non-MSVC compilers do not support ' + eh + ' exception handling.' + 52 'You may want to set eh to \'default\'.') 53 54class CPPCompiler(CLikeCompiler, Compiler): 55 56 @classmethod 57 def attribute_check_func(cls, name): 58 try: 59 return CXX_FUNC_ATTRIBUTES.get(name, C_FUNC_ATTRIBUTES[name]) 60 except KeyError: 61 raise MesonException('Unknown function attribute "{}"'.format(name)) 62 63 language = 'cpp' 64 65 def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool, 66 info: 'MachineInfo', exe_wrap: T.Optional[str] = None, **kwargs): 67 # If a child ObjCPP class has already set it, don't set it ourselves 68 Compiler.__init__(self, exelist, version, for_machine, info, **kwargs) 69 CLikeCompiler.__init__(self, is_cross, exe_wrap) 70 71 @staticmethod 72 def get_display_language(): 73 return 'C++' 74 75 def get_no_stdinc_args(self): 76 return ['-nostdinc++'] 77 78 def sanity_check(self, work_dir, environment): 79 code = 'class breakCCompiler;int main(void) { return 0; }\n' 80 return self.sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code) 81 82 def get_compiler_check_args(self): 83 # -fpermissive allows non-conforming code to compile which is necessary 84 # for many C++ checks. Particularly, the has_header_symbol check is 85 # too strict without this and always fails. 86 return super().get_compiler_check_args() + ['-fpermissive'] 87 88 def has_header_symbol(self, hname, symbol, prefix, env, *, extra_args=None, dependencies=None): 89 # Check if it's a C-like symbol 90 found, cached = super().has_header_symbol(hname, symbol, prefix, env, 91 extra_args=extra_args, 92 dependencies=dependencies) 93 if found: 94 return True, cached 95 # Check if it's a class or a template 96 if extra_args is None: 97 extra_args = [] 98 fargs = {'prefix': prefix, 'header': hname, 'symbol': symbol} 99 t = '''{prefix} 100 #include <{header}> 101 using {symbol}; 102 int main(void) {{ return 0; }}''' 103 return self.compiles(t.format(**fargs), env, extra_args=extra_args, 104 dependencies=dependencies) 105 106 def _test_cpp_std_arg(self, cpp_std_value): 107 # Test whether the compiler understands a -std=XY argument 108 assert(cpp_std_value.startswith('-std=')) 109 110 # This test does not use has_multi_arguments() for two reasons: 111 # 1. has_multi_arguments() requires an env argument, which the compiler 112 # object does not have at this point. 113 # 2. even if it did have an env object, that might contain another more 114 # recent -std= argument, which might lead to a cascaded failure. 115 CPP_TEST = 'int i = static_cast<int>(0);' 116 with self.compile(CPP_TEST, extra_args=[cpp_std_value], mode='compile') as p: 117 if p.returncode == 0: 118 mlog.debug('Compiler accepts {}:'.format(cpp_std_value), 'YES') 119 return True 120 else: 121 mlog.debug('Compiler accepts {}:'.format(cpp_std_value), 'NO') 122 return False 123 124 @functools.lru_cache() 125 def _find_best_cpp_std(self, cpp_std): 126 # The initial version mapping approach to make falling back 127 # from '-std=c++14' to '-std=c++1y' was too brittle. For instance, 128 # Apple's Clang uses a different versioning scheme to upstream LLVM, 129 # making the whole detection logic awfully brittle. Instead, let's 130 # just see if feeding GCC or Clang our '-std=' setting works, and 131 # if not, try the fallback argument. 132 CPP_FALLBACKS = { 133 'c++11': 'c++0x', 134 'gnu++11': 'gnu++0x', 135 'c++14': 'c++1y', 136 'gnu++14': 'gnu++1y', 137 'c++17': 'c++1z', 138 'gnu++17': 'gnu++1z' 139 } 140 141 # Currently, remapping is only supported for Clang, Elbrus and GCC 142 assert(self.id in frozenset(['clang', 'lcc', 'gcc', 'emscripten'])) 143 144 if cpp_std not in CPP_FALLBACKS: 145 # 'c++03' and 'c++98' don't have fallback types 146 return '-std=' + cpp_std 147 148 for i in (cpp_std, CPP_FALLBACKS[cpp_std]): 149 cpp_std_value = '-std=' + i 150 if self._test_cpp_std_arg(cpp_std_value): 151 return cpp_std_value 152 153 raise MesonException('C++ Compiler does not support -std={}'.format(cpp_std)) 154 155 156class ClangCPPCompiler(ClangCompiler, CPPCompiler): 157 def __init__(self, exelist, version, for_machine: MachineChoice, 158 is_cross, info: 'MachineInfo', exe_wrapper=None, 159 defines : T.Optional[T.List[str]] = None, **kwargs): 160 CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, 161 info, exe_wrapper, **kwargs) 162 ClangCompiler.__init__(self, defines) 163 default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'] 164 self.warn_args = {'0': [], 165 '1': default_warn_args, 166 '2': default_warn_args + ['-Wextra'], 167 '3': default_warn_args + ['-Wextra', '-Wpedantic']} 168 169 def get_options(self): 170 opts = CPPCompiler.get_options(self) 171 opts.update({ 172 'eh': coredata.UserComboOption( 173 'C++ exception handling type.', 174 ['none', 'default', 'a', 's', 'sc'], 175 'default', 176 ), 177 'rtti': coredata.UserBooleanOption('Enable RTTI', True), 178 'std': coredata.UserComboOption( 179 'C++ language standard to use', 180 ['none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a', 181 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a'], 182 'none', 183 ), 184 }) 185 if self.info.is_windows() or self.info.is_cygwin(): 186 opts.update({ 187 'winlibs': coredata.UserArrayOption( 188 'Standard Win libraries to link against', 189 gnu_winlibs, 190 ), 191 }) 192 return opts 193 194 def get_option_compile_args(self, options): 195 args = [] 196 std = options['std'] 197 if std.value != 'none': 198 args.append(self._find_best_cpp_std(std.value)) 199 200 non_msvc_eh_options(options['eh'].value, args) 201 202 if not options['rtti'].value: 203 args.append('-fno-rtti') 204 205 return args 206 207 def get_option_link_args(self, options): 208 if self.info.is_windows() or self.info.is_cygwin(): 209 return options['winlibs'].value[:] 210 return [] 211 212 def language_stdlib_only_link_flags(self): 213 return ['-lstdc++'] 214 215 216class AppleClangCPPCompiler(ClangCPPCompiler): 217 def language_stdlib_only_link_flags(self): 218 return ['-lc++'] 219 220 221class EmscriptenCPPCompiler(EmscriptenMixin, LinkerEnvVarsMixin, ClangCPPCompiler): 222 def __init__(self, exelist, version, for_machine: MachineChoice, 223 is_cross: bool, info: 'MachineInfo', exe_wrapper=None, **kwargs): 224 if not is_cross: 225 raise MesonException('Emscripten compiler can only be used for cross compilation.') 226 ClangCPPCompiler.__init__(self, exelist=exelist, version=version, 227 for_machine=for_machine, is_cross=is_cross, 228 info=info, exe_wrapper=exe_wrapper, **kwargs) 229 self.id = 'emscripten' 230 231 def get_option_compile_args(self, options): 232 args = [] 233 std = options['std'] 234 if std.value != 'none': 235 args.append(self._find_best_cpp_std(std.value)) 236 return args 237 238 239class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler): 240 def __init__(self, exelist, version, for_machine: MachineChoice, 241 is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): 242 CPPCompiler.__init__(self, exelist=exelist, version=version, 243 for_machine=for_machine, is_cross=is_cross, 244 info=info, exe_wrapper=exe_wrapper, **kwargs) 245 ArmclangCompiler.__init__(self) 246 default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'] 247 self.warn_args = {'0': [], 248 '1': default_warn_args, 249 '2': default_warn_args + ['-Wextra'], 250 '3': default_warn_args + ['-Wextra', '-Wpedantic']} 251 252 def get_options(self): 253 opts = CPPCompiler.get_options(self) 254 opts.update({ 255 'eh': coredata.UserComboOption( 256 'C++ exception handling type.', 257 ['none', 'default', 'a', 's', 'sc'], 258 'default', 259 ), 260 'std': coredata.UserComboOption( 261 'C++ language standard to use', 262 [ 263 'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 264 'gnu++98', 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17', 265 ], 266 'none', 267 ), 268 }) 269 return opts 270 271 def get_option_compile_args(self, options): 272 args = [] 273 std = options['std'] 274 if std.value != 'none': 275 args.append('-std=' + std.value) 276 277 non_msvc_eh_options(options['eh'].value, args) 278 279 return args 280 281 def get_option_link_args(self, options): 282 return [] 283 284 285class GnuCPPCompiler(GnuCompiler, CPPCompiler): 286 def __init__(self, exelist, version, for_machine: MachineChoice, 287 is_cross, info: 'MachineInfo', exe_wrap, defines, **kwargs): 288 CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrap, **kwargs) 289 GnuCompiler.__init__(self, defines) 290 default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor'] 291 self.warn_args = {'0': [], 292 '1': default_warn_args, 293 '2': default_warn_args + ['-Wextra'], 294 '3': default_warn_args + ['-Wextra', '-Wpedantic']} 295 296 def get_options(self): 297 opts = CPPCompiler.get_options(self) 298 opts.update({ 299 'eh': coredata.UserComboOption( 300 'C++ exception handling type.', 301 ['none', 'default', 'a', 's', 'sc'], 302 'default', 303 ), 304 'rtti': coredata.UserBooleanOption('Enable RTTI', True), 305 'std': coredata.UserComboOption( 306 'C++ language standard to use', 307 ['none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a', 308 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z', 'gnu++2a'], 309 'none', 310 ), 311 'debugstl': coredata.UserBooleanOption( 312 'STL debug mode', 313 False, 314 ) 315 }) 316 if self.info.is_windows() or self.info.is_cygwin(): 317 opts.update({ 318 'winlibs': coredata.UserArrayOption( 319 'Standard Win libraries to link against', 320 gnu_winlibs, 321 ), 322 }) 323 return opts 324 325 def get_option_compile_args(self, options): 326 args = [] 327 std = options['std'] 328 if std.value != 'none': 329 args.append(self._find_best_cpp_std(std.value)) 330 331 non_msvc_eh_options(options['eh'].value, args) 332 333 if not options['rtti'].value: 334 args.append('-fno-rtti') 335 336 if options['debugstl'].value: 337 args.append('-D_GLIBCXX_DEBUG=1') 338 return args 339 340 def get_option_link_args(self, options): 341 if self.info.is_windows() or self.info.is_cygwin(): 342 return options['winlibs'].value[:] 343 return [] 344 345 def get_pch_use_args(self, pch_dir, header): 346 return ['-fpch-preprocess', '-include', os.path.basename(header)] 347 348 def language_stdlib_only_link_flags(self): 349 return ['-lstdc++'] 350 351 352class PGICPPCompiler(PGICompiler, CPPCompiler): 353 def __init__(self, exelist, version, for_machine: MachineChoice, 354 is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): 355 CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, **kwargs) 356 PGICompiler.__init__(self) 357 358 359class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler): 360 def __init__(self, exelist, version, for_machine: MachineChoice, 361 is_cross, info: 'MachineInfo', exe_wrapper=None, 362 defines=None, **kwargs): 363 GnuCPPCompiler.__init__(self, exelist, version, for_machine, 364 is_cross, info, exe_wrapper, defines, 365 **kwargs) 366 ElbrusCompiler.__init__(self) 367 368 # It does not support c++/gnu++ 17 and 1z, but still does support 0x, 1y, and gnu++98. 369 def get_options(self): 370 opts = CPPCompiler.get_options(self) 371 opts.update({ 372 'eh': coredata.UserComboOption( 373 'C++ exception handling type.', 374 ['none', 'default', 'a', 's', 'sc'], 375 'default', 376 ), 377 'std': coredata.UserComboOption( 378 'C++ language standard to use', 379 [ 380 'none', 'c++98', 'c++03', 'c++0x', 'c++11', 'c++14', 'c++1y', 381 'gnu++98', 'gnu++03', 'gnu++0x', 'gnu++11', 'gnu++14', 'gnu++1y', 382 ], 383 'none', 384 ), 385 'debugstl': coredata.UserBooleanOption( 386 'STL debug mode', 387 False, 388 ), 389 }) 390 return opts 391 392 # Elbrus C++ compiler does not have lchmod, but there is only linker warning, not compiler error. 393 # So we should explicitly fail at this case. 394 def has_function(self, funcname, prefix, env, *, extra_args=None, dependencies=None): 395 if funcname == 'lchmod': 396 return False, False 397 else: 398 return super().has_function(funcname, prefix, env, 399 extra_args=extra_args, 400 dependencies=dependencies) 401 402 # Elbrus C++ compiler does not support RTTI, so don't check for it. 403 def get_option_compile_args(self, options): 404 args = [] 405 std = options['std'] 406 if std.value != 'none': 407 args.append(self._find_best_cpp_std(std.value)) 408 409 non_msvc_eh_options(options['eh'].value, args) 410 411 if options['debugstl'].value: 412 args.append('-D_GLIBCXX_DEBUG=1') 413 return args 414 415 416class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): 417 def __init__(self, exelist, version, for_machine: MachineChoice, 418 is_cross, info: 'MachineInfo', exe_wrap, **kwargs): 419 CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, 420 info, exe_wrap, **kwargs) 421 IntelGnuLikeCompiler.__init__(self) 422 self.lang_header = 'c++-header' 423 default_warn_args = ['-Wall', '-w3', '-diag-disable:remark', 424 '-Wpch-messages', '-Wnon-virtual-dtor'] 425 self.warn_args = {'0': [], 426 '1': default_warn_args, 427 '2': default_warn_args + ['-Wextra'], 428 '3': default_warn_args + ['-Wextra']} 429 430 def get_options(self): 431 opts = CPPCompiler.get_options(self) 432 # Every Unix compiler under the sun seems to accept -std=c++03, 433 # with the exception of ICC. Instead of preventing the user from 434 # globally requesting C++03, we transparently remap it to C++98 435 c_stds = ['c++98', 'c++03'] 436 g_stds = ['gnu++98', 'gnu++03'] 437 if version_compare(self.version, '>=15.0.0'): 438 c_stds += ['c++11', 'c++14'] 439 g_stds += ['gnu++11'] 440 if version_compare(self.version, '>=16.0.0'): 441 c_stds += ['c++17'] 442 if version_compare(self.version, '>=17.0.0'): 443 g_stds += ['gnu++14'] 444 opts.update({ 445 'eh': coredata.UserComboOption( 446 'C++ exception handling type.', 447 ['none', 'default', 'a', 's', 'sc'], 448 'default', 449 ), 450 'rtti': coredata.UserBooleanOption('Enable RTTI', True), 451 'std': coredata.UserComboOption( 452 'C++ language standard to use', 453 ['none'] + c_stds + g_stds, 454 'none', 455 ), 456 'debugstl': coredata.UserBooleanOption('STL debug mode', False), 457 }) 458 return opts 459 460 def get_option_compile_args(self, options): 461 args = [] 462 std = options['std'] 463 if std.value != 'none': 464 remap_cpp03 = { 465 'c++03': 'c++98', 466 'gnu++03': 'gnu++98' 467 } 468 args.append('-std=' + remap_cpp03.get(std.value, std.value)) 469 if options['eh'].value == 'none': 470 args.append('-fno-exceptions') 471 if not options['rtti'].value: 472 args.append('-fno-rtti') 473 if options['debugstl'].value: 474 args.append('-D_GLIBCXX_DEBUG=1') 475 return args 476 477 def get_option_link_args(self, options): 478 return [] 479 480 481class VisualStudioLikeCPPCompilerMixin: 482 483 """Mixin for C++ specific method overrides in MSVC-like compilers.""" 484 485 VC_VERSION_MAP = { 486 'none': (True, None), 487 'vc++11': (True, 11), 488 'vc++14': (True, 14), 489 'vc++17': (True, 17), 490 'vc++latest': (True, "latest"), 491 'c++11': (False, 11), 492 'c++14': (False, 14), 493 'c++17': (False, 17), 494 'c++latest': (False, "latest"), 495 } 496 497 def get_option_link_args(self, options): 498 return options['winlibs'].value[:] 499 500 def _get_options_impl(self, opts, cpp_stds: T.List[str]): 501 opts.update({ 502 'eh': coredata.UserComboOption( 503 'C++ exception handling type.', 504 ['none', 'default', 'a', 's', 'sc'], 505 'default', 506 ), 507 'rtti': coredata.UserBooleanOption('Enable RTTI', True), 508 'std': coredata.UserComboOption( 509 'C++ language standard to use', 510 cpp_stds, 511 'none', 512 ), 513 'winlibs': coredata.UserArrayOption( 514 'Windows libs to link against.', 515 msvc_winlibs, 516 ), 517 }) 518 return opts 519 520 def get_option_compile_args(self, options): 521 args = [] 522 523 eh = options['eh'] 524 if eh.value == 'default': 525 args.append('/EHsc') 526 elif eh.value == 'none': 527 args.append('/EHs-c-') 528 else: 529 args.append('/EH' + eh.value) 530 531 if not options['rtti'].value: 532 args.append('/GR-') 533 534 permissive, ver = self.VC_VERSION_MAP[options['std'].value] 535 536 if ver is not None: 537 args.append('/std:c++{}'.format(ver)) 538 539 if not permissive: 540 args.append('/permissive-') 541 542 return args 543 544 def get_compiler_check_args(self): 545 # XXX: this is a hack because so much GnuLike stuff is in the base CPPCompiler class. 546 return CLikeCompiler.get_compiler_check_args(self) 547 548 549class CPP11AsCPP14Mixin: 550 551 """Mixin class for VisualStudio and ClangCl to replace C++11 std with C++14. 552 553 This is a limitation of Clang and MSVC that ICL doesn't share. 554 """ 555 556 def get_option_compile_args(self, options): 557 # Note: there is no explicit flag for supporting C++11; we attempt to do the best we can 558 # which means setting the C++ standard version to C++14, in compilers that support it 559 # (i.e., after VS2015U3) 560 # if one is using anything before that point, one cannot set the standard. 561 if options['std'].value in {'vc++11', 'c++11'}: 562 mlog.warning(self.id, 'does not support C++11;', 563 'attempting best effort; setting the standard to C++14', once=True) 564 # Don't mutate anything we're going to change, we need to use 565 # deepcopy since we're messing with members, and we can't simply 566 # copy the members because the option proxy doesn't support it. 567 options = copy.deepcopy(options) 568 if options['std'].value == 'vc++11': 569 options['std'].value = 'vc++14' 570 else: 571 options['std'].value = 'c++14' 572 return super().get_option_compile_args(options) 573 574 575class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, MSVCCompiler, CPPCompiler): 576 def __init__(self, exelist, version, for_machine: MachineChoice, 577 is_cross: bool, info: 'MachineInfo', exe_wrap, target, **kwargs): 578 CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrap, **kwargs) 579 MSVCCompiler.__init__(self, target) 580 self.base_options = ['b_pch', 'b_vscrt'] # FIXME add lto, pgo and the like 581 self.id = 'msvc' 582 583 def get_options(self): 584 cpp_stds = ['none', 'c++11', 'vc++11'] 585 # Visual Studio 2015 and later 586 if version_compare(self.version, '>=19'): 587 cpp_stds.extend(['c++14', 'c++latest', 'vc++latest']) 588 # Visual Studio 2017 and later 589 if version_compare(self.version, '>=19.11'): 590 cpp_stds.extend(['vc++14', 'c++17', 'vc++17']) 591 return self._get_options_impl(super().get_options(), cpp_stds) 592 593 def get_option_compile_args(self, options): 594 if options['std'].value != 'none' and version_compare(self.version, '<19.00.24210'): 595 mlog.warning('This version of MSVC does not support cpp_std arguments') 596 options = copy.copy(options) 597 options['std'].value = 'none' 598 599 args = super().get_option_compile_args(options) 600 601 if version_compare(self.version, '<19.11'): 602 try: 603 i = args.index('/permissive-') 604 except ValueError: 605 return args 606 del args[i] 607 return args 608 609class ClangClCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, ClangClCompiler, CPPCompiler): 610 def __init__(self, exelist, version, for_machine: MachineChoice, 611 is_cross, info: 'MachineInfo', exe_wrap, target, **kwargs): 612 CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, 613 info, exe_wrap, **kwargs) 614 ClangClCompiler.__init__(self, target) 615 self.id = 'clang-cl' 616 617 def get_options(self): 618 cpp_stds = ['none', 'c++11', 'vc++11', 'c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest'] 619 return self._get_options_impl(super().get_options(), cpp_stds) 620 621 622class IntelClCPPCompiler(VisualStudioLikeCPPCompilerMixin, IntelVisualStudioLikeCompiler, CPPCompiler): 623 624 def __init__(self, exelist, version, for_machine: MachineChoice, 625 is_cross, info: 'MachineInfo', exe_wrap, target, **kwargs): 626 CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, 627 info, exe_wrap, **kwargs) 628 IntelVisualStudioLikeCompiler.__init__(self, target) 629 630 def get_options(self): 631 # This has only been tested with version 19.0, 632 cpp_stds = ['none', 'c++11', 'vc++11', 'c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest'] 633 return self._get_options_impl(super().get_options(), cpp_stds) 634 635 636class ArmCPPCompiler(ArmCompiler, CPPCompiler): 637 def __init__(self, exelist, version, for_machine: MachineChoice, 638 is_cross, info: 'MachineInfo', exe_wrap=None, **kwargs): 639 CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, 640 info, exe_wrap, **kwargs) 641 ArmCompiler.__init__(self) 642 643 def get_options(self): 644 opts = CPPCompiler.get_options(self) 645 opts.update({ 646 'std': coredata.UserComboOption( 647 'C++ language standard to use', 648 ['none', 'c++03', 'c++11'], 649 'none', 650 ), 651 }) 652 return opts 653 654 def get_option_compile_args(self, options): 655 args = [] 656 std = options['std'] 657 if std.value == 'c++11': 658 args.append('--cpp11') 659 elif std.value == 'c++03': 660 args.append('--cpp') 661 return args 662 663 def get_option_link_args(self, options): 664 return [] 665 666 def get_compiler_check_args(self): 667 return [] 668 669 670class CcrxCPPCompiler(CcrxCompiler, CPPCompiler): 671 def __init__(self, exelist, version, for_machine: MachineChoice, 672 is_cross, info: 'MachineInfo', exe_wrap=None, **kwargs): 673 CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, 674 info, exe_wrap, **kwargs) 675 CcrxCompiler.__init__(self) 676 677 # Override CCompiler.get_always_args 678 def get_always_args(self): 679 return ['-nologo', '-lang=cpp'] 680 681 def get_option_compile_args(self, options): 682 return [] 683 684 def get_compile_only_args(self): 685 return [] 686 687 def get_output_args(self, target): 688 return ['-output=obj=%s' % target] 689 690 def get_option_link_args(self, options): 691 return [] 692 693 def get_compiler_check_args(self): 694 return [] 695 696class C2000CPPCompiler(C2000Compiler, CPPCompiler): 697 def __init__(self, exelist, version, for_machine: MachineChoice, 698 is_cross, info: 'MachineInfo', exe_wrap=None, **kwargs): 699 CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, 700 info, exe_wrap, **kwargs) 701 C2000Compiler.__init__(self) 702 703 def get_options(self): 704 opts = CPPCompiler.get_options(self) 705 opts.update({'cpp_std': coredata.UserComboOption('C++ language standard to use', 706 ['none', 'c++03'], 707 'none')}) 708 return opts 709 710 def get_always_args(self): 711 return ['-nologo', '-lang=cpp'] 712 713 def get_option_compile_args(self, options): 714 return [] 715 716 def get_compile_only_args(self): 717 return [] 718 719 def get_output_args(self, target): 720 return ['-output=obj=%s' % target] 721 722 def get_option_link_args(self, options): 723 return [] 724 725 def get_compiler_check_args(self): 726 return [] 727