1# Copyright 2012-2019 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 abc 16import contextlib, os.path, re, tempfile 17import itertools 18import typing as T 19from functools import lru_cache 20 21from .. import coredata 22from .. import mlog 23from .. import mesonlib 24from ..linkers import LinkerEnvVarsMixin 25from ..mesonlib import ( 26 EnvironmentException, MachineChoice, MesonException, 27 Popen_safe, split_args 28) 29from ..envconfig import ( 30 Properties, get_env_var 31) 32from ..arglist import CompilerArgs 33 34if T.TYPE_CHECKING: 35 from ..coredata import OptionDictType 36 from ..envconfig import MachineInfo 37 from ..environment import Environment 38 from ..linkers import DynamicLinker # noqa: F401 39 40 CompilerType = T.TypeVar('CompilerType', bound=Compiler) 41 42"""This file contains the data files of all compilers Meson knows 43about. To support a new compiler, add its information below. 44Also add corresponding autodetection code in environment.py.""" 45 46header_suffixes = ('h', 'hh', 'hpp', 'hxx', 'H', 'ipp', 'moc', 'vapi', 'di') 47obj_suffixes = ('o', 'obj', 'res') 48lib_suffixes = ('a', 'lib', 'dll', 'dll.a', 'dylib', 'so') 49# Mapping of language to suffixes of files that should always be in that language 50# This means we can't include .h headers here since they could be C, C++, ObjC, etc. 51lang_suffixes = { 52 'c': ('c',), 53 'cpp': ('cpp', 'cc', 'cxx', 'c++', 'hh', 'hpp', 'ipp', 'hxx', 'ino'), 54 'cuda': ('cu',), 55 # f90, f95, f03, f08 are for free-form fortran ('f90' recommended) 56 # f, for, ftn, fpp are for fixed-form fortran ('f' or 'for' recommended) 57 'fortran': ('f90', 'f95', 'f03', 'f08', 'f', 'for', 'ftn', 'fpp'), 58 'd': ('d', 'di'), 59 'objc': ('m',), 60 'objcpp': ('mm',), 61 'rust': ('rs',), 62 'vala': ('vala', 'vapi', 'gs'), 63 'cs': ('cs',), 64 'swift': ('swift',), 65 'java': ('java',), 66} 67all_languages = lang_suffixes.keys() 68cpp_suffixes = lang_suffixes['cpp'] + ('h',) 69c_suffixes = lang_suffixes['c'] + ('h',) 70# List of languages that by default consume and output libraries following the 71# C ABI; these can generally be used interchangebly 72clib_langs = ('objcpp', 'cpp', 'objc', 'c', 'fortran',) 73# List of languages that can be linked with C code directly by the linker 74# used in build.py:process_compilers() and build.py:get_dynamic_linker() 75clink_langs = ('d', 'cuda') + clib_langs 76clink_suffixes = () 77for _l in clink_langs + ('vala',): 78 clink_suffixes += lang_suffixes[_l] 79clink_suffixes += ('h', 'll', 's') 80all_suffixes = set(itertools.chain(*lang_suffixes.values(), clink_suffixes)) 81 82# Languages that should use LDFLAGS arguments when linking. 83languages_using_ldflags = {'objcpp', 'cpp', 'objc', 'c', 'fortran', 'd', 'cuda'} 84# Languages that should use CPPFLAGS arguments when linking. 85languages_using_cppflags = {'c', 'cpp', 'objc', 'objcpp'} 86soregex = re.compile(r'.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$') 87 88# Environment variables that each lang uses. 89cflags_mapping = {'c': 'CFLAGS', 90 'cpp': 'CXXFLAGS', 91 'cuda': 'CUFLAGS', 92 'objc': 'OBJCFLAGS', 93 'objcpp': 'OBJCXXFLAGS', 94 'fortran': 'FFLAGS', 95 'd': 'DFLAGS', 96 'vala': 'VALAFLAGS', 97 'rust': 'RUSTFLAGS'} 98 99# All these are only for C-linkable languages; see `clink_langs` above. 100 101def sort_clink(lang): 102 ''' 103 Sorting function to sort the list of languages according to 104 reversed(compilers.clink_langs) and append the unknown langs in the end. 105 The purpose is to prefer C over C++ for files that can be compiled by 106 both such as assembly, C, etc. Also applies to ObjC, ObjC++, etc. 107 ''' 108 if lang not in clink_langs: 109 return 1 110 return -clink_langs.index(lang) 111 112def is_header(fname): 113 if hasattr(fname, 'fname'): 114 fname = fname.fname 115 suffix = fname.split('.')[-1] 116 return suffix in header_suffixes 117 118def is_source(fname): 119 if hasattr(fname, 'fname'): 120 fname = fname.fname 121 suffix = fname.split('.')[-1].lower() 122 return suffix in clink_suffixes 123 124def is_assembly(fname): 125 if hasattr(fname, 'fname'): 126 fname = fname.fname 127 return fname.split('.')[-1].lower() == 's' 128 129def is_llvm_ir(fname): 130 if hasattr(fname, 'fname'): 131 fname = fname.fname 132 return fname.split('.')[-1] == 'll' 133 134@lru_cache(maxsize=None) 135def cached_by_name(fname): 136 suffix = fname.split('.')[-1] 137 return suffix in obj_suffixes 138 139def is_object(fname): 140 if hasattr(fname, 'fname'): 141 fname = fname.fname 142 return cached_by_name(fname) 143 144def is_library(fname): 145 if hasattr(fname, 'fname'): 146 fname = fname.fname 147 148 if soregex.match(fname): 149 return True 150 151 suffix = fname.split('.')[-1] 152 return suffix in lib_suffixes 153 154def is_known_suffix(fname): 155 if hasattr(fname, 'fname'): 156 fname = fname.fname 157 suffix = fname.split('.')[-1] 158 159 return suffix in all_suffixes 160 161cuda_buildtype_args = {'plain': [], 162 'debug': [], 163 'debugoptimized': [], 164 'release': [], 165 'minsize': [], 166 } 167java_buildtype_args = {'plain': [], 168 'debug': ['-g'], 169 'debugoptimized': ['-g'], 170 'release': [], 171 'minsize': [], 172 'custom': [], 173 } 174 175rust_buildtype_args = {'plain': [], 176 'debug': [], 177 'debugoptimized': [], 178 'release': [], 179 'minsize': [], 180 'custom': [], 181 } 182 183d_gdc_buildtype_args = {'plain': [], 184 'debug': [], 185 'debugoptimized': ['-finline-functions'], 186 'release': ['-finline-functions'], 187 'minsize': [], 188 'custom': [], 189 } 190 191d_ldc_buildtype_args = {'plain': [], 192 'debug': [], 193 'debugoptimized': ['-enable-inlining', '-Hkeep-all-bodies'], 194 'release': ['-enable-inlining', '-Hkeep-all-bodies'], 195 'minsize': [], 196 'custom': [], 197 } 198 199d_dmd_buildtype_args = {'plain': [], 200 'debug': [], 201 'debugoptimized': ['-inline'], 202 'release': ['-inline'], 203 'minsize': [], 204 'custom': [], 205 } 206 207mono_buildtype_args = {'plain': [], 208 'debug': [], 209 'debugoptimized': ['-optimize+'], 210 'release': ['-optimize+'], 211 'minsize': [], 212 'custom': [], 213 } 214 215swift_buildtype_args = {'plain': [], 216 'debug': [], 217 'debugoptimized': [], 218 'release': [], 219 'minsize': [], 220 'custom': [], 221 } 222 223gnu_winlibs = ['-lkernel32', '-luser32', '-lgdi32', '-lwinspool', '-lshell32', 224 '-lole32', '-loleaut32', '-luuid', '-lcomdlg32', '-ladvapi32'] 225 226msvc_winlibs = ['kernel32.lib', 'user32.lib', 'gdi32.lib', 227 'winspool.lib', 'shell32.lib', 'ole32.lib', 'oleaut32.lib', 228 'uuid.lib', 'comdlg32.lib', 'advapi32.lib'] 229 230clike_optimization_args = {'0': [], 231 'g': [], 232 '1': ['-O1'], 233 '2': ['-O2'], 234 '3': ['-O3'], 235 's': ['-Os'], 236 } 237 238cuda_optimization_args = {'0': [], 239 'g': ['-O0'], 240 '1': ['-O1'], 241 '2': ['-O2'], 242 '3': ['-O3'], 243 's': ['-O3'] 244 } 245 246cuda_debug_args = {False: [], 247 True: ['-g']} 248 249clike_debug_args = {False: [], 250 True: ['-g']} 251 252base_options = {'b_pch': coredata.UserBooleanOption('Use precompiled headers', True), 253 'b_lto': coredata.UserBooleanOption('Use link time optimization', False), 254 'b_sanitize': coredata.UserComboOption('Code sanitizer to use', 255 ['none', 'address', 'thread', 'undefined', 'memory', 'address,undefined'], 256 'none'), 257 'b_lundef': coredata.UserBooleanOption('Use -Wl,--no-undefined when linking', True), 258 'b_asneeded': coredata.UserBooleanOption('Use -Wl,--as-needed when linking', True), 259 'b_pgo': coredata.UserComboOption('Use profile guided optimization', 260 ['off', 'generate', 'use'], 261 'off'), 262 'b_coverage': coredata.UserBooleanOption('Enable coverage tracking.', 263 False), 264 'b_colorout': coredata.UserComboOption('Use colored output', 265 ['auto', 'always', 'never'], 266 'always'), 267 'b_ndebug': coredata.UserComboOption('Disable asserts', 268 ['true', 'false', 'if-release'], 'false'), 269 'b_staticpic': coredata.UserBooleanOption('Build static libraries as position independent', 270 True), 271 'b_pie': coredata.UserBooleanOption('Build executables as position independent', 272 False), 273 'b_bitcode': coredata.UserBooleanOption('Generate and embed bitcode (only macOS/iOS/tvOS)', 274 False), 275 'b_vscrt': coredata.UserComboOption('VS run-time library type to use.', 276 ['none', 'md', 'mdd', 'mt', 'mtd', 'from_buildtype'], 277 'from_buildtype'), 278 } 279 280def option_enabled(boptions, options, option): 281 try: 282 if option not in boptions: 283 return False 284 return options[option].value 285 except KeyError: 286 return False 287 288def get_base_compile_args(options, compiler): 289 args = [] 290 try: 291 if options['b_lto'].value: 292 args.extend(compiler.get_lto_compile_args()) 293 except KeyError: 294 pass 295 try: 296 args += compiler.get_colorout_args(options['b_colorout'].value) 297 except KeyError: 298 pass 299 try: 300 args += compiler.sanitizer_compile_args(options['b_sanitize'].value) 301 except KeyError: 302 pass 303 try: 304 pgo_val = options['b_pgo'].value 305 if pgo_val == 'generate': 306 args.extend(compiler.get_profile_generate_args()) 307 elif pgo_val == 'use': 308 args.extend(compiler.get_profile_use_args()) 309 except KeyError: 310 pass 311 try: 312 if options['b_coverage'].value: 313 args += compiler.get_coverage_args() 314 except KeyError: 315 pass 316 try: 317 if (options['b_ndebug'].value == 'true' or 318 (options['b_ndebug'].value == 'if-release' and 319 options['buildtype'].value in {'release', 'plain'})): 320 args += compiler.get_disable_assert_args() 321 except KeyError: 322 pass 323 # This does not need a try...except 324 if option_enabled(compiler.base_options, options, 'b_bitcode'): 325 args.append('-fembed-bitcode') 326 try: 327 crt_val = options['b_vscrt'].value 328 buildtype = options['buildtype'].value 329 try: 330 args += compiler.get_crt_compile_args(crt_val, buildtype) 331 except AttributeError: 332 pass 333 except KeyError: 334 pass 335 return args 336 337def get_base_link_args(options, linker, is_shared_module): 338 args = [] 339 try: 340 if options['b_lto'].value: 341 args.extend(linker.get_lto_link_args()) 342 except KeyError: 343 pass 344 try: 345 args += linker.sanitizer_link_args(options['b_sanitize'].value) 346 except KeyError: 347 pass 348 try: 349 pgo_val = options['b_pgo'].value 350 if pgo_val == 'generate': 351 args.extend(linker.get_profile_generate_args()) 352 elif pgo_val == 'use': 353 args.extend(linker.get_profile_use_args()) 354 except KeyError: 355 pass 356 try: 357 if options['b_coverage'].value: 358 args += linker.get_coverage_link_args() 359 except KeyError: 360 pass 361 362 as_needed = option_enabled(linker.base_options, options, 'b_asneeded') 363 bitcode = option_enabled(linker.base_options, options, 'b_bitcode') 364 # Shared modules cannot be built with bitcode_bundle because 365 # -bitcode_bundle is incompatible with -undefined and -bundle 366 if bitcode and not is_shared_module: 367 args.extend(linker.bitcode_args()) 368 elif as_needed: 369 # -Wl,-dead_strip_dylibs is incompatible with bitcode 370 args.extend(linker.get_asneeded_args()) 371 372 # Apple's ld (the only one that supports bitcode) does not like -undefined 373 # arguments or -headerpad_max_install_names when bitcode is enabled 374 if not bitcode: 375 args.extend(linker.headerpad_args()) 376 if (not is_shared_module and 377 option_enabled(linker.base_options, options, 'b_lundef')): 378 args.extend(linker.no_undefined_link_args()) 379 else: 380 args.extend(linker.get_allow_undefined_link_args()) 381 382 try: 383 crt_val = options['b_vscrt'].value 384 buildtype = options['buildtype'].value 385 try: 386 args += linker.get_crt_link_args(crt_val, buildtype) 387 except AttributeError: 388 pass 389 except KeyError: 390 pass 391 return args 392 393 394class CrossNoRunException(MesonException): 395 pass 396 397class RunResult: 398 def __init__(self, compiled, returncode=999, stdout='UNDEFINED', stderr='UNDEFINED'): 399 self.compiled = compiled 400 self.returncode = returncode 401 self.stdout = stdout 402 self.stderr = stderr 403 404 405class Compiler(metaclass=abc.ABCMeta): 406 # Libraries to ignore in find_library() since they are provided by the 407 # compiler or the C library. Currently only used for MSVC. 408 ignore_libs = () 409 # Libraries that are internal compiler implementations, and must not be 410 # manually searched. 411 internal_libs = () 412 413 LINKER_PREFIX = None # type: T.Union[None, str, T.List[str]] 414 INVOKES_LINKER = True 415 416 def __init__(self, exelist, version, for_machine: MachineChoice, info: 'MachineInfo', 417 linker: T.Optional['DynamicLinker'] = None, **kwargs): 418 if isinstance(exelist, str): 419 self.exelist = [exelist] 420 elif isinstance(exelist, list): 421 self.exelist = exelist 422 else: 423 raise TypeError('Unknown argument to Compiler') 424 # In case it's been overridden by a child class already 425 if not hasattr(self, 'file_suffixes'): 426 self.file_suffixes = lang_suffixes[self.language] 427 if not hasattr(self, 'can_compile_suffixes'): 428 self.can_compile_suffixes = set(self.file_suffixes) 429 self.default_suffix = self.file_suffixes[0] 430 self.version = version 431 if 'full_version' in kwargs: 432 self.full_version = kwargs['full_version'] 433 else: 434 self.full_version = None 435 self.for_machine = for_machine 436 self.base_options = [] 437 self.linker = linker 438 self.info = info 439 440 def __repr__(self): 441 repr_str = "<{0}: v{1} `{2}`>" 442 return repr_str.format(self.__class__.__name__, self.version, 443 ' '.join(self.exelist)) 444 445 @lru_cache(maxsize=None) 446 def can_compile(self, src) -> bool: 447 if hasattr(src, 'fname'): 448 src = src.fname 449 suffix = os.path.splitext(src)[1].lower() 450 if suffix and suffix[1:] in self.can_compile_suffixes: 451 return True 452 return False 453 454 def get_id(self) -> str: 455 return self.id 456 457 def get_linker_id(self) -> str: 458 # There is not guarantee that we have a dynamic linker instance, as 459 # some languages don't have separate linkers and compilers. In those 460 # cases return the compiler id 461 try: 462 return self.linker.id 463 except AttributeError: 464 return self.id 465 466 def get_version_string(self) -> str: 467 details = [self.id, self.version] 468 if self.full_version: 469 details += ['"%s"' % (self.full_version)] 470 return '(%s)' % (' '.join(details)) 471 472 def get_language(self) -> str: 473 return self.language 474 475 @classmethod 476 def get_display_language(cls) -> str: 477 return cls.language.capitalize() 478 479 def get_default_suffix(self) -> str: 480 return self.default_suffix 481 482 def get_define(self, dname, prefix, env, extra_args, dependencies) -> T.Tuple[str, bool]: 483 raise EnvironmentException('%s does not support get_define ' % self.get_id()) 484 485 def compute_int(self, expression, low, high, guess, prefix, env, extra_args, dependencies) -> int: 486 raise EnvironmentException('%s does not support compute_int ' % self.get_id()) 487 488 def compute_parameters_with_absolute_paths(self, parameter_list, build_dir): 489 raise EnvironmentException('%s does not support compute_parameters_with_absolute_paths ' % self.get_id()) 490 491 def has_members(self, typename, membernames, prefix, env, *, 492 extra_args=None, dependencies=None) -> T.Tuple[bool, bool]: 493 raise EnvironmentException('%s does not support has_member(s) ' % self.get_id()) 494 495 def has_type(self, typename, prefix, env, extra_args, *, 496 dependencies=None) -> T.Tuple[bool, bool]: 497 raise EnvironmentException('%s does not support has_type ' % self.get_id()) 498 499 def symbols_have_underscore_prefix(self, env) -> bool: 500 raise EnvironmentException('%s does not support symbols_have_underscore_prefix ' % self.get_id()) 501 502 def get_exelist(self): 503 return self.exelist[:] 504 505 def get_linker_exelist(self) -> T.List[str]: 506 return self.linker.get_exelist() 507 508 def get_linker_output_args(self, outputname: str) -> T.List[str]: 509 return self.linker.get_output_args(outputname) 510 511 def get_builtin_define(self, *args, **kwargs): 512 raise EnvironmentException('%s does not support get_builtin_define.' % self.id) 513 514 def has_builtin_define(self, *args, **kwargs): 515 raise EnvironmentException('%s does not support has_builtin_define.' % self.id) 516 517 def get_always_args(self): 518 return [] 519 520 def can_linker_accept_rsp(self) -> bool: 521 """ 522 Determines whether the linker can accept arguments using the @rsp syntax. 523 """ 524 return self.linker.get_accepts_rsp() 525 526 def get_linker_always_args(self) -> T.List[str]: 527 return self.linker.get_always_args() 528 529 def get_linker_lib_prefix(self): 530 return self.linker.get_lib_prefix() 531 532 def gen_import_library_args(self, implibname): 533 """ 534 Used only on Windows for libraries that need an import library. 535 This currently means C, C++, Fortran. 536 """ 537 return [] 538 539 def get_linker_args_from_envvars(self, 540 for_machine: MachineChoice, 541 is_cross: bool) -> T.List[str]: 542 return self.linker.get_args_from_envvars(for_machine, is_cross) 543 544 def get_options(self) -> T.Dict[str, coredata.UserOption]: 545 return {} 546 547 def get_option_compile_args(self, options): 548 return [] 549 550 def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: 551 return self.linker.get_option_args(options) 552 553 def check_header(self, *args, **kwargs) -> T.Tuple[bool, bool]: 554 raise EnvironmentException('Language %s does not support header checks.' % self.get_display_language()) 555 556 def has_header(self, *args, **kwargs) -> T.Tuple[bool, bool]: 557 raise EnvironmentException('Language %s does not support header checks.' % self.get_display_language()) 558 559 def has_header_symbol(self, *args, **kwargs) -> T.Tuple[bool, bool]: 560 raise EnvironmentException('Language %s does not support header symbol checks.' % self.get_display_language()) 561 562 def compiles(self, *args, **kwargs) -> T.Tuple[bool, bool]: 563 raise EnvironmentException('Language %s does not support compile checks.' % self.get_display_language()) 564 565 def links(self, *args, **kwargs) -> T.Tuple[bool, bool]: 566 raise EnvironmentException('Language %s does not support link checks.' % self.get_display_language()) 567 568 def run(self, *args, **kwargs) -> RunResult: 569 raise EnvironmentException('Language %s does not support run checks.' % self.get_display_language()) 570 571 def sizeof(self, *args, **kwargs) -> int: 572 raise EnvironmentException('Language %s does not support sizeof checks.' % self.get_display_language()) 573 574 def alignment(self, *args, **kwargs) -> int: 575 raise EnvironmentException('Language %s does not support alignment checks.' % self.get_display_language()) 576 577 def has_function(self, *args, **kwargs) -> T.Tuple[bool, bool]: 578 raise EnvironmentException('Language %s does not support function checks.' % self.get_display_language()) 579 580 @classmethod 581 def unix_args_to_native(cls, args): 582 "Always returns a copy that can be independently mutated" 583 return args[:] 584 585 @classmethod 586 def native_args_to_unix(cls, args: T.List[str]) -> T.List[str]: 587 "Always returns a copy that can be independently mutated" 588 return args[:] 589 590 def find_library(self, *args, **kwargs): 591 raise EnvironmentException('Language {} does not support library finding.'.format(self.get_display_language())) 592 593 def get_library_dirs(self, *args, **kwargs): 594 return () 595 596 def get_program_dirs(self, *args, **kwargs): 597 return [] 598 599 def has_multi_arguments(self, args, env) -> T.Tuple[bool, bool]: 600 raise EnvironmentException( 601 'Language {} does not support has_multi_arguments.'.format( 602 self.get_display_language())) 603 604 def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: 605 return self.linker.has_multi_arguments(args, env) 606 607 def _get_compile_output(self, dirname, mode): 608 # In pre-processor mode, the output is sent to stdout and discarded 609 if mode == 'preprocess': 610 return None 611 # Extension only matters if running results; '.exe' is 612 # guaranteed to be executable on every platform. 613 if mode == 'link': 614 suffix = 'exe' 615 else: 616 suffix = 'obj' 617 return os.path.join(dirname, 'output.' + suffix) 618 619 def get_compiler_args_for_mode(self, mode): 620 args = [] 621 args += self.get_always_args() 622 if mode == 'compile': 623 args += self.get_compile_only_args() 624 if mode == 'preprocess': 625 args += self.get_preprocess_only_args() 626 return args 627 628 def compiler_args(self, args: T.Optional[T.Iterable[str]] = None) -> CompilerArgs: 629 """Return an appropriate CompilerArgs instance for this class.""" 630 return CompilerArgs(self, args) 631 632 @contextlib.contextmanager 633 def compile(self, code: str, extra_args: list = None, *, mode: str = 'link', want_output: bool = False, temp_dir: str = None): 634 if extra_args is None: 635 extra_args = [] 636 try: 637 with tempfile.TemporaryDirectory(dir=temp_dir) as tmpdirname: 638 no_ccache = False 639 if isinstance(code, str): 640 srcname = os.path.join(tmpdirname, 641 'testfile.' + self.default_suffix) 642 with open(srcname, 'w') as ofile: 643 ofile.write(code) 644 # ccache would result in a cache miss 645 no_ccache = True 646 elif isinstance(code, mesonlib.File): 647 srcname = code.fname 648 649 # Construct the compiler command-line 650 commands = self.compiler_args() 651 commands.append(srcname) 652 # Preprocess mode outputs to stdout, so no output args 653 if mode != 'preprocess': 654 output = self._get_compile_output(tmpdirname, mode) 655 commands += self.get_output_args(output) 656 commands.extend(self.get_compiler_args_for_mode(mode)) 657 # extra_args must be last because it could contain '/link' to 658 # pass args to VisualStudio's linker. In that case everything 659 # in the command line after '/link' is given to the linker. 660 commands += extra_args 661 # Generate full command-line with the exelist 662 commands = self.get_exelist() + commands.to_native() 663 mlog.debug('Running compile:') 664 mlog.debug('Working directory: ', tmpdirname) 665 mlog.debug('Command line: ', ' '.join(commands), '\n') 666 mlog.debug('Code:\n', code) 667 os_env = os.environ.copy() 668 os_env['LC_ALL'] = 'C' 669 if no_ccache: 670 os_env['CCACHE_DISABLE'] = '1' 671 p, p.stdo, p.stde = Popen_safe(commands, cwd=tmpdirname, env=os_env) 672 mlog.debug('Compiler stdout:\n', p.stdo) 673 mlog.debug('Compiler stderr:\n', p.stde) 674 p.commands = commands 675 p.input_name = srcname 676 if want_output: 677 p.output_name = output 678 p.cached = False # Make sure that the cached attribute always exists 679 yield p 680 except OSError: 681 # On Windows antivirus programs and the like hold on to files so 682 # they can't be deleted. There's not much to do in this case. Also, 683 # catch OSError because the directory is then no longer empty. 684 pass 685 686 @contextlib.contextmanager 687 def cached_compile(self, code, cdata: coredata.CoreData, *, extra_args=None, mode: str = 'link', temp_dir=None): 688 assert(isinstance(cdata, coredata.CoreData)) 689 690 # Calculate the key 691 textra_args = tuple(extra_args) if extra_args is not None else None 692 key = (tuple(self.exelist), self.version, code, textra_args, mode) 693 694 # Check if not cached 695 if key not in cdata.compiler_check_cache: 696 with self.compile(code, extra_args=extra_args, mode=mode, want_output=False, temp_dir=temp_dir) as p: 697 # Remove all attributes except the following 698 # This way the object can be serialized 699 tokeep = ['args', 'commands', 'input_name', 'output_name', 700 'pid', 'returncode', 'stdo', 'stde', 'text_mode'] 701 todel = [x for x in vars(p).keys() if x not in tokeep] 702 for i in todel: 703 delattr(p, i) 704 p.cached = False 705 cdata.compiler_check_cache[key] = p 706 yield p 707 return 708 709 # Return cached 710 p = cdata.compiler_check_cache[key] 711 p.cached = True 712 mlog.debug('Using cached compile:') 713 mlog.debug('Cached command line: ', ' '.join(p.commands), '\n') 714 mlog.debug('Code:\n', code) 715 mlog.debug('Cached compiler stdout:\n', p.stdo) 716 mlog.debug('Cached compiler stderr:\n', p.stde) 717 yield p 718 719 def get_colorout_args(self, colortype): 720 return [] 721 722 # Some compilers (msvc) write debug info to a separate file. 723 # These args specify where it should be written. 724 def get_compile_debugfile_args(self, rel_obj, **kwargs): 725 return [] 726 727 def get_link_debugfile_name(self, targetfile: str) -> str: 728 return self.linker.get_debugfile_name(targetfile) 729 730 def get_link_debugfile_args(self, targetfile: str) -> T.List[str]: 731 return self.linker.get_debugfile_args(targetfile) 732 733 def get_std_shared_lib_link_args(self) -> T.List[str]: 734 return self.linker.get_std_shared_lib_args() 735 736 def get_std_shared_module_link_args(self, options: 'OptionDictType') -> T.List[str]: 737 return self.linker.get_std_shared_module_args(options) 738 739 def get_link_whole_for(self, args: T.List[str]) -> T.List[str]: 740 return self.linker.get_link_whole_for(args) 741 742 def get_allow_undefined_link_args(self) -> T.List[str]: 743 return self.linker.get_allow_undefined_args() 744 745 def no_undefined_link_args(self) -> T.List[str]: 746 return self.linker.no_undefined_args() 747 748 # Compiler arguments needed to enable the given instruction set. 749 # May be [] meaning nothing needed or None meaning the given set 750 # is not supported. 751 def get_instruction_set_args(self, instruction_set): 752 return None 753 754 def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, 755 rpath_paths: str, build_rpath: str, 756 install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: 757 return self.linker.build_rpath_args( 758 env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath) 759 760 def thread_flags(self, env): 761 return [] 762 763 def openmp_flags(self): 764 raise EnvironmentException('Language %s does not support OpenMP flags.' % self.get_display_language()) 765 766 def openmp_link_flags(self): 767 return self.openmp_flags() 768 769 def language_stdlib_only_link_flags(self): 770 return [] 771 772 def gnu_symbol_visibility_args(self, vistype): 773 return [] 774 775 def get_gui_app_args(self, value): 776 return [] 777 778 def has_func_attribute(self, name, env): 779 raise EnvironmentException( 780 'Language {} does not support function attributes.'.format(self.get_display_language())) 781 782 def get_pic_args(self): 783 m = 'Language {} does not support position-independent code' 784 raise EnvironmentException(m.format(self.get_display_language())) 785 786 def get_pie_args(self): 787 m = 'Language {} does not support position-independent executable' 788 raise EnvironmentException(m.format(self.get_display_language())) 789 790 def get_pie_link_args(self) -> T.List[str]: 791 return self.linker.get_pie_args() 792 793 def get_argument_syntax(self): 794 """Returns the argument family type. 795 796 Compilers fall into families if they try to emulate the command line 797 interface of another compiler. For example, clang is in the GCC family 798 since it accepts most of the same arguments as GCC. ICL (ICC on 799 windows) is in the MSVC family since it accepts most of the same 800 arguments as MSVC. 801 """ 802 return 'other' 803 804 def get_profile_generate_args(self): 805 raise EnvironmentException( 806 '%s does not support get_profile_generate_args ' % self.get_id()) 807 808 def get_profile_use_args(self): 809 raise EnvironmentException( 810 '%s does not support get_profile_use_args ' % self.get_id()) 811 812 def get_undefined_link_args(self) -> T.List[str]: 813 return self.linker.get_undefined_link_args() 814 815 def remove_linkerlike_args(self, args): 816 rm_exact = ('-headerpad_max_install_names',) 817 rm_prefixes = ('-Wl,', '-L',) 818 rm_next = ('-L', '-framework',) 819 ret = [] 820 iargs = iter(args) 821 for arg in iargs: 822 # Remove this argument 823 if arg in rm_exact: 824 continue 825 # If the argument starts with this, but is not *exactly* this 826 # f.ex., '-L' should match ['-Lfoo'] but not ['-L', 'foo'] 827 if arg.startswith(rm_prefixes) and arg not in rm_prefixes: 828 continue 829 # Ignore this argument and the one after it 830 if arg in rm_next: 831 next(iargs) 832 continue 833 ret.append(arg) 834 return ret 835 836 def get_lto_compile_args(self) -> T.List[str]: 837 return [] 838 839 def get_lto_link_args(self) -> T.List[str]: 840 return self.linker.get_lto_args() 841 842 def sanitizer_compile_args(self, value: str) -> T.List[str]: 843 return [] 844 845 def sanitizer_link_args(self, value: str) -> T.List[str]: 846 return self.linker.sanitizer_args(value) 847 848 def get_asneeded_args(self) -> T.List[str]: 849 return self.linker.get_asneeded_args() 850 851 def headerpad_args(self) -> T.List[str]: 852 return self.linker.headerpad_args() 853 854 def bitcode_args(self) -> T.List[str]: 855 return self.linker.bitcode_args() 856 857 def get_buildtype_linker_args(self, buildtype: str) -> T.List[str]: 858 return self.linker.get_buildtype_args(buildtype) 859 860 def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str, 861 suffix: str, soversion: str, 862 darwin_versions: T.Tuple[str, str], 863 is_shared_module: bool) -> T.List[str]: 864 return self.linker.get_soname_args( 865 env, prefix, shlib_name, suffix, soversion, 866 darwin_versions, is_shared_module) 867 868 def get_target_link_args(self, target): 869 return target.link_args 870 871 def get_dependency_compile_args(self, dep): 872 return dep.get_compile_args() 873 874 def get_dependency_link_args(self, dep): 875 return dep.get_link_args() 876 877 @classmethod 878 def use_linker_args(cls, linker: str) -> T.List[str]: 879 """Get a list of arguments to pass to the compiler to set the linker. 880 """ 881 return [] 882 883 def get_coverage_link_args(self) -> T.List[str]: 884 return self.linker.get_coverage_args() 885 886 def get_disable_assert_args(self) -> T.List[str]: 887 return [] 888 889 890def get_largefile_args(compiler): 891 ''' 892 Enable transparent large-file-support for 32-bit UNIX systems 893 ''' 894 if not (compiler.get_argument_syntax() == 'msvc' or compiler.info.is_darwin()): 895 # Enable large-file support unconditionally on all platforms other 896 # than macOS and MSVC. macOS is now 64-bit-only so it doesn't 897 # need anything special, and MSVC doesn't have automatic LFS. 898 # You must use the 64-bit counterparts explicitly. 899 # glibc, musl, and uclibc, and all BSD libcs support this. On Android, 900 # support for transparent LFS is available depending on the version of 901 # Bionic: https://github.com/android/platform_bionic#32-bit-abi-bugs 902 # https://code.google.com/p/android/issues/detail?id=64613 903 # 904 # If this breaks your code, fix it! It's been 20+ years! 905 return ['-D_FILE_OFFSET_BITS=64'] 906 # We don't enable -D_LARGEFILE64_SOURCE since that enables 907 # transitionary features and must be enabled by programs that use 908 # those features explicitly. 909 return [] 910 911 912def get_args_from_envvars(lang: str, 913 for_machine: MachineChoice, 914 is_cross: bool, 915 use_linker_args: bool) -> T.Tuple[T.List[str], T.List[str]]: 916 """ 917 Returns a tuple of (compile_flags, link_flags) for the specified language 918 from the inherited environment 919 """ 920 if lang not in cflags_mapping: 921 return [], [] 922 923 compile_flags = [] # type: T.List[str] 924 link_flags = [] # type: T.List[str] 925 926 env_compile_flags = get_env_var(for_machine, is_cross, cflags_mapping[lang]) 927 if env_compile_flags is not None: 928 compile_flags += split_args(env_compile_flags) 929 930 # Link flags (same for all languages) 931 if lang in languages_using_ldflags: 932 link_flags += LinkerEnvVarsMixin.get_args_from_envvars(for_machine, is_cross) 933 if use_linker_args: 934 # When the compiler is used as a wrapper around the linker (such as 935 # with GCC and Clang), the compile flags can be needed while linking 936 # too. This is also what Autotools does. However, we don't want to do 937 # this when the linker is stand-alone such as with MSVC C/C++, etc. 938 link_flags = compile_flags + link_flags 939 940 # Pre-processor flags for certain languages 941 if lang in languages_using_cppflags: 942 env_preproc_flags = get_env_var(for_machine, is_cross, 'CPPFLAGS') 943 if env_preproc_flags is not None: 944 compile_flags += split_args(env_preproc_flags) 945 946 return compile_flags, link_flags 947 948 949def get_global_options(lang: str, 950 comp: T.Type[Compiler], 951 for_machine: MachineChoice, 952 is_cross: bool, 953 properties: Properties) -> T.Dict[str, coredata.UserOption]: 954 """Retreive options that apply to all compilers for a given language.""" 955 description = 'Extra arguments passed to the {}'.format(lang) 956 opts = { 957 'args': coredata.UserArrayOption( 958 description + ' compiler', 959 [], split_args=True, user_input=True, allow_dups=True), 960 'link_args': coredata.UserArrayOption( 961 description + ' linker', 962 [], split_args=True, user_input=True, allow_dups=True), 963 } 964 965 # Get from env vars. 966 compile_args, link_args = get_args_from_envvars( 967 lang, 968 for_machine, 969 is_cross, 970 comp.INVOKES_LINKER) 971 972 for k, o in opts.items(): 973 user_k = lang + '_' + k 974 if user_k in properties: 975 # Get from configuration files. 976 o.set_value(properties[user_k]) 977 elif k == 'args': 978 o.set_value(compile_args) 979 elif k == 'link_args': 980 o.set_value(link_args) 981 982 return opts 983