diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index b1a572fb3..12643b0a5 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.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())) diff --git a/mesonbuild/compilers/mixins/arm.py b/mesonbuild/compilers/mixins/arm.py index 142e692b1..25fb545c5 100644 --- a/mesonbuild/compilers/mixins/arm.py +++ b/mesonbuild/compilers/mixins/arm.py @@ -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: diff --git a/mesonbuild/compilers/mixins/c2000.py b/mesonbuild/compilers/mixins/c2000.py index eb66003aa..aca1ee8ef 100644 --- a/mesonbuild/compilers/mixins/c2000.py +++ b/mesonbuild/compilers/mixins/c2000.py @@ -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: diff --git a/mesonbuild/compilers/mixins/ccrx.py b/mesonbuild/compilers/mixins/ccrx.py index 4ac815a9d..fb8279791 100644 --- a/mesonbuild/compilers/mixins/ccrx.py +++ b/mesonbuild/compilers/mixins/ccrx.py @@ -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 diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py index 8d80751fb..8c8594454 100644 --- a/mesonbuild/compilers/mixins/clang.py +++ b/mesonbuild/compilers/mixins/clang.py @@ -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'): diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 3baef50cc..e146f5f62 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -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]: diff --git a/mesonbuild/compilers/mixins/compcert.py b/mesonbuild/compilers/mixins/compcert.py index fd144bea8..0f816a819 100644 --- a/mesonbuild/compilers/mixins/compcert.py +++ b/mesonbuild/compilers/mixins/compcert.py @@ -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' diff --git a/mesonbuild/compilers/mixins/elbrus.py b/mesonbuild/compilers/mixins/elbrus.py index 3a7437ce4..2ea359950 100644 --- a/mesonbuild/compilers/mixins/elbrus.py +++ b/mesonbuild/compilers/mixins/elbrus.py @@ -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' diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py index f15db40bf..87bc40c87 100644 --- a/mesonbuild/compilers/mixins/emscripten.py +++ b/mesonbuild/compilers/mixins/emscripten.py @@ -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', diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py index f7b24c8c2..9c60fcbd9 100644 --- a/mesonbuild/compilers/mixins/gnu.py +++ b/mesonbuild/compilers/mixins/gnu.py @@ -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 diff --git a/mesonbuild/compilers/mixins/intel.py b/mesonbuild/compilers/mixins/intel.py index cbbfc7a73..b83e5c484 100644 --- a/mesonbuild/compilers/mixins/intel.py +++ b/mesonbuild/compilers/mixins/intel.py @@ -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.... diff --git a/mesonbuild/compilers/mixins/islinker.py b/mesonbuild/compilers/mixins/islinker.py index 6fc8c4eb7..ce7a8af47 100644 --- a/mesonbuild/compilers/mixins/islinker.py +++ b/mesonbuild/compilers/mixins/islinker.py @@ -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") diff --git a/mesonbuild/compilers/mixins/pgi.py b/mesonbuild/compilers/mixins/pgi.py index d69abdad9..f6ad279f9 100644 --- a/mesonbuild/compilers/mixins/pgi.py +++ b/mesonbuild/compilers/mixins/pgi.py @@ -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'] diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py index 06866783f..d9abb9540 100644 --- a/mesonbuild/compilers/mixins/visualstudio.py +++ b/mesonbuild/compilers/mixins/visualstudio.py @@ -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 diff --git a/mesonbuild/compilers/mixins/xc16.py b/mesonbuild/compilers/mixins/xc16.py index ed9be1502..edc5f2ca1 100644 --- a/mesonbuild/compilers/mixins/xc16.py +++ b/mesonbuild/compilers/mixins/xc16.py @@ -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: diff --git a/mesonbuild/linkers.py b/mesonbuild/linkers.py index d85c88e79..ed28fa3cf 100644 --- a/mesonbuild/linkers.py +++ b/mesonbuild/linkers.py @@ -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))