compilers: Tell mypy that the compiler mixins are just that

We do this by making the mixins inherit the Compiler class only when
mypy is examining the code (using some clever inheritance shenanigans).
This caught a bunch of issues, and also lets us delete a ton of code.
pull/7786/head
Dylan Baker 4 years ago
parent 2c0fbe161d
commit 682d22129c
  1. 23
      mesonbuild/compilers/compilers.py
  2. 24
      mesonbuild/compilers/mixins/arm.py
  3. 13
      mesonbuild/compilers/mixins/c2000.py
  4. 9
      mesonbuild/compilers/mixins/ccrx.py
  5. 18
      mesonbuild/compilers/mixins/clang.py
  6. 57
      mesonbuild/compilers/mixins/clike.py
  7. 12
      mesonbuild/compilers/mixins/compcert.py
  8. 3
      mesonbuild/compilers/mixins/elbrus.py
  9. 18
      mesonbuild/compilers/mixins/emscripten.py
  10. 34
      mesonbuild/compilers/mixins/gnu.py
  11. 8
      mesonbuild/compilers/mixins/intel.py
  12. 17
      mesonbuild/compilers/mixins/islinker.py
  13. 14
      mesonbuild/compilers/mixins/pgi.py
  14. 36
      mesonbuild/compilers/mixins/visualstudio.py
  15. 13
      mesonbuild/compilers/mixins/xc16.py
  16. 1
      mesonbuild/linkers.py

@ -440,10 +440,10 @@ class CompileResult:
class Compiler(metaclass=abc.ABCMeta):
# Libraries to ignore in find_library() since they are provided by the
# compiler or the C library. Currently only used for MSVC.
ignore_libs = () # type: T.Tuple[str, ...]
ignore_libs = [] # type: T.List[str]
# Libraries that are internal compiler implementations, and must not be
# manually searched.
internal_libs = () # type: T.Tuple[str, ...]
internal_libs = [] # type: T.List[str]
LINKER_PREFIX = None # type: T.Union[None, str, T.List[str]]
INVOKES_LINKER = True
@ -518,18 +518,18 @@ class Compiler(metaclass=abc.ABCMeta):
raise EnvironmentException('%s does not support get_define ' % self.get_id())
def compute_int(self, expression: str, low: T.Optional[int], high: T.Optional[int],
guess: T.Optional[int], prefix: str, env: 'Environment',
extra_args: T.List[str], dependencies: T.List['Dependency']) -> int:
guess: T.Optional[int], prefix: str, env: 'Environment', *,
extra_args: T.Optional[T.List[str]], dependencies: T.Optional[T.List['Dependency']]) -> int:
raise EnvironmentException('%s does not support compute_int ' % self.get_id())
def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str],
build_dir: str) -> T.List[str]:
raise EnvironmentException('%s does not support compute_parameters_with_absolute_paths ' % self.get_id())
def has_members(self, typename: str, membernames: T.Iterable[str],
def has_members(self, typename: str, membernames: T.List[str],
prefix: str, env: 'Environment', *,
extra_args: T.Optional[T.Iterable[str]] = None,
dependencies: T.Optional[T.Iterable['Dependency']] = None) -> T.Tuple[bool, bool]:
extra_args: T.Optional[T.List[str]] = None,
dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]:
raise EnvironmentException('%s does not support has_member(s) ' % self.get_id())
def has_type(self, typename: str, prefix: str, env: 'Environment',
@ -662,8 +662,8 @@ class Compiler(metaclass=abc.ABCMeta):
raise EnvironmentException('Language %s does not support alignment checks.' % self.get_display_language())
def has_function(self, funcname: str, prefix: str, env: 'Environment', *,
extra_args: T.Optional[T.Iterable[str]] = None,
dependencies: T.Optional[T.Iterable['Dependency']] = None) -> T.Tuple[bool, bool]:
extra_args: T.Optional[T.List[str]] = None,
dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]:
"""See if a function exists.
Returns a two item tuple of bools. The first bool is whether the
@ -672,8 +672,7 @@ class Compiler(metaclass=abc.ABCMeta):
"""
raise EnvironmentException('Language %s does not support function checks.' % self.get_display_language())
@classmethod
def unix_args_to_native(cls, args: T.List[str]) -> T.List[str]:
def unix_args_to_native(self, args: T.List[str]) -> T.List[str]:
"Always returns a copy that can be independently mutated"
return args.copy()
@ -878,7 +877,7 @@ class Compiler(metaclass=abc.ABCMeta):
def get_gui_app_args(self, value: bool) -> T.List[str]:
return []
def has_func_attribute(self, name: str, env: 'Environment') -> T.List[str]:
def has_func_attribute(self, name: str, env: 'Environment') -> T.Tuple[bool, bool]:
raise EnvironmentException(
'Language {} does not support function attributes.'.format(self.get_display_language()))

@ -23,8 +23,14 @@ from ..compilers import clike_debug_args
from .clang import clang_color_args
if T.TYPE_CHECKING:
from ...envconfig import MachineChoice
from ...environment import Environment
from ...compilers.compilers import Compiler
else:
# This is a bit clever, for mypy we pretend that these mixins descend from
# Compiler, so we get all of the methods and attributes defined for us, but
# for runtime we make them descend from object (which all classes normally
# do). This gives up DRYer type checking, with no runtime impact
Compiler = object
arm_buildtype_args = {
'plain': [],
@ -63,14 +69,10 @@ armclang_optimization_args = {
} # type: T.Dict[str, T.List[str]]
class ArmCompiler:
class ArmCompiler(Compiler):
"""Functionality that is common to all ARM family compilers."""
if T.TYPE_CHECKING:
is_cross = True
can_compile_suffixes = set() # type: T.Set[str]
def __init__(self) -> None:
if not self.is_cross:
raise mesonlib.EnvironmentException('armcc supports only cross-compilation.')
@ -133,15 +135,7 @@ class ArmCompiler:
return parameter_list
class ArmclangCompiler:
if T.TYPE_CHECKING:
can_compile_suffixes = set() # type: T.Set[str]
is_cross = True
version = '0'
linker = ArmClangDynamicLinker(MachineChoice.HOST, version='1.2.3')
def get_pch_name(self, name: str) -> str: ...
class ArmclangCompiler(Compiler):
def __init__(self) -> None:
if not self.is_cross:

@ -21,6 +21,13 @@ from ...mesonlib import EnvironmentException
if T.TYPE_CHECKING:
from ...environment import Environment
from ...compilers.compilers import Compiler
else:
# This is a bit clever, for mypy we pretend that these mixins descend from
# Compiler, so we get all of the methods and attributes defined for us, but
# for runtime we make them descend from object (which all classes normally
# do). This gives up DRYer type checking, with no runtime impact
Compiler = object
c2000_buildtype_args = {
'plain': [],
@ -46,11 +53,7 @@ c2000_debug_args = {
} # type: T.Dict[bool, T.List[str]]
class C2000Compiler:
if T.TYPE_CHECKING:
is_cross = True
can_compile_suffixes = set() # type: T.Set[str]
class C2000Compiler(Compiler):
def __init__(self) -> None:
if not self.is_cross:

@ -21,6 +21,13 @@ from ...mesonlib import EnvironmentException
if T.TYPE_CHECKING:
from ...environment import Environment
from ...compilers.compilers import Compiler
else:
# This is a bit clever, for mypy we pretend that these mixins descend from
# Compiler, so we get all of the methods and attributes defined for us, but
# for runtime we make them descend from object (which all classes normally
# do). This gives up DRYer type checking, with no runtime impact
Compiler = object
ccrx_buildtype_args = {
'plain': [],
@ -46,7 +53,7 @@ ccrx_debug_args = {
} # type: T.Dict[bool, T.List[str]]
class CcrxCompiler:
class CcrxCompiler(Compiler):
if T.TYPE_CHECKING:
is_cross = True

@ -23,10 +23,8 @@ from ...linkers import AppleDynamicLinker
from .gnu import GnuLikeCompiler
if T.TYPE_CHECKING:
from ...envconfig import MachineChoice
from ...environment import Environment
from ...dependencies import Dependency # noqa: F401
from ...linkers import AppleDynamicLinker
clang_color_args = {
'auto': ['-Xclang', '-fcolor-diagnostics'],
@ -45,11 +43,6 @@ clang_optimization_args = {
class ClangCompiler(GnuLikeCompiler):
if T.TYPE_CHECKING:
linker = AppleDynamicLinker([], MachineChoice.HOST, '', [])
def get_pch_name(self, name: str) -> str: ...
def __init__(self, defines: T.Optional[T.Dict[str, str]]):
super().__init__()
self.id = 'clang'
@ -83,14 +76,11 @@ class ClangCompiler(GnuLikeCompiler):
# so it might change semantics at any time.
return ['-include-pch', os.path.join(pch_dir, self.get_pch_name(header))]
def has_multi_arguments(self, args: T.List[str], env: 'Environment') -> T.List[str]:
def has_multi_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]:
myargs = ['-Werror=unknown-warning-option', '-Werror=unused-command-line-argument']
if mesonlib.version_compare(self.version, '>=3.6.0'):
myargs.append('-Werror=ignored-optimization-argument')
# Mypy doesn't understand co-coperative inheritance
return super().has_multi_arguments( # type: ignore
myargs + args,
env)
return super().has_multi_arguments(myargs + args, env)
def has_function(self, funcname: str, prefix: str, env: 'Environment', *,
extra_args: T.Optional[T.List[str]] = None,
@ -104,10 +94,8 @@ class ClangCompiler(GnuLikeCompiler):
# TODO: this really should be communicated by the linker
if isinstance(self.linker, AppleDynamicLinker) and mesonlib.version_compare(self.version, '>=8.0'):
extra_args.append('-Wl,-no_weak_imports')
# Mypy doesn't understand co-coperative inheritance
ret = super().has_function(funcname, prefix, env, extra_args=extra_args, # type: ignore
return super().has_function(funcname, prefix, env, extra_args=extra_args,
dependencies=dependencies)
return T.cast(T.Tuple[bool, bool], ret)
def openmp_flags(self) -> T.List[str]:
if mesonlib.version_compare(self.version, '>=3.8.0'):

@ -40,10 +40,15 @@ from .. import compilers
from .visualstudio import VisualStudioLikeCompiler
if T.TYPE_CHECKING:
from ...coredata import CoreData
from ...dependencies import Dependency, ExternalProgram
from ...environment import Environment
from ...linkers import DynamicLinker
from ...compilers.compilers import Compiler
else:
# This is a bit clever, for mypy we pretend that these mixins descend from
# Compiler, so we get all of the methods and attributes defined for us, but
# for runtime we make them descend from object (which all classes normally
# do). This gives up DRYer type checking, with no runtime impact
Compiler = object
GROUP_FLAGS = re.compile(r'''\.so (?:\.[0-9]+)? (?:\.[0-9]+)? (?:\.[0-9]+)?$ |
^(?:-Wl,)?-l |
@ -115,46 +120,13 @@ class CLikeCompilerArgs(arglist.CompilerArgs):
return 'CLikeCompilerArgs({!r}, {!r})'.format(self.compiler, self._container)
class CLikeCompiler:
class CLikeCompiler(Compiler):
"""Shared bits for the C and CPP Compilers."""
if T.TYPE_CHECKING:
can_compile_suffixes = set() # type: T.Set[str]
exelist = [] # type: T.List[str]
for_machine = mesonlib.MachineChoice.HOST
id = ''
ignore_libs = () # type: T.Tuple[str, ...]
language = ''
linker = SolarisDynamicLinker([], mesonlib.MachineChoice.HOST, [], []) # type: DynamicLinker
warn_args = {} # type: T.Dict[str, T.List[str]]
@staticmethod
def attribute_check_func(name: str) -> str:...
def get_allow_undefined_link_args(self) -> T.List[str]: ...
def get_compiler_args_for_mode(self, mode: str) -> T.List[str]: ...
def get_display_language(self) -> str: ...
def get_largefile_args(self) -> T.List[str]: ...
def get_linker_always_args(self) -> T.List[str]: ...
def get_pch_suffix(self) -> str: ...
def get_id(self) -> str: ...
def name_string(self) -> str: ...
def remove_linkerlike_args(self, args: T.List[str]) -> T.List[str]: ...
@classmethod
def use_linker_args(cls, linker: str) -> T.List[str]: ...
@contextlib.contextmanager
def compile(self, code: 'mesonlib.FileOrString',
extra_args: T.Union[None, arglist.CompilerArgs, T.List[str]] = None,
*, mode: str = 'link', want_output: bool = False,
temp_dir: T.Optional[str] = None) -> T.Iterator[T.Optional[compilers.CompileResult]]: ...
@contextlib.contextmanager
def cached_compile(self, code: str, cdata: 'CoreData', *,
extra_args: T.Union[None, arglist.CompilerArgs, T.List[str]] = None,
mode: str = 'link',
temp_dir: T.Optional[str] = None) -> T.Iterator[T.Optional[compilers.CompileResult]]: ...
# TODO: Replace this manual cache with functools.lru_cache
find_library_cache = {} # type: T.Dict[T.Tuple[T.Tuple[str, ...], str, T.Tuple[str, ...], str, LibType], T.Optional[T.List[str]]]
find_framework_cache = {} # type: T.Dict[T.Tuple[T.Tuple[str, ...], str, T.Tuple[str, ...], bool], T.Optional[T.List[str]]]
@ -170,9 +142,9 @@ class CLikeCompiler:
else:
self.exe_wrapper = exe_wrapper.get_command()
def compiler_args(self, args: T.Optional[T.List[str]] = None) -> CLikeCompilerArgs:
def compiler_args(self, args: T.Optional[T.Iterable[str]] = None) -> CLikeCompilerArgs:
# This is correct, mypy just doesn't understand co-operative inheritance
return CLikeCompilerArgs(self, args) # type: ignore
return CLikeCompilerArgs(self, args)
def needs_static_linker(self) -> bool:
return True # When compiling static libraries, so yes.
@ -296,13 +268,16 @@ class CLikeCompiler:
return self._get_library_dirs(env, elf_class).copy()
@functools.lru_cache()
def get_program_dirs(self, env: 'Environment') -> T.List[str]:
def _get_program_dirs(self, env: 'Environment') -> T.List[str]:
'''
Programs used by the compiler. Also where toolchain DLLs such as
libstdc++-6.dll are found with MinGW.
'''
return self.get_compiler_dirs(env, 'programs')
def get_program_dirs(self, env: 'Environment') -> T.List[str]:
return self._get_program_dirs(env).copy()
def get_pic_args(self) -> T.List[str]:
return ['-fPIC']
@ -506,7 +481,7 @@ class CLikeCompiler:
return args
def compiles(self, code: str, env: 'Environment', *,
extra_args: T.Optional[T.List[str]] = None,
extra_args: T.Union[None, T.List[str], arglist.CompilerArgs] = None,
dependencies: T.Optional[T.List['Dependency']] = None,
mode: str = 'compile',
disable_cache: bool = False) -> T.Tuple[bool, bool]:
@ -529,7 +504,7 @@ class CLikeCompiler:
yield r
def links(self, code: str, env: 'Environment', *,
extra_args: T.Optional[T.List[str]] = None,
extra_args: T.Union[None, T.List[str], arglist.CompilerArgs] = None,
dependencies: T.Optional[T.List['Dependency']] = None,
mode: str = 'compile',
disable_cache: bool = False) -> T.Tuple[bool, bool]:

@ -20,6 +20,13 @@ import typing as T
if T.TYPE_CHECKING:
from ...environment import Environment
from ...compilers.compilers import Compiler
else:
# This is a bit clever, for mypy we pretend that these mixins descend from
# Compiler, so we get all of the methods and attributes defined for us, but
# for runtime we make them descend from object (which all classes normally
# do). This gives up DRYer type checking, with no runtime impact
Compiler = object
ccomp_buildtype_args = {
'plain': [''],
@ -51,10 +58,7 @@ ccomp_args_to_wul = [
r"^-r$"
] # type: T.List[str]
class CompCertCompiler:
if T.TYPE_CHECKING:
can_compile_suffixes = set() # type: T.Set[str]
class CompCertCompiler(Compiler):
def __init__(self) -> None:
self.id = 'ccomp'

@ -31,9 +31,6 @@ class ElbrusCompiler(GnuLikeCompiler):
# Elbrus compiler is nearly like GCC, but does not support
# PCH, LTO, sanitizers and color output as of version 1.21.x.
if T.TYPE_CHECKING:
exelist = [] # type: T.List[str]
def __init__(self) -> None:
super().__init__()
self.id = 'lcc'

@ -20,15 +20,17 @@ import typing as T
from ... import coredata
if T.TYPE_CHECKING:
from ...envconfig import MachineChoice
from ...environment import Environment
from ...compilers.compilers import Compiler
else:
# This is a bit clever, for mypy we pretend that these mixins descend from
# Compiler, so we get all of the methods and attributes defined for us, but
# for runtime we make them descend from object (which all classes normally
# do). This gives up DRYer type checking, with no runtime impact
Compiler = object
class EmscriptenMixin:
if T.TYPE_CHECKING:
for_machine = MachineChoice.HOST
language = ''
class EmscriptenMixin(Compiler):
def _get_compile_output(self, dirname: str, mode: str) -> str:
# In pre-processor mode, the output is sent to stdout and discarded
@ -54,9 +56,7 @@ class EmscriptenMixin:
return args
def get_options(self) -> 'coredata.OptionDictType':
# Mypy and co-operative inheritance
_opts = super().get_options() # type: ignore
opts = T.cast('coredata.OptionDictType', _opts)
opts = super().get_options()
opts.update({
'{}_thread_count'.format(self.language): coredata.UserIntegerOption(
'Number of threads to use in web assembly, set to 0 to disable',

@ -26,14 +26,14 @@ from ... import mesonlib
from ... import mlog
if T.TYPE_CHECKING:
import contextlib
from .. import compilers
from ... import arglist
from ...coredata import UserOption # noqa: F401
from ...dependency import Dependency
from ...envconfig import MachineInfo
from ...environment import Environment
from .clike import CLikeCompiler as Compiler
else:
# This is a bit clever, for mypy we pretend that these mixins descend from
# Compiler, so we get all of the methods and attributes defined for us, but
# for runtime we make them descend from object (which all classes normally
# do). This gives up DRYer type checking, with no runtime impact
Compiler = object
# XXX: prevent circular references.
# FIXME: this really is a posix interface not a c-like interface
@ -135,7 +135,7 @@ def gnulike_default_include_dirs(compiler: T.Tuple[str], lang: str) -> T.List[st
return paths
class GnuLikeCompiler(metaclass=abc.ABCMeta):
class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta):
"""
GnuLikeCompiler is a common interface to all compilers implementing
the GNU-style commandline interface. This includes GCC, Clang
@ -143,21 +143,6 @@ class GnuLikeCompiler(metaclass=abc.ABCMeta):
that the actual concrete subclass define their own implementation.
"""
if T.TYPE_CHECKING:
can_compile_suffixes = set() # type: T.Set[str]
exelist = [] # type: T.List[str]
info = MachineInfo('', '', '', '')
language = ''
version = ''
@contextlib.contextmanager
def _build_wrapper(self, code: str, env: 'Environment',
extra_args: T.Union[None, arglist.CompilerArgs, T.List[str]] = None,
dependencies: T.Optional[T.List['Dependency']] = None,
mode: str = 'compile', want_output: bool = False,
disable_cache: bool = False,
temp_dir: str = None) -> T.Iterator[T.Optional[compilers.CompileResult]]: ...
LINKER_PREFIX = '-Wl,'
def __init__(self) -> None:
@ -354,8 +339,7 @@ class GnuCompiler(GnuLikeCompiler):
def get_warn_args(self, level: str) -> T.List[str]:
# Mypy doesn't understand cooperative inheritance
_args = super().get_warn_args(level) # type: ignore
args = T.cast(T.List[str], _args)
args = super().get_warn_args(level)
if mesonlib.version_compare(self.version, '<4.8.0') and '-Wpedantic' in args:
# -Wpedantic was added in 4.8.0
# https://gcc.gnu.org/gcc-4.8/changes.html

@ -28,8 +28,6 @@ from .gnu import GnuLikeCompiler
from .visualstudio import VisualStudioLikeCompiler
if T.TYPE_CHECKING:
import subprocess # noqa: F401
from ...arglist import CompilerArgs
from ...dependencies import Dependency
from ...environment import Environment
@ -115,8 +113,7 @@ class IntelGnuLikeCompiler(GnuLikeCompiler):
'-diag-error', '10157', # Ignoring argument of the wrong type
'-diag-error', '10158', # Argument must be separate. Can be hit by trying an option like -foo-bar=foo when -foo=bar is a valid option but -foo-bar isn't
]
ret = super().compiles(code, env, extra_args=extra_args, dependencies=dependencies, mode=mode, disable_cache=disable_cache) # type: ignore
return T.cast(T.Tuple[bool, bool], ret)
return super().compiles(code, env, extra_args=extra_args, dependencies=dependencies, mode=mode, disable_cache=disable_cache)
def get_profile_generate_args(self) -> T.List[str]:
return ['-prof-gen=threadsafe']
@ -176,8 +173,7 @@ class IntelVisualStudioLikeCompiler(VisualStudioLikeCompiler):
'/Qdiag-error:10157', # Ignoring argument of the wrong type
'/Qdiag-error:10158', # Argument must be separate. Can be hit by trying an option like -foo-bar=foo when -foo=bar is a valid option but -foo-bar isn't
])
ret = super().compiles(code, env, extra_args=extra_args, dependencies=dependencies, mode=mode, disable_cache=disable_cache) # type: ignore
return T.cast(T.Tuple[bool, bool], ret)
return super().compiles(code, env, extra_args=extra_args, dependencies=dependencies, mode=mode, disable_cache=disable_cache)
def get_toolset_version(self) -> T.Optional[str]:
# Avoid circular dependencies....

@ -27,9 +27,16 @@ from ... import mesonlib
if T.TYPE_CHECKING:
from ...coredata import OptionDictType
from ...environment import Environment
from ...compilers.compilers import Compiler
else:
# This is a bit clever, for mypy we pretend that these mixins descend from
# Compiler, so we get all of the methods and attributes defined for us, but
# for runtime we make them descend from object (which all classes normally
# do). This gives up DRYer type checking, with no runtime impact
Compiler = object
class BasicLinkerIsCompilerMixin:
class BasicLinkerIsCompilerMixin(Compiler):
"""Provides a baseline of methods that a linker would implement.
@ -38,10 +45,6 @@ class BasicLinkerIsCompilerMixin:
functionality itself.
"""
if T.TYPE_CHECKING:
exelist = [] # type: T.List[str]
id = ''
def sanitizer_link_args(self, value: str) -> T.List[str]:
return []
@ -103,8 +106,8 @@ class BasicLinkerIsCompilerMixin:
def bitcode_args(self) -> T.List[str]:
raise mesonlib.MesonException("This linker doesn't support bitcode bundles")
def get_soname_args(self, for_machine: 'mesonlib.MachineChoice',
prefix: str, shlib_name: str, suffix: str, soversion: str,
def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
suffix: str, soversion: str,
darwin_versions: T.Tuple[str, str],
is_shared_module: bool) -> T.List[str]:
raise mesonlib.MesonException("This linker doesn't support soname args")

@ -21,8 +21,14 @@ from pathlib import Path
from ..compilers import clike_debug_args, clike_optimization_args
if T.TYPE_CHECKING:
from ...envconfig import MachineInfo
from ...environment import Environment
from ...compilers.compilers import Compiler
else:
# This is a bit clever, for mypy we pretend that these mixins descend from
# Compiler, so we get all of the methods and attributes defined for us, but
# for runtime we make them descend from object (which all classes normally
# do). This gives up DRYer type checking, with no runtime impact
Compiler = object
pgi_buildtype_args = {
'plain': [],
@ -34,11 +40,7 @@ pgi_buildtype_args = {
} # type: T.Dict[str, T.List[str]]
class PGICompiler:
if T.TYPE_CHECKING:
info = MachineInfo('', '', '', '')
language = ''
class PGICompiler(Compiler):
def __init__(self) -> None:
self.base_options = ['b_pch']

@ -20,18 +20,19 @@ import abc
import os
import typing as T
from ... import arglist
from ... import mesonlib
from ... import mlog
if T.TYPE_CHECKING:
from contextlib import contextmanager
from ...arglist import CompilerArgs
from ...compilers.compilers import CompileResult
from ...dependencies import Dependency
from ...envconfig import MachineChoice
from ...environment import Environment
from ...linkers import MSVCDynamicLinker
from .clike import CLikeCompiler as Compiler
else:
# This is a bit clever, for mypy we pretend that these mixins descend from
# Compiler, so we get all of the methods and attributes defined for us, but
# for runtime we make them descend from object (which all classes normally
# do). This gives up DRYer type checking, with no runtime impact
Compiler = object
vs32_instruction_set_args = {
'mmx': ['/arch:SSE'], # There does not seem to be a flag just for MMX
@ -92,7 +93,7 @@ msvc_debug_args = {
} # type: T.Dict[bool, T.List[str]]
class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
"""A common interface for all compilers implementing an MSVC-style
interface.
@ -102,24 +103,10 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
This class implements as much common logic as possible.
"""
if T.TYPE_CHECKING:
linker = MSVCDynamicLinker(MachineChoice.HOST, [])
version = ''
@contextmanager # yes, yes, it's a half truth.
def _build_wrapper(self, code: str, env: 'Environment',
extra_args: T.Union[None, 'CompilerArgs', T.List[str]] = None,
dependencies: T.Optional[T.List['Dependency']] = None,
mode: str = 'compile', want_output: bool = False,
disable_cache: bool = False,
temp_dir: str = None) -> T.Iterator[T.Optional[CompileResult]]: ...
std_warn_args = ['/W3']
std_opt_args = ['/O2']
# XXX: this is copied in this patch only to avoid circular dependencies
#ignore_libs = unixy_compiler_internal_libs
ignore_libs = ('m', 'c', 'pthread', 'dl', 'rt', 'execinfo')
internal_libs = ()
ignore_libs = arglist.UNIXY_COMPILER_INTERNAL_LIBS + ['execinfo']
internal_libs = [] # type: T.List[str]
crt_args = {
'none': [],
@ -156,6 +143,7 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta):
self.machine = 'arm'
else:
self.machine = target
assert self.linker is not None
self.linker.machine = self.machine
# Override CCompiler.get_always_args

@ -21,6 +21,13 @@ from ...mesonlib import EnvironmentException
if T.TYPE_CHECKING:
from ...environment import Environment
from ...compilers.compilers import Compiler
else:
# This is a bit clever, for mypy we pretend that these mixins descend from
# Compiler, so we get all of the methods and attributes defined for us, but
# for runtime we make them descend from object (which all classes normally
# do). This gives up DRYer type checking, with no runtime impact
Compiler = object
xc16_buildtype_args = {
'plain': [],
@ -46,11 +53,7 @@ xc16_debug_args = {
} # type: T.Dict[bool, T.List[str]]
class Xc16Compiler:
if T.TYPE_CHECKING:
can_compile_suffixes = set() # type: T.Set[str]
is_cross = True
class Xc16Compiler(Compiler):
def __init__(self) -> None:
if not self.is_cross:

@ -351,6 +351,7 @@ class DynamicLinker(LinkerEnvVarsMixin, metaclass=abc.ABCMeta):
self.version = version
self.prefix_arg = prefix_arg
self.always_args = always_args
self.machine = None # type: T.Optional[str]
def __repr__(self) -> str:
return '<{}: v{} `{}`>'.format(type(self).__name__, self.version, ' '.join(self.exelist))

Loading…
Cancel
Save