1# Copyright 2012-2020 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 os.path 16import typing as T 17 18from .. import coredata 19from .. import mlog 20from ..mesonlib import MachineChoice, MesonException, version_compare, OptionKey 21from .c_function_attributes import C_FUNC_ATTRIBUTES 22from .mixins.clike import CLikeCompiler 23from .mixins.ccrx import CcrxCompiler 24from .mixins.xc16 import Xc16Compiler 25from .mixins.compcert import CompCertCompiler 26from .mixins.c2000 import C2000Compiler 27from .mixins.arm import ArmCompiler, ArmclangCompiler 28from .mixins.visualstudio import MSVCCompiler, ClangClCompiler 29from .mixins.gnu import GnuCompiler 30from .mixins.intel import IntelGnuLikeCompiler, IntelVisualStudioLikeCompiler 31from .mixins.clang import ClangCompiler 32from .mixins.elbrus import ElbrusCompiler 33from .mixins.pgi import PGICompiler 34from .mixins.emscripten import EmscriptenMixin 35from .compilers import ( 36 gnu_winlibs, 37 msvc_winlibs, 38 Compiler, 39) 40 41if T.TYPE_CHECKING: 42 from ..coredata import KeyedOptionDictType 43 from ..dependencies import Dependency 44 from ..envconfig import MachineInfo 45 from ..environment import Environment 46 from ..linkers import DynamicLinker 47 from ..programs import ExternalProgram 48 from .compilers import CompileCheckMode 49 50 CompilerMixinBase = Compiler 51else: 52 CompilerMixinBase = object 53 54 55class CCompiler(CLikeCompiler, Compiler): 56 57 @staticmethod 58 def attribute_check_func(name: str) -> str: 59 try: 60 return C_FUNC_ATTRIBUTES[name] 61 except KeyError: 62 raise MesonException(f'Unknown function attribute "{name}"') 63 64 language = 'c' 65 66 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, 67 info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, 68 linker: T.Optional['DynamicLinker'] = None, 69 full_version: T.Optional[str] = None): 70 # If a child ObjC or CPP class has already set it, don't set it ourselves 71 Compiler.__init__(self, exelist, version, for_machine, info, 72 is_cross=is_cross, full_version=full_version, linker=linker) 73 CLikeCompiler.__init__(self, exe_wrapper) 74 75 def get_no_stdinc_args(self) -> T.List[str]: 76 return ['-nostdinc'] 77 78 def sanity_check(self, work_dir: str, environment: 'Environment') -> None: 79 code = 'int main(void) { int class=0; return class; }\n' 80 return self._sanity_check_impl(work_dir, environment, 'sanitycheckc.c', code) 81 82 def has_header_symbol(self, hname: str, symbol: str, prefix: str, 83 env: 'Environment', *, 84 extra_args: T.Union[None, T.List[str], T.Callable[['CompileCheckMode'], T.List[str]]] = None, 85 dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: 86 fargs = {'prefix': prefix, 'header': hname, 'symbol': symbol} 87 t = '''{prefix} 88 #include <{header}> 89 int main(void) {{ 90 /* If it's not defined as a macro, try to use as a symbol */ 91 #ifndef {symbol} 92 {symbol}; 93 #endif 94 return 0; 95 }}''' 96 return self.compiles(t.format(**fargs), env, extra_args=extra_args, 97 dependencies=dependencies) 98 99 def get_options(self) -> 'KeyedOptionDictType': 100 opts = super().get_options() 101 opts.update({ 102 OptionKey('std', machine=self.for_machine, lang=self.language): coredata.UserComboOption( 103 'C language standard to use', 104 ['none'], 105 'none', 106 ) 107 }) 108 return opts 109 110 111class _ClangCStds(CompilerMixinBase): 112 113 """Mixin class for clang based compilers for setting C standards. 114 115 This is used by both ClangCCompiler and ClangClCompiler, as they share 116 the same versions 117 """ 118 119 _C17_VERSION = '>=6.0.0' 120 _C18_VERSION = '>=8.0.0' 121 _C2X_VERSION = '>=9.0.0' 122 123 def get_options(self) -> 'KeyedOptionDictType': 124 opts = super().get_options() 125 c_stds = ['c89', 'c99', 'c11'] 126 g_stds = ['gnu89', 'gnu99', 'gnu11'] 127 # https://releases.llvm.org/6.0.0/tools/clang/docs/ReleaseNotes.html 128 # https://en.wikipedia.org/wiki/Xcode#Latest_versions 129 if version_compare(self.version, self._C17_VERSION): 130 c_stds += ['c17'] 131 g_stds += ['gnu17'] 132 if version_compare(self.version, self._C18_VERSION): 133 c_stds += ['c18'] 134 g_stds += ['gnu18'] 135 if version_compare(self.version, self._C2X_VERSION): 136 c_stds += ['c2x'] 137 g_stds += ['gnu2x'] 138 opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = ['none'] + c_stds + g_stds 139 return opts 140 141 142class ClangCCompiler(_ClangCStds, ClangCompiler, CCompiler): 143 144 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, 145 info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, 146 linker: T.Optional['DynamicLinker'] = None, 147 defines: T.Optional[T.Dict[str, str]] = None, 148 full_version: T.Optional[str] = None): 149 CCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, linker=linker, full_version=full_version) 150 ClangCompiler.__init__(self, defines) 151 default_warn_args = ['-Wall', '-Winvalid-pch'] 152 self.warn_args = {'0': [], 153 '1': default_warn_args, 154 '2': default_warn_args + ['-Wextra'], 155 '3': default_warn_args + ['-Wextra', '-Wpedantic']} 156 157 def get_options(self) -> 'KeyedOptionDictType': 158 opts = super().get_options() 159 if self.info.is_windows() or self.info.is_cygwin(): 160 opts.update({ 161 OptionKey('winlibs', machine=self.for_machine, lang=self.language): coredata.UserArrayOption( 162 'Standard Win libraries to link against', 163 gnu_winlibs, 164 ), 165 }) 166 return opts 167 168 def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 169 args = [] 170 std = options[OptionKey('std', machine=self.for_machine, lang=self.language)] 171 if std.value != 'none': 172 args.append('-std=' + std.value) 173 return args 174 175 def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 176 if self.info.is_windows() or self.info.is_cygwin(): 177 # without a typedict mypy can't understand this. 178 libs = options[OptionKey('winlibs', machine=self.for_machine, lang=self.language)].value.copy() 179 assert isinstance(libs, list) 180 for l in libs: 181 assert isinstance(l, str) 182 return libs 183 return [] 184 185 186class AppleClangCCompiler(ClangCCompiler): 187 188 """Handle the differences between Apple Clang and Vanilla Clang. 189 190 Right now this just handles the differences between the versions that new 191 C standards were added. 192 """ 193 194 _C17_VERSION = '>=10.0.0' 195 _C18_VERSION = '>=11.0.0' 196 _C2X_VERSION = '>=11.0.0' 197 198 199class EmscriptenCCompiler(EmscriptenMixin, ClangCCompiler): 200 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, 201 info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, 202 linker: T.Optional['DynamicLinker'] = None, 203 defines: T.Optional[T.Dict[str, str]] = None, 204 full_version: T.Optional[str] = None): 205 if not is_cross: 206 raise MesonException('Emscripten compiler can only be used for cross compilation.') 207 ClangCCompiler.__init__(self, exelist, version, for_machine, is_cross, 208 info, exe_wrapper=exe_wrapper, linker=linker, 209 defines=defines, full_version=full_version) 210 self.id = 'emscripten' 211 212 213class ArmclangCCompiler(ArmclangCompiler, CCompiler): 214 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, 215 info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, 216 linker: T.Optional['DynamicLinker'] = None, 217 full_version: T.Optional[str] = None): 218 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 219 info, exe_wrapper, linker=linker, full_version=full_version) 220 ArmclangCompiler.__init__(self) 221 default_warn_args = ['-Wall', '-Winvalid-pch'] 222 self.warn_args = {'0': [], 223 '1': default_warn_args, 224 '2': default_warn_args + ['-Wextra'], 225 '3': default_warn_args + ['-Wextra', '-Wpedantic']} 226 227 def get_options(self) -> 'KeyedOptionDictType': 228 opts = CCompiler.get_options(self) 229 key = OptionKey('std', machine=self.for_machine, lang=self.language) 230 opts[key].choices = ['none', 'c90', 'c99', 'c11', 'gnu90', 'gnu99', 'gnu11'] 231 return opts 232 233 def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 234 args = [] 235 std = options[OptionKey('std', machine=self.for_machine, lang=self.language)] 236 if std.value != 'none': 237 args.append('-std=' + std.value) 238 return args 239 240 def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 241 return [] 242 243 244class GnuCCompiler(GnuCompiler, CCompiler): 245 246 _C18_VERSION = '>=8.0.0' 247 _C2X_VERSION = '>=9.0.0' 248 _INVALID_PCH_VERSION = ">=3.4.0" 249 250 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, 251 info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, 252 linker: T.Optional['DynamicLinker'] = None, 253 defines: T.Optional[T.Dict[str, str]] = None, 254 full_version: T.Optional[str] = None): 255 CCompiler.__init__(self, exelist, version, for_machine, is_cross, info, exe_wrapper, linker=linker, full_version=full_version) 256 GnuCompiler.__init__(self, defines) 257 default_warn_args = ['-Wall'] 258 if version_compare(self.version, self._INVALID_PCH_VERSION): 259 default_warn_args += ['-Winvalid-pch'] 260 self.warn_args = {'0': [], 261 '1': default_warn_args, 262 '2': default_warn_args + ['-Wextra'], 263 '3': default_warn_args + ['-Wextra', '-Wpedantic']} 264 265 def get_options(self) -> 'KeyedOptionDictType': 266 opts = CCompiler.get_options(self) 267 c_stds = ['c89', 'c99', 'c11'] 268 g_stds = ['gnu89', 'gnu99', 'gnu11'] 269 if version_compare(self.version, self._C18_VERSION): 270 c_stds += ['c17', 'c18'] 271 g_stds += ['gnu17', 'gnu18'] 272 if version_compare(self.version, self._C2X_VERSION): 273 c_stds += ['c2x'] 274 g_stds += ['gnu2x'] 275 key = OptionKey('std', machine=self.for_machine, lang=self.language) 276 opts[key].choices = ['none'] + c_stds + g_stds 277 if self.info.is_windows() or self.info.is_cygwin(): 278 opts.update({ 279 key.evolve('winlibs'): coredata.UserArrayOption( 280 'Standard Win libraries to link against', 281 gnu_winlibs, 282 ), 283 }) 284 return opts 285 286 def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 287 args = [] 288 std = options[OptionKey('std', lang=self.language, machine=self.for_machine)] 289 if std.value != 'none': 290 args.append('-std=' + std.value) 291 return args 292 293 def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 294 if self.info.is_windows() or self.info.is_cygwin(): 295 # without a typeddict mypy can't figure this out 296 libs: T.List[str] = options[OptionKey('winlibs', lang=self.language, machine=self.for_machine)].value.copy() 297 assert isinstance(libs, list) 298 for l in libs: 299 assert isinstance(l, str) 300 return libs 301 return [] 302 303 def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: 304 return ['-fpch-preprocess', '-include', os.path.basename(header)] 305 306 307class PGICCompiler(PGICompiler, CCompiler): 308 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, 309 info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, 310 linker: T.Optional['DynamicLinker'] = None, 311 full_version: T.Optional[str] = None): 312 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 313 info, exe_wrapper, linker=linker, full_version=full_version) 314 PGICompiler.__init__(self) 315 316 317class NvidiaHPC_CCompiler(PGICompiler, CCompiler): 318 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, 319 info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, 320 linker: T.Optional['DynamicLinker'] = None, 321 full_version: T.Optional[str] = None): 322 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 323 info, exe_wrapper, linker=linker, full_version=full_version) 324 PGICompiler.__init__(self) 325 self.id = 'nvidia_hpc' 326 327 328class ElbrusCCompiler(ElbrusCompiler, CCompiler): 329 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, 330 info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, 331 linker: T.Optional['DynamicLinker'] = None, 332 defines: T.Optional[T.Dict[str, str]] = None, 333 full_version: T.Optional[str] = None): 334 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 335 info, exe_wrapper, linker=linker, full_version=full_version) 336 ElbrusCompiler.__init__(self) 337 338 def get_options(self) -> 'KeyedOptionDictType': 339 opts = CCompiler.get_options(self) 340 stds = ['c89', 'c9x', 'c99', 'gnu89', 'gnu9x', 'gnu99'] 341 stds += ['iso9899:1990', 'iso9899:199409', 'iso9899:1999'] 342 if version_compare(self.version, '>=1.20.00'): 343 stds += ['c11', 'gnu11'] 344 if version_compare(self.version, '>=1.21.00') and version_compare(self.version, '<1.22.00'): 345 stds += ['c90', 'c1x', 'gnu90', 'gnu1x', 'iso9899:2011'] 346 if version_compare(self.version, '>=1.23.00'): 347 stds += ['c90', 'c1x', 'gnu90', 'gnu1x', 'iso9899:2011'] 348 if version_compare(self.version, '>=1.26.00'): 349 stds += ['c17', 'c18', 'iso9899:2017', 'iso9899:2018', 'gnu17', 'gnu18'] 350 opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = ['none'] + stds 351 return opts 352 353 # Elbrus C compiler does not have lchmod, but there is only linker warning, not compiler error. 354 # So we should explicitly fail at this case. 355 def has_function(self, funcname: str, prefix: str, env: 'Environment', *, 356 extra_args: T.Optional[T.List[str]] = None, 357 dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]: 358 if funcname == 'lchmod': 359 return False, False 360 else: 361 return super().has_function(funcname, prefix, env, 362 extra_args=extra_args, 363 dependencies=dependencies) 364 365 366class IntelCCompiler(IntelGnuLikeCompiler, CCompiler): 367 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, 368 info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, 369 linker: T.Optional['DynamicLinker'] = None, 370 full_version: T.Optional[str] = None): 371 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 372 info, exe_wrapper, linker=linker, full_version=full_version) 373 IntelGnuLikeCompiler.__init__(self) 374 self.lang_header = 'c-header' 375 default_warn_args = ['-Wall', '-w3', '-diag-disable:remark'] 376 self.warn_args = {'0': [], 377 '1': default_warn_args, 378 '2': default_warn_args + ['-Wextra'], 379 '3': default_warn_args + ['-Wextra']} 380 381 def get_options(self) -> 'KeyedOptionDictType': 382 opts = CCompiler.get_options(self) 383 c_stds = ['c89', 'c99'] 384 g_stds = ['gnu89', 'gnu99'] 385 if version_compare(self.version, '>=16.0.0'): 386 c_stds += ['c11'] 387 opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = ['none'] + c_stds + g_stds 388 return opts 389 390 def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 391 args = [] 392 std = options[OptionKey('std', machine=self.for_machine, lang=self.language)] 393 if std.value != 'none': 394 args.append('-std=' + std.value) 395 return args 396 397 398class VisualStudioLikeCCompilerMixin(CompilerMixinBase): 399 400 """Shared methods that apply to MSVC-like C compilers.""" 401 402 def get_options(self) -> 'KeyedOptionDictType': 403 opts = super().get_options() 404 opts.update({ 405 OptionKey('winlibs', machine=self.for_machine, lang=self.language): coredata.UserArrayOption( 406 'Windows libs to link against.', 407 msvc_winlibs, 408 ), 409 }) 410 return opts 411 412 def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 413 # need a TypeDict to make this work 414 key = OptionKey('winlibs', machine=self.for_machine, lang=self.language) 415 libs = options[key].value.copy() 416 assert isinstance(libs, list) 417 for l in libs: 418 assert isinstance(l, str) 419 return libs 420 421 422class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompiler): 423 424 _C11_VERSION = '>=19.28' 425 _C17_VERSION = '>=19.28' 426 427 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, 428 is_cross: bool, info: 'MachineInfo', target: str, 429 exe_wrapper: T.Optional['ExternalProgram'] = None, 430 linker: T.Optional['DynamicLinker'] = None, 431 full_version: T.Optional[str] = None): 432 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 433 info, exe_wrapper, linker=linker, 434 full_version=full_version) 435 MSVCCompiler.__init__(self, target) 436 437 def get_options(self) -> 'KeyedOptionDictType': 438 opts = super().get_options() 439 c_stds = ['c89', 'c99'] 440 # Need to have these to be compatible with projects 441 # that set c_std to e.g. gnu99. 442 # https://github.com/mesonbuild/meson/issues/7611 443 g_stds = ['gnu89', 'gnu90', 'gnu9x', 'gnu99'] 444 if version_compare(self.version, self._C11_VERSION): 445 c_stds += ['c11'] 446 g_stds += ['gnu1x', 'gnu11'] 447 if version_compare(self.version, self._C17_VERSION): 448 c_stds += ['c17', 'c18'] 449 g_stds += ['gnu17', 'gnu18'] 450 key = OptionKey('std', machine=self.for_machine, lang=self.language) 451 opts[key].choices = ['none'] + c_stds + g_stds 452 return opts 453 454 def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 455 args = [] 456 std = options[OptionKey('std', machine=self.for_machine, lang=self.language)] 457 if std.value.startswith('gnu'): 458 mlog.log_once( 459 'cl.exe does not actually support gnu standards, and meson ' 460 'will instead demote to the nearest ISO C standard. This ' 461 'may cause compilation to fail.') 462 # As of MVSC 16.8, /std:c11 and /std:c17 are the only valid C standard options. 463 if std.value in {'c11', 'gnu1x', 'gnu11'}: 464 args.append('/std:c11') 465 elif std.value in {'c17', 'c18', 'gnu17', 'gnu18'}: 466 args.append('/std:c17') 467 return args 468 469 470class ClangClCCompiler(_ClangCStds, ClangClCompiler, VisualStudioLikeCCompilerMixin, CCompiler): 471 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, 472 is_cross: bool, info: 'MachineInfo', target: str, 473 exe_wrapper: T.Optional['ExternalProgram'] = None, 474 linker: T.Optional['DynamicLinker'] = None, 475 full_version: T.Optional[str] = None): 476 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 477 info, exe_wrapper, linker=linker, 478 full_version=full_version) 479 ClangClCompiler.__init__(self, target) 480 481 def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 482 key = OptionKey('std', machine=self.for_machine, lang=self.language) 483 std = options[key].value 484 if std != "none": 485 return [f'/clang:-std={std}'] 486 return [] 487 488 489class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerMixin, CCompiler): 490 491 """Intel "ICL" compiler abstraction.""" 492 493 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, 494 is_cross: bool, info: 'MachineInfo', target: str, 495 exe_wrapper: T.Optional['ExternalProgram'] = None, 496 linker: T.Optional['DynamicLinker'] = None, 497 full_version: T.Optional[str] = None): 498 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 499 info, exe_wrapper, linker=linker, 500 full_version=full_version) 501 IntelVisualStudioLikeCompiler.__init__(self, target) 502 503 def get_options(self) -> 'KeyedOptionDictType': 504 opts = super().get_options() 505 key = OptionKey('std', machine=self.for_machine, lang=self.language) 506 opts[key].choices = ['none', 'c89', 'c99', 'c11'] 507 return opts 508 509 def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 510 args = [] 511 key = OptionKey('std', machine=self.for_machine, lang=self.language) 512 std = options[key] 513 if std.value == 'c89': 514 mlog.log_once("ICL doesn't explicitly implement c89, setting the standard to 'none', which is close.") 515 elif std.value != 'none': 516 args.append('/Qstd:' + std.value) 517 return args 518 519 520class ArmCCompiler(ArmCompiler, CCompiler): 521 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, 522 is_cross: bool, info: 'MachineInfo', 523 exe_wrapper: T.Optional['ExternalProgram'] = None, 524 linker: T.Optional['DynamicLinker'] = None, 525 full_version: T.Optional[str] = None): 526 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 527 info, exe_wrapper, linker=linker, 528 full_version=full_version) 529 ArmCompiler.__init__(self) 530 531 def get_options(self) -> 'KeyedOptionDictType': 532 opts = CCompiler.get_options(self) 533 key = OptionKey('std', machine=self.for_machine, lang=self.language) 534 opts[key].choices = ['none', 'c89', 'c99', 'c11'] 535 return opts 536 537 def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 538 args = [] 539 key = OptionKey('std', machine=self.for_machine, lang=self.language) 540 std = options[key] 541 if std.value != 'none': 542 args.append('--' + std.value) 543 return args 544 545 546class CcrxCCompiler(CcrxCompiler, CCompiler): 547 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, 548 is_cross: bool, info: 'MachineInfo', 549 exe_wrapper: T.Optional['ExternalProgram'] = None, 550 linker: T.Optional['DynamicLinker'] = None, 551 full_version: T.Optional[str] = None): 552 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 553 info, exe_wrapper, linker=linker, full_version=full_version) 554 CcrxCompiler.__init__(self) 555 556 # Override CCompiler.get_always_args 557 def get_always_args(self) -> T.List[str]: 558 return ['-nologo'] 559 560 def get_options(self) -> 'KeyedOptionDictType': 561 opts = CCompiler.get_options(self) 562 key = OptionKey('std', machine=self.for_machine, lang=self.language) 563 opts[key].choices = ['none', 'c89', 'c99'] 564 return opts 565 566 def get_no_stdinc_args(self) -> T.List[str]: 567 return [] 568 569 def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 570 args = [] 571 key = OptionKey('std', machine=self.for_machine, lang=self.language) 572 std = options[key] 573 if std.value == 'c89': 574 args.append('-lang=c') 575 elif std.value == 'c99': 576 args.append('-lang=c99') 577 return args 578 579 def get_compile_only_args(self) -> T.List[str]: 580 return [] 581 582 def get_no_optimization_args(self) -> T.List[str]: 583 return ['-optimize=0'] 584 585 def get_output_args(self, target: str) -> T.List[str]: 586 return [f'-output=obj={target}'] 587 588 def get_werror_args(self) -> T.List[str]: 589 return ['-change_message=error'] 590 591 def get_include_args(self, path: str, is_system: bool) -> T.List[str]: 592 if path == '': 593 path = '.' 594 return ['-include=' + path] 595 596 597class Xc16CCompiler(Xc16Compiler, CCompiler): 598 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, 599 is_cross: bool, info: 'MachineInfo', 600 exe_wrapper: T.Optional['ExternalProgram'] = None, 601 linker: T.Optional['DynamicLinker'] = None, 602 full_version: T.Optional[str] = None): 603 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 604 info, exe_wrapper, linker=linker, full_version=full_version) 605 Xc16Compiler.__init__(self) 606 607 def get_options(self) -> 'KeyedOptionDictType': 608 opts = CCompiler.get_options(self) 609 key = OptionKey('std', machine=self.for_machine, lang=self.language) 610 opts[key].choices = ['none', 'c89', 'c99', 'gnu89', 'gnu99'] 611 return opts 612 613 def get_no_stdinc_args(self) -> T.List[str]: 614 return [] 615 616 def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 617 args = [] 618 key = OptionKey('std', machine=self.for_machine, lang=self.language) 619 std = options[key] 620 if std.value != 'none': 621 args.append('-ansi') 622 args.append('-std=' + std.value) 623 return args 624 625 def get_compile_only_args(self) -> T.List[str]: 626 return [] 627 628 def get_no_optimization_args(self) -> T.List[str]: 629 return ['-O0'] 630 631 def get_output_args(self, target: str) -> T.List[str]: 632 return [f'-o{target}'] 633 634 def get_werror_args(self) -> T.List[str]: 635 return ['-change_message=error'] 636 637 def get_include_args(self, path: str, is_system: bool) -> T.List[str]: 638 if path == '': 639 path = '.' 640 return ['-I' + path] 641 642class CompCertCCompiler(CompCertCompiler, CCompiler): 643 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, 644 is_cross: bool, info: 'MachineInfo', 645 exe_wrapper: T.Optional['ExternalProgram'] = None, 646 linker: T.Optional['DynamicLinker'] = None, 647 full_version: T.Optional[str] = None): 648 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 649 info, exe_wrapper, linker=linker, full_version=full_version) 650 CompCertCompiler.__init__(self) 651 652 def get_options(self) -> 'KeyedOptionDictType': 653 opts = CCompiler.get_options(self) 654 key = OptionKey('std', machine=self.for_machine, lang=self.language) 655 opts[key].choices = ['none', 'c89', 'c99'] 656 return opts 657 658 def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 659 return [] 660 661 def get_no_optimization_args(self) -> T.List[str]: 662 return ['-O0'] 663 664 def get_output_args(self, target: str) -> T.List[str]: 665 return [f'-o{target}'] 666 667 def get_werror_args(self) -> T.List[str]: 668 return ['-Werror'] 669 670 def get_include_args(self, path: str, is_system: bool) -> T.List[str]: 671 if path == '': 672 path = '.' 673 return ['-I' + path] 674 675class C2000CCompiler(C2000Compiler, CCompiler): 676 def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice, 677 is_cross: bool, info: 'MachineInfo', 678 exe_wrapper: T.Optional['ExternalProgram'] = None, 679 linker: T.Optional['DynamicLinker'] = None, 680 full_version: T.Optional[str] = None): 681 CCompiler.__init__(self, exelist, version, for_machine, is_cross, 682 info, exe_wrapper, linker=linker, full_version=full_version) 683 C2000Compiler.__init__(self) 684 685 # Override CCompiler.get_always_args 686 def get_always_args(self) -> T.List[str]: 687 return [] 688 689 def get_options(self) -> 'KeyedOptionDictType': 690 opts = CCompiler.get_options(self) 691 key = OptionKey('std', machine=self.for_machine, lang=self.language) 692 opts[key].choices = ['none', 'c89', 'c99', 'c11'] 693 return opts 694 695 def get_no_stdinc_args(self) -> T.List[str]: 696 return [] 697 698 def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 699 args = [] 700 key = OptionKey('std', machine=self.for_machine, lang=self.language) 701 std = options[key] 702 if std.value != 'none': 703 args.append('--' + std.value) 704 return args 705 706 def get_compile_only_args(self) -> T.List[str]: 707 return [] 708 709 def get_no_optimization_args(self) -> T.List[str]: 710 return ['-Ooff'] 711 712 def get_output_args(self, target: str) -> T.List[str]: 713 return [f'--output_file={target}'] 714 715 def get_werror_args(self) -> T.List[str]: 716 return ['-change_message=error'] 717 718 def get_include_args(self, path: str, is_system: bool) -> T.List[str]: 719 if path == '': 720 path = '.' 721 return ['--include_path=' + path] 722