diff options
23 files changed, 494 insertions, 463 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index f211f16..1786fef 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -2797,7 +2797,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) else: return compiler.get_compile_debugfile_args(objfile, pch=False) - def get_link_debugfile_name(self, linker, target, outname): + def get_link_debugfile_name(self, linker, target, outname) -> T.Optional[str]: return linker.get_link_debugfile_name(outname) def get_link_debugfile_args(self, linker, target, outname): diff --git a/mesonbuild/compilers/asm.py b/mesonbuild/compilers/asm.py index e34b4a6..f25473b 100644 --- a/mesonbuild/compilers/asm.py +++ b/mesonbuild/compilers/asm.py @@ -11,7 +11,7 @@ if T.TYPE_CHECKING: from ..mesonlib import MachineChoice from ..envconfig import MachineInfo -nasm_optimization_args = { +nasm_optimization_args: T.Dict[str, T.List[str]] = { 'plain': [], '0': ['-O0'], 'g': ['-O0'], @@ -19,7 +19,7 @@ nasm_optimization_args = { '2': ['-Ox'], '3': ['-Ox'], 's': ['-Ox'], -} # type: T.Dict[str, T.List[str]] +} class NasmCompiler(Compiler): @@ -69,7 +69,7 @@ class NasmCompiler(Compiler): return ['-o', outputname] def unix_args_to_native(self, args: T.List[str]) -> T.List[str]: - outargs = [] + outargs: T.List[str] = [] for arg in args: if arg == '-pthread': continue @@ -295,7 +295,12 @@ class MetrowerksAsmCompiler(MetrowerksCompiler, Compiler): Compiler.__init__(self, ccache, exelist, version, for_machine, info, linker, full_version, is_cross) MetrowerksCompiler.__init__(self) - self.warn_args = {'0': [], '1': [], '2': [], '3': [], 'everything': []} # type: T.Dict[str, T.List[str]] + self.warn_args: T.Dict[str, T.List[str]] = { + '0': [], + '1': [], + '2': [], + '3': [], + 'everything': []} self.can_compile_suffixes.add('s') def get_crt_compile_args(self, crt_val: str, buildtype: str) -> T.List[str]: diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index dda0f38..cb8eae5 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -92,12 +92,12 @@ clib_langs = ('objcpp', 'cpp', 'objc', 'c', 'nasm', 'fortran') clink_langs = ('d', 'cuda') + clib_langs SUFFIX_TO_LANG = dict(itertools.chain(*( - [(suffix, lang) for suffix in v] for lang, v in lang_suffixes.items()))) # type: T.Dict[str, str] + [(suffix, lang) for suffix in v] for lang, v in lang_suffixes.items()))) # Languages that should use LDFLAGS arguments when linking. -LANGUAGES_USING_LDFLAGS = {'objcpp', 'cpp', 'objc', 'c', 'fortran', 'd', 'cuda'} # type: T.Set[str] +LANGUAGES_USING_LDFLAGS = {'objcpp', 'cpp', 'objc', 'c', 'fortran', 'd', 'cuda'} # Languages that should use CPPFLAGS arguments when linking. -LANGUAGES_USING_CPPFLAGS = {'c', 'cpp', 'objc', 'objcpp'} # type: T.Set[str] +LANGUAGES_USING_CPPFLAGS = {'c', 'cpp', 'objc', 'objcpp'} soregex = re.compile(r'.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$') # Environment variables that each lang uses. @@ -190,99 +190,114 @@ class CompileCheckMode(enum.Enum): LINK = 'link' -cuda_buildtype_args = {'plain': [], - 'debug': ['-g', '-G'], - 'debugoptimized': ['-g', '-lineinfo'], - 'release': [], - 'minsize': [], - 'custom': [], - } # type: T.Dict[str, T.List[str]] -java_buildtype_args = {'plain': [], - 'debug': ['-g'], - 'debugoptimized': ['-g'], - 'release': [], - 'minsize': [], - 'custom': [], - } # type: T.Dict[str, T.List[str]] - -rust_buildtype_args = {'plain': [], - 'debug': [], - 'debugoptimized': [], - 'release': [], - 'minsize': [], - 'custom': [], - } # type: T.Dict[str, T.List[str]] - -d_gdc_buildtype_args = {'plain': [], - 'debug': [], - 'debugoptimized': ['-finline-functions'], - 'release': ['-finline-functions'], - 'minsize': [], - 'custom': [], - } # type: T.Dict[str, T.List[str]] - -d_ldc_buildtype_args = {'plain': [], - 'debug': [], - 'debugoptimized': ['-enable-inlining', '-Hkeep-all-bodies'], - 'release': ['-enable-inlining', '-Hkeep-all-bodies'], - 'minsize': [], - 'custom': [], - } # type: T.Dict[str, T.List[str]] - -d_dmd_buildtype_args = {'plain': [], - 'debug': [], - 'debugoptimized': ['-inline'], - 'release': ['-inline'], - 'minsize': [], - 'custom': [], - } # type: T.Dict[str, T.List[str]] - -mono_buildtype_args = {'plain': [], - 'debug': [], - 'debugoptimized': ['-optimize+'], - 'release': ['-optimize+'], - 'minsize': [], - 'custom': [], - } # type: T.Dict[str, T.List[str]] - -swift_buildtype_args = {'plain': [], - 'debug': [], - 'debugoptimized': [], - 'release': [], - 'minsize': [], - 'custom': [], - } # type: T.Dict[str, T.List[str]] +cuda_buildtype_args: T.Dict[str, T.List[str]] = { + 'plain': [], + 'debug': ['-g', '-G'], + 'debugoptimized': ['-g', '-lineinfo'], + 'release': [], + 'minsize': [], + 'custom': [], +} + +java_buildtype_args: T.Dict[str, T.List[str]] = { + 'plain': [], + 'debug': ['-g'], + 'debugoptimized': ['-g'], + 'release': [], + 'minsize': [], + 'custom': [], +} + +rust_buildtype_args: T.Dict[str, T.List[str]] = { + 'plain': [], + 'debug': [], + 'debugoptimized': [], + 'release': [], + 'minsize': [], + 'custom': [], +} + +d_gdc_buildtype_args: T.Dict[str, T.List[str]] = { + 'plain': [], + 'debug': [], + 'debugoptimized': ['-finline-functions'], + 'release': ['-finline-functions'], + 'minsize': [], + 'custom': [], +} + +d_ldc_buildtype_args: T.Dict[str, T.List[str]] = { + 'plain': [], + 'debug': [], + 'debugoptimized': ['-enable-inlining', '-Hkeep-all-bodies'], + 'release': ['-enable-inlining', '-Hkeep-all-bodies'], + 'minsize': [], + 'custom': [], +} + +d_dmd_buildtype_args: T.Dict[str, T.List[str]] = { + 'plain': [], + 'debug': [], + 'debugoptimized': ['-inline'], + 'release': ['-inline'], + 'minsize': [], + 'custom': [], +} + +mono_buildtype_args: T.Dict[str, T.List[str]] = { + 'plain': [], + 'debug': [], + 'debugoptimized': ['-optimize+'], + 'release': ['-optimize+'], + 'minsize': [], + 'custom': [], +} + +swift_buildtype_args: T.Dict[str, T.List[str]] = { + 'plain': [], + 'debug': [], + 'debugoptimized': [], + 'release': [], + 'minsize': [], + 'custom': [], +} gnu_winlibs = ['-lkernel32', '-luser32', '-lgdi32', '-lwinspool', '-lshell32', - '-lole32', '-loleaut32', '-luuid', '-lcomdlg32', '-ladvapi32'] # type: T.List[str] + '-lole32', '-loleaut32', '-luuid', '-lcomdlg32', '-ladvapi32'] msvc_winlibs = ['kernel32.lib', 'user32.lib', 'gdi32.lib', 'winspool.lib', 'shell32.lib', 'ole32.lib', 'oleaut32.lib', - 'uuid.lib', 'comdlg32.lib', 'advapi32.lib'] # type: T.List[str] - -clike_optimization_args = {'plain': [], - '0': [], - 'g': [], - '1': ['-O1'], - '2': ['-O2'], - '3': ['-O3'], - 's': ['-Os'], - } # type: T.Dict[str, T.List[str]] - -cuda_optimization_args = {'plain': [], - '0': [], - 'g': ['-O0'], - '1': ['-O1'], - '2': ['-O2'], - '3': ['-O3'], - 's': ['-O3'] - } # type: T.Dict[str, T.List[str]] - -cuda_debug_args = {False: [], - True: ['-g']} # type: T.Dict[bool, T.List[str]] - -clike_debug_args = {False: [], - True: ['-g']} # type: T.Dict[bool, T.List[str]] + 'uuid.lib', 'comdlg32.lib', 'advapi32.lib'] + +clike_optimization_args: T.Dict[str, T.List[str]] = { + 'plain': [], + '0': [], + 'g': [], + '1': ['-O1'], + '2': ['-O2'], + '3': ['-O3'], + 's': ['-Os'], +} + +cuda_optimization_args: T.Dict[str, T.List[str]] = { + 'plain': [], + '0': [], + 'g': ['-O0'], + '1': ['-O1'], + '2': ['-O2'], + '3': ['-O3'], + 's': ['-O3'] +} + +cuda_debug_args: T.Dict[bool, T.List[str]] = { + False: [], + True: ['-g'] +} + +clike_debug_args: T.Dict[bool, T.List[str]] = { + False: [], + True: ['-g'] +} base_options: 'KeyedOptionDictType' = { OptionKey('b_pch'): coredata.UserBooleanOption('Use precompiled headers', True), @@ -350,7 +365,7 @@ def are_asserts_disabled(options: KeyedOptionDictType) -> bool: def get_base_compile_args(options: 'KeyedOptionDictType', compiler: 'Compiler') -> T.List[str]: - args = [] # type T.List[str] + args: T.List[str] = [] try: if options[OptionKey('b_lto')].value: args.extend(compiler.get_lto_compile_args( @@ -399,7 +414,7 @@ def get_base_compile_args(options: 'KeyedOptionDictType', compiler: 'Compiler') def get_base_link_args(options: 'KeyedOptionDictType', linker: 'Compiler', is_shared_module: bool, build_dir: str) -> T.List[str]: - args = [] # type: T.List[str] + args: T.List[str] = [] try: if options[OptionKey('b_lto')].value: thinlto_cache_dir = None @@ -499,18 +514,18 @@ class CompileResult(HoldableObject): class Compiler(HoldableObject, 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.List[str] + ignore_libs: T.List[str] = [] # Libraries that are internal compiler implementations, and must not be # manually searched. - internal_libs = [] # type: T.List[str] + internal_libs: T.List[str] = [] - LINKER_PREFIX = None # type: T.Union[None, str, T.List[str]] + LINKER_PREFIX: T.Union[None, str, T.List[str]] = None INVOKES_LINKER = True language: str id: str warn_args: T.Dict[str, T.List[str]] - mode: str = 'COMPILER' + mode = CompileCheckMode.COMPILE def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, info: 'MachineInfo', @@ -522,7 +537,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta): if not hasattr(self, 'file_suffixes'): self.file_suffixes = lang_suffixes[self.language] if not hasattr(self, 'can_compile_suffixes'): - self.can_compile_suffixes = set(self.file_suffixes) + self.can_compile_suffixes: T.Set[str] = set(self.file_suffixes) self.default_suffix = self.file_suffixes[0] self.version = version self.full_version = full_version @@ -784,22 +799,18 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta): def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: return self.linker.has_multi_arguments(args, env) - def _get_compile_output(self, dirname: str, mode: str) -> str: - # TODO: mode should really be an enum - # In pre-processor mode, the output is sent to stdout and discarded - if mode == 'preprocess': - return None + def _get_compile_output(self, dirname: str, mode: CompileCheckMode) -> str: + assert mode != CompileCheckMode.PREPROCESS, 'In pre-processor mode, the output is sent to stdout and discarded' # Extension only matters if running results; '.exe' is # guaranteed to be executable on every platform. - if mode == 'link': + if mode == CompileCheckMode.LINK: suffix = 'exe' else: suffix = 'obj' return os.path.join(dirname, 'output.' + suffix) def get_compiler_args_for_mode(self, mode: CompileCheckMode) -> T.List[str]: - # TODO: mode should really be an enum - args = [] # type: T.List[str] + args: T.List[str] = [] args += self.get_always_args() if mode is CompileCheckMode.COMPILE: args += self.get_compile_only_args() @@ -816,9 +827,13 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta): @contextlib.contextmanager def compile(self, code: 'mesonlib.FileOrString', extra_args: T.Union[None, CompilerArgs, T.List[str]] = None, - *, mode: str = 'link', want_output: bool = False, + *, mode: CompileCheckMode = CompileCheckMode.LINK, want_output: bool = False, temp_dir: T.Optional[str] = None) -> T.Iterator[T.Optional[CompileResult]]: # TODO: there isn't really any reason for this to be a contextmanager + + if mode == CompileCheckMode.PREPROCESS: + assert not want_output, 'In pre-processor mode, the output is sent to stdout and discarded' + if extra_args is None: extra_args = [] @@ -845,8 +860,8 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta): commands.append(srcname) # Preprocess mode outputs to stdout, so no output args - output = self._get_compile_output(tmpdirname, mode) - if mode != 'preprocess': + if mode != CompileCheckMode.PREPROCESS: + output = self._get_compile_output(tmpdirname, mode) commands += self.get_output_args(output) commands.extend(self.get_compiler_args_for_mode(CompileCheckMode(mode))) @@ -874,13 +889,13 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta): @contextlib.contextmanager def cached_compile(self, code: 'mesonlib.FileOrString', cdata: coredata.CoreData, *, extra_args: T.Union[None, T.List[str], CompilerArgs] = None, - mode: str = 'link', + mode: CompileCheckMode = CompileCheckMode.LINK, temp_dir: T.Optional[str] = None) -> T.Iterator[T.Optional[CompileResult]]: # TODO: There's isn't really any reason for this to be a context manager # Calculate the key - textra_args = tuple(extra_args) if extra_args is not None else tuple() # type: T.Tuple[str, ...] - key = (tuple(self.exelist), self.version, code, textra_args, mode) # type: coredata.CompilerCheckCacheKey + textra_args: T.Tuple[str, ...] = tuple(extra_args) if extra_args is not None else tuple() + key: coredata.CompilerCheckCacheKey = (tuple(self.exelist), self.version, code, textra_args, mode) # Check if not cached, and generate, otherwise get from the cache if key in cdata.compiler_check_cache: @@ -906,7 +921,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta): def get_compile_debugfile_args(self, rel_obj: str, pch: bool = False) -> T.List[str]: return [] - def get_link_debugfile_name(self, targetfile: str) -> str: + def get_link_debugfile_name(self, targetfile: str) -> T.Optional[str]: return self.linker.get_debugfile_name(targetfile) def get_link_debugfile_args(self, targetfile: str) -> T.List[str]: @@ -1013,7 +1028,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta): rm_exact = ('-headerpad_max_install_names',) rm_prefixes = ('-Wl,', '-L',) rm_next = ('-L', '-framework',) - ret = [] # T.List[str] + ret: T.List[str] = [] iargs = iter(args) for arg in iargs: # Remove this argument @@ -1283,15 +1298,14 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta): def _build_wrapper(self, code: 'mesonlib.FileOrString', env: 'Environment', extra_args: T.Union[None, CompilerArgs, T.List[str], T.Callable[[CompileCheckMode], 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]]: + mode: CompileCheckMode = CompileCheckMode.COMPILE, want_output: bool = False, + disable_cache: bool = False) -> T.Iterator[T.Optional[CompileResult]]: """Helper for getting a cached value when possible. This method isn't meant to be called externally, it's mean to be wrapped by other methods like compiles() and links(). """ - args = self.build_wrapper_args(env, extra_args, dependencies, CompileCheckMode(mode)) + args = self.build_wrapper_args(env, extra_args, dependencies, mode) if disable_cache or want_output: with self.compile(code, extra_args=args, mode=mode, want_output=want_output, temp_dir=env.scratch_dir) as r: yield r @@ -1302,7 +1316,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta): def compiles(self, code: 'mesonlib.FileOrString', env: 'Environment', *, extra_args: T.Union[None, T.List[str], CompilerArgs, T.Callable[[CompileCheckMode], T.List[str]]] = None, dependencies: T.Optional[T.List['Dependency']] = None, - mode: str = 'compile', + mode: CompileCheckMode = CompileCheckMode.COMPILE, disable_cache: bool = False) -> T.Tuple[bool, bool]: with self._build_wrapper(code, env, extra_args, dependencies, mode, disable_cache=disable_cache) as p: return p.returncode == 0, p.cached @@ -1311,16 +1325,15 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta): compiler: T.Optional['Compiler'] = None, extra_args: T.Union[None, T.List[str], CompilerArgs, T.Callable[[CompileCheckMode], T.List[str]]] = None, dependencies: T.Optional[T.List['Dependency']] = None, - mode: str = 'compile', disable_cache: bool = False) -> T.Tuple[bool, bool]: if compiler: with compiler._build_wrapper(code, env, dependencies=dependencies, want_output=True) as r: objfile = mesonlib.File.from_absolute_file(r.output_name) return self.compiles(objfile, env, extra_args=extra_args, - dependencies=dependencies, mode='link', disable_cache=True) + dependencies=dependencies, mode=CompileCheckMode.LINK, disable_cache=True) return self.compiles(code, env, extra_args=extra_args, - dependencies=dependencies, mode='link', disable_cache=disable_cache) + dependencies=dependencies, mode=CompileCheckMode.LINK, disable_cache=disable_cache) def get_feature_args(self, kwargs: T.Dict[str, T.Any], build_to_src: str) -> T.List[str]: """Used by D for extra language features.""" diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 0c68923..7e8c327 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -26,6 +26,7 @@ from .compilers import ( gnu_winlibs, msvc_winlibs, Compiler, + CompileCheckMode, ) from .c_function_attributes import CXX_FUNC_ATTRIBUTES, C_FUNC_ATTRIBUTES from .mixins.clike import CLikeCompiler @@ -43,7 +44,6 @@ from .mixins.metrowerks import MetrowerksCompiler from .mixins.metrowerks import mwccarm_instruction_set_args, mwcceppc_instruction_set_args if T.TYPE_CHECKING: - from .compilers import CompileCheckMode from ..coredata import MutableKeyedOptionDictType, KeyedOptionDictType from ..dependencies import Dependency from ..envconfig import MachineInfo @@ -82,8 +82,8 @@ class CPPCompiler(CLikeCompiler, Compiler): full_version=full_version) CLikeCompiler.__init__(self, exe_wrapper) - @staticmethod - def get_display_language() -> str: + @classmethod + def get_display_language(cls) -> str: return 'C++' def get_no_stdinc_args(self) -> T.List[str]: @@ -129,7 +129,7 @@ class CPPCompiler(CLikeCompiler, Compiler): # 2. even if it did have an env object, that might contain another more # recent -std= argument, which might lead to a cascaded failure. CPP_TEST = 'int i = static_cast<int>(0);' - with self.compile(CPP_TEST, extra_args=[cpp_std_value], mode='compile') as p: + with self.compile(CPP_TEST, extra_args=[cpp_std_value], mode=CompileCheckMode.COMPILE) as p: if p.returncode == 0: mlog.debug(f'Compiler accepts {cpp_std_value}:', 'YES') return True @@ -263,7 +263,7 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCompiler, CPPCompiler): return opts def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] key = OptionKey('std', machine=self.for_machine, lang=self.language) std = options[key] if std.value != 'none': @@ -315,7 +315,7 @@ class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler): defines=defines, full_version=full_version) def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] key = OptionKey('std', machine=self.for_machine, lang=self.language) std = options[key] if std.value != 'none': @@ -359,7 +359,7 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler): return opts def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] key = OptionKey('std', machine=self.for_machine, lang=self.language) std = options[key] if std.value != 'none': @@ -425,7 +425,7 @@ class GnuCPPCompiler(_StdCPPLibMixin, GnuCompiler, CPPCompiler): return opts def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] key = OptionKey('std', machine=self.for_machine, lang=self.language) std = options[key] if std.value != 'none': @@ -536,7 +536,7 @@ class ElbrusCPPCompiler(ElbrusCompiler, CPPCompiler): # Elbrus C++ compiler does not support RTTI, so don't check for it. def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] key = OptionKey('std', machine=self.for_machine, lang=self.language) std = options[key] if std.value != 'none': @@ -597,7 +597,7 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler): return opts def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] key = OptionKey('std', machine=self.for_machine, lang=self.language) std = options[key] if std.value != 'none': @@ -664,7 +664,7 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase): return opts def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] key = OptionKey('std', machine=self.for_machine, lang=self.language) eh = options[key.evolve('eh')] @@ -829,7 +829,7 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler): return opts def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] key = OptionKey('std', machine=self.for_machine, lang=self.language) std = options[key] if std.value == 'c++11': @@ -864,8 +864,8 @@ class CcrxCPPCompiler(CcrxCompiler, CPPCompiler): def get_compile_only_args(self) -> T.List[str]: return [] - def get_output_args(self, target: str) -> T.List[str]: - return [f'-output=obj={target}'] + def get_output_args(self, outputname: str) -> T.List[str]: + return [f'-output=obj={outputname}'] def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: return [] @@ -889,7 +889,7 @@ class TICPPCompiler(TICompiler, CPPCompiler): return opts def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] key = OptionKey('std', machine=self.for_machine, lang=self.language) std = options[key] if std.value != 'none': @@ -928,7 +928,7 @@ class MetrowerksCPPCompilerARM(MetrowerksCompiler, CPPCompiler): return opts def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] std = options[OptionKey('std', machine=self.for_machine, lang=self.language)] if std.value != 'none': args.append('-lang') @@ -957,7 +957,7 @@ class MetrowerksCPPCompilerEmbeddedPowerPC(MetrowerksCompiler, CPPCompiler): return opts def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] std = options[OptionKey('std', machine=self.for_machine, lang=self.language)] if std.value != 'none': args.append('-lang ' + std.value) diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index c6e70b2..08ebb75 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -50,40 +50,46 @@ if T.TYPE_CHECKING: else: CompilerMixinBase = object -d_feature_args = {'gcc': {'unittest': '-funittest', - 'debug': '-fdebug', - 'version': '-fversion', - 'import_dir': '-J' - }, - 'llvm': {'unittest': '-unittest', - 'debug': '-d-debug', - 'version': '-d-version', - 'import_dir': '-J' - }, - 'dmd': {'unittest': '-unittest', - 'debug': '-debug', - 'version': '-version', - 'import_dir': '-J' - } - } # type: T.Dict[str, T.Dict[str, str]] - -ldc_optimization_args = {'plain': [], - '0': [], - 'g': [], - '1': ['-O1'], - '2': ['-O2'], - '3': ['-O3'], - 's': ['-Oz'], - } # type: T.Dict[str, T.List[str]] - -dmd_optimization_args = {'plain': [], - '0': [], - 'g': [], - '1': ['-O'], - '2': ['-O'], - '3': ['-O'], - 's': ['-O'], - } # type: T.Dict[str, T.List[str]] +d_feature_args: T.Dict[str, T.Dict[str, str]] = { + 'gcc': { + 'unittest': '-funittest', + 'debug': '-fdebug', + 'version': '-fversion', + 'import_dir': '-J' + }, + 'llvm': { + 'unittest': '-unittest', + 'debug': '-d-debug', + 'version': '-d-version', + 'import_dir': '-J' + }, + 'dmd': { + 'unittest': '-unittest', + 'debug': '-debug', + 'version': '-version', + 'import_dir': '-J' + } +} + +ldc_optimization_args: T.Dict[str, T.List[str]] = { + 'plain': [], + '0': [], + 'g': [], + '1': ['-O1'], + '2': ['-O2'], + '3': ['-O3'], + 's': ['-Oz'], +} + +dmd_optimization_args: T.Dict[str, T.List[str]] = { + 'plain': [], + '0': [], + 'g': [], + '1': ['-O'], + '2': ['-O'], + '3': ['-O'], + 's': ['-O'], +} class DmdLikeCompilerMixin(CompilerMixinBase): @@ -102,7 +108,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase): self._dmd_has_depfile = version_compare(dmd_frontend_version, ">=2.095.0") if T.TYPE_CHECKING: - mscrt_args = {} # type: T.Dict[str, T.List[str]] + mscrt_args: T.Dict[str, T.List[str]] = {} def _get_target_arch_args(self) -> T.List[str]: ... @@ -166,7 +172,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase): def get_feature_args(self, kwargs: T.Dict[str, T.Any], build_to_src: str) -> T.List[str]: # TODO: using a TypeDict here would improve this - res = [] + res: T.List[str] = [] # get_feature_args can be called multiple times for the same target when there is generated source # so we have to copy the kwargs (target.d_features) dict before popping from it kwargs = kwargs.copy() @@ -271,7 +277,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase): # The way that dmd and ldc pass rpath to gcc is different than we would # do directly, each argument -rpath and the value to rpath, need to be # split into two separate arguments both prefaced with the -L=. - args = [] + args: T.List[str] = [] (rpath_args, rpath_dirs_to_remove) = super().build_rpath_args( env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath) for r in rpath_args: @@ -292,7 +298,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase): # can understand. # The flags might have been added by pkg-config files, # and are therefore out of the user's control. - dcargs = [] + dcargs: T.List[str] = [] # whether we hit a linker argument that expect another arg # see the comment in the "-L" section link_expect_arg = False @@ -301,7 +307,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase): ] for arg in args: # Translate OS specific arguments first. - osargs = [] # type: T.List[str] + osargs: T.List[str] = [] if info.is_windows(): osargs = cls.translate_arg_to_windows(arg) elif info.is_darwin(): @@ -415,7 +421,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase): @classmethod def translate_arg_to_windows(cls, arg: str) -> T.List[str]: - args = [] + args: T.List[str] = [] if arg.startswith('-Wl,'): # Translate linker arguments here. linkargs = arg[arg.index(',') + 1:].split(',') @@ -441,7 +447,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase): @classmethod def _translate_arg_to_osx(cls, arg: str) -> T.List[str]: - args = [] + args: T.List[str] = [] if arg.startswith('-install_name'): args.append('-L=' + arg) return args @@ -494,15 +500,14 @@ class DmdLikeCompilerMixin(CompilerMixinBase): # LDC and DMD actually do use a linker, but they proxy all of that with # their own arguments + soargs: T.List[str] = [] if self.linker.id.startswith('ld.'): - soargs = [] for arg in sargs: a, b = arg.split(',', maxsplit=1) soargs.append(a) soargs.append(self.LINKER_PREFIX + b) return soargs elif self.linker.id.startswith('ld64'): - soargs = [] for arg in sargs: if not arg.startswith(self.LINKER_PREFIX): soargs.append(self.LINKER_PREFIX + arg) @@ -583,7 +588,7 @@ class DCompiler(Compiler): def get_feature_args(self, kwargs: T.Dict[str, T.Any], build_to_src: str) -> T.List[str]: # TODO: using a TypeDict here would improve this - res = [] + res: T.List[str] = [] # get_feature_args can be called multiple times for the same target when there is generated source # so we have to copy the kwargs (target.d_features) dict before popping from it kwargs = kwargs.copy() @@ -713,7 +718,7 @@ class DCompiler(Compiler): if need_exe_wrapper and self.exe_wrapper is None: raise compilers.CrossNoRunException('Can not run test applications in this cross environment.') extra_args = self._get_compile_extra_args(extra_args) - with self._build_wrapper(code, env, extra_args, dependencies, mode='link', want_output=True) as p: + with self._build_wrapper(code, env, extra_args, dependencies, mode=CompileCheckMode.LINK, want_output=True) as p: if p.returncode != 0: mlog.debug(f'Could not compile test file {p.input_name}: {p.returncode}\n') return compilers.RunResult(False) @@ -786,7 +791,7 @@ class DCompiler(Compiler): import {hname}; ''' return self.compiles(code, env, extra_args=extra_args, - dependencies=dependencies, mode='compile', disable_cache=disable_cache) + dependencies=dependencies, mode=CompileCheckMode.COMPILE, disable_cache=disable_cache) class GnuDCompiler(GnuCompiler, DCompiler): diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index 7c836b7..a80fdff 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -20,6 +20,7 @@ from .. import coredata from .compilers import ( clike_debug_args, Compiler, + CompileCheckMode, ) from .mixins.clike import CLikeCompiler from .mixins.gnu import ( @@ -43,7 +44,6 @@ if T.TYPE_CHECKING: from ..linkers.linkers import DynamicLinker from ..mesonlib import MachineChoice from ..programs import ExternalProgram - from .compilers import CompileCheckMode class FortranCompiler(CLikeCompiler, Compiler): @@ -170,7 +170,7 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler): return opts def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] key = OptionKey('std', machine=self.for_machine, lang=self.language) std = options[key] if std.value != 'none': @@ -207,7 +207,7 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler): ''' code = f'{prefix}\n#include <{hname}>' return self.compiles(code, env, extra_args=extra_args, - dependencies=dependencies, mode='preprocess', disable_cache=disable_cache) + dependencies=dependencies, mode=CompileCheckMode.PREPROCESS, disable_cache=disable_cache) class ElbrusFortranCompiler(ElbrusCompiler, FortranCompiler): @@ -311,7 +311,7 @@ class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler): return opts def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] key = OptionKey('std', machine=self.for_machine, lang=self.language) std = options[key] stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} @@ -364,7 +364,7 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler): return opts def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] key = OptionKey('std', machine=self.for_machine, lang=self.language) std = options[key] stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} diff --git a/mesonbuild/compilers/mixins/ccrx.py b/mesonbuild/compilers/mixins/ccrx.py index 1c22214..71c1033 100644 --- a/mesonbuild/compilers/mixins/ccrx.py +++ b/mesonbuild/compilers/mixins/ccrx.py @@ -31,35 +31,35 @@ else: # do). This gives up DRYer type checking, with no runtime impact Compiler = object -ccrx_buildtype_args = { +ccrx_buildtype_args: T.Dict[str, T.List[str]] = { 'plain': [], 'debug': [], 'debugoptimized': [], 'release': [], 'minsize': [], 'custom': [], -} # type: T.Dict[str, T.List[str]] +} -ccrx_optimization_args = { +ccrx_optimization_args: T.Dict[str, T.List[str]] = { '0': ['-optimize=0'], 'g': ['-optimize=0'], '1': ['-optimize=1'], '2': ['-optimize=2'], '3': ['-optimize=max'], 's': ['-optimize=2', '-size'] -} # type: T.Dict[str, T.List[str]] +} -ccrx_debug_args = { +ccrx_debug_args: T.Dict[bool, T.List[str]] = { False: [], True: ['-debug'] -} # type: T.Dict[bool, T.List[str]] +} class CcrxCompiler(Compiler): if T.TYPE_CHECKING: is_cross = True - can_compile_suffixes = set() # type: T.Set[str] + can_compile_suffixes: T.Set[str] = set() id = 'ccrx' @@ -68,12 +68,13 @@ class CcrxCompiler(Compiler): raise EnvironmentException('ccrx supports only cross-compilation.') # Assembly self.can_compile_suffixes.add('src') - default_warn_args = [] # type: T.List[str] - self.warn_args = {'0': [], - '1': default_warn_args, - '2': default_warn_args + [], - '3': default_warn_args + [], - 'everything': default_warn_args + []} # type: T.Dict[str, T.List[str]] + default_warn_args: T.List[str] = [] + self.warn_args: T.Dict[str, T.List[str]] = { + '0': [], + '1': default_warn_args, + '2': default_warn_args + [], + '3': default_warn_args + [], + 'everything': default_warn_args + []} def get_pic_args(self) -> T.List[str]: # PIC support is not enabled by default for CCRX, @@ -109,7 +110,7 @@ class CcrxCompiler(Compiler): @classmethod def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]: - result = [] + result: T.List[str] = [] for i in args: if i.startswith('-D'): i = '-define=' + i[2:] diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py index b43b246..24f24a8 100644 --- a/mesonbuild/compilers/mixins/clang.py +++ b/mesonbuild/compilers/mixins/clang.py @@ -30,13 +30,13 @@ if T.TYPE_CHECKING: from ...environment import Environment from ...dependencies import Dependency # noqa: F401 -clang_color_args = { +clang_color_args: T.Dict[str, T.List[str]] = { 'auto': ['-fcolor-diagnostics'], 'always': ['-fcolor-diagnostics'], 'never': ['-fno-color-diagnostics'], -} # type: T.Dict[str, T.List[str]] +} -clang_optimization_args = { +clang_optimization_args: T.Dict[str, T.List[str]] = { 'plain': [], '0': ['-O0'], 'g': ['-Og'], @@ -44,7 +44,7 @@ clang_optimization_args = { '2': ['-O2'], '3': ['-O3'], 's': ['-Oz'], -} # type: T.Dict[str, T.List[str]] +} class ClangCompiler(GnuLikeCompiler): diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index cec6b75..da36185 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -103,7 +103,7 @@ class CLikeCompilerArgs(arglist.CompilerArgs): default_dirs = self.compiler.get_default_include_dirs() if default_dirs: real_default_dirs = [self._cached_realpath(i) for i in default_dirs] - bad_idx_list = [] # type: T.List[int] + bad_idx_list: T.List[int] = [] for i, each in enumerate(new): if not each.startswith('-isystem'): continue @@ -136,11 +136,11 @@ class CLikeCompiler(Compiler): """Shared bits for the C and CPP Compilers.""" if T.TYPE_CHECKING: - warn_args = {} # type: T.Dict[str, T.List[str]] + warn_args: T.Dict[str, T.List[str]] = {} # 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]]] + find_library_cache: T.Dict[T.Tuple[T.Tuple[str, ...], str, T.Tuple[str, ...], str, LibType], T.Optional[T.List[str]]] = {} + find_framework_cache: T.Dict[T.Tuple[T.Tuple[str, ...], str, T.Tuple[str, ...], bool], T.Optional[T.List[str]]] = {} internal_libs = arglist.UNIXY_COMPILER_INTERNAL_LIBS def __init__(self, exe_wrapper: T.Optional['ExternalProgram'] = None): @@ -226,7 +226,7 @@ class CLikeCompiler(Compiler): # system directories aren't mixed, we only need to check one file for each # directory and go by that. If we can't check the file for some reason, assume # the compiler knows what it's doing, and accept the directory anyway. - retval = [] + retval: T.List[str] = [] for d in dirs: files = [f for f in os.listdir(d) if f.endswith('.so') and os.path.isfile(os.path.join(d, f))] # if no files, accept directory and move on @@ -370,7 +370,7 @@ class CLikeCompiler(Compiler): #include <{hname}> #endif''' return self.compiles(code, env, extra_args=extra_args, - dependencies=dependencies, mode='preprocess', disable_cache=disable_cache) + dependencies=dependencies, mode=CompileCheckMode.PREPROCESS, disable_cache=disable_cache) def has_header_symbol(self, hname: str, symbol: str, prefix: str, env: 'Environment', *, @@ -389,8 +389,8 @@ class CLikeCompiler(Compiler): dependencies=dependencies) def _get_basic_compiler_args(self, env: 'Environment', mode: CompileCheckMode) -> T.Tuple[T.List[str], T.List[str]]: - cargs = [] # type: T.List[str] - largs = [] # type: T.List[str] + cargs: T.List[str] = [] + largs: T.List[str] = [] if mode is CompileCheckMode.LINK: # Sometimes we need to manually select the CRT to use with MSVC. # One example is when trying to do a compiler check that involves @@ -446,8 +446,8 @@ class CLikeCompiler(Compiler): # TODO: we want to ensure the front end does the listifing here dependencies = [dependencies] # Collect compiler arguments - cargs = self.compiler_args() # type: arglist.CompilerArgs - largs = [] # type: T.List[str] + cargs: arglist.CompilerArgs = self.compiler_args() + largs: T.List[str] = [] for d in dependencies: # Add compile flags needed by dependencies cargs += d.get_compile_args() @@ -475,7 +475,7 @@ class CLikeCompiler(Compiler): need_exe_wrapper = env.need_exe_wrapper(self.for_machine) if need_exe_wrapper and self.exe_wrapper is None: raise compilers.CrossNoRunException('Can not run test applications in this cross environment.') - with self._build_wrapper(code, env, extra_args, dependencies, mode='link', want_output=True) as p: + with self._build_wrapper(code, env, extra_args, dependencies, mode=CompileCheckMode.LINK, want_output=True) as p: if p.returncode != 0: mlog.debug(f'Could not compile test file {p.input_name}: {p.returncode}\n') return compilers.RunResult(False) @@ -678,9 +678,9 @@ class CLikeCompiler(Compiler): {delim}\n{dname}''' args = self.build_wrapper_args(env, extra_args, dependencies, mode=CompileCheckMode.PREPROCESS).to_native() - func = functools.partial(self.cached_compile, code, env.coredata, extra_args=args, mode='preprocess') + func = functools.partial(self.cached_compile, code, env.coredata, extra_args=args, mode=CompileCheckMode.PREPROCESS) if disable_cache: - func = functools.partial(self.compile, code, extra_args=args, mode='preprocess', temp_dir=env.scratch_dir) + func = functools.partial(self.compile, code, extra_args=args, mode=CompileCheckMode.PREPROCESS) with func() as p: cached = p.cached if p.returncode != 0: @@ -805,7 +805,7 @@ class CLikeCompiler(Compiler): # # class StrProto(typing.Protocol): # def __str__(self) -> str: ... - fargs = {'prefix': prefix, 'func': funcname} # type: T.Dict[str, T.Union[str, bool, int]] + fargs: T.Dict[str, T.Union[str, bool, int]] = {'prefix': prefix, 'func': funcname} # glibc defines functions that are not available on Linux as stubs that # fail with ENOSYS (such as e.g. lchmod). In this case we want to fail @@ -919,7 +919,7 @@ class CLikeCompiler(Compiler): ''' args = self.get_compiler_check_args(CompileCheckMode.COMPILE) n = '_symbols_have_underscore_prefix_searchbin' - with self._build_wrapper(code, env, extra_args=args, mode='compile', want_output=True, temp_dir=env.scratch_dir) as p: + with self._build_wrapper(code, env, extra_args=args, mode=CompileCheckMode.COMPILE, want_output=True) as p: if p.returncode != 0: raise RuntimeError(f'BUG: Unable to compile {n!r} check: {p.stderr}') if not os.path.isfile(p.output_name): @@ -954,7 +954,7 @@ class CLikeCompiler(Compiler): #endif {delim}MESON_UNDERSCORE_PREFIX ''' - with self._build_wrapper(code, env, mode='preprocess', want_output=False, temp_dir=env.scratch_dir) as p: + with self._build_wrapper(code, env, mode=CompileCheckMode.PREPROCESS, want_output=False) as p: if p.returncode != 0: raise RuntimeError(f'BUG: Unable to preprocess _symbols_have_underscore_prefix_define check: {p.stdout}') symbol_prefix = p.stdout.partition(delim)[-1].rstrip() @@ -1002,7 +1002,7 @@ class CLikeCompiler(Compiler): return self._symbols_have_underscore_prefix_searchbin(env) def _get_patterns(self, env: 'Environment', prefixes: T.List[str], suffixes: T.List[str], shared: bool = False) -> T.List[str]: - patterns = [] # type: T.List[str] + patterns: T.List[str] = [] for p in prefixes: for s in suffixes: patterns.append(p + '{}.' + s) @@ -1066,7 +1066,7 @@ class CLikeCompiler(Compiler): @staticmethod def _sort_shlibs_openbsd(libs: T.List[str]) -> T.List[str]: - filtered = [] # type: T.List[str] + filtered: T.List[str] = [] for lib in libs: # Validate file as a shared library of type libfoo.so.X.Y ret = lib.rsplit('.so.', maxsplit=1) @@ -1205,7 +1205,7 @@ class CLikeCompiler(Compiler): os_env = os.environ.copy() os_env['LC_ALL'] = 'C' _, _, stde = mesonlib.Popen_safe(commands, env=os_env, stdin=subprocess.PIPE) - paths = [] # T.List[str] + paths: T.List[str] = [] for line in stde.split('\n'): if '(framework directory)' not in line: continue @@ -1216,7 +1216,7 @@ class CLikeCompiler(Compiler): def _find_framework_real(self, name: str, env: 'Environment', extra_dirs: T.List[str], allow_system: bool) -> T.Optional[T.List[str]]: code = 'int main(void) { return 0; }' - link_args = [] + link_args: T.List[str] = [] for d in extra_dirs: link_args += ['-F' + d] # We can pass -Z to disable searching in the system frameworks, but @@ -1269,11 +1269,11 @@ class CLikeCompiler(Compiler): return args.copy() def has_arguments(self, args: T.List[str], env: 'Environment', code: str, - mode: str) -> T.Tuple[bool, bool]: + mode: CompileCheckMode) -> T.Tuple[bool, bool]: return self.compiles(code, env, extra_args=args, mode=mode) def _has_multi_arguments(self, args: T.List[str], env: 'Environment', code: str) -> T.Tuple[bool, bool]: - new_args = [] # type: T.List[str] + new_args: T.List[str] = [] for arg in args: # some compilers, e.g. GCC, don't warn for unsupported warning-disable # flags, so when we are testing a flag like "-Wno-forgotten-towel", also @@ -1289,7 +1289,7 @@ class CLikeCompiler(Compiler): 'the compiler you are using. has_link_argument or ' 'other similar method can be used instead.') new_args.append(arg) - return self.has_arguments(new_args, env, code, mode='compile') + return self.has_arguments(new_args, env, code, mode=CompileCheckMode.COMPILE) def has_multi_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: return self._has_multi_arguments(args, env, 'extern int i;\nint i;\n') @@ -1300,7 +1300,7 @@ class CLikeCompiler(Compiler): # false positive. args = self.linker.fatal_warnings() + args args = self.linker_to_compiler_args(args) - return self.has_arguments(args, env, code, mode='link') + return self.has_arguments(args, env, code, mode=CompileCheckMode.LINK) def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: return self._has_multi_link_arguments(args, env, 'int main(void) { return 0; }\n') @@ -1340,7 +1340,7 @@ class CLikeCompiler(Compiler): @functools.lru_cache(maxsize=None) def can_compile(self, src: 'mesonlib.FileOrString') -> bool: # Files we preprocess can be anything, e.g. .in - if self.mode == 'PREPROCESSOR': + if self.mode == CompileCheckMode.PREPROCESS: return True return super().can_compile(src) @@ -1348,6 +1348,6 @@ class CLikeCompiler(Compiler): if not self.preprocessor: self.preprocessor = copy.copy(self) self.preprocessor.exelist = self.exelist + self.get_preprocess_to_file_args() - self.preprocessor.mode = 'PREPROCESSOR' + self.preprocessor.mode = CompileCheckMode.PREPROCESS self.modes.append(self.preprocessor) return self.preprocessor diff --git a/mesonbuild/compilers/mixins/compcert.py b/mesonbuild/compilers/mixins/compcert.py index d9c21a8..ac4d5aa 100644 --- a/mesonbuild/compilers/mixins/compcert.py +++ b/mesonbuild/compilers/mixins/compcert.py @@ -30,16 +30,16 @@ else: # do). This gives up DRYer type checking, with no runtime impact Compiler = object -ccomp_buildtype_args = { +ccomp_buildtype_args: T.Dict[str, T.List[str]] = { 'plain': [''], 'debug': ['-O0', '-g'], 'debugoptimized': ['-O0', '-g'], 'release': ['-O3'], 'minsize': ['-Os'], 'custom': ['-Obranchless'], -} # type: T.Dict[str, T.List[str]] +} -ccomp_optimization_args = { +ccomp_optimization_args: T.Dict[str, T.List[str]] = { 'plain': [], '0': ['-O0'], 'g': ['-O0'], @@ -47,19 +47,19 @@ ccomp_optimization_args = { '2': ['-O2'], '3': ['-O3'], 's': ['-Os'] -} # type: T.Dict[str, T.List[str]] +} -ccomp_debug_args = { +ccomp_debug_args: T.Dict[bool, T.List[str]] = { False: [], True: ['-g'] -} # type: T.Dict[bool, T.List[str]] +} # As of CompCert 20.04, these arguments should be passed to the underlying gcc linker (via -WUl,<arg>) # There are probably (many) more, but these are those used by picolibc -ccomp_args_to_wul = [ +ccomp_args_to_wul: T.List[str] = [ r"^-ffreestanding$", r"^-r$" -] # type: T.List[str] +] class CompCertCompiler(Compiler): @@ -69,12 +69,13 @@ class CompCertCompiler(Compiler): # Assembly self.can_compile_suffixes.add('s') self.can_compile_suffixes.add('sx') - default_warn_args = [] # type: T.List[str] - self.warn_args = {'0': [], - '1': default_warn_args, - '2': default_warn_args + [], - '3': default_warn_args + [], - 'everything': default_warn_args + []} # type: T.Dict[str, T.List[str]] + default_warn_args: T.List[str] = [] + self.warn_args: T.Dict[str, T.List[str]] = { + '0': [], + '1': default_warn_args, + '2': default_warn_args + [], + '3': default_warn_args + [], + 'everything': default_warn_args + []} def get_always_args(self) -> T.List[str]: return [] @@ -95,7 +96,7 @@ class CompCertCompiler(Compiler): @classmethod def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]: "Always returns a copy that can be independently mutated" - patched_args = [] # type: T.List[str] + patched_args: T.List[str] = [] for arg in args: added = 0 for ptrn in ccomp_args_to_wul: diff --git a/mesonbuild/compilers/mixins/elbrus.py b/mesonbuild/compilers/mixins/elbrus.py index 872649b..ad6b7ca 100644 --- a/mesonbuild/compilers/mixins/elbrus.py +++ b/mesonbuild/compilers/mixins/elbrus.py @@ -74,7 +74,7 @@ class ElbrusCompiler(GnuLikeCompiler): os_env['LC_ALL'] = 'C' p = subprocess.Popen(self.get_exelist(ccache=False) + ['-xc', '-E', '-v', '-'], env=os_env, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stderr = p.stderr.read().decode('utf-8', errors='replace') - includes = [] + includes: T.List[str] = [] for line in stderr.split('\n'): if line.lstrip().startswith('--sys_include'): includes.append(re.sub(r'\s*\\$', '', re.sub(r'^\s*--sys_include\s*', '', line))) @@ -91,7 +91,7 @@ class ElbrusCompiler(GnuLikeCompiler): return 'pch' def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: - args = [] + args: T.List[str] = [] std = options[OptionKey('std', lang=self.language, machine=self.for_machine)] if std.value != 'none': args.append('-std=' + std.value) diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py index 22b7655..fef22b9 100644 --- a/mesonbuild/compilers/mixins/emscripten.py +++ b/mesonbuild/compilers/mixins/emscripten.py @@ -22,6 +22,7 @@ from ... import coredata from ... import mesonlib from ...mesonlib import OptionKey from ...mesonlib import LibType +from mesonbuild.compilers.compilers import CompileCheckMode if T.TYPE_CHECKING: from ...environment import Environment @@ -36,7 +37,7 @@ else: def wrap_js_includes(args: T.List[str]) -> T.List[str]: - final_args = [] + final_args: T.List[str] = [] for i in args: if i.endswith('.js') and not i.startswith('-'): final_args += ['--js-library', i] @@ -46,14 +47,12 @@ def wrap_js_includes(args: T.List[str]) -> T.List[str]: 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 - if mode == 'preprocess': - return None + def _get_compile_output(self, dirname: str, mode: CompileCheckMode) -> str: + assert mode != CompileCheckMode.PREPROCESS, 'In pre-processor mode, the output is sent to stdout and discarded' # Unlike sane toolchains, emcc infers the kind of output from its name. # This is the only reason why this method is overridden; compiler tests # do not work well with the default exe/obj suffices. - if mode == 'link': + if mode == CompileCheckMode.LINK: suffix = 'js' else: suffix = 'o' diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py index 93b367b..2b18732 100644 --- a/mesonbuild/compilers/mixins/gnu.py +++ b/mesonbuild/compilers/mixins/gnu.py @@ -27,6 +27,7 @@ import typing as T from ... import mesonlib from ... import mlog from ...mesonlib import OptionKey +from mesonbuild.compilers.compilers import CompileCheckMode if T.TYPE_CHECKING: from ..._typing import ImmutableListProtocol @@ -41,21 +42,21 @@ else: # XXX: prevent circular references. # FIXME: this really is a posix interface not a c-like interface -clike_debug_args = { +clike_debug_args: T.Dict[bool, T.List[str]] = { False: [], True: ['-g'], -} # type: T.Dict[bool, T.List[str]] +} -gnulike_buildtype_args = { +gnulike_buildtype_args: T.Dict[str, T.List[str]] = { 'plain': [], 'debug': [], 'debugoptimized': [], 'release': [], 'minsize': [], 'custom': [], -} # type: T.Dict[str, T.List[str]] +} -gnu_optimization_args = { +gnu_optimization_args: T.Dict[str, T.List[str]] = { 'plain': [], '0': ['-O0'], 'g': ['-Og'], @@ -63,9 +64,9 @@ gnu_optimization_args = { '2': ['-O2'], '3': ['-O3'], 's': ['-Os'], -} # type: T.Dict[str, T.List[str]] +} -gnulike_instruction_set_args = { +gnulike_instruction_set_args: T.Dict[str, T.List[str]] = { 'mmx': ['-mmmx'], 'sse': ['-msse'], 'sse2': ['-msse2'], @@ -76,22 +77,22 @@ gnulike_instruction_set_args = { 'avx': ['-mavx'], 'avx2': ['-mavx2'], 'neon': ['-mfpu=neon'], -} # type: T.Dict[str, T.List[str]] +} -gnu_symbol_visibility_args = { +gnu_symbol_visibility_args: T.Dict[str, T.List[str]] = { '': [], 'default': ['-fvisibility=default'], 'internal': ['-fvisibility=internal'], 'hidden': ['-fvisibility=hidden'], 'protected': ['-fvisibility=protected'], 'inlineshidden': ['-fvisibility=hidden', '-fvisibility-inlines-hidden'], -} # type: T.Dict[str, T.List[str]] +} -gnu_color_args = { +gnu_color_args: T.Dict[str, T.List[str]] = { 'auto': ['-fdiagnostics-color=auto'], 'always': ['-fdiagnostics-color=always'], 'never': ['-fdiagnostics-color=never'], -} # type: T.Dict[str, T.List[str]] +} # Warnings collected from the GCC source and documentation. This is an # objective set of all the warnings flags that apply to general projects: the @@ -117,7 +118,7 @@ gnu_color_args = { # # Omitted warnings enabled elsewhere in meson: # -Winvalid-pch (GCC 3.4.0) -gnu_common_warning_args = { +gnu_common_warning_args: T.Dict[str, T.List[str]] = { "0.0.0": [ "-Wcast-qual", "-Wconversion", @@ -212,7 +213,7 @@ gnu_common_warning_args = { "-Wopenacc-parallelism", "-Wtrivial-auto-var-init", ], -} # type: T.Dict[str, T.List[str]] +} # GCC warnings for C # Omitted non-general or legacy warnings: @@ -222,7 +223,7 @@ gnu_common_warning_args = { # -Wdeclaration-after-statement # -Wtraditional # -Wtraditional-conversion -gnu_c_warning_args = { +gnu_c_warning_args: T.Dict[str, T.List[str]] = { "0.0.0": [ "-Wbad-function-cast", "-Wmissing-prototypes", @@ -239,7 +240,7 @@ gnu_c_warning_args = { "4.5.0": [ "-Wunsuffixed-float-constants", ], -} # type: T.Dict[str, T.List[str]] +} # GCC warnings for C++ # Omitted non-general or legacy warnings: @@ -249,7 +250,7 @@ gnu_c_warning_args = { # -Wctad-maybe-unsupported # -Wnamespaces # -Wtemplates -gnu_cpp_warning_args = { +gnu_cpp_warning_args: T.Dict[str, T.List[str]] = { "0.0.0": [ "-Wctor-dtor-privacy", "-Weffc++", @@ -308,13 +309,13 @@ gnu_cpp_warning_args = { "-Wdeprecated-enum-float-conversion", "-Winvalid-imported-macros", ], -} # type: T.Dict[str, T.List[str]] +} # GCC warnings for Objective C and Objective C++ # Omitted non-general or legacy warnings: # -Wtraditional # -Wtraditional-conversion -gnu_objc_warning_args = { +gnu_objc_warning_args: T.Dict[str, T.List[str]] = { "0.0.0": [ "-Wselector", ], @@ -325,7 +326,7 @@ gnu_objc_warning_args = { "-Wassign-intercept", "-Wstrict-selector-match", ], -} # type: T.Dict[str, T.List[str]] +} _LANG_MAP = { 'c': 'c', @@ -344,7 +345,7 @@ def gnulike_default_include_dirs(compiler: T.Tuple[str, ...], lang: str) -> 'Imm cmd = list(compiler) + [f'-x{lang}', '-E', '-v', '-'] _, stdout, _ = mesonlib.Popen_safe(cmd, stderr=subprocess.STDOUT, env=env) parse_state = 0 - paths = [] # type: T.List[str] + paths: T.List[str] = [] for line in stdout.split('\n'): line = line.strip(' \n\r\t') if parse_state == 0: @@ -464,7 +465,7 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta): def _get_search_dirs(self, env: 'Environment') -> str: extra_args = ['--print-search-dirs'] with self._build_wrapper('', env, extra_args=extra_args, - dependencies=None, mode='compile', + dependencies=None, mode=CompileCheckMode.COMPILE, want_output=True) as p: return p.stdout @@ -482,7 +483,7 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta): # pathlib treats empty paths as '.', so filter those out paths = [p for p in pathstr.split(pathsep) if p] - result = [] + result: T.List[str] = [] for p in paths: # GCC returns paths like this: # /usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/lib @@ -528,8 +529,8 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta): args.append('-fno-omit-frame-pointer') return args - def get_output_args(self, target: str) -> T.List[str]: - return ['-o', target] + def get_output_args(self, outputname: str) -> T.List[str]: + return ['-o', outputname] def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: return ['-MD', '-MQ', outtarget, '-MF', outfile] @@ -589,7 +590,7 @@ class GnuCompiler(GnuLikeCompiler): return args def supported_warn_args(self, warn_args_by_version: T.Dict[str, T.List[str]]) -> T.List[str]: - result = [] + result: T.List[str] = [] for version, warn_args in warn_args_by_version.items(): if mesonlib.version_compare(self.version, '>=' + version): result += warn_args @@ -613,7 +614,7 @@ class GnuCompiler(GnuLikeCompiler): return ['-fopenmp'] def has_arguments(self, args: T.List[str], env: 'Environment', code: str, - mode: str) -> T.Tuple[bool, bool]: + mode: CompileCheckMode) -> T.Tuple[bool, bool]: # For some compiler command line arguments, the GNU compilers will # emit a warning on stderr indicating that an option is valid for a # another language, but still complete with exit_success diff --git a/mesonbuild/compilers/mixins/intel.py b/mesonbuild/compilers/mixins/intel.py index b793fa8..9af05e0 100644 --- a/mesonbuild/compilers/mixins/intel.py +++ b/mesonbuild/compilers/mixins/intel.py @@ -50,14 +50,14 @@ class IntelGnuLikeCompiler(GnuLikeCompiler): minsize: -O2 """ - BUILD_ARGS = { + BUILD_ARGS: T.Dict[str, T.List[str]] = { 'plain': [], 'debug': ["-g", "-traceback"], 'debugoptimized': ["-g", "-traceback"], 'release': [], 'minsize': [], 'custom': [], - } # type: T.Dict[str, T.List[str]] + } OPTIM_ARGS: T.Dict[str, T.List[str]] = { 'plain': [], @@ -89,8 +89,8 @@ class IntelGnuLikeCompiler(GnuLikeCompiler): return ['-pch', '-pch_dir', os.path.join(pch_dir), '-x', self.lang_header, '-include', header, '-x', 'none'] - def get_pch_name(self, header_name: str) -> str: - return os.path.basename(header_name) + '.' + self.get_pch_suffix() + def get_pch_name(self, name: str) -> str: + return os.path.basename(name) + '.' + self.get_pch_suffix() def openmp_flags(self) -> T.List[str]: if mesonlib.version_compare(self.version, '>=15.0.0'): @@ -129,14 +129,14 @@ class IntelVisualStudioLikeCompiler(VisualStudioLikeCompiler): """Abstractions for ICL, the Intel compiler on Windows.""" - BUILD_ARGS = { + BUILD_ARGS: T.Dict[str, T.List[str]] = { 'plain': [], 'debug': ["/Zi", "/traceback"], 'debugoptimized': ["/Zi", "/traceback"], 'release': [], 'minsize': [], 'custom': [], - } # type: T.Dict[str, T.List[str]] + } OPTIM_ARGS: T.Dict[str, T.List[str]] = { 'plain': [], diff --git a/mesonbuild/compilers/mixins/islinker.py b/mesonbuild/compilers/mixins/islinker.py index 711e3e3..cfdd746 100644 --- a/mesonbuild/compilers/mixins/islinker.py +++ b/mesonbuild/compilers/mixins/islinker.py @@ -120,8 +120,8 @@ class BasicLinkerIsCompilerMixin(Compiler): def get_buildtype_linker_args(self, buildtype: str) -> T.List[str]: return [] - def get_link_debugfile_name(self, targetfile: str) -> str: - return '' + def get_link_debugfile_name(self, targetfile: str) -> T.Optional[str]: + return None def thread_flags(self, env: 'Environment') -> T.List[str]: return [] diff --git a/mesonbuild/compilers/mixins/metrowerks.py b/mesonbuild/compilers/mixins/metrowerks.py index 4390145..83a1c1d 100644 --- a/mesonbuild/compilers/mixins/metrowerks.py +++ b/mesonbuild/compilers/mixins/metrowerks.py @@ -30,16 +30,16 @@ else: # do). This gives up DRYer type checking, with no runtime impact Compiler = object -mwcc_buildtype_args = { +mwcc_buildtype_args: T.Dict[str, T.List[str]] = { 'plain': [], 'debug': ['-g'], 'debugoptimized': ['-g', '-O4'], 'release': ['-O4,p'], 'minsize': ['-Os'], 'custom': [], -} # type: T.Dict[str, T.List[str]] +} -mwccarm_instruction_set_args = { +mwccarm_instruction_set_args: T.Dict[str, T.List[str]] = { 'generic': ['-proc', 'generic'], 'v4': ['-proc', 'v4'], 'v4t': ['-proc', 'v4t'], @@ -69,9 +69,9 @@ mwccarm_instruction_set_args = { 'pxa261': ['-proc', 'pxa261'], 'pxa262': ['-proc', 'pxa262'], 'pxa263': ['-proc', 'pxa263'] -} # type: T.Dict[str, T.List[str]] +} -mwcceppc_instruction_set_args = { +mwcceppc_instruction_set_args: T.Dict[str, T.List[str]] = { 'generic': ['-proc', 'generic'], '401': ['-proc', '401'], '403': ['-proc', '403'], @@ -97,9 +97,9 @@ mwcceppc_instruction_set_args = { '8260': ['-proc', '8260'], 'e500': ['-proc', 'e500'], 'gekko': ['-proc', 'gekko'], -} # type: T.Dict[str, T.List[str]] +} -mwasmarm_instruction_set_args = { +mwasmarm_instruction_set_args: T.Dict[str, T.List[str]] = { 'arm4': ['-proc', 'arm4'], 'arm4t': ['-proc', 'arm4t'], 'arm4xm': ['-proc', 'arm4xm'], @@ -112,9 +112,9 @@ mwasmarm_instruction_set_args = { 'arm5TExP': ['-proc', 'arm5TExP'], 'arm6': ['-proc', 'arm6'], 'xscale': ['-proc', 'xscale'] -} # type: T.Dict[str, T.List[str]] +} -mwasmeppc_instruction_set_args = { +mwasmeppc_instruction_set_args: T.Dict[str, T.List[str]] = { '401': ['-proc', '401'], '403': ['-proc', '403'], '505': ['-proc', '505'], @@ -165,9 +165,9 @@ mwasmeppc_instruction_set_args = { '5674': ['-proc', '5674'], 'gekko': ['-proc', 'gekko'], 'generic': ['-proc', 'generic'], -} # type: T.Dict[str, T.List[str]] +} -mwcc_optimization_args = { +mwcc_optimization_args: T.Dict[str, T.List[str]] = { 'plain': [], '0': ['-O0'], 'g': ['-Op'], @@ -175,12 +175,12 @@ mwcc_optimization_args = { '2': ['-O2'], '3': ['-O3'], 's': ['-Os'] -} # type: T.Dict[str, T.List[str]] +} -mwcc_debug_args = { +mwcc_debug_args: T.Dict[bool, T.List[str]] = { False: [], True: ['-g'] -} # type: T.Dict[bool, T.List[str]] +} class MetrowerksCompiler(Compiler): @@ -197,12 +197,13 @@ class MetrowerksCompiler(Compiler): self.base_options = { OptionKey(o) for o in ['b_pch', 'b_ndebug']} - default_warn_args = [] # type: T.List[str] - self.warn_args = {'0': ['-w', 'off'], - '1': default_warn_args, - '2': default_warn_args + ['-w', 'most'], - '3': default_warn_args + ['-w', 'all'], - 'everything': default_warn_args + ['-w', 'full']} # type: T.Dict[str, T.List[str]] + default_warn_args: T.List[str] = [] + self.warn_args: T.Dict[str, T.List[str]] = { + '0': ['-w', 'off'], + '1': default_warn_args, + '2': default_warn_args + ['-w', 'most'], + '3': default_warn_args + ['-w', 'all'], + 'everything': default_warn_args + ['-w', 'full']} def depfile_for_object(self, objfile: str) -> T.Optional[str]: # Earlier versions of these compilers do not support specifying @@ -248,8 +249,8 @@ class MetrowerksCompiler(Compiler): def get_optimization_args(self, optimization_level: str) -> T.List[str]: return mwcc_optimization_args[optimization_level] - def get_output_args(self, target: str) -> T.List[str]: - return ['-o', target] + def get_output_args(self, outputname: str) -> T.List[str]: + return ['-o', outputname] def get_pic_args(self) -> T.List[str]: return ['-pic'] @@ -277,7 +278,7 @@ class MetrowerksCompiler(Compiler): @classmethod def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]: - result = [] + result: T.List[str] = [] for i in args: if i.startswith('-D'): i = '-D' + i[2:] diff --git a/mesonbuild/compilers/mixins/ti.py b/mesonbuild/compilers/mixins/ti.py index 950c97f..ae23c84 100644 --- a/mesonbuild/compilers/mixins/ti.py +++ b/mesonbuild/compilers/mixins/ti.py @@ -31,16 +31,16 @@ else: # do). This gives up DRYer type checking, with no runtime impact Compiler = object -ti_buildtype_args = { +ti_buildtype_args: T.Dict[str, T.List[str]] = { 'plain': [], 'debug': [], 'debugoptimized': [], 'release': [], 'minsize': [], 'custom': [], -} # type: T.Dict[str, T.List[str]] +} -ti_optimization_args = { +ti_optimization_args: T.Dict[str, T.List[str]] = { 'plain': [], '0': ['-O0'], 'g': ['-Ooff'], @@ -48,12 +48,12 @@ ti_optimization_args = { '2': ['-O2'], '3': ['-O3'], 's': ['-O4'] -} # type: T.Dict[str, T.List[str]] +} -ti_debug_args = { +ti_debug_args: T.Dict[bool, T.List[str]] = { False: [], True: ['-g'] -} # type: T.Dict[bool, T.List[str]] +} class TICompiler(Compiler): @@ -67,12 +67,13 @@ class TICompiler(Compiler): self.can_compile_suffixes.add('asm') # Assembly self.can_compile_suffixes.add('cla') # Control Law Accelerator (CLA) used in C2000 - default_warn_args = [] # type: T.List[str] - self.warn_args = {'0': [], - '1': default_warn_args, - '2': default_warn_args + [], - '3': default_warn_args + [], - 'everything': default_warn_args + []} # type: T.Dict[str, T.List[str]] + default_warn_args: T.List[str] = [] + self.warn_args: T.Dict[str, T.List[str]] = { + '0': [], + '1': default_warn_args, + '2': default_warn_args + [], + '3': default_warn_args + [], + 'everything': default_warn_args + []} def get_pic_args(self) -> T.List[str]: # PIC support is not enabled by default for TI compilers, @@ -112,8 +113,8 @@ class TICompiler(Compiler): def get_no_optimization_args(self) -> T.List[str]: return ['-Ooff'] - def get_output_args(self, target: str) -> T.List[str]: - return [f'--output_file={target}'] + def get_output_args(self, outputname: str) -> T.List[str]: + return [f'--output_file={outputname}'] def get_werror_args(self) -> T.List[str]: return ['--emit_warnings_as_errors'] @@ -125,7 +126,7 @@ class TICompiler(Compiler): @classmethod def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]: - result = [] + result: T.List[str] = [] for i in args: if i.startswith('-D'): i = '--define=' + i[2:] diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py index acf475a..24f1132 100644 --- a/mesonbuild/compilers/mixins/visualstudio.py +++ b/mesonbuild/compilers/mixins/visualstudio.py @@ -24,6 +24,7 @@ import typing as T from ... import arglist from ... import mesonlib from ... import mlog +from mesonbuild.compilers.compilers import CompileCheckMode if T.TYPE_CHECKING: from ...environment import Environment @@ -36,7 +37,7 @@ else: # do). This gives up DRYer type checking, with no runtime impact Compiler = object -vs32_instruction_set_args = { +vs32_instruction_set_args: T.Dict[str, T.Optional[T.List[str]]] = { 'mmx': ['/arch:SSE'], # There does not seem to be a flag just for MMX 'sse': ['/arch:SSE'], 'sse2': ['/arch:SSE2'], @@ -46,10 +47,10 @@ vs32_instruction_set_args = { 'avx': ['/arch:AVX'], 'avx2': ['/arch:AVX2'], 'neon': None, -} # T.Dicst[str, T.Optional[T.List[str]]] +} # The 64 bit compiler defaults to /arch:avx. -vs64_instruction_set_args = { +vs64_instruction_set_args: T.Dict[str, T.Optional[T.List[str]]] = { 'mmx': ['/arch:AVX'], 'sse': ['/arch:AVX'], 'sse2': ['/arch:AVX'], @@ -60,9 +61,9 @@ vs64_instruction_set_args = { 'avx': ['/arch:AVX'], 'avx2': ['/arch:AVX2'], 'neon': None, -} # T.Dicst[str, T.Optional[T.List[str]]] +} -msvc_optimization_args = { +msvc_optimization_args: T.Dict[str, T.List[str]] = { 'plain': [], '0': ['/Od'], 'g': [], # No specific flag to optimize debugging, /Zi or /ZI will create debug information @@ -70,12 +71,12 @@ msvc_optimization_args = { '2': ['/O2'], '3': ['/O2', '/Gw'], 's': ['/O1', '/Gw'], -} # type: T.Dict[str, T.List[str]] +} -msvc_debug_args = { +msvc_debug_args: T.Dict[bool, T.List[str]] = { False: [], True: ['/Zi'] -} # type: T.Dict[bool, T.List[str]] +} class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta): @@ -91,15 +92,15 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta): std_warn_args = ['/W3'] std_opt_args = ['/O2'] ignore_libs = arglist.UNIXY_COMPILER_INTERNAL_LIBS + ['execinfo'] - internal_libs = [] # type: T.List[str] + internal_libs: T.List[str] = [] - crt_args = { + crt_args: T.Dict[str, T.List[str]] = { 'none': [], 'md': ['/MD'], 'mdd': ['/MDd'], 'mt': ['/MT'], 'mtd': ['/MTd'], - } # type: T.Dict[str, T.List[str]] + } # /showIncludes is needed for build dependency tracking in Ninja # See: https://ninja-build.org/manual.html#_deps @@ -108,13 +109,13 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta): # It is also dropped if Visual Studio 2013 or earlier is used, since it would # not be supported in that case. always_args = ['/nologo', '/showIncludes', '/utf-8'] - warn_args = { + warn_args: T.Dict[str, T.List[str]] = { '0': [], '1': ['/W2'], '2': ['/W3'], '3': ['/W4'], 'everything': ['/Wall'], - } # type: T.Dict[str, T.List[str]] + } INVOKES_LINKER = False @@ -146,8 +147,8 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta): def get_pch_suffix(self) -> str: return 'pch' - def get_pch_name(self, header: str) -> str: - chopped = os.path.basename(header).split('.')[:-1] + def get_pch_name(self, name: str) -> str: + chopped = os.path.basename(name).split('.')[:-1] chopped.append(self.get_pch_suffix()) pchname = '.'.join(chopped) return pchname @@ -180,12 +181,12 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta): raise mesonlib.MesonException('VS only supports address sanitizer at the moment.') return ['/fsanitize=address'] - def get_output_args(self, target: str) -> T.List[str]: - if self.mode == 'PREPROCESSOR': - return ['/Fi' + target] - if target.endswith('.exe'): - return ['/Fe' + target] - return ['/Fo' + target] + def get_output_args(self, outputname: str) -> T.List[str]: + if self.mode == CompileCheckMode.PREPROCESS: + return ['/Fi' + outputname] + if outputname.endswith('.exe'): + return ['/Fe' + outputname] + return ['/Fo' + outputname] def get_buildtype_args(self, buildtype: str) -> T.List[str]: return [] @@ -276,7 +277,7 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta): @classmethod def native_args_to_unix(cls, args: T.List[str]) -> T.List[str]: - result = [] + result: T.List[str] = [] for arg in args: if arg.startswith(('/LIBPATH:', '-LIBPATH:')): result.append('-L' + arg[9:]) @@ -307,8 +308,8 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta): # Visual Studio is special. It ignores some arguments it does not # understand and you can't tell it to error out on those. # http://stackoverflow.com/questions/15259720/how-can-i-make-the-microsoft-c-compiler-treat-unknown-flags-as-errors-rather-t - def has_arguments(self, args: T.List[str], env: 'Environment', code: str, mode: str) -> T.Tuple[bool, bool]: - warning_text = '4044' if mode == 'link' else '9002' + def has_arguments(self, args: T.List[str], env: 'Environment', code: str, mode: CompileCheckMode) -> T.Tuple[bool, bool]: + warning_text = '4044' if mode == CompileCheckMode.LINK else '9002' with self._build_wrapper(code, env, extra_args=args, mode=mode) as p: if p.returncode != 0: return False, p.cached @@ -471,8 +472,8 @@ class ClangClCompiler(VisualStudioLikeCompiler): self.can_compile_suffixes.add('s') self.can_compile_suffixes.add('sx') - def has_arguments(self, args: T.List[str], env: 'Environment', code: str, mode: str) -> T.Tuple[bool, bool]: - if mode != 'link': + def has_arguments(self, args: T.List[str], env: 'Environment', code: str, mode: CompileCheckMode) -> T.Tuple[bool, bool]: + if mode != CompileCheckMode.LINK: args = args + ['-Werror=unknown-argument', '-Werror=unknown-warning-option'] return super().has_arguments(args, env, code, mode) @@ -490,7 +491,7 @@ class ClangClCompiler(VisualStudioLikeCompiler): def get_dependency_compile_args(self, dep: 'Dependency') -> T.List[str]: if dep.get_include_type() == 'system': - converted = [] + converted: T.List[str] = [] for i in dep.get_compile_args(): if i.startswith('-isystem'): converted += ['/clang:' + i] diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py index 40cfc14..c6af04a 100644 --- a/mesonbuild/compilers/vala.py +++ b/mesonbuild/compilers/vala.py @@ -19,7 +19,7 @@ import typing as T from .. import mlog from ..mesonlib import EnvironmentException, version_compare, OptionKey -from .compilers import Compiler, LibType +from .compilers import CompileCheckMode, Compiler, LibType if T.TYPE_CHECKING: from ..envconfig import MachineInfo @@ -46,7 +46,7 @@ class ValaCompiler(Compiler): def get_debug_args(self, is_debug: bool) -> T.List[str]: return ['--debug'] if is_debug else [] - def get_output_args(self, target: str) -> T.List[str]: + def get_output_args(self, outputname: str) -> T.List[str]: return [] # Because compiles into C. def get_compile_only_args(self) -> T.List[str]: @@ -64,7 +64,7 @@ class ValaCompiler(Compiler): def get_always_args(self) -> T.List[str]: return ['-C'] - def get_warn_args(self, warning_level: str) -> T.List[str]: + def get_warn_args(self, level: str) -> T.List[str]: return [] def get_no_warn_args(self) -> T.List[str]: @@ -100,7 +100,7 @@ class ValaCompiler(Compiler): extra_flags += self.get_compile_only_args() else: extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language) - with self.cached_compile(code, environment.coredata, extra_args=extra_flags, mode='compile') as p: + with self.cached_compile(code, environment.coredata, extra_args=extra_flags, mode=CompileCheckMode.COMPILE) as p: if p.returncode != 0: msg = f'Vala compiler {self.name_string()!r} cannot compile programs' raise EnvironmentException(msg) @@ -122,7 +122,7 @@ class ValaCompiler(Compiler): args += env.coredata.get_external_args(self.for_machine, self.language) vapi_args = ['--pkg', libname] args += vapi_args - with self.cached_compile(code, env.coredata, extra_args=args, mode='compile') as p: + with self.cached_compile(code, env.coredata, extra_args=args, mode=CompileCheckMode.COMPILE) as p: if p.returncode == 0: return vapi_args # Not found? Try to find the vapi file itself. diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 9bdb509..a6178f0 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -39,7 +39,7 @@ import typing as T if T.TYPE_CHECKING: from . import dependencies - from .compilers.compilers import Compiler, CompileResult, RunResult + from .compilers.compilers import Compiler, CompileResult, RunResult, CompileCheckMode from .dependencies.detect import TV_DepID from .environment import Environment from .mesonlib import OptionOverrideProxy, FileOrString @@ -48,7 +48,7 @@ if T.TYPE_CHECKING: OptionDictType = T.Union[T.Dict[str, 'UserOption[T.Any]'], OptionOverrideProxy] MutableKeyedOptionDictType = T.Dict['OptionKey', 'UserOption[T.Any]'] KeyedOptionDictType = T.Union[MutableKeyedOptionDictType, OptionOverrideProxy] - CompilerCheckCacheKey = T.Tuple[T.Tuple[str, ...], str, FileOrString, T.Tuple[str, ...], str] + CompilerCheckCacheKey = T.Tuple[T.Tuple[str, ...], str, FileOrString, T.Tuple[str, ...], CompileCheckMode] # code, args RunCheckCacheKey = T.Tuple[str, T.Tuple[str, ...]] @@ -81,7 +81,7 @@ DEFAULT_YIELDING = False _T = T.TypeVar('_T') -def get_genvs_default_buildtype_list() -> list: +def get_genvs_default_buildtype_list() -> list[str]: # just debug, debugoptimized, and release for now # but this should probably be configurable through some extra option, alongside --genvslite. return buildtypelist[1:-2] @@ -139,7 +139,7 @@ class UserStringOption(UserOption[str]): return value class UserBooleanOption(UserOption[bool]): - def __init__(self, description: str, value, yielding: bool = DEFAULT_YIELDING, + def __init__(self, description: str, value: bool, yielding: bool = DEFAULT_YIELDING, deprecated: T.Union[bool, str, T.Dict[str, str], T.List[str]] = False): super().__init__(description, [True, False], yielding, deprecated) self.set_value(value) @@ -164,7 +164,7 @@ class UserIntegerOption(UserOption[int]): min_value, max_value, default_value = value self.min_value = min_value self.max_value = max_value - c = [] + c: T.List[str] = [] if min_value is not None: c.append('>=' + str(min_value)) if max_value is not None: @@ -368,13 +368,13 @@ class DependencyCache: """ def __init__(self, builtins: 'KeyedOptionDictType', for_machine: MachineChoice): - self.__cache = OrderedDict() # type: T.MutableMapping[TV_DepID, DependencySubCache] + self.__cache: T.MutableMapping[TV_DepID, DependencySubCache] = OrderedDict() self.__builtins = builtins self.__pkg_conf_key = OptionKey('pkg_config_path', machine=for_machine) self.__cmake_key = OptionKey('cmake_prefix_path', machine=for_machine) def __calculate_subkey(self, type_: DependencyCacheType) -> T.Tuple[str, ...]: - data: T.Dict[str, T.List[str]] = { + data: T.Dict[DependencyCacheType, T.List[str]] = { DependencyCacheType.PKG_CONFIG: stringlistify(self.__builtins[self.__pkg_conf_key].value), DependencyCacheType.CMAKE: stringlistify(self.__builtins[self.__cmake_key].value), DependencyCacheType.OTHER: [], @@ -419,7 +419,7 @@ class DependencyCache: def items(self) -> T.Iterator[T.Tuple['TV_DepID', T.List['dependencies.Dependency']]]: for k, v in self.__cache.items(): - vs = [] + vs: T.List[dependencies.Dependency] = [] for t in v.types: subkey = self.__calculate_subkey(t) if subkey in v: @@ -482,7 +482,7 @@ class CoreData: self.version = version self.options: 'MutableKeyedOptionDictType' = {} self.cross_files = self.__load_config_files(options, scratch_dir, 'cross') - self.compilers = PerMachine(OrderedDict(), OrderedDict()) # type: PerMachine[T.Dict[str, Compiler]] + self.compilers: PerMachine[T.Dict[str, Compiler]] = PerMachine(OrderedDict(), OrderedDict()) # Set of subprojects that have already been initialized once, this is # required to be stored and reloaded with the coredata, as we don't @@ -518,9 +518,9 @@ class CoreData: if not filenames: return [] - found_invalid = [] # type: T.List[str] - missing = [] # type: T.List[str] - real = [] # type: T.List[str] + found_invalid: T.List[str] = [] + missing: T.List[str] = [] + real: T.List[str] = [] for i, f in enumerate(filenames): f = os.path.expanduser(os.path.expandvars(f)) if os.path.exists(f): @@ -571,7 +571,7 @@ class CoreData: if self.cross_files: BUILTIN_OPTIONS[OptionKey('libdir')].default = 'lib' - def sanitize_prefix(self, prefix): + def sanitize_prefix(self, prefix: str) -> str: prefix = os.path.expanduser(prefix) if not os.path.isabs(prefix): raise MesonException(f'prefix value {prefix!r} must be an absolute path') @@ -731,7 +731,7 @@ class CoreData: self.run_check_cache.clear() def get_nondefault_buildtype_args(self) -> T.List[T.Union[T.Tuple[str, str, str], T.Tuple[str, bool, bool]]]: - result = [] + result: T.List[T.Union[T.Tuple[str, str, str], T.Tuple[str, bool, bool]]] = [] value = self.options[OptionKey('buildtype')].value if value == 'plain': opt = 'plain' @@ -955,18 +955,18 @@ class CmdLineFileParser(configparser.ConfigParser): # storing subproject options like "subproject:option=value" super().__init__(delimiters=['='], interpolation=None) - def read(self, filenames: T.Union['StrOrBytesPath', T.Iterable['StrOrBytesPath']], encoding: str = 'utf-8') -> T.List[str]: + def read(self, filenames: T.Union['StrOrBytesPath', T.Iterable['StrOrBytesPath']], encoding: T.Optional[str] = 'utf-8') -> T.List[str]: return super().read(filenames, encoding) - def optionxform(self, option: str) -> str: + def optionxform(self, optionstr: str) -> str: # Don't call str.lower() on keys - return option + return optionstr class MachineFileParser(): def __init__(self, filenames: T.List[str]) -> None: self.parser = CmdLineFileParser() - self.constants = {'True': True, 'False': False} - self.sections = {} + self.constants: T.Dict[str, T.Union[str, bool, int, T.List[str]]] = {'True': True, 'False': False} + self.sections: T.Dict[str, T.Dict[str, T.Union[str, bool, int, T.List[str]]]] = {} try: self.parser.read(filenames) @@ -982,9 +982,9 @@ class MachineFileParser(): continue self.sections[s] = self._parse_section(s) - def _parse_section(self, s): + def _parse_section(self, s: str) -> T.Dict[str, T.Union[str, bool, int, T.List[str]]]: self.scope = self.constants.copy() - section = {} + section: T.Dict[str, T.Union[str, bool, int, T.List[str]]] = {} for entry, value in self.parser.items(s): if ' ' in entry or '\t' in entry or "'" in entry or '"' in entry: raise EnvironmentException(f'Malformed variable name {entry!r} in machine file.') @@ -1001,7 +1001,7 @@ class MachineFileParser(): self.scope[entry] = res return section - def _evaluate_statement(self, node): + def _evaluate_statement(self, node: mparser.BaseNode) -> T.Union[str, bool, int, T.List[str]]: if isinstance(node, (mparser.StringNode)): return node.value elif isinstance(node, mparser.BooleanNode): @@ -1009,6 +1009,7 @@ class MachineFileParser(): elif isinstance(node, mparser.NumberNode): return node.value elif isinstance(node, mparser.ArrayNode): + # TODO: This is where recursive types would come in handy return [self._evaluate_statement(arg) for arg in node.args.arguments] elif isinstance(node, mparser.IdNode): return self.scope[node.value] @@ -1024,7 +1025,7 @@ class MachineFileParser(): return os.path.join(l, r) raise EnvironmentException('Unsupported node type') -def parse_machine_files(filenames): +def parse_machine_files(filenames: T.List[str]): parser = MachineFileParser(filenames) return parser.sections @@ -1057,7 +1058,7 @@ def write_cmd_line_file(build_dir: str, options: argparse.Namespace) -> None: filename = get_cmd_line_file(build_dir) config = CmdLineFileParser() - properties = OrderedDict() + properties: OrderedDict[str, str] = OrderedDict() if options.cross_file: properties['cross_file'] = options.cross_file if options.native_file: diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index ff7ae3a..ce7c9f1 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -82,7 +82,7 @@ def _get_env_var(for_machine: MachineChoice, is_cross: bool, var_name: str) -> T return value -def detect_gcovr(min_version='3.3', log=False): +def detect_gcovr(min_version: str = '3.3', log: bool = False): gcovr_exe = 'gcovr' try: p, found = Popen_safe([gcovr_exe, '--version'])[0:2] @@ -178,7 +178,7 @@ def get_llvm_tool_names(tool: str) -> T.List[str]: '-15', # Debian development snapshot '-devel', # FreeBSD development snapshot ] - names = [] + names: T.List[str] = [] for suffix in suffixes: names.append(tool + suffix) return names @@ -197,15 +197,16 @@ def detect_scanbuild() -> T.List[str]: Return: a single-element list of the found scan-build binary ready to be passed to Popen() """ - exelist = [] + exelist: T.List[str] = [] if 'SCANBUILD' in os.environ: exelist = split_args(os.environ['SCANBUILD']) else: tools = get_llvm_tool_names('scan-build') for tool in tools: - if shutil.which(tool) is not None: - exelist = [shutil.which(tool)] + which = shutil.which(tool) + if which is not None: + exelist = [which] break if exelist: @@ -270,7 +271,7 @@ def detect_windows_arch(compilers: CompilersDict) -> str: return 'x86' return os_arch -def any_compiler_has_define(compilers: CompilersDict, define): +def any_compiler_has_define(compilers: CompilersDict, define: str) -> bool: for c in compilers.values(): try: if c.has_builtin_define(define): @@ -488,7 +489,7 @@ class Environment: os.makedirs(self.log_dir, exist_ok=True) os.makedirs(self.info_dir, exist_ok=True) try: - self.coredata = coredata.load(self.get_build_dir()) # type: coredata.CoreData + self.coredata: coredata.CoreData = coredata.load(self.get_build_dir()) self.first_invocation = False except FileNotFoundError: self.create_new_coredata(options) @@ -521,13 +522,13 @@ class Environment: # Similar to coredata.compilers, but lower level in that there is no # meta data, only names/paths. - binaries = PerMachineDefaultable() # type: PerMachineDefaultable[BinaryTable] + binaries: PerMachineDefaultable[BinaryTable] = PerMachineDefaultable() # Misc other properties about each machine. - properties = PerMachineDefaultable() # type: PerMachineDefaultable[Properties] + properties: PerMachineDefaultable[Properties] = PerMachineDefaultable() # CMake toolchain variables - cmakevars = PerMachineDefaultable() # type: PerMachineDefaultable[CMakeVariables] + cmakevars: PerMachineDefaultable[CMakeVariables] = PerMachineDefaultable() ## Setup build machine defaults @@ -813,7 +814,7 @@ class Environment: return is_object(fname) @lru_cache(maxsize=None) - def is_library(self, fname): + def is_library(self, fname: mesonlib.FileOrString): return is_library(fname) def lookup_binary_entry(self, for_machine: MachineChoice, name: str) -> T.Optional[T.List[str]]: @@ -873,7 +874,7 @@ class Environment: def get_datadir(self) -> str: return self.coredata.get_option(OptionKey('datadir')) - def get_compiler_system_lib_dirs(self, for_machine: MachineChoice): + def get_compiler_system_lib_dirs(self, for_machine: MachineChoice) -> T.List[str]: for comp in self.coredata.compilers[for_machine].values(): if comp.id == 'clang': index = 1 @@ -892,7 +893,7 @@ class Environment: out = out.split('\n')[index].lstrip('libraries: =').split(':') return [os.path.normpath(p) for p in out] - def get_compiler_system_include_dirs(self, for_machine: MachineChoice): + def get_compiler_system_include_dirs(self, for_machine: MachineChoice) -> T.List[str]: for comp in self.coredata.compilers[for_machine].values(): if comp.id == 'clang': break diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py index edd4085..8f413c8 100644 --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py @@ -86,7 +86,7 @@ class StaticLinker: def native_args_to_unix(cls, args: T.List[str]) -> T.List[str]: return args[:] - def get_link_debugfile_name(self, targetfile: str) -> str: + def get_link_debugfile_name(self, targetfile: str) -> T.Optional[str]: return None def get_link_debugfile_args(self, targetfile: str) -> T.List[str]: @@ -122,7 +122,7 @@ class VisualStudioLikeLinker: return self.always_args.copy() def get_output_args(self, target: str) -> T.List[str]: - args = [] # type: T.List[str] + args: T.List[str] = [] if self.machine: args += ['/MACHINE:' + self.machine] args += ['/OUT:' + target] @@ -355,14 +355,14 @@ class DynamicLinker(metaclass=abc.ABCMeta): """Base class for dynamic linkers.""" - _BUILDTYPE_ARGS = { + _BUILDTYPE_ARGS: T.Dict[str, T.List[str]] = { 'plain': [], 'debug': [], 'debugoptimized': [], 'release': [], 'minsize': [], 'custom': [], - } # type: T.Dict[str, T.List[str]] + } @abc.abstractproperty def id(self) -> str: @@ -374,7 +374,7 @@ class DynamicLinker(metaclass=abc.ABCMeta): return args elif isinstance(self.prefix_arg, str): return [self.prefix_arg + arg for arg in args] - ret = [] + ret: T.List[str] = [] for arg in args: ret += self.prefix_arg + [arg] return ret @@ -387,7 +387,7 @@ class DynamicLinker(metaclass=abc.ABCMeta): self.version = version self.prefix_arg = prefix_arg self.always_args = always_args - self.machine = None # type: T.Optional[str] + self.machine: T.Optional[str] = None def __repr__(self) -> str: return '<{}: v{} `{}`>'.format(type(self).__name__, self.version, ' '.join(self.exelist)) @@ -428,7 +428,7 @@ class DynamicLinker(metaclass=abc.ABCMeta): def has_multi_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]: raise EnvironmentException(f'Language {self.id} does not support has_multi_link_arguments.') - def get_debugfile_name(self, targetfile: str) -> str: + def get_debugfile_name(self, targetfile: str) -> T.Optional[str]: '''Name of debug file written out (see below)''' return None @@ -479,7 +479,7 @@ class DynamicLinker(metaclass=abc.ABCMeta): f'Linker {self.id} does not support allow undefined') @abc.abstractmethod - def get_output_args(self, outname: str) -> T.List[str]: + def get_output_args(self, outputname: str) -> T.List[str]: pass def get_coverage_args(self) -> T.List[str]: @@ -560,8 +560,8 @@ class PosixDynamicLinkerMixin: GNU-like that it makes sense to split this out. """ - def get_output_args(self, outname: str) -> T.List[str]: - return ['-o', outname] + def get_output_args(self, outputname: str) -> T.List[str]: + return ['-o', outputname] def get_std_shared_lib_args(self) -> T.List[str]: return ['-shared'] @@ -582,16 +582,16 @@ class GnuLikeDynamicLinkerMixin: for_machine = MachineChoice.HOST def _apply_prefix(self, arg: T.Union[str, T.List[str]]) -> T.List[str]: ... - _BUILDTYPE_ARGS = { + _BUILDTYPE_ARGS: T.Dict[str, T.List[str]] = { 'plain': [], 'debug': [], 'debugoptimized': [], 'release': ['-O1'], 'minsize': [], 'custom': [], - } # type: T.Dict[str, T.List[str]] + } - _SUBSYSTEMS = { + _SUBSYSTEMS: T.Dict[str, str] = { "native": "1", "windows": "windows", "console": "console", @@ -601,7 +601,7 @@ class GnuLikeDynamicLinkerMixin: "efi_runtime_driver": "12", "efi_rom": "13", "boot_application": "16", - } # type: T.Dict[str, str] + } def get_buildtype_args(self, buildtype: str) -> T.List[str]: # We can override these in children by just overriding the @@ -670,14 +670,14 @@ class GnuLikeDynamicLinkerMixin: return ([], set()) if not rpath_paths and not install_rpath and not build_rpath: return ([], set()) - args = [] + args: T.List[str] = [] origin_placeholder = '$ORIGIN' processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) # Need to deduplicate rpaths, as macOS's install_name_tool # is *very* allergic to duplicate -delete_rpath arguments # when calling depfixer on installation. all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths]) - rpath_dirs_to_remove = set() + rpath_dirs_to_remove: T.Set[bytes] = set() for p in all_paths: rpath_dirs_to_remove.add(p.encode('utf8')) # Build_rpath is used as-is (it is usually absolute). @@ -769,7 +769,7 @@ class AppleDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): return [] def get_link_whole_for(self, args: T.List[str]) -> T.List[str]: - result = [] # type: T.List[str] + result: T.List[str] = [] for a in args: result.extend(self._apply_prefix('-force_load')) result.append(a) @@ -812,7 +812,7 @@ class AppleDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: if not rpath_paths and not install_rpath and not build_rpath: return ([], set()) - args = [] + args: T.List[str] = [] # @loader_path is the equivalent of $ORIGIN on macOS # https://stackoverflow.com/q/26280738 origin_placeholder = '@loader_path' @@ -1152,7 +1152,7 @@ class NAGDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: if not rpath_paths and not install_rpath and not build_rpath: return ([], set()) - args = [] + args: T.List[str] = [] origin_placeholder = '$ORIGIN' processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths]) @@ -1225,7 +1225,7 @@ class VisualStudioLikeLinkerMixin: for_machine = MachineChoice.HOST def _apply_prefix(self, arg: T.Union[str, T.List[str]]) -> T.List[str]: ... - _BUILDTYPE_ARGS = { + _BUILDTYPE_ARGS: T.Dict[str, T.List[str]] = { 'plain': [], 'debug': [], 'debugoptimized': [], @@ -1234,7 +1234,7 @@ class VisualStudioLikeLinkerMixin: 'release': ['/OPT:REF'], 'minsize': ['/INCREMENTAL:NO', '/OPT:REF'], 'custom': [], - } # type: T.Dict[str, T.List[str]] + } def __init__(self, exelist: T.List[str], for_machine: mesonlib.MachineChoice, prefix_arg: T.Union[str, T.List[str]], always_args: T.List[str], *, @@ -1273,7 +1273,7 @@ class VisualStudioLikeLinkerMixin: def get_link_whole_for(self, args: T.List[str]) -> T.List[str]: # Only since VS2015 args = mesonlib.listify(args) - l = [] # T.List[str] + l: T.List[str] = [] for a in args: l.extend(self._apply_prefix('/WHOLEARCHIVE:' + a)) return l @@ -1409,7 +1409,7 @@ class SolarisDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): return ([], set()) processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) all_paths = mesonlib.OrderedSet([os.path.join('$ORIGIN', p) for p in processed_rpaths]) - rpath_dirs_to_remove = set() + rpath_dirs_to_remove: T.Set[bytes] = set() for p in all_paths: rpath_dirs_to_remove.add(p.encode('utf8')) if build_rpath != '': @@ -1473,7 +1473,7 @@ class AIXDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, rpath_paths: T.Tuple[str, ...], build_rpath: str, install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: - all_paths = mesonlib.OrderedSet() # type: mesonlib.OrderedSet[str] + all_paths: mesonlib.OrderedSet[str] = mesonlib.OrderedSet() # install_rpath first, followed by other paths, and the system path last if install_rpath != '': all_paths.add(install_rpath) @@ -1596,8 +1596,8 @@ class MetrowerksLinker(DynamicLinker): def get_linker_always_args(self) -> T.List[str]: return [] - def get_output_args(self, target: str) -> T.List[str]: - return ['-o', target] + def get_output_args(self, outputname: str) -> T.List[str]: + return ['-o', outputname] def get_search_args(self, dirname: str) -> T.List[str]: return self._apply_prefix('-L' + dirname) diff --git a/mesonbuild/utils/universal.py b/mesonbuild/utils/universal.py index 8cfc04d..d78fadd 100644 --- a/mesonbuild/utils/universal.py +++ b/mesonbuild/utils/universal.py @@ -41,7 +41,7 @@ if T.TYPE_CHECKING: from .._typing import ImmutableListProtocol from ..build import ConfigurationData - from ..coredata import KeyedOptionDictType, UserOption + from ..coredata import KeyedOptionDictType, UserOption, StrOrBytesPath from ..environment import Environment from ..compilers.compilers import Compiler from ..interpreterbase.baseobjects import SubProject @@ -172,7 +172,7 @@ __all__ = [ # TODO: this is such a hack, this really should be either in coredata or in the # interpreter # {subproject: project_meson_version} -project_meson_versions = collections.defaultdict(str) # type: T.DefaultDict[str, str] +project_meson_versions: T.DefaultDict[str, str] = collections.defaultdict(str) from glob import glob @@ -194,14 +194,15 @@ class GitException(MesonException): self.output = output.strip() if output else '' GIT = shutil.which('git') -def git(cmd: T.List[str], workingdir: T.Union[str, bytes, os.PathLike], check: bool = False, **kwargs: T.Any) -> T.Tuple[subprocess.Popen, str, str]: - cmd = [GIT] + cmd +def git(cmd: T.List[str], workingdir: StrOrBytesPath, check: bool = False, **kwargs: T.Any) -> T.Tuple[subprocess.Popen[str], str, str]: + assert GIT is not None, 'Callers should make sure it exists' + cmd = [GIT, *cmd] p, o, e = Popen_safe(cmd, cwd=workingdir, **kwargs) if check and p.returncode != 0: raise GitException('Git command failed: ' + str(cmd), e) return p, o, e -def quiet_git(cmd: T.List[str], workingdir: T.Union[str, bytes, os.PathLike], check: bool = False) -> T.Tuple[bool, str]: +def quiet_git(cmd: T.List[str], workingdir: StrOrBytesPath, check: bool = False) -> T.Tuple[bool, str]: if not GIT: m = 'Git program not found.' if check: @@ -212,7 +213,7 @@ def quiet_git(cmd: T.List[str], workingdir: T.Union[str, bytes, os.PathLike], ch return False, e return True, o -def verbose_git(cmd: T.List[str], workingdir: T.Union[str, bytes, os.PathLike], check: bool = False) -> bool: +def verbose_git(cmd: T.List[str], workingdir: StrOrBytesPath, check: bool = False) -> bool: if not GIT: m = 'Git program not found.' if check: @@ -514,7 +515,7 @@ class PerMachine(T.Generic[_T]): machines, we can elaborate the original and then redefault them and thus avoid repeating the elaboration explicitly. """ - unfreeze = PerMachineDefaultable() # type: PerMachineDefaultable[T.Optional[_T]] + unfreeze: PerMachineDefaultable[T.Optional[_T]] = PerMachineDefaultable() unfreeze.build = self.build unfreeze.host = self.host if unfreeze.host == unfreeze.build: @@ -543,7 +544,7 @@ class PerThreeMachine(PerMachine[_T]): machines, we can elaborate the original and then redefault them and thus avoid repeating the elaboration explicitly. """ - unfreeze = PerThreeMachineDefaultable() # type: PerThreeMachineDefaultable[T.Optional[_T]] + unfreeze: PerThreeMachineDefaultable[T.Optional[_T]] = PerThreeMachineDefaultable() unfreeze.build = self.build unfreeze.host = self.host unfreeze.target = self.target @@ -595,7 +596,7 @@ class PerMachineDefaultable(PerMachine[T.Optional[_T]]): return m.default_missing() -class PerThreeMachineDefaultable(PerMachineDefaultable, PerThreeMachine[T.Optional[_T]]): +class PerThreeMachineDefaultable(PerMachineDefaultable[T.Optional[_T]], PerThreeMachine[T.Optional[_T]]): """Extends `PerThreeMachine` with the ability to default from `None`s. """ def __init__(self) -> None: @@ -921,8 +922,8 @@ def version_compare(vstr1: str, vstr2: str) -> bool: def version_compare_many(vstr1: str, conditions: T.Union[str, T.Iterable[str]]) -> T.Tuple[bool, T.List[str], T.List[str]]: if isinstance(conditions, str): conditions = [conditions] - found = [] - not_found = [] + found: T.List[str] = [] + not_found: T.List[str] = [] for req in conditions: if not version_compare(vstr1, req): not_found.append(req) @@ -1131,7 +1132,7 @@ if is_windows(): return result def split_args(cmd: str) -> T.List[str]: - result = [] + result: T.List[str] = [] arg = '' num_backslashes = 0 num_quotes = 0 @@ -1179,7 +1180,7 @@ def join_args(args: T.Iterable[str]) -> str: def do_replacement(regex: T.Pattern[str], line: str, variable_format: Literal['meson', 'cmake', 'cmake@'], confdata: T.Union[T.Dict[str, T.Tuple[str, T.Optional[str]]], 'ConfigurationData']) -> T.Tuple[str, T.Set[str]]: - missing_variables = set() # type: T.Set[str] + missing_variables: T.Set[str] = set() if variable_format == 'cmake': start_tag = '${' backslash_tag = '\\${' @@ -1218,10 +1219,10 @@ def do_define(regex: T.Pattern[str], line: str, confdata: 'ConfigurationData', variable_format: Literal['meson', 'cmake', 'cmake@'], subproject: T.Optional[SubProject] = None) -> str: def get_cmake_define(line: str, confdata: 'ConfigurationData') -> str: arr = line.split() - define_value = [] + define_value: T.List[str] = [] for token in arr[2:]: try: - (v, desc) = confdata.get(token) + v, _ = confdata.get(token) define_value += [str(v)] except KeyError: define_value += [token] @@ -1237,7 +1238,7 @@ def do_define(regex: T.Pattern[str], line: str, confdata: 'ConfigurationData', varname = arr[1] try: - (v, desc) = confdata.get(varname) + v, _ = confdata.get(varname) except KeyError: return '/* #undef %s */\n' % varname if isinstance(v, bool): @@ -1253,7 +1254,7 @@ def do_define(regex: T.Pattern[str], line: str, confdata: 'ConfigurationData', else: result = get_cmake_define(line, confdata) result = f'#define {varname} {result}\n' - (result, missing_variable) = do_replacement(regex, result, variable_format, confdata) + result, _ = do_replacement(regex, result, variable_format, confdata) return result else: raise MesonException('#mesondefine argument "%s" is of unknown type.' % varname) @@ -1267,9 +1268,9 @@ def get_variable_regex(variable_format: Literal['meson', 'cmake', 'cmake@'] = 'm regex = re.compile(r'(?:\\\\)+(?=\\?\$)|\\\${|\${([-a-zA-Z0-9_]+)}') return regex -def do_conf_str(src: str, data: list, confdata: 'ConfigurationData', +def do_conf_str(src: str, data: T.List[str], confdata: 'ConfigurationData', variable_format: Literal['meson', 'cmake', 'cmake@'], - encoding: str = 'utf-8', subproject: T.Optional[SubProject] = None) -> T.Tuple[T.List[str], T.Set[str], bool]: + subproject: T.Optional[SubProject] = None) -> T.Tuple[T.List[str], T.Set[str], bool]: def line_is_valid(line: str, variable_format: str) -> bool: if variable_format == 'meson': if '#cmakedefine' in line: @@ -1285,8 +1286,8 @@ def do_conf_str(src: str, data: list, confdata: 'ConfigurationData', if variable_format != 'meson': search_token = '#cmakedefine' - result = [] - missing_variables = set() + result: T.List[str] = [] + missing_variables: T.Set[str] = set() # Detect when the configuration data is empty and no tokens were found # during substitution so we can warn the user to use the `copy:` kwarg. confdata_useless = not confdata.keys() @@ -1314,7 +1315,7 @@ def do_conf_file(src: str, dst: str, confdata: 'ConfigurationData', except Exception as e: raise MesonException(f'Could not read input file {src}: {e!s}') - (result, missing_variables, confdata_useless) = do_conf_str(src, data, confdata, variable_format, encoding, subproject) + (result, missing_variables, confdata_useless) = do_conf_str(src, data, confdata, variable_format, subproject) dst_tmp = dst + '~' try: with open(dst_tmp, 'w', encoding=encoding, newline='') as f: @@ -1394,7 +1395,7 @@ def listify(item: T.Any, flatten: bool = True) -> T.List[T.Any]: ''' if not isinstance(item, list): return [item] - result = [] # type: T.List[T.Any] + result: T.List[T.Any] = [] for i in item: if flatten and isinstance(i, list): result += listify(i, flatten=True) @@ -1435,7 +1436,7 @@ def stringlistify(item: T.Union[T.Any, T.Sequence[T.Any]]) -> T.List[str]: def expand_arguments(args: T.Iterable[str]) -> T.Optional[T.List[str]]: - expended_args = [] # type: T.List[str] + expended_args: T.List[str] = [] for arg in args: if not arg.startswith('@'): expended_args.append(arg) @@ -1554,8 +1555,8 @@ def iter_regexin_iter(regexiter: T.Iterable[str], initer: T.Iterable[str]) -> T. def _substitute_values_check_errors(command: T.List[str], values: T.Dict[str, T.Union[str, T.List[str]]]) -> None: # Error checking - inregex = ['@INPUT([0-9]+)?@', '@PLAINNAME@', '@BASENAME@'] # type: T.List[str] - outregex = ['@OUTPUT([0-9]+)?@', '@OUTDIR@'] # type: T.List[str] + inregex: T.List[str] = ['@INPUT([0-9]+)?@', '@PLAINNAME@', '@BASENAME@'] + outregex: T.List[str] = ['@OUTPUT([0-9]+)?@', '@OUTDIR@'] if '@INPUT@' not in values: # Error out if any input-derived templates are present in the command match = iter_regexin_iter(inregex, command) @@ -1619,7 +1620,7 @@ def substitute_values(command: T.List[str], values: T.Dict[str, T.Union[str, T.L _substitute_values_check_errors(command, values) # Substitution - outcmd = [] # type: T.List[str] + outcmd: T.List[str] = [] rx_keys = [re.escape(key) for key in values if key not in ('@INPUT@', '@OUTPUT@')] value_rx = re.compile('|'.join(rx_keys)) if rx_keys else None for vv in command: @@ -1685,7 +1686,7 @@ def get_filenames_templates_dict(inputs: T.List[str], outputs: T.List[str]) -> T @OUTPUT0@, @OUTPUT1@, ... one for each output file ''' - values = {} # type: T.Dict[str, T.Union[str, T.List[str]]] + values: T.Dict[str, T.Union[str, T.List[str]]] = {} # Gather values derived from the input if inputs: # We want to substitute all the inputs. @@ -1964,7 +1965,7 @@ try: from tqdm import tqdm except ImportError: # ideally we would use a typing.Protocol here, but it's part of typing_extensions until 3.8 - ProgressBar = ProgressBarFallback # type: T.Union[T.Type[ProgressBarFallback], T.Type[ProgressBarTqdm]] + ProgressBar: T.Union[T.Type[ProgressBarFallback], T.Type[ProgressBarTqdm]] = ProgressBarFallback else: class ProgressBarTqdm(tqdm): def __init__(self, *args: T.Any, bar_type: T.Optional[str] = None, **kwargs: T.Any) -> None: @@ -1991,7 +1992,7 @@ class RealPathAction(argparse.Action): super().__init__(option_strings, dest, nargs=None, default=default, **kwargs) def __call__(self, parser: argparse.ArgumentParser, namespace: argparse.Namespace, - values: T.Union[str, T.Sequence[T.Any], None], option_string: str = None) -> None: + values: T.Union[str, T.Sequence[T.Any], None], option_string: T.Optional[str] = None) -> None: assert isinstance(values, str) setattr(namespace, self.dest, os.path.abspath(os.path.realpath(values))) @@ -2025,9 +2026,9 @@ def get_wine_shortpath(winecmd: T.List[str], wine_paths: T.List[str], return wine_path # Check paths that can be reduced by making them relative to workdir. - rel_paths = [] + rel_paths: T.List[str] = [] if workdir: - abs_paths = [] + abs_paths: T.List[str] = [] for p in wine_paths: try: rel = Path(p).relative_to(workdir) @@ -2064,7 +2065,7 @@ def get_wine_shortpath(winecmd: T.List[str], wine_paths: T.List[str], def run_once(func: T.Callable[..., _T]) -> T.Callable[..., _T]: - ret = [] # type: T.List[_T] + ret: T.List[_T] = [] @wraps(func) def wrapper(*args: T.Any, **kwargs: T.Any) -> _T: |