Merge pull request #11976 from tristan957/cleanups

Some various type related cleanups
pull/11727/merge
Jussi Pakkanen 1 year ago committed by GitHub
commit 0dba7340ec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      mesonbuild/backend/ninjabackend.py
  2. 13
      mesonbuild/compilers/asm.py
  3. 257
      mesonbuild/compilers/compilers.py
  4. 34
      mesonbuild/compilers/cpp.py
  5. 97
      mesonbuild/compilers/d.py
  6. 10
      mesonbuild/compilers/fortran.py
  7. 29
      mesonbuild/compilers/mixins/ccrx.py
  8. 8
      mesonbuild/compilers/mixins/clang.py
  9. 52
      mesonbuild/compilers/mixins/clike.py
  10. 31
      mesonbuild/compilers/mixins/compcert.py
  11. 4
      mesonbuild/compilers/mixins/elbrus.py
  12. 11
      mesonbuild/compilers/mixins/emscripten.py
  13. 55
      mesonbuild/compilers/mixins/gnu.py
  14. 12
      mesonbuild/compilers/mixins/intel.py
  15. 4
      mesonbuild/compilers/mixins/islinker.py
  16. 47
      mesonbuild/compilers/mixins/metrowerks.py
  17. 31
      mesonbuild/compilers/mixins/ti.py
  18. 55
      mesonbuild/compilers/mixins/visualstudio.py
  19. 10
      mesonbuild/compilers/vala.py
  20. 49
      mesonbuild/coredata.py
  21. 27
      mesonbuild/environment.py
  22. 52
      mesonbuild/linkers/linkers.py
  23. 67
      mesonbuild/utils/universal.py

@ -2797,7 +2797,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
else: else:
return compiler.get_compile_debugfile_args(objfile, pch=False) 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) return linker.get_link_debugfile_name(outname)
def get_link_debugfile_args(self, linker, target, outname): def get_link_debugfile_args(self, linker, target, outname):

@ -11,7 +11,7 @@ if T.TYPE_CHECKING:
from ..mesonlib import MachineChoice from ..mesonlib import MachineChoice
from ..envconfig import MachineInfo from ..envconfig import MachineInfo
nasm_optimization_args = { nasm_optimization_args: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'0': ['-O0'], '0': ['-O0'],
'g': ['-O0'], 'g': ['-O0'],
@ -19,7 +19,7 @@ nasm_optimization_args = {
'2': ['-Ox'], '2': ['-Ox'],
'3': ['-Ox'], '3': ['-Ox'],
's': ['-Ox'], 's': ['-Ox'],
} # type: T.Dict[str, T.List[str]] }
class NasmCompiler(Compiler): class NasmCompiler(Compiler):
@ -69,7 +69,7 @@ class NasmCompiler(Compiler):
return ['-o', outputname] return ['-o', outputname]
def unix_args_to_native(self, args: T.List[str]) -> T.List[str]: def unix_args_to_native(self, args: T.List[str]) -> T.List[str]:
outargs = [] outargs: T.List[str] = []
for arg in args: for arg in args:
if arg == '-pthread': if arg == '-pthread':
continue continue
@ -295,7 +295,12 @@ class MetrowerksAsmCompiler(MetrowerksCompiler, Compiler):
Compiler.__init__(self, ccache, exelist, version, for_machine, info, linker, full_version, is_cross) Compiler.__init__(self, ccache, exelist, version, for_machine, info, linker, full_version, is_cross)
MetrowerksCompiler.__init__(self) 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') self.can_compile_suffixes.add('s')
def get_crt_compile_args(self, crt_val: str, buildtype: str) -> T.List[str]: def get_crt_compile_args(self, crt_val: str, buildtype: str) -> T.List[str]:

@ -92,12 +92,12 @@ clib_langs = ('objcpp', 'cpp', 'objc', 'c', 'nasm', 'fortran')
clink_langs = ('d', 'cuda') + clib_langs clink_langs = ('d', 'cuda') + clib_langs
SUFFIX_TO_LANG = dict(itertools.chain(*( 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 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 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]+)?$') soregex = re.compile(r'.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$')
# Environment variables that each lang uses. # Environment variables that each lang uses.
@ -190,99 +190,114 @@ class CompileCheckMode(enum.Enum):
LINK = 'link' LINK = 'link'
cuda_buildtype_args = {'plain': [], cuda_buildtype_args: T.Dict[str, T.List[str]] = {
'debug': ['-g', '-G'], 'plain': [],
'debugoptimized': ['-g', '-lineinfo'], 'debug': ['-g', '-G'],
'release': [], 'debugoptimized': ['-g', '-lineinfo'],
'minsize': [], 'release': [],
'custom': [], 'minsize': [],
} # type: T.Dict[str, T.List[str]] 'custom': [],
java_buildtype_args = {'plain': [], }
'debug': ['-g'],
'debugoptimized': ['-g'], java_buildtype_args: T.Dict[str, T.List[str]] = {
'release': [], 'plain': [],
'minsize': [], 'debug': ['-g'],
'custom': [], 'debugoptimized': ['-g'],
} # type: T.Dict[str, T.List[str]] 'release': [],
'minsize': [],
rust_buildtype_args = {'plain': [], 'custom': [],
'debug': [], }
'debugoptimized': [],
'release': [], rust_buildtype_args: T.Dict[str, T.List[str]] = {
'minsize': [], 'plain': [],
'custom': [], 'debug': [],
} # type: T.Dict[str, T.List[str]] 'debugoptimized': [],
'release': [],
d_gdc_buildtype_args = {'plain': [], 'minsize': [],
'debug': [], 'custom': [],
'debugoptimized': ['-finline-functions'], }
'release': ['-finline-functions'],
'minsize': [], d_gdc_buildtype_args: T.Dict[str, T.List[str]] = {
'custom': [], 'plain': [],
} # type: T.Dict[str, T.List[str]] 'debug': [],
'debugoptimized': ['-finline-functions'],
d_ldc_buildtype_args = {'plain': [], 'release': ['-finline-functions'],
'debug': [], 'minsize': [],
'debugoptimized': ['-enable-inlining', '-Hkeep-all-bodies'], 'custom': [],
'release': ['-enable-inlining', '-Hkeep-all-bodies'], }
'minsize': [],
'custom': [], d_ldc_buildtype_args: T.Dict[str, T.List[str]] = {
} # type: T.Dict[str, T.List[str]] 'plain': [],
'debug': [],
d_dmd_buildtype_args = {'plain': [], 'debugoptimized': ['-enable-inlining', '-Hkeep-all-bodies'],
'debug': [], 'release': ['-enable-inlining', '-Hkeep-all-bodies'],
'debugoptimized': ['-inline'], 'minsize': [],
'release': ['-inline'], 'custom': [],
'minsize': [], }
'custom': [],
} # type: T.Dict[str, T.List[str]] d_dmd_buildtype_args: T.Dict[str, T.List[str]] = {
'plain': [],
mono_buildtype_args = {'plain': [], 'debug': [],
'debug': [], 'debugoptimized': ['-inline'],
'debugoptimized': ['-optimize+'], 'release': ['-inline'],
'release': ['-optimize+'], 'minsize': [],
'minsize': [], 'custom': [],
'custom': [], }
} # type: T.Dict[str, T.List[str]]
mono_buildtype_args: T.Dict[str, T.List[str]] = {
swift_buildtype_args = {'plain': [], 'plain': [],
'debug': [], 'debug': [],
'debugoptimized': [], 'debugoptimized': ['-optimize+'],
'release': [], 'release': ['-optimize+'],
'minsize': [], 'minsize': [],
'custom': [], 'custom': [],
} # type: T.Dict[str, T.List[str]] }
swift_buildtype_args: T.Dict[str, T.List[str]] = {
'plain': [],
'debug': [],
'debugoptimized': [],
'release': [],
'minsize': [],
'custom': [],
}
gnu_winlibs = ['-lkernel32', '-luser32', '-lgdi32', '-lwinspool', '-lshell32', 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', msvc_winlibs = ['kernel32.lib', 'user32.lib', 'gdi32.lib',
'winspool.lib', 'shell32.lib', 'ole32.lib', 'oleaut32.lib', 'winspool.lib', 'shell32.lib', 'ole32.lib', 'oleaut32.lib',
'uuid.lib', 'comdlg32.lib', 'advapi32.lib'] # type: T.List[str] 'uuid.lib', 'comdlg32.lib', 'advapi32.lib']
clike_optimization_args = {'plain': [], clike_optimization_args: T.Dict[str, T.List[str]] = {
'0': [], 'plain': [],
'g': [], '0': [],
'1': ['-O1'], 'g': [],
'2': ['-O2'], '1': ['-O1'],
'3': ['-O3'], '2': ['-O2'],
's': ['-Os'], '3': ['-O3'],
} # type: T.Dict[str, T.List[str]] 's': ['-Os'],
}
cuda_optimization_args = {'plain': [],
'0': [], cuda_optimization_args: T.Dict[str, T.List[str]] = {
'g': ['-O0'], 'plain': [],
'1': ['-O1'], '0': [],
'2': ['-O2'], 'g': ['-O0'],
'3': ['-O3'], '1': ['-O1'],
's': ['-O3'] '2': ['-O2'],
} # type: T.Dict[str, T.List[str]] '3': ['-O3'],
's': ['-O3']
cuda_debug_args = {False: [], }
True: ['-g']} # type: T.Dict[bool, T.List[str]]
cuda_debug_args: T.Dict[bool, T.List[str]] = {
clike_debug_args = {False: [], False: [],
True: ['-g']} # type: T.Dict[bool, T.List[str]] True: ['-g']
}
clike_debug_args: T.Dict[bool, T.List[str]] = {
False: [],
True: ['-g']
}
base_options: 'KeyedOptionDictType' = { base_options: 'KeyedOptionDictType' = {
OptionKey('b_pch'): coredata.UserBooleanOption('Use precompiled headers', True), 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]: def get_base_compile_args(options: 'KeyedOptionDictType', compiler: 'Compiler') -> T.List[str]:
args = [] # type T.List[str] args: T.List[str] = []
try: try:
if options[OptionKey('b_lto')].value: if options[OptionKey('b_lto')].value:
args.extend(compiler.get_lto_compile_args( 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', def get_base_link_args(options: 'KeyedOptionDictType', linker: 'Compiler',
is_shared_module: bool, build_dir: str) -> T.List[str]: is_shared_module: bool, build_dir: str) -> T.List[str]:
args = [] # type: T.List[str] args: T.List[str] = []
try: try:
if options[OptionKey('b_lto')].value: if options[OptionKey('b_lto')].value:
thinlto_cache_dir = None thinlto_cache_dir = None
@ -499,18 +514,18 @@ class CompileResult(HoldableObject):
class Compiler(HoldableObject, metaclass=abc.ABCMeta): class Compiler(HoldableObject, metaclass=abc.ABCMeta):
# Libraries to ignore in find_library() since they are provided by the # Libraries to ignore in find_library() since they are provided by the
# compiler or the C library. Currently only used for MSVC. # 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 # Libraries that are internal compiler implementations, and must not be
# manually searched. # 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 INVOKES_LINKER = True
language: str language: str
id: str id: str
warn_args: T.Dict[str, T.List[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, def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str,
for_machine: MachineChoice, info: 'MachineInfo', for_machine: MachineChoice, info: 'MachineInfo',
@ -522,7 +537,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
if not hasattr(self, 'file_suffixes'): if not hasattr(self, 'file_suffixes'):
self.file_suffixes = lang_suffixes[self.language] self.file_suffixes = lang_suffixes[self.language]
if not hasattr(self, 'can_compile_suffixes'): 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.default_suffix = self.file_suffixes[0]
self.version = version self.version = version
self.full_version = full_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]: def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]:
return self.linker.has_multi_arguments(args, env) return self.linker.has_multi_arguments(args, env)
def _get_compile_output(self, dirname: str, mode: str) -> str: def _get_compile_output(self, dirname: str, mode: CompileCheckMode) -> str:
# TODO: mode should really be an enum assert mode != CompileCheckMode.PREPROCESS, 'In pre-processor mode, the output is sent to stdout and discarded'
# In pre-processor mode, the output is sent to stdout and discarded
if mode == 'preprocess':
return None
# Extension only matters if running results; '.exe' is # Extension only matters if running results; '.exe' is
# guaranteed to be executable on every platform. # guaranteed to be executable on every platform.
if mode == 'link': if mode == CompileCheckMode.LINK:
suffix = 'exe' suffix = 'exe'
else: else:
suffix = 'obj' suffix = 'obj'
return os.path.join(dirname, 'output.' + suffix) return os.path.join(dirname, 'output.' + suffix)
def get_compiler_args_for_mode(self, mode: CompileCheckMode) -> T.List[str]: def get_compiler_args_for_mode(self, mode: CompileCheckMode) -> T.List[str]:
# TODO: mode should really be an enum args: T.List[str] = []
args = [] # type: T.List[str]
args += self.get_always_args() args += self.get_always_args()
if mode is CompileCheckMode.COMPILE: if mode is CompileCheckMode.COMPILE:
args += self.get_compile_only_args() args += self.get_compile_only_args()
@ -816,9 +827,13 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
@contextlib.contextmanager @contextlib.contextmanager
def compile(self, code: 'mesonlib.FileOrString', def compile(self, code: 'mesonlib.FileOrString',
extra_args: T.Union[None, CompilerArgs, T.List[str]] = None, 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]]: temp_dir: T.Optional[str] = None) -> T.Iterator[T.Optional[CompileResult]]:
# TODO: there isn't really any reason for this to be a contextmanager # 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: if extra_args is None:
extra_args = [] extra_args = []
@ -845,8 +860,8 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
commands.append(srcname) commands.append(srcname)
# Preprocess mode outputs to stdout, so no output args # Preprocess mode outputs to stdout, so no output args
output = self._get_compile_output(tmpdirname, mode) if mode != CompileCheckMode.PREPROCESS:
if mode != 'preprocess': output = self._get_compile_output(tmpdirname, mode)
commands += self.get_output_args(output) commands += self.get_output_args(output)
commands.extend(self.get_compiler_args_for_mode(CompileCheckMode(mode))) commands.extend(self.get_compiler_args_for_mode(CompileCheckMode(mode)))
@ -874,13 +889,13 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
@contextlib.contextmanager @contextlib.contextmanager
def cached_compile(self, code: 'mesonlib.FileOrString', cdata: coredata.CoreData, *, def cached_compile(self, code: 'mesonlib.FileOrString', cdata: coredata.CoreData, *,
extra_args: T.Union[None, T.List[str], CompilerArgs] = None, 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]]: 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 # TODO: There's isn't really any reason for this to be a context manager
# Calculate the key # Calculate the key
textra_args = tuple(extra_args) if extra_args is not None else tuple() # type: T.Tuple[str, ...] textra_args: T.Tuple[str, ...] = tuple(extra_args) if extra_args is not None else tuple()
key = (tuple(self.exelist), self.version, code, textra_args, mode) # type: coredata.CompilerCheckCacheKey key: coredata.CompilerCheckCacheKey = (tuple(self.exelist), self.version, code, textra_args, mode)
# Check if not cached, and generate, otherwise get from the cache # Check if not cached, and generate, otherwise get from the cache
if key in cdata.compiler_check_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]: def get_compile_debugfile_args(self, rel_obj: str, pch: bool = False) -> T.List[str]:
return [] 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) return self.linker.get_debugfile_name(targetfile)
def get_link_debugfile_args(self, targetfile: str) -> T.List[str]: 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_exact = ('-headerpad_max_install_names',)
rm_prefixes = ('-Wl,', '-L',) rm_prefixes = ('-Wl,', '-L',)
rm_next = ('-L', '-framework',) rm_next = ('-L', '-framework',)
ret = [] # T.List[str] ret: T.List[str] = []
iargs = iter(args) iargs = iter(args)
for arg in iargs: for arg in iargs:
# Remove this argument # Remove this argument
@ -1283,15 +1298,14 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
def _build_wrapper(self, code: 'mesonlib.FileOrString', env: 'Environment', 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, extra_args: T.Union[None, CompilerArgs, T.List[str], T.Callable[[CompileCheckMode], T.List[str]]] = None,
dependencies: T.Optional[T.List['Dependency']] = None, dependencies: T.Optional[T.List['Dependency']] = None,
mode: str = 'compile', want_output: bool = False, mode: CompileCheckMode = CompileCheckMode.COMPILE, want_output: bool = False,
disable_cache: bool = False, disable_cache: bool = False) -> T.Iterator[T.Optional[CompileResult]]:
temp_dir: str = None) -> T.Iterator[T.Optional[CompileResult]]:
"""Helper for getting a cached value when possible. """Helper for getting a cached value when possible.
This method isn't meant to be called externally, it's mean to be This method isn't meant to be called externally, it's mean to be
wrapped by other methods like compiles() and links(). 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: 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: with self.compile(code, extra_args=args, mode=mode, want_output=want_output, temp_dir=env.scratch_dir) as r:
yield r yield r
@ -1302,7 +1316,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
def compiles(self, code: 'mesonlib.FileOrString', env: 'Environment', *, def compiles(self, code: 'mesonlib.FileOrString', env: 'Environment', *,
extra_args: T.Union[None, T.List[str], CompilerArgs, T.Callable[[CompileCheckMode], T.List[str]]] = None, extra_args: T.Union[None, T.List[str], CompilerArgs, T.Callable[[CompileCheckMode], T.List[str]]] = None,
dependencies: T.Optional[T.List['Dependency']] = None, dependencies: T.Optional[T.List['Dependency']] = None,
mode: str = 'compile', mode: CompileCheckMode = CompileCheckMode.COMPILE,
disable_cache: bool = False) -> T.Tuple[bool, bool]: disable_cache: bool = False) -> T.Tuple[bool, bool]:
with self._build_wrapper(code, env, extra_args, dependencies, mode, disable_cache=disable_cache) as p: with self._build_wrapper(code, env, extra_args, dependencies, mode, disable_cache=disable_cache) as p:
return p.returncode == 0, p.cached return p.returncode == 0, p.cached
@ -1311,16 +1325,15 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
compiler: T.Optional['Compiler'] = None, compiler: T.Optional['Compiler'] = None,
extra_args: T.Union[None, T.List[str], CompilerArgs, T.Callable[[CompileCheckMode], T.List[str]]] = None, extra_args: T.Union[None, T.List[str], CompilerArgs, T.Callable[[CompileCheckMode], T.List[str]]] = None,
dependencies: T.Optional[T.List['Dependency']] = None, dependencies: T.Optional[T.List['Dependency']] = None,
mode: str = 'compile',
disable_cache: bool = False) -> T.Tuple[bool, bool]: disable_cache: bool = False) -> T.Tuple[bool, bool]:
if compiler: if compiler:
with compiler._build_wrapper(code, env, dependencies=dependencies, want_output=True) as r: with compiler._build_wrapper(code, env, dependencies=dependencies, want_output=True) as r:
objfile = mesonlib.File.from_absolute_file(r.output_name) objfile = mesonlib.File.from_absolute_file(r.output_name)
return self.compiles(objfile, env, extra_args=extra_args, 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, 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]: 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.""" """Used by D for extra language features."""

@ -26,6 +26,7 @@ from .compilers import (
gnu_winlibs, gnu_winlibs,
msvc_winlibs, msvc_winlibs,
Compiler, Compiler,
CompileCheckMode,
) )
from .c_function_attributes import CXX_FUNC_ATTRIBUTES, C_FUNC_ATTRIBUTES from .c_function_attributes import CXX_FUNC_ATTRIBUTES, C_FUNC_ATTRIBUTES
from .mixins.clike import CLikeCompiler 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 from .mixins.metrowerks import mwccarm_instruction_set_args, mwcceppc_instruction_set_args
if T.TYPE_CHECKING: if T.TYPE_CHECKING:
from .compilers import CompileCheckMode
from ..coredata import MutableKeyedOptionDictType, KeyedOptionDictType from ..coredata import MutableKeyedOptionDictType, KeyedOptionDictType
from ..dependencies import Dependency from ..dependencies import Dependency
from ..envconfig import MachineInfo from ..envconfig import MachineInfo
@ -82,8 +82,8 @@ class CPPCompiler(CLikeCompiler, Compiler):
full_version=full_version) full_version=full_version)
CLikeCompiler.__init__(self, exe_wrapper) CLikeCompiler.__init__(self, exe_wrapper)
@staticmethod @classmethod
def get_display_language() -> str: def get_display_language(cls) -> str:
return 'C++' return 'C++'
def get_no_stdinc_args(self) -> T.List[str]: 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 # 2. even if it did have an env object, that might contain another more
# recent -std= argument, which might lead to a cascaded failure. # recent -std= argument, which might lead to a cascaded failure.
CPP_TEST = 'int i = static_cast<int>(0);' 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: if p.returncode == 0:
mlog.debug(f'Compiler accepts {cpp_std_value}:', 'YES') mlog.debug(f'Compiler accepts {cpp_std_value}:', 'YES')
return True return True
@ -263,7 +263,7 @@ class ClangCPPCompiler(_StdCPPLibMixin, ClangCompiler, CPPCompiler):
return opts return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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) key = OptionKey('std', machine=self.for_machine, lang=self.language)
std = options[key] std = options[key]
if std.value != 'none': if std.value != 'none':
@ -315,7 +315,7 @@ class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler):
defines=defines, full_version=full_version) defines=defines, full_version=full_version)
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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) key = OptionKey('std', machine=self.for_machine, lang=self.language)
std = options[key] std = options[key]
if std.value != 'none': if std.value != 'none':
@ -359,7 +359,7 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
return opts return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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) key = OptionKey('std', machine=self.for_machine, lang=self.language)
std = options[key] std = options[key]
if std.value != 'none': if std.value != 'none':
@ -425,7 +425,7 @@ class GnuCPPCompiler(_StdCPPLibMixin, GnuCompiler, CPPCompiler):
return opts return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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) key = OptionKey('std', machine=self.for_machine, lang=self.language)
std = options[key] std = options[key]
if std.value != 'none': 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. # Elbrus C++ compiler does not support RTTI, so don't check for it.
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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) key = OptionKey('std', machine=self.for_machine, lang=self.language)
std = options[key] std = options[key]
if std.value != 'none': if std.value != 'none':
@ -597,7 +597,7 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler):
return opts return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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) key = OptionKey('std', machine=self.for_machine, lang=self.language)
std = options[key] std = options[key]
if std.value != 'none': if std.value != 'none':
@ -664,7 +664,7 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase):
return opts return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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) key = OptionKey('std', machine=self.for_machine, lang=self.language)
eh = options[key.evolve('eh')] eh = options[key.evolve('eh')]
@ -829,7 +829,7 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler):
return opts return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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) key = OptionKey('std', machine=self.for_machine, lang=self.language)
std = options[key] std = options[key]
if std.value == 'c++11': if std.value == 'c++11':
@ -864,8 +864,8 @@ class CcrxCPPCompiler(CcrxCompiler, CPPCompiler):
def get_compile_only_args(self) -> T.List[str]: def get_compile_only_args(self) -> T.List[str]:
return [] return []
def get_output_args(self, target: str) -> T.List[str]: def get_output_args(self, outputname: str) -> T.List[str]:
return [f'-output=obj={target}'] return [f'-output=obj={outputname}']
def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]: def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return [] return []
@ -889,7 +889,7 @@ class TICPPCompiler(TICompiler, CPPCompiler):
return opts return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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) key = OptionKey('std', machine=self.for_machine, lang=self.language)
std = options[key] std = options[key]
if std.value != 'none': if std.value != 'none':
@ -928,7 +928,7 @@ class MetrowerksCPPCompilerARM(MetrowerksCompiler, CPPCompiler):
return opts return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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)] std = options[OptionKey('std', machine=self.for_machine, lang=self.language)]
if std.value != 'none': if std.value != 'none':
args.append('-lang') args.append('-lang')
@ -957,7 +957,7 @@ class MetrowerksCPPCompilerEmbeddedPowerPC(MetrowerksCompiler, CPPCompiler):
return opts return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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)] std = options[OptionKey('std', machine=self.for_machine, lang=self.language)]
if std.value != 'none': if std.value != 'none':
args.append('-lang ' + std.value) args.append('-lang ' + std.value)

@ -50,40 +50,46 @@ if T.TYPE_CHECKING:
else: else:
CompilerMixinBase = object CompilerMixinBase = object
d_feature_args = {'gcc': {'unittest': '-funittest', d_feature_args: T.Dict[str, T.Dict[str, str]] = {
'debug': '-fdebug', 'gcc': {
'version': '-fversion', 'unittest': '-funittest',
'import_dir': '-J' 'debug': '-fdebug',
}, 'version': '-fversion',
'llvm': {'unittest': '-unittest', 'import_dir': '-J'
'debug': '-d-debug', },
'version': '-d-version', 'llvm': {
'import_dir': '-J' 'unittest': '-unittest',
}, 'debug': '-d-debug',
'dmd': {'unittest': '-unittest', 'version': '-d-version',
'debug': '-debug', 'import_dir': '-J'
'version': '-version', },
'import_dir': '-J' 'dmd': {
} 'unittest': '-unittest',
} # type: T.Dict[str, T.Dict[str, str]] 'debug': '-debug',
'version': '-version',
ldc_optimization_args = {'plain': [], 'import_dir': '-J'
'0': [], }
'g': [], }
'1': ['-O1'],
'2': ['-O2'], ldc_optimization_args: T.Dict[str, T.List[str]] = {
'3': ['-O3'], 'plain': [],
's': ['-Oz'], '0': [],
} # type: T.Dict[str, T.List[str]] 'g': [],
'1': ['-O1'],
dmd_optimization_args = {'plain': [], '2': ['-O2'],
'0': [], '3': ['-O3'],
'g': [], 's': ['-Oz'],
'1': ['-O'], }
'2': ['-O'],
'3': ['-O'], dmd_optimization_args: T.Dict[str, T.List[str]] = {
's': ['-O'], 'plain': [],
} # type: T.Dict[str, T.List[str]] '0': [],
'g': [],
'1': ['-O'],
'2': ['-O'],
'3': ['-O'],
's': ['-O'],
}
class DmdLikeCompilerMixin(CompilerMixinBase): class DmdLikeCompilerMixin(CompilerMixinBase):
@ -102,7 +108,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase):
self._dmd_has_depfile = version_compare(dmd_frontend_version, ">=2.095.0") self._dmd_has_depfile = version_compare(dmd_frontend_version, ">=2.095.0")
if T.TYPE_CHECKING: 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]: ... 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]: 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 # 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 # 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 # so we have to copy the kwargs (target.d_features) dict before popping from it
kwargs = kwargs.copy() 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 # 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 # do directly, each argument -rpath and the value to rpath, need to be
# split into two separate arguments both prefaced with the -L=. # 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( (rpath_args, rpath_dirs_to_remove) = super().build_rpath_args(
env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath) env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath)
for r in rpath_args: for r in rpath_args:
@ -292,7 +298,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase):
# can understand. # can understand.
# The flags might have been added by pkg-config files, # The flags might have been added by pkg-config files,
# and are therefore out of the user's control. # and are therefore out of the user's control.
dcargs = [] dcargs: T.List[str] = []
# whether we hit a linker argument that expect another arg # whether we hit a linker argument that expect another arg
# see the comment in the "-L" section # see the comment in the "-L" section
link_expect_arg = False link_expect_arg = False
@ -301,7 +307,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase):
] ]
for arg in args: for arg in args:
# Translate OS specific arguments first. # Translate OS specific arguments first.
osargs = [] # type: T.List[str] osargs: T.List[str] = []
if info.is_windows(): if info.is_windows():
osargs = cls.translate_arg_to_windows(arg) osargs = cls.translate_arg_to_windows(arg)
elif info.is_darwin(): elif info.is_darwin():
@ -415,7 +421,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase):
@classmethod @classmethod
def translate_arg_to_windows(cls, arg: str) -> T.List[str]: def translate_arg_to_windows(cls, arg: str) -> T.List[str]:
args = [] args: T.List[str] = []
if arg.startswith('-Wl,'): if arg.startswith('-Wl,'):
# Translate linker arguments here. # Translate linker arguments here.
linkargs = arg[arg.index(',') + 1:].split(',') linkargs = arg[arg.index(',') + 1:].split(',')
@ -441,7 +447,7 @@ class DmdLikeCompilerMixin(CompilerMixinBase):
@classmethod @classmethod
def _translate_arg_to_osx(cls, arg: str) -> T.List[str]: def _translate_arg_to_osx(cls, arg: str) -> T.List[str]:
args = [] args: T.List[str] = []
if arg.startswith('-install_name'): if arg.startswith('-install_name'):
args.append('-L=' + arg) args.append('-L=' + arg)
return args return args
@ -494,15 +500,14 @@ class DmdLikeCompilerMixin(CompilerMixinBase):
# LDC and DMD actually do use a linker, but they proxy all of that with # LDC and DMD actually do use a linker, but they proxy all of that with
# their own arguments # their own arguments
soargs: T.List[str] = []
if self.linker.id.startswith('ld.'): if self.linker.id.startswith('ld.'):
soargs = []
for arg in sargs: for arg in sargs:
a, b = arg.split(',', maxsplit=1) a, b = arg.split(',', maxsplit=1)
soargs.append(a) soargs.append(a)
soargs.append(self.LINKER_PREFIX + b) soargs.append(self.LINKER_PREFIX + b)
return soargs return soargs
elif self.linker.id.startswith('ld64'): elif self.linker.id.startswith('ld64'):
soargs = []
for arg in sargs: for arg in sargs:
if not arg.startswith(self.LINKER_PREFIX): if not arg.startswith(self.LINKER_PREFIX):
soargs.append(self.LINKER_PREFIX + arg) 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]: 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 # 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 # 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 # so we have to copy the kwargs (target.d_features) dict before popping from it
kwargs = kwargs.copy() kwargs = kwargs.copy()
@ -713,7 +718,7 @@ class DCompiler(Compiler):
if need_exe_wrapper and self.exe_wrapper is None: if need_exe_wrapper and self.exe_wrapper is None:
raise compilers.CrossNoRunException('Can not run test applications in this cross environment.') raise compilers.CrossNoRunException('Can not run test applications in this cross environment.')
extra_args = self._get_compile_extra_args(extra_args) 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: if p.returncode != 0:
mlog.debug(f'Could not compile test file {p.input_name}: {p.returncode}\n') mlog.debug(f'Could not compile test file {p.input_name}: {p.returncode}\n')
return compilers.RunResult(False) return compilers.RunResult(False)
@ -786,7 +791,7 @@ class DCompiler(Compiler):
import {hname}; import {hname};
''' '''
return self.compiles(code, env, extra_args=extra_args, 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): class GnuDCompiler(GnuCompiler, DCompiler):

@ -20,6 +20,7 @@ from .. import coredata
from .compilers import ( from .compilers import (
clike_debug_args, clike_debug_args,
Compiler, Compiler,
CompileCheckMode,
) )
from .mixins.clike import CLikeCompiler from .mixins.clike import CLikeCompiler
from .mixins.gnu import ( from .mixins.gnu import (
@ -43,7 +44,6 @@ if T.TYPE_CHECKING:
from ..linkers.linkers import DynamicLinker from ..linkers.linkers import DynamicLinker
from ..mesonlib import MachineChoice from ..mesonlib import MachineChoice
from ..programs import ExternalProgram from ..programs import ExternalProgram
from .compilers import CompileCheckMode
class FortranCompiler(CLikeCompiler, Compiler): class FortranCompiler(CLikeCompiler, Compiler):
@ -170,7 +170,7 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler):
return opts return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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) key = OptionKey('std', machine=self.for_machine, lang=self.language)
std = options[key] std = options[key]
if std.value != 'none': if std.value != 'none':
@ -207,7 +207,7 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler):
''' '''
code = f'{prefix}\n#include <{hname}>' code = f'{prefix}\n#include <{hname}>'
return self.compiles(code, env, extra_args=extra_args, 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): class ElbrusFortranCompiler(ElbrusCompiler, FortranCompiler):
@ -311,7 +311,7 @@ class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler):
return opts return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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) key = OptionKey('std', machine=self.for_machine, lang=self.language)
std = options[key] std = options[key]
stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'}
@ -364,7 +364,7 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler):
return opts return opts
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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) key = OptionKey('std', machine=self.for_machine, lang=self.language)
std = options[key] std = options[key]
stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'}

@ -31,35 +31,35 @@ else:
# do). This gives up DRYer type checking, with no runtime impact # do). This gives up DRYer type checking, with no runtime impact
Compiler = object Compiler = object
ccrx_buildtype_args = { ccrx_buildtype_args: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'debug': [], 'debug': [],
'debugoptimized': [], 'debugoptimized': [],
'release': [], 'release': [],
'minsize': [], 'minsize': [],
'custom': [], 'custom': [],
} # type: T.Dict[str, T.List[str]] }
ccrx_optimization_args = { ccrx_optimization_args: T.Dict[str, T.List[str]] = {
'0': ['-optimize=0'], '0': ['-optimize=0'],
'g': ['-optimize=0'], 'g': ['-optimize=0'],
'1': ['-optimize=1'], '1': ['-optimize=1'],
'2': ['-optimize=2'], '2': ['-optimize=2'],
'3': ['-optimize=max'], '3': ['-optimize=max'],
's': ['-optimize=2', '-size'] 's': ['-optimize=2', '-size']
} # type: T.Dict[str, T.List[str]] }
ccrx_debug_args = { ccrx_debug_args: T.Dict[bool, T.List[str]] = {
False: [], False: [],
True: ['-debug'] True: ['-debug']
} # type: T.Dict[bool, T.List[str]] }
class CcrxCompiler(Compiler): class CcrxCompiler(Compiler):
if T.TYPE_CHECKING: if T.TYPE_CHECKING:
is_cross = True is_cross = True
can_compile_suffixes = set() # type: T.Set[str] can_compile_suffixes: T.Set[str] = set()
id = 'ccrx' id = 'ccrx'
@ -68,12 +68,13 @@ class CcrxCompiler(Compiler):
raise EnvironmentException('ccrx supports only cross-compilation.') raise EnvironmentException('ccrx supports only cross-compilation.')
# Assembly # Assembly
self.can_compile_suffixes.add('src') self.can_compile_suffixes.add('src')
default_warn_args = [] # type: T.List[str] default_warn_args: T.List[str] = []
self.warn_args = {'0': [], self.warn_args: T.Dict[str, T.List[str]] = {
'1': default_warn_args, '0': [],
'2': default_warn_args + [], '1': default_warn_args,
'3': default_warn_args + [], '2': default_warn_args + [],
'everything': default_warn_args + []} # type: T.Dict[str, T.List[str]] '3': default_warn_args + [],
'everything': default_warn_args + []}
def get_pic_args(self) -> T.List[str]: def get_pic_args(self) -> T.List[str]:
# PIC support is not enabled by default for CCRX, # PIC support is not enabled by default for CCRX,
@ -109,7 +110,7 @@ class CcrxCompiler(Compiler):
@classmethod @classmethod
def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]: def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]:
result = [] result: T.List[str] = []
for i in args: for i in args:
if i.startswith('-D'): if i.startswith('-D'):
i = '-define=' + i[2:] i = '-define=' + i[2:]

@ -30,13 +30,13 @@ if T.TYPE_CHECKING:
from ...environment import Environment from ...environment import Environment
from ...dependencies import Dependency # noqa: F401 from ...dependencies import Dependency # noqa: F401
clang_color_args = { clang_color_args: T.Dict[str, T.List[str]] = {
'auto': ['-fcolor-diagnostics'], 'auto': ['-fcolor-diagnostics'],
'always': ['-fcolor-diagnostics'], 'always': ['-fcolor-diagnostics'],
'never': ['-fno-color-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': [], 'plain': [],
'0': ['-O0'], '0': ['-O0'],
'g': ['-Og'], 'g': ['-Og'],
@ -44,7 +44,7 @@ clang_optimization_args = {
'2': ['-O2'], '2': ['-O2'],
'3': ['-O3'], '3': ['-O3'],
's': ['-Oz'], 's': ['-Oz'],
} # type: T.Dict[str, T.List[str]] }
class ClangCompiler(GnuLikeCompiler): class ClangCompiler(GnuLikeCompiler):

@ -103,7 +103,7 @@ class CLikeCompilerArgs(arglist.CompilerArgs):
default_dirs = self.compiler.get_default_include_dirs() default_dirs = self.compiler.get_default_include_dirs()
if default_dirs: if default_dirs:
real_default_dirs = [self._cached_realpath(i) for i in 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): for i, each in enumerate(new):
if not each.startswith('-isystem'): if not each.startswith('-isystem'):
continue continue
@ -136,11 +136,11 @@ class CLikeCompiler(Compiler):
"""Shared bits for the C and CPP Compilers.""" """Shared bits for the C and CPP Compilers."""
if T.TYPE_CHECKING: 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 # 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_library_cache: 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_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 internal_libs = arglist.UNIXY_COMPILER_INTERNAL_LIBS
def __init__(self, exe_wrapper: T.Optional['ExternalProgram'] = None): 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 # 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 # 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. # the compiler knows what it's doing, and accept the directory anyway.
retval = [] retval: T.List[str] = []
for d in dirs: 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))] 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 # if no files, accept directory and move on
@ -370,7 +370,7 @@ class CLikeCompiler(Compiler):
#include <{hname}> #include <{hname}>
#endif''' #endif'''
return self.compiles(code, env, extra_args=extra_args, 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, def has_header_symbol(self, hname: str, symbol: str, prefix: str,
env: 'Environment', *, env: 'Environment', *,
@ -389,8 +389,8 @@ class CLikeCompiler(Compiler):
dependencies=dependencies) dependencies=dependencies)
def _get_basic_compiler_args(self, env: 'Environment', mode: CompileCheckMode) -> T.Tuple[T.List[str], T.List[str]]: def _get_basic_compiler_args(self, env: 'Environment', mode: CompileCheckMode) -> T.Tuple[T.List[str], T.List[str]]:
cargs = [] # type: T.List[str] cargs: T.List[str] = []
largs = [] # type: T.List[str] largs: T.List[str] = []
if mode is CompileCheckMode.LINK: if mode is CompileCheckMode.LINK:
# Sometimes we need to manually select the CRT to use with MSVC. # Sometimes we need to manually select the CRT to use with MSVC.
# One example is when trying to do a compiler check that involves # 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 # TODO: we want to ensure the front end does the listifing here
dependencies = [dependencies] dependencies = [dependencies]
# Collect compiler arguments # Collect compiler arguments
cargs = self.compiler_args() # type: arglist.CompilerArgs cargs: arglist.CompilerArgs = self.compiler_args()
largs = [] # type: T.List[str] largs: T.List[str] = []
for d in dependencies: for d in dependencies:
# Add compile flags needed by dependencies # Add compile flags needed by dependencies
cargs += d.get_compile_args() cargs += d.get_compile_args()
@ -475,7 +475,7 @@ class CLikeCompiler(Compiler):
need_exe_wrapper = env.need_exe_wrapper(self.for_machine) need_exe_wrapper = env.need_exe_wrapper(self.for_machine)
if need_exe_wrapper and self.exe_wrapper is None: if need_exe_wrapper and self.exe_wrapper is None:
raise compilers.CrossNoRunException('Can not run test applications in this cross environment.') 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: if p.returncode != 0:
mlog.debug(f'Could not compile test file {p.input_name}: {p.returncode}\n') mlog.debug(f'Could not compile test file {p.input_name}: {p.returncode}\n')
return compilers.RunResult(False) return compilers.RunResult(False)
@ -678,9 +678,9 @@ class CLikeCompiler(Compiler):
{delim}\n{dname}''' {delim}\n{dname}'''
args = self.build_wrapper_args(env, extra_args, dependencies, args = self.build_wrapper_args(env, extra_args, dependencies,
mode=CompileCheckMode.PREPROCESS).to_native() 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: 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: with func() as p:
cached = p.cached cached = p.cached
if p.returncode != 0: if p.returncode != 0:
@ -805,7 +805,7 @@ class CLikeCompiler(Compiler):
# #
# class StrProto(typing.Protocol): # class StrProto(typing.Protocol):
# def __str__(self) -> str: ... # 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 # 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 # 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) args = self.get_compiler_check_args(CompileCheckMode.COMPILE)
n = '_symbols_have_underscore_prefix_searchbin' 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: if p.returncode != 0:
raise RuntimeError(f'BUG: Unable to compile {n!r} check: {p.stderr}') raise RuntimeError(f'BUG: Unable to compile {n!r} check: {p.stderr}')
if not os.path.isfile(p.output_name): if not os.path.isfile(p.output_name):
@ -954,7 +954,7 @@ class CLikeCompiler(Compiler):
#endif #endif
{delim}MESON_UNDERSCORE_PREFIX {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: if p.returncode != 0:
raise RuntimeError(f'BUG: Unable to preprocess _symbols_have_underscore_prefix_define check: {p.stdout}') raise RuntimeError(f'BUG: Unable to preprocess _symbols_have_underscore_prefix_define check: {p.stdout}')
symbol_prefix = p.stdout.partition(delim)[-1].rstrip() symbol_prefix = p.stdout.partition(delim)[-1].rstrip()
@ -1002,7 +1002,7 @@ class CLikeCompiler(Compiler):
return self._symbols_have_underscore_prefix_searchbin(env) 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]: 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 p in prefixes:
for s in suffixes: for s in suffixes:
patterns.append(p + '{}.' + s) patterns.append(p + '{}.' + s)
@ -1066,7 +1066,7 @@ class CLikeCompiler(Compiler):
@staticmethod @staticmethod
def _sort_shlibs_openbsd(libs: T.List[str]) -> T.List[str]: def _sort_shlibs_openbsd(libs: T.List[str]) -> T.List[str]:
filtered = [] # type: T.List[str] filtered: T.List[str] = []
for lib in libs: for lib in libs:
# Validate file as a shared library of type libfoo.so.X.Y # Validate file as a shared library of type libfoo.so.X.Y
ret = lib.rsplit('.so.', maxsplit=1) ret = lib.rsplit('.so.', maxsplit=1)
@ -1205,7 +1205,7 @@ class CLikeCompiler(Compiler):
os_env = os.environ.copy() os_env = os.environ.copy()
os_env['LC_ALL'] = 'C' os_env['LC_ALL'] = 'C'
_, _, stde = mesonlib.Popen_safe(commands, env=os_env, stdin=subprocess.PIPE) _, _, 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'): for line in stde.split('\n'):
if '(framework directory)' not in line: if '(framework directory)' not in line:
continue 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]]: 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; }' code = 'int main(void) { return 0; }'
link_args = [] link_args: T.List[str] = []
for d in extra_dirs: for d in extra_dirs:
link_args += ['-F' + d] link_args += ['-F' + d]
# We can pass -Z to disable searching in the system frameworks, but # We can pass -Z to disable searching in the system frameworks, but
@ -1269,11 +1269,11 @@ class CLikeCompiler(Compiler):
return args.copy() return args.copy()
def has_arguments(self, args: T.List[str], env: 'Environment', code: str, 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) 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]: 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: for arg in args:
# some compilers, e.g. GCC, don't warn for unsupported warning-disable # 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 # 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 ' 'the compiler you are using. has_link_argument or '
'other similar method can be used instead.') 'other similar method can be used instead.')
new_args.append(arg) 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]: 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') return self._has_multi_arguments(args, env, 'extern int i;\nint i;\n')
@ -1300,7 +1300,7 @@ class CLikeCompiler(Compiler):
# false positive. # false positive.
args = self.linker.fatal_warnings() + args args = self.linker.fatal_warnings() + args
args = self.linker_to_compiler_args(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]: 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') 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) @functools.lru_cache(maxsize=None)
def can_compile(self, src: 'mesonlib.FileOrString') -> bool: def can_compile(self, src: 'mesonlib.FileOrString') -> bool:
# Files we preprocess can be anything, e.g. .in # Files we preprocess can be anything, e.g. .in
if self.mode == 'PREPROCESSOR': if self.mode == CompileCheckMode.PREPROCESS:
return True return True
return super().can_compile(src) return super().can_compile(src)
@ -1348,6 +1348,6 @@ class CLikeCompiler(Compiler):
if not self.preprocessor: if not self.preprocessor:
self.preprocessor = copy.copy(self) self.preprocessor = copy.copy(self)
self.preprocessor.exelist = self.exelist + self.get_preprocess_to_file_args() 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) self.modes.append(self.preprocessor)
return self.preprocessor return self.preprocessor

@ -30,16 +30,16 @@ else:
# do). This gives up DRYer type checking, with no runtime impact # do). This gives up DRYer type checking, with no runtime impact
Compiler = object Compiler = object
ccomp_buildtype_args = { ccomp_buildtype_args: T.Dict[str, T.List[str]] = {
'plain': [''], 'plain': [''],
'debug': ['-O0', '-g'], 'debug': ['-O0', '-g'],
'debugoptimized': ['-O0', '-g'], 'debugoptimized': ['-O0', '-g'],
'release': ['-O3'], 'release': ['-O3'],
'minsize': ['-Os'], 'minsize': ['-Os'],
'custom': ['-Obranchless'], 'custom': ['-Obranchless'],
} # type: T.Dict[str, T.List[str]] }
ccomp_optimization_args = { ccomp_optimization_args: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'0': ['-O0'], '0': ['-O0'],
'g': ['-O0'], 'g': ['-O0'],
@ -47,19 +47,19 @@ ccomp_optimization_args = {
'2': ['-O2'], '2': ['-O2'],
'3': ['-O3'], '3': ['-O3'],
's': ['-Os'] 's': ['-Os']
} # type: T.Dict[str, T.List[str]] }
ccomp_debug_args = { ccomp_debug_args: T.Dict[bool, T.List[str]] = {
False: [], False: [],
True: ['-g'] 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>) # 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 # 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"^-ffreestanding$",
r"^-r$" r"^-r$"
] # type: T.List[str] ]
class CompCertCompiler(Compiler): class CompCertCompiler(Compiler):
@ -69,12 +69,13 @@ class CompCertCompiler(Compiler):
# Assembly # Assembly
self.can_compile_suffixes.add('s') self.can_compile_suffixes.add('s')
self.can_compile_suffixes.add('sx') self.can_compile_suffixes.add('sx')
default_warn_args = [] # type: T.List[str] default_warn_args: T.List[str] = []
self.warn_args = {'0': [], self.warn_args: T.Dict[str, T.List[str]] = {
'1': default_warn_args, '0': [],
'2': default_warn_args + [], '1': default_warn_args,
'3': default_warn_args + [], '2': default_warn_args + [],
'everything': default_warn_args + []} # type: T.Dict[str, T.List[str]] '3': default_warn_args + [],
'everything': default_warn_args + []}
def get_always_args(self) -> T.List[str]: def get_always_args(self) -> T.List[str]:
return [] return []
@ -95,7 +96,7 @@ class CompCertCompiler(Compiler):
@classmethod @classmethod
def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]: def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]:
"Always returns a copy that can be independently mutated" "Always returns a copy that can be independently mutated"
patched_args = [] # type: T.List[str] patched_args: T.List[str] = []
for arg in args: for arg in args:
added = 0 added = 0
for ptrn in ccomp_args_to_wul: for ptrn in ccomp_args_to_wul:

@ -74,7 +74,7 @@ class ElbrusCompiler(GnuLikeCompiler):
os_env['LC_ALL'] = 'C' 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) 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') stderr = p.stderr.read().decode('utf-8', errors='replace')
includes = [] includes: T.List[str] = []
for line in stderr.split('\n'): for line in stderr.split('\n'):
if line.lstrip().startswith('--sys_include'): if line.lstrip().startswith('--sys_include'):
includes.append(re.sub(r'\s*\\$', '', re.sub(r'^\s*--sys_include\s*', '', line))) includes.append(re.sub(r'\s*\\$', '', re.sub(r'^\s*--sys_include\s*', '', line)))
@ -91,7 +91,7 @@ class ElbrusCompiler(GnuLikeCompiler):
return 'pch' return 'pch'
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]: 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)] std = options[OptionKey('std', lang=self.language, machine=self.for_machine)]
if std.value != 'none': if std.value != 'none':
args.append('-std=' + std.value) args.append('-std=' + std.value)

@ -22,6 +22,7 @@ from ... import coredata
from ... import mesonlib from ... import mesonlib
from ...mesonlib import OptionKey from ...mesonlib import OptionKey
from ...mesonlib import LibType from ...mesonlib import LibType
from mesonbuild.compilers.compilers import CompileCheckMode
if T.TYPE_CHECKING: if T.TYPE_CHECKING:
from ...environment import Environment from ...environment import Environment
@ -36,7 +37,7 @@ else:
def wrap_js_includes(args: T.List[str]) -> T.List[str]: def wrap_js_includes(args: T.List[str]) -> T.List[str]:
final_args = [] final_args: T.List[str] = []
for i in args: for i in args:
if i.endswith('.js') and not i.startswith('-'): if i.endswith('.js') and not i.startswith('-'):
final_args += ['--js-library', i] final_args += ['--js-library', i]
@ -46,14 +47,12 @@ def wrap_js_includes(args: T.List[str]) -> T.List[str]:
class EmscriptenMixin(Compiler): class EmscriptenMixin(Compiler):
def _get_compile_output(self, dirname: str, mode: str) -> str: def _get_compile_output(self, dirname: str, mode: CompileCheckMode) -> str:
# In pre-processor mode, the output is sent to stdout and discarded assert mode != CompileCheckMode.PREPROCESS, 'In pre-processor mode, the output is sent to stdout and discarded'
if mode == 'preprocess':
return None
# Unlike sane toolchains, emcc infers the kind of output from its name. # Unlike sane toolchains, emcc infers the kind of output from its name.
# This is the only reason why this method is overridden; compiler tests # This is the only reason why this method is overridden; compiler tests
# do not work well with the default exe/obj suffices. # do not work well with the default exe/obj suffices.
if mode == 'link': if mode == CompileCheckMode.LINK:
suffix = 'js' suffix = 'js'
else: else:
suffix = 'o' suffix = 'o'

@ -27,6 +27,7 @@ import typing as T
from ... import mesonlib from ... import mesonlib
from ... import mlog from ... import mlog
from ...mesonlib import OptionKey from ...mesonlib import OptionKey
from mesonbuild.compilers.compilers import CompileCheckMode
if T.TYPE_CHECKING: if T.TYPE_CHECKING:
from ..._typing import ImmutableListProtocol from ..._typing import ImmutableListProtocol
@ -41,21 +42,21 @@ else:
# XXX: prevent circular references. # XXX: prevent circular references.
# FIXME: this really is a posix interface not a c-like interface # 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: [], False: [],
True: ['-g'], True: ['-g'],
} # type: T.Dict[bool, T.List[str]] }
gnulike_buildtype_args = { gnulike_buildtype_args: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'debug': [], 'debug': [],
'debugoptimized': [], 'debugoptimized': [],
'release': [], 'release': [],
'minsize': [], 'minsize': [],
'custom': [], 'custom': [],
} # type: T.Dict[str, T.List[str]] }
gnu_optimization_args = { gnu_optimization_args: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'0': ['-O0'], '0': ['-O0'],
'g': ['-Og'], 'g': ['-Og'],
@ -63,9 +64,9 @@ gnu_optimization_args = {
'2': ['-O2'], '2': ['-O2'],
'3': ['-O3'], '3': ['-O3'],
's': ['-Os'], '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'], 'mmx': ['-mmmx'],
'sse': ['-msse'], 'sse': ['-msse'],
'sse2': ['-msse2'], 'sse2': ['-msse2'],
@ -76,22 +77,22 @@ gnulike_instruction_set_args = {
'avx': ['-mavx'], 'avx': ['-mavx'],
'avx2': ['-mavx2'], 'avx2': ['-mavx2'],
'neon': ['-mfpu=neon'], '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'], 'default': ['-fvisibility=default'],
'internal': ['-fvisibility=internal'], 'internal': ['-fvisibility=internal'],
'hidden': ['-fvisibility=hidden'], 'hidden': ['-fvisibility=hidden'],
'protected': ['-fvisibility=protected'], 'protected': ['-fvisibility=protected'],
'inlineshidden': ['-fvisibility=hidden', '-fvisibility-inlines-hidden'], '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'], 'auto': ['-fdiagnostics-color=auto'],
'always': ['-fdiagnostics-color=always'], 'always': ['-fdiagnostics-color=always'],
'never': ['-fdiagnostics-color=never'], 'never': ['-fdiagnostics-color=never'],
} # type: T.Dict[str, T.List[str]] }
# Warnings collected from the GCC source and documentation. This is an # Warnings collected from the GCC source and documentation. This is an
# objective set of all the warnings flags that apply to general projects: the # 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: # Omitted warnings enabled elsewhere in meson:
# -Winvalid-pch (GCC 3.4.0) # -Winvalid-pch (GCC 3.4.0)
gnu_common_warning_args = { gnu_common_warning_args: T.Dict[str, T.List[str]] = {
"0.0.0": [ "0.0.0": [
"-Wcast-qual", "-Wcast-qual",
"-Wconversion", "-Wconversion",
@ -212,7 +213,7 @@ gnu_common_warning_args = {
"-Wopenacc-parallelism", "-Wopenacc-parallelism",
"-Wtrivial-auto-var-init", "-Wtrivial-auto-var-init",
], ],
} # type: T.Dict[str, T.List[str]] }
# GCC warnings for C # GCC warnings for C
# Omitted non-general or legacy warnings: # Omitted non-general or legacy warnings:
@ -222,7 +223,7 @@ gnu_common_warning_args = {
# -Wdeclaration-after-statement # -Wdeclaration-after-statement
# -Wtraditional # -Wtraditional
# -Wtraditional-conversion # -Wtraditional-conversion
gnu_c_warning_args = { gnu_c_warning_args: T.Dict[str, T.List[str]] = {
"0.0.0": [ "0.0.0": [
"-Wbad-function-cast", "-Wbad-function-cast",
"-Wmissing-prototypes", "-Wmissing-prototypes",
@ -239,7 +240,7 @@ gnu_c_warning_args = {
"4.5.0": [ "4.5.0": [
"-Wunsuffixed-float-constants", "-Wunsuffixed-float-constants",
], ],
} # type: T.Dict[str, T.List[str]] }
# GCC warnings for C++ # GCC warnings for C++
# Omitted non-general or legacy warnings: # Omitted non-general or legacy warnings:
@ -249,7 +250,7 @@ gnu_c_warning_args = {
# -Wctad-maybe-unsupported # -Wctad-maybe-unsupported
# -Wnamespaces # -Wnamespaces
# -Wtemplates # -Wtemplates
gnu_cpp_warning_args = { gnu_cpp_warning_args: T.Dict[str, T.List[str]] = {
"0.0.0": [ "0.0.0": [
"-Wctor-dtor-privacy", "-Wctor-dtor-privacy",
"-Weffc++", "-Weffc++",
@ -308,13 +309,13 @@ gnu_cpp_warning_args = {
"-Wdeprecated-enum-float-conversion", "-Wdeprecated-enum-float-conversion",
"-Winvalid-imported-macros", "-Winvalid-imported-macros",
], ],
} # type: T.Dict[str, T.List[str]] }
# GCC warnings for Objective C and Objective C++ # GCC warnings for Objective C and Objective C++
# Omitted non-general or legacy warnings: # Omitted non-general or legacy warnings:
# -Wtraditional # -Wtraditional
# -Wtraditional-conversion # -Wtraditional-conversion
gnu_objc_warning_args = { gnu_objc_warning_args: T.Dict[str, T.List[str]] = {
"0.0.0": [ "0.0.0": [
"-Wselector", "-Wselector",
], ],
@ -325,7 +326,7 @@ gnu_objc_warning_args = {
"-Wassign-intercept", "-Wassign-intercept",
"-Wstrict-selector-match", "-Wstrict-selector-match",
], ],
} # type: T.Dict[str, T.List[str]] }
_LANG_MAP = { _LANG_MAP = {
'c': 'c', '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', '-'] cmd = list(compiler) + [f'-x{lang}', '-E', '-v', '-']
_, stdout, _ = mesonlib.Popen_safe(cmd, stderr=subprocess.STDOUT, env=env) _, stdout, _ = mesonlib.Popen_safe(cmd, stderr=subprocess.STDOUT, env=env)
parse_state = 0 parse_state = 0
paths = [] # type: T.List[str] paths: T.List[str] = []
for line in stdout.split('\n'): for line in stdout.split('\n'):
line = line.strip(' \n\r\t') line = line.strip(' \n\r\t')
if parse_state == 0: if parse_state == 0:
@ -464,7 +465,7 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta):
def _get_search_dirs(self, env: 'Environment') -> str: def _get_search_dirs(self, env: 'Environment') -> str:
extra_args = ['--print-search-dirs'] extra_args = ['--print-search-dirs']
with self._build_wrapper('', env, extra_args=extra_args, with self._build_wrapper('', env, extra_args=extra_args,
dependencies=None, mode='compile', dependencies=None, mode=CompileCheckMode.COMPILE,
want_output=True) as p: want_output=True) as p:
return p.stdout return p.stdout
@ -482,7 +483,7 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta):
# pathlib treats empty paths as '.', so filter those out # pathlib treats empty paths as '.', so filter those out
paths = [p for p in pathstr.split(pathsep) if p] paths = [p for p in pathstr.split(pathsep) if p]
result = [] result: T.List[str] = []
for p in paths: for p in paths:
# GCC returns paths like this: # GCC returns paths like this:
# /usr/lib/gcc/x86_64-linux-gnu/8/../../../../x86_64-linux-gnu/lib # /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') args.append('-fno-omit-frame-pointer')
return args return args
def get_output_args(self, target: str) -> T.List[str]: def get_output_args(self, outputname: str) -> T.List[str]:
return ['-o', target] return ['-o', outputname]
def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]: def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]:
return ['-MD', '-MQ', outtarget, '-MF', outfile] return ['-MD', '-MQ', outtarget, '-MF', outfile]
@ -589,7 +590,7 @@ class GnuCompiler(GnuLikeCompiler):
return args return args
def supported_warn_args(self, warn_args_by_version: T.Dict[str, T.List[str]]) -> T.List[str]: 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(): for version, warn_args in warn_args_by_version.items():
if mesonlib.version_compare(self.version, '>=' + version): if mesonlib.version_compare(self.version, '>=' + version):
result += warn_args result += warn_args
@ -613,7 +614,7 @@ class GnuCompiler(GnuLikeCompiler):
return ['-fopenmp'] return ['-fopenmp']
def has_arguments(self, args: T.List[str], env: 'Environment', code: str, 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 # For some compiler command line arguments, the GNU compilers will
# emit a warning on stderr indicating that an option is valid for a # emit a warning on stderr indicating that an option is valid for a
# another language, but still complete with exit_success # another language, but still complete with exit_success

@ -50,14 +50,14 @@ class IntelGnuLikeCompiler(GnuLikeCompiler):
minsize: -O2 minsize: -O2
""" """
BUILD_ARGS = { BUILD_ARGS: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'debug': ["-g", "-traceback"], 'debug': ["-g", "-traceback"],
'debugoptimized': ["-g", "-traceback"], 'debugoptimized': ["-g", "-traceback"],
'release': [], 'release': [],
'minsize': [], 'minsize': [],
'custom': [], 'custom': [],
} # type: T.Dict[str, T.List[str]] }
OPTIM_ARGS: T.Dict[str, T.List[str]] = { OPTIM_ARGS: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
@ -89,8 +89,8 @@ class IntelGnuLikeCompiler(GnuLikeCompiler):
return ['-pch', '-pch_dir', os.path.join(pch_dir), '-x', return ['-pch', '-pch_dir', os.path.join(pch_dir), '-x',
self.lang_header, '-include', header, '-x', 'none'] self.lang_header, '-include', header, '-x', 'none']
def get_pch_name(self, header_name: str) -> str: def get_pch_name(self, name: str) -> str:
return os.path.basename(header_name) + '.' + self.get_pch_suffix() return os.path.basename(name) + '.' + self.get_pch_suffix()
def openmp_flags(self) -> T.List[str]: def openmp_flags(self) -> T.List[str]:
if mesonlib.version_compare(self.version, '>=15.0.0'): if mesonlib.version_compare(self.version, '>=15.0.0'):
@ -129,14 +129,14 @@ class IntelVisualStudioLikeCompiler(VisualStudioLikeCompiler):
"""Abstractions for ICL, the Intel compiler on Windows.""" """Abstractions for ICL, the Intel compiler on Windows."""
BUILD_ARGS = { BUILD_ARGS: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'debug': ["/Zi", "/traceback"], 'debug': ["/Zi", "/traceback"],
'debugoptimized': ["/Zi", "/traceback"], 'debugoptimized': ["/Zi", "/traceback"],
'release': [], 'release': [],
'minsize': [], 'minsize': [],
'custom': [], 'custom': [],
} # type: T.Dict[str, T.List[str]] }
OPTIM_ARGS: T.Dict[str, T.List[str]] = { OPTIM_ARGS: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],

@ -120,8 +120,8 @@ class BasicLinkerIsCompilerMixin(Compiler):
def get_buildtype_linker_args(self, buildtype: str) -> T.List[str]: def get_buildtype_linker_args(self, buildtype: str) -> T.List[str]:
return [] return []
def get_link_debugfile_name(self, targetfile: str) -> str: def get_link_debugfile_name(self, targetfile: str) -> T.Optional[str]:
return '' return None
def thread_flags(self, env: 'Environment') -> T.List[str]: def thread_flags(self, env: 'Environment') -> T.List[str]:
return [] return []

@ -30,16 +30,16 @@ else:
# do). This gives up DRYer type checking, with no runtime impact # do). This gives up DRYer type checking, with no runtime impact
Compiler = object Compiler = object
mwcc_buildtype_args = { mwcc_buildtype_args: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'debug': ['-g'], 'debug': ['-g'],
'debugoptimized': ['-g', '-O4'], 'debugoptimized': ['-g', '-O4'],
'release': ['-O4,p'], 'release': ['-O4,p'],
'minsize': ['-Os'], 'minsize': ['-Os'],
'custom': [], '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'], 'generic': ['-proc', 'generic'],
'v4': ['-proc', 'v4'], 'v4': ['-proc', 'v4'],
'v4t': ['-proc', 'v4t'], 'v4t': ['-proc', 'v4t'],
@ -69,9 +69,9 @@ mwccarm_instruction_set_args = {
'pxa261': ['-proc', 'pxa261'], 'pxa261': ['-proc', 'pxa261'],
'pxa262': ['-proc', 'pxa262'], 'pxa262': ['-proc', 'pxa262'],
'pxa263': ['-proc', 'pxa263'] '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'], 'generic': ['-proc', 'generic'],
'401': ['-proc', '401'], '401': ['-proc', '401'],
'403': ['-proc', '403'], '403': ['-proc', '403'],
@ -97,9 +97,9 @@ mwcceppc_instruction_set_args = {
'8260': ['-proc', '8260'], '8260': ['-proc', '8260'],
'e500': ['-proc', 'e500'], 'e500': ['-proc', 'e500'],
'gekko': ['-proc', 'gekko'], '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'], 'arm4': ['-proc', 'arm4'],
'arm4t': ['-proc', 'arm4t'], 'arm4t': ['-proc', 'arm4t'],
'arm4xm': ['-proc', 'arm4xm'], 'arm4xm': ['-proc', 'arm4xm'],
@ -112,9 +112,9 @@ mwasmarm_instruction_set_args = {
'arm5TExP': ['-proc', 'arm5TExP'], 'arm5TExP': ['-proc', 'arm5TExP'],
'arm6': ['-proc', 'arm6'], 'arm6': ['-proc', 'arm6'],
'xscale': ['-proc', 'xscale'] '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'], '401': ['-proc', '401'],
'403': ['-proc', '403'], '403': ['-proc', '403'],
'505': ['-proc', '505'], '505': ['-proc', '505'],
@ -165,9 +165,9 @@ mwasmeppc_instruction_set_args = {
'5674': ['-proc', '5674'], '5674': ['-proc', '5674'],
'gekko': ['-proc', 'gekko'], 'gekko': ['-proc', 'gekko'],
'generic': ['-proc', 'generic'], 'generic': ['-proc', 'generic'],
} # type: T.Dict[str, T.List[str]] }
mwcc_optimization_args = { mwcc_optimization_args: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'0': ['-O0'], '0': ['-O0'],
'g': ['-Op'], 'g': ['-Op'],
@ -175,12 +175,12 @@ mwcc_optimization_args = {
'2': ['-O2'], '2': ['-O2'],
'3': ['-O3'], '3': ['-O3'],
's': ['-Os'] 's': ['-Os']
} # type: T.Dict[str, T.List[str]] }
mwcc_debug_args = { mwcc_debug_args: T.Dict[bool, T.List[str]] = {
False: [], False: [],
True: ['-g'] True: ['-g']
} # type: T.Dict[bool, T.List[str]] }
class MetrowerksCompiler(Compiler): class MetrowerksCompiler(Compiler):
@ -197,12 +197,13 @@ class MetrowerksCompiler(Compiler):
self.base_options = { self.base_options = {
OptionKey(o) for o in ['b_pch', 'b_ndebug']} OptionKey(o) for o in ['b_pch', 'b_ndebug']}
default_warn_args = [] # type: T.List[str] default_warn_args: T.List[str] = []
self.warn_args = {'0': ['-w', 'off'], self.warn_args: T.Dict[str, T.List[str]] = {
'1': default_warn_args, '0': ['-w', 'off'],
'2': default_warn_args + ['-w', 'most'], '1': default_warn_args,
'3': default_warn_args + ['-w', 'all'], '2': default_warn_args + ['-w', 'most'],
'everything': default_warn_args + ['-w', 'full']} # type: T.Dict[str, T.List[str]] '3': default_warn_args + ['-w', 'all'],
'everything': default_warn_args + ['-w', 'full']}
def depfile_for_object(self, objfile: str) -> T.Optional[str]: def depfile_for_object(self, objfile: str) -> T.Optional[str]:
# Earlier versions of these compilers do not support specifying # 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]: def get_optimization_args(self, optimization_level: str) -> T.List[str]:
return mwcc_optimization_args[optimization_level] return mwcc_optimization_args[optimization_level]
def get_output_args(self, target: str) -> T.List[str]: def get_output_args(self, outputname: str) -> T.List[str]:
return ['-o', target] return ['-o', outputname]
def get_pic_args(self) -> T.List[str]: def get_pic_args(self) -> T.List[str]:
return ['-pic'] return ['-pic']
@ -277,7 +278,7 @@ class MetrowerksCompiler(Compiler):
@classmethod @classmethod
def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]: def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]:
result = [] result: T.List[str] = []
for i in args: for i in args:
if i.startswith('-D'): if i.startswith('-D'):
i = '-D' + i[2:] i = '-D' + i[2:]

@ -31,16 +31,16 @@ else:
# do). This gives up DRYer type checking, with no runtime impact # do). This gives up DRYer type checking, with no runtime impact
Compiler = object Compiler = object
ti_buildtype_args = { ti_buildtype_args: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'debug': [], 'debug': [],
'debugoptimized': [], 'debugoptimized': [],
'release': [], 'release': [],
'minsize': [], 'minsize': [],
'custom': [], 'custom': [],
} # type: T.Dict[str, T.List[str]] }
ti_optimization_args = { ti_optimization_args: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'0': ['-O0'], '0': ['-O0'],
'g': ['-Ooff'], 'g': ['-Ooff'],
@ -48,12 +48,12 @@ ti_optimization_args = {
'2': ['-O2'], '2': ['-O2'],
'3': ['-O3'], '3': ['-O3'],
's': ['-O4'] 's': ['-O4']
} # type: T.Dict[str, T.List[str]] }
ti_debug_args = { ti_debug_args: T.Dict[bool, T.List[str]] = {
False: [], False: [],
True: ['-g'] True: ['-g']
} # type: T.Dict[bool, T.List[str]] }
class TICompiler(Compiler): class TICompiler(Compiler):
@ -67,12 +67,13 @@ class TICompiler(Compiler):
self.can_compile_suffixes.add('asm') # Assembly self.can_compile_suffixes.add('asm') # Assembly
self.can_compile_suffixes.add('cla') # Control Law Accelerator (CLA) used in C2000 self.can_compile_suffixes.add('cla') # Control Law Accelerator (CLA) used in C2000
default_warn_args = [] # type: T.List[str] default_warn_args: T.List[str] = []
self.warn_args = {'0': [], self.warn_args: T.Dict[str, T.List[str]] = {
'1': default_warn_args, '0': [],
'2': default_warn_args + [], '1': default_warn_args,
'3': default_warn_args + [], '2': default_warn_args + [],
'everything': default_warn_args + []} # type: T.Dict[str, T.List[str]] '3': default_warn_args + [],
'everything': default_warn_args + []}
def get_pic_args(self) -> T.List[str]: def get_pic_args(self) -> T.List[str]:
# PIC support is not enabled by default for TI compilers, # 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]: def get_no_optimization_args(self) -> T.List[str]:
return ['-Ooff'] return ['-Ooff']
def get_output_args(self, target: str) -> T.List[str]: def get_output_args(self, outputname: str) -> T.List[str]:
return [f'--output_file={target}'] return [f'--output_file={outputname}']
def get_werror_args(self) -> T.List[str]: def get_werror_args(self) -> T.List[str]:
return ['--emit_warnings_as_errors'] return ['--emit_warnings_as_errors']
@ -125,7 +126,7 @@ class TICompiler(Compiler):
@classmethod @classmethod
def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]: def _unix_args_to_native(cls, args: T.List[str], info: MachineInfo) -> T.List[str]:
result = [] result: T.List[str] = []
for i in args: for i in args:
if i.startswith('-D'): if i.startswith('-D'):
i = '--define=' + i[2:] i = '--define=' + i[2:]

@ -24,6 +24,7 @@ import typing as T
from ... import arglist from ... import arglist
from ... import mesonlib from ... import mesonlib
from ... import mlog from ... import mlog
from mesonbuild.compilers.compilers import CompileCheckMode
if T.TYPE_CHECKING: if T.TYPE_CHECKING:
from ...environment import Environment from ...environment import Environment
@ -36,7 +37,7 @@ else:
# do). This gives up DRYer type checking, with no runtime impact # do). This gives up DRYer type checking, with no runtime impact
Compiler = object 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 'mmx': ['/arch:SSE'], # There does not seem to be a flag just for MMX
'sse': ['/arch:SSE'], 'sse': ['/arch:SSE'],
'sse2': ['/arch:SSE2'], 'sse2': ['/arch:SSE2'],
@ -46,10 +47,10 @@ vs32_instruction_set_args = {
'avx': ['/arch:AVX'], 'avx': ['/arch:AVX'],
'avx2': ['/arch:AVX2'], 'avx2': ['/arch:AVX2'],
'neon': None, 'neon': None,
} # T.Dicst[str, T.Optional[T.List[str]]] }
# The 64 bit compiler defaults to /arch:avx. # 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'], 'mmx': ['/arch:AVX'],
'sse': ['/arch:AVX'], 'sse': ['/arch:AVX'],
'sse2': ['/arch:AVX'], 'sse2': ['/arch:AVX'],
@ -60,9 +61,9 @@ vs64_instruction_set_args = {
'avx': ['/arch:AVX'], 'avx': ['/arch:AVX'],
'avx2': ['/arch:AVX2'], 'avx2': ['/arch:AVX2'],
'neon': None, 'neon': None,
} # T.Dicst[str, T.Optional[T.List[str]]] }
msvc_optimization_args = { msvc_optimization_args: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'0': ['/Od'], '0': ['/Od'],
'g': [], # No specific flag to optimize debugging, /Zi or /ZI will create debug information 'g': [], # No specific flag to optimize debugging, /Zi or /ZI will create debug information
@ -70,12 +71,12 @@ msvc_optimization_args = {
'2': ['/O2'], '2': ['/O2'],
'3': ['/O2', '/Gw'], '3': ['/O2', '/Gw'],
's': ['/O1', '/Gw'], 's': ['/O1', '/Gw'],
} # type: T.Dict[str, T.List[str]] }
msvc_debug_args = { msvc_debug_args: T.Dict[bool, T.List[str]] = {
False: [], False: [],
True: ['/Zi'] True: ['/Zi']
} # type: T.Dict[bool, T.List[str]] }
class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta): class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
@ -91,15 +92,15 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
std_warn_args = ['/W3'] std_warn_args = ['/W3']
std_opt_args = ['/O2'] std_opt_args = ['/O2']
ignore_libs = arglist.UNIXY_COMPILER_INTERNAL_LIBS + ['execinfo'] 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': [], 'none': [],
'md': ['/MD'], 'md': ['/MD'],
'mdd': ['/MDd'], 'mdd': ['/MDd'],
'mt': ['/MT'], 'mt': ['/MT'],
'mtd': ['/MTd'], 'mtd': ['/MTd'],
} # type: T.Dict[str, T.List[str]] }
# /showIncludes is needed for build dependency tracking in Ninja # /showIncludes is needed for build dependency tracking in Ninja
# See: https://ninja-build.org/manual.html#_deps # 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 # It is also dropped if Visual Studio 2013 or earlier is used, since it would
# not be supported in that case. # not be supported in that case.
always_args = ['/nologo', '/showIncludes', '/utf-8'] always_args = ['/nologo', '/showIncludes', '/utf-8']
warn_args = { warn_args: T.Dict[str, T.List[str]] = {
'0': [], '0': [],
'1': ['/W2'], '1': ['/W2'],
'2': ['/W3'], '2': ['/W3'],
'3': ['/W4'], '3': ['/W4'],
'everything': ['/Wall'], 'everything': ['/Wall'],
} # type: T.Dict[str, T.List[str]] }
INVOKES_LINKER = False INVOKES_LINKER = False
@ -146,8 +147,8 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
def get_pch_suffix(self) -> str: def get_pch_suffix(self) -> str:
return 'pch' return 'pch'
def get_pch_name(self, header: str) -> str: def get_pch_name(self, name: str) -> str:
chopped = os.path.basename(header).split('.')[:-1] chopped = os.path.basename(name).split('.')[:-1]
chopped.append(self.get_pch_suffix()) chopped.append(self.get_pch_suffix())
pchname = '.'.join(chopped) pchname = '.'.join(chopped)
return pchname return pchname
@ -180,12 +181,12 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
raise mesonlib.MesonException('VS only supports address sanitizer at the moment.') raise mesonlib.MesonException('VS only supports address sanitizer at the moment.')
return ['/fsanitize=address'] return ['/fsanitize=address']
def get_output_args(self, target: str) -> T.List[str]: def get_output_args(self, outputname: str) -> T.List[str]:
if self.mode == 'PREPROCESSOR': if self.mode == CompileCheckMode.PREPROCESS:
return ['/Fi' + target] return ['/Fi' + outputname]
if target.endswith('.exe'): if outputname.endswith('.exe'):
return ['/Fe' + target] return ['/Fe' + outputname]
return ['/Fo' + target] return ['/Fo' + outputname]
def get_buildtype_args(self, buildtype: str) -> T.List[str]: def get_buildtype_args(self, buildtype: str) -> T.List[str]:
return [] return []
@ -276,7 +277,7 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
@classmethod @classmethod
def native_args_to_unix(cls, args: T.List[str]) -> T.List[str]: def native_args_to_unix(cls, args: T.List[str]) -> T.List[str]:
result = [] result: T.List[str] = []
for arg in args: for arg in args:
if arg.startswith(('/LIBPATH:', '-LIBPATH:')): if arg.startswith(('/LIBPATH:', '-LIBPATH:')):
result.append('-L' + arg[9:]) 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 # Visual Studio is special. It ignores some arguments it does not
# understand and you can't tell it to error out on those. # 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 # 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]: def has_arguments(self, args: T.List[str], env: 'Environment', code: str, mode: CompileCheckMode) -> T.Tuple[bool, bool]:
warning_text = '4044' if mode == 'link' else '9002' warning_text = '4044' if mode == CompileCheckMode.LINK else '9002'
with self._build_wrapper(code, env, extra_args=args, mode=mode) as p: with self._build_wrapper(code, env, extra_args=args, mode=mode) as p:
if p.returncode != 0: if p.returncode != 0:
return False, p.cached return False, p.cached
@ -471,8 +472,8 @@ class ClangClCompiler(VisualStudioLikeCompiler):
self.can_compile_suffixes.add('s') self.can_compile_suffixes.add('s')
self.can_compile_suffixes.add('sx') self.can_compile_suffixes.add('sx')
def has_arguments(self, args: T.List[str], env: 'Environment', code: str, mode: str) -> T.Tuple[bool, bool]: def has_arguments(self, args: T.List[str], env: 'Environment', code: str, mode: CompileCheckMode) -> T.Tuple[bool, bool]:
if mode != 'link': if mode != CompileCheckMode.LINK:
args = args + ['-Werror=unknown-argument', '-Werror=unknown-warning-option'] args = args + ['-Werror=unknown-argument', '-Werror=unknown-warning-option']
return super().has_arguments(args, env, code, mode) 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]: def get_dependency_compile_args(self, dep: 'Dependency') -> T.List[str]:
if dep.get_include_type() == 'system': if dep.get_include_type() == 'system':
converted = [] converted: T.List[str] = []
for i in dep.get_compile_args(): for i in dep.get_compile_args():
if i.startswith('-isystem'): if i.startswith('-isystem'):
converted += ['/clang:' + i] converted += ['/clang:' + i]

@ -19,7 +19,7 @@ import typing as T
from .. import mlog from .. import mlog
from ..mesonlib import EnvironmentException, version_compare, OptionKey from ..mesonlib import EnvironmentException, version_compare, OptionKey
from .compilers import Compiler, LibType from .compilers import CompileCheckMode, Compiler, LibType
if T.TYPE_CHECKING: if T.TYPE_CHECKING:
from ..envconfig import MachineInfo from ..envconfig import MachineInfo
@ -46,7 +46,7 @@ class ValaCompiler(Compiler):
def get_debug_args(self, is_debug: bool) -> T.List[str]: def get_debug_args(self, is_debug: bool) -> T.List[str]:
return ['--debug'] if is_debug else [] 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. return [] # Because compiles into C.
def get_compile_only_args(self) -> T.List[str]: def get_compile_only_args(self) -> T.List[str]:
@ -64,7 +64,7 @@ class ValaCompiler(Compiler):
def get_always_args(self) -> T.List[str]: def get_always_args(self) -> T.List[str]:
return ['-C'] return ['-C']
def get_warn_args(self, warning_level: str) -> T.List[str]: def get_warn_args(self, level: str) -> T.List[str]:
return [] return []
def get_no_warn_args(self) -> T.List[str]: def get_no_warn_args(self) -> T.List[str]:
@ -100,7 +100,7 @@ class ValaCompiler(Compiler):
extra_flags += self.get_compile_only_args() extra_flags += self.get_compile_only_args()
else: else:
extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language) 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: if p.returncode != 0:
msg = f'Vala compiler {self.name_string()!r} cannot compile programs' msg = f'Vala compiler {self.name_string()!r} cannot compile programs'
raise EnvironmentException(msg) raise EnvironmentException(msg)
@ -122,7 +122,7 @@ class ValaCompiler(Compiler):
args += env.coredata.get_external_args(self.for_machine, self.language) args += env.coredata.get_external_args(self.for_machine, self.language)
vapi_args = ['--pkg', libname] vapi_args = ['--pkg', libname]
args += vapi_args 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: if p.returncode == 0:
return vapi_args return vapi_args
# Not found? Try to find the vapi file itself. # Not found? Try to find the vapi file itself.

@ -39,7 +39,7 @@ import typing as T
if T.TYPE_CHECKING: if T.TYPE_CHECKING:
from . import dependencies 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 .dependencies.detect import TV_DepID
from .environment import Environment from .environment import Environment
from .mesonlib import OptionOverrideProxy, FileOrString from .mesonlib import OptionOverrideProxy, FileOrString
@ -48,7 +48,7 @@ if T.TYPE_CHECKING:
OptionDictType = T.Union[T.Dict[str, 'UserOption[T.Any]'], OptionOverrideProxy] OptionDictType = T.Union[T.Dict[str, 'UserOption[T.Any]'], OptionOverrideProxy]
MutableKeyedOptionDictType = T.Dict['OptionKey', 'UserOption[T.Any]'] MutableKeyedOptionDictType = T.Dict['OptionKey', 'UserOption[T.Any]']
KeyedOptionDictType = T.Union[MutableKeyedOptionDictType, OptionOverrideProxy] 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 # code, args
RunCheckCacheKey = T.Tuple[str, T.Tuple[str, ...]] RunCheckCacheKey = T.Tuple[str, T.Tuple[str, ...]]
@ -81,7 +81,7 @@ DEFAULT_YIELDING = False
_T = T.TypeVar('_T') _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 # just debug, debugoptimized, and release for now
# but this should probably be configurable through some extra option, alongside --genvslite. # but this should probably be configurable through some extra option, alongside --genvslite.
return buildtypelist[1:-2] return buildtypelist[1:-2]
@ -139,7 +139,7 @@ class UserStringOption(UserOption[str]):
return value return value
class UserBooleanOption(UserOption[bool]): 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): deprecated: T.Union[bool, str, T.Dict[str, str], T.List[str]] = False):
super().__init__(description, [True, False], yielding, deprecated) super().__init__(description, [True, False], yielding, deprecated)
self.set_value(value) self.set_value(value)
@ -164,7 +164,7 @@ class UserIntegerOption(UserOption[int]):
min_value, max_value, default_value = value min_value, max_value, default_value = value
self.min_value = min_value self.min_value = min_value
self.max_value = max_value self.max_value = max_value
c = [] c: T.List[str] = []
if min_value is not None: if min_value is not None:
c.append('>=' + str(min_value)) c.append('>=' + str(min_value))
if max_value is not None: if max_value is not None:
@ -368,13 +368,13 @@ class DependencyCache:
""" """
def __init__(self, builtins: 'KeyedOptionDictType', for_machine: MachineChoice): 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.__builtins = builtins
self.__pkg_conf_key = OptionKey('pkg_config_path', machine=for_machine) self.__pkg_conf_key = OptionKey('pkg_config_path', machine=for_machine)
self.__cmake_key = OptionKey('cmake_prefix_path', machine=for_machine) self.__cmake_key = OptionKey('cmake_prefix_path', machine=for_machine)
def __calculate_subkey(self, type_: DependencyCacheType) -> T.Tuple[str, ...]: 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.PKG_CONFIG: stringlistify(self.__builtins[self.__pkg_conf_key].value),
DependencyCacheType.CMAKE: stringlistify(self.__builtins[self.__cmake_key].value), DependencyCacheType.CMAKE: stringlistify(self.__builtins[self.__cmake_key].value),
DependencyCacheType.OTHER: [], DependencyCacheType.OTHER: [],
@ -419,7 +419,7 @@ class DependencyCache:
def items(self) -> T.Iterator[T.Tuple['TV_DepID', T.List['dependencies.Dependency']]]: def items(self) -> T.Iterator[T.Tuple['TV_DepID', T.List['dependencies.Dependency']]]:
for k, v in self.__cache.items(): for k, v in self.__cache.items():
vs = [] vs: T.List[dependencies.Dependency] = []
for t in v.types: for t in v.types:
subkey = self.__calculate_subkey(t) subkey = self.__calculate_subkey(t)
if subkey in v: if subkey in v:
@ -482,7 +482,7 @@ class CoreData:
self.version = version self.version = version
self.options: 'MutableKeyedOptionDictType' = {} self.options: 'MutableKeyedOptionDictType' = {}
self.cross_files = self.__load_config_files(options, scratch_dir, 'cross') 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 # Set of subprojects that have already been initialized once, this is
# required to be stored and reloaded with the coredata, as we don't # required to be stored and reloaded with the coredata, as we don't
@ -518,9 +518,9 @@ class CoreData:
if not filenames: if not filenames:
return [] return []
found_invalid = [] # type: T.List[str] found_invalid: T.List[str] = []
missing = [] # type: T.List[str] missing: T.List[str] = []
real = [] # type: T.List[str] real: T.List[str] = []
for i, f in enumerate(filenames): for i, f in enumerate(filenames):
f = os.path.expanduser(os.path.expandvars(f)) f = os.path.expanduser(os.path.expandvars(f))
if os.path.exists(f): if os.path.exists(f):
@ -571,7 +571,7 @@ class CoreData:
if self.cross_files: if self.cross_files:
BUILTIN_OPTIONS[OptionKey('libdir')].default = 'lib' BUILTIN_OPTIONS[OptionKey('libdir')].default = 'lib'
def sanitize_prefix(self, prefix): def sanitize_prefix(self, prefix: str) -> str:
prefix = os.path.expanduser(prefix) prefix = os.path.expanduser(prefix)
if not os.path.isabs(prefix): if not os.path.isabs(prefix):
raise MesonException(f'prefix value {prefix!r} must be an absolute path') raise MesonException(f'prefix value {prefix!r} must be an absolute path')
@ -731,7 +731,7 @@ class CoreData:
self.run_check_cache.clear() 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]]]: 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 value = self.options[OptionKey('buildtype')].value
if value == 'plain': if value == 'plain':
opt = 'plain' opt = 'plain'
@ -955,18 +955,18 @@ class CmdLineFileParser(configparser.ConfigParser):
# storing subproject options like "subproject:option=value" # storing subproject options like "subproject:option=value"
super().__init__(delimiters=['='], interpolation=None) 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) return super().read(filenames, encoding)
def optionxform(self, option: str) -> str: def optionxform(self, optionstr: str) -> str:
# Don't call str.lower() on keys # Don't call str.lower() on keys
return option return optionstr
class MachineFileParser(): class MachineFileParser():
def __init__(self, filenames: T.List[str]) -> None: def __init__(self, filenames: T.List[str]) -> None:
self.parser = CmdLineFileParser() self.parser = CmdLineFileParser()
self.constants = {'True': True, 'False': False} self.constants: T.Dict[str, T.Union[str, bool, int, T.List[str]]] = {'True': True, 'False': False}
self.sections = {} self.sections: T.Dict[str, T.Dict[str, T.Union[str, bool, int, T.List[str]]]] = {}
try: try:
self.parser.read(filenames) self.parser.read(filenames)
@ -982,9 +982,9 @@ class MachineFileParser():
continue continue
self.sections[s] = self._parse_section(s) 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() 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): for entry, value in self.parser.items(s):
if ' ' in entry or '\t' in entry or "'" in entry or '"' in entry: if ' ' in entry or '\t' in entry or "'" in entry or '"' in entry:
raise EnvironmentException(f'Malformed variable name {entry!r} in machine file.') raise EnvironmentException(f'Malformed variable name {entry!r} in machine file.')
@ -1001,7 +1001,7 @@ class MachineFileParser():
self.scope[entry] = res self.scope[entry] = res
return section 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)): if isinstance(node, (mparser.StringNode)):
return node.value return node.value
elif isinstance(node, mparser.BooleanNode): elif isinstance(node, mparser.BooleanNode):
@ -1009,6 +1009,7 @@ class MachineFileParser():
elif isinstance(node, mparser.NumberNode): elif isinstance(node, mparser.NumberNode):
return node.value return node.value
elif isinstance(node, mparser.ArrayNode): 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] return [self._evaluate_statement(arg) for arg in node.args.arguments]
elif isinstance(node, mparser.IdNode): elif isinstance(node, mparser.IdNode):
return self.scope[node.value] return self.scope[node.value]
@ -1024,7 +1025,7 @@ class MachineFileParser():
return os.path.join(l, r) return os.path.join(l, r)
raise EnvironmentException('Unsupported node type') raise EnvironmentException('Unsupported node type')
def parse_machine_files(filenames): def parse_machine_files(filenames: T.List[str]):
parser = MachineFileParser(filenames) parser = MachineFileParser(filenames)
return parser.sections 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) filename = get_cmd_line_file(build_dir)
config = CmdLineFileParser() config = CmdLineFileParser()
properties = OrderedDict() properties: OrderedDict[str, str] = OrderedDict()
if options.cross_file: if options.cross_file:
properties['cross_file'] = options.cross_file properties['cross_file'] = options.cross_file
if options.native_file: if options.native_file:

@ -82,7 +82,7 @@ def _get_env_var(for_machine: MachineChoice, is_cross: bool, var_name: str) -> T
return value 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' gcovr_exe = 'gcovr'
try: try:
p, found = Popen_safe([gcovr_exe, '--version'])[0:2] 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 '-15', # Debian development snapshot
'-devel', # FreeBSD development snapshot '-devel', # FreeBSD development snapshot
] ]
names = [] names: T.List[str] = []
for suffix in suffixes: for suffix in suffixes:
names.append(tool + suffix) names.append(tool + suffix)
return names 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 Return: a single-element list of the found scan-build binary ready to be
passed to Popen() passed to Popen()
""" """
exelist = [] exelist: T.List[str] = []
if 'SCANBUILD' in os.environ: if 'SCANBUILD' in os.environ:
exelist = split_args(os.environ['SCANBUILD']) exelist = split_args(os.environ['SCANBUILD'])
else: else:
tools = get_llvm_tool_names('scan-build') tools = get_llvm_tool_names('scan-build')
for tool in tools: for tool in tools:
if shutil.which(tool) is not None: which = shutil.which(tool)
exelist = [shutil.which(tool)] if which is not None:
exelist = [which]
break break
if exelist: if exelist:
@ -270,7 +271,7 @@ def detect_windows_arch(compilers: CompilersDict) -> str:
return 'x86' return 'x86'
return os_arch 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(): for c in compilers.values():
try: try:
if c.has_builtin_define(define): if c.has_builtin_define(define):
@ -488,7 +489,7 @@ class Environment:
os.makedirs(self.log_dir, exist_ok=True) os.makedirs(self.log_dir, exist_ok=True)
os.makedirs(self.info_dir, exist_ok=True) os.makedirs(self.info_dir, exist_ok=True)
try: 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 self.first_invocation = False
except FileNotFoundError: except FileNotFoundError:
self.create_new_coredata(options) self.create_new_coredata(options)
@ -521,13 +522,13 @@ class Environment:
# Similar to coredata.compilers, but lower level in that there is no # Similar to coredata.compilers, but lower level in that there is no
# meta data, only names/paths. # meta data, only names/paths.
binaries = PerMachineDefaultable() # type: PerMachineDefaultable[BinaryTable] binaries: PerMachineDefaultable[BinaryTable] = PerMachineDefaultable()
# Misc other properties about each machine. # Misc other properties about each machine.
properties = PerMachineDefaultable() # type: PerMachineDefaultable[Properties] properties: PerMachineDefaultable[Properties] = PerMachineDefaultable()
# CMake toolchain variables # CMake toolchain variables
cmakevars = PerMachineDefaultable() # type: PerMachineDefaultable[CMakeVariables] cmakevars: PerMachineDefaultable[CMakeVariables] = PerMachineDefaultable()
## Setup build machine defaults ## Setup build machine defaults
@ -813,7 +814,7 @@ class Environment:
return is_object(fname) return is_object(fname)
@lru_cache(maxsize=None) @lru_cache(maxsize=None)
def is_library(self, fname): def is_library(self, fname: mesonlib.FileOrString):
return is_library(fname) return is_library(fname)
def lookup_binary_entry(self, for_machine: MachineChoice, name: str) -> T.Optional[T.List[str]]: 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: def get_datadir(self) -> str:
return self.coredata.get_option(OptionKey('datadir')) 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(): for comp in self.coredata.compilers[for_machine].values():
if comp.id == 'clang': if comp.id == 'clang':
index = 1 index = 1
@ -892,7 +893,7 @@ class Environment:
out = out.split('\n')[index].lstrip('libraries: =').split(':') out = out.split('\n')[index].lstrip('libraries: =').split(':')
return [os.path.normpath(p) for p in out] 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(): for comp in self.coredata.compilers[for_machine].values():
if comp.id == 'clang': if comp.id == 'clang':
break break

@ -86,7 +86,7 @@ class StaticLinker:
def native_args_to_unix(cls, args: T.List[str]) -> T.List[str]: def native_args_to_unix(cls, args: T.List[str]) -> T.List[str]:
return args[:] return args[:]
def get_link_debugfile_name(self, targetfile: str) -> str: def get_link_debugfile_name(self, targetfile: str) -> T.Optional[str]:
return None return None
def get_link_debugfile_args(self, targetfile: str) -> T.List[str]: def get_link_debugfile_args(self, targetfile: str) -> T.List[str]:
@ -122,7 +122,7 @@ class VisualStudioLikeLinker:
return self.always_args.copy() return self.always_args.copy()
def get_output_args(self, target: str) -> T.List[str]: def get_output_args(self, target: str) -> T.List[str]:
args = [] # type: T.List[str] args: T.List[str] = []
if self.machine: if self.machine:
args += ['/MACHINE:' + self.machine] args += ['/MACHINE:' + self.machine]
args += ['/OUT:' + target] args += ['/OUT:' + target]
@ -355,14 +355,14 @@ class DynamicLinker(metaclass=abc.ABCMeta):
"""Base class for dynamic linkers.""" """Base class for dynamic linkers."""
_BUILDTYPE_ARGS = { _BUILDTYPE_ARGS: T.Dict[str, T.List[str]] = {
'plain': [], 'plain': [],
'debug': [], 'debug': [],
'debugoptimized': [], 'debugoptimized': [],
'release': [], 'release': [],
'minsize': [], 'minsize': [],
'custom': [], 'custom': [],
} # type: T.Dict[str, T.List[str]] }
@abc.abstractproperty @abc.abstractproperty
def id(self) -> str: def id(self) -> str:
@ -374,7 +374,7 @@ class DynamicLinker(metaclass=abc.ABCMeta):
return args return args
elif isinstance(self.prefix_arg, str): elif isinstance(self.prefix_arg, str):
return [self.prefix_arg + arg for arg in args] return [self.prefix_arg + arg for arg in args]
ret = [] ret: T.List[str] = []
for arg in args: for arg in args:
ret += self.prefix_arg + [arg] ret += self.prefix_arg + [arg]
return ret return ret
@ -387,7 +387,7 @@ class DynamicLinker(metaclass=abc.ABCMeta):
self.version = version self.version = version
self.prefix_arg = prefix_arg self.prefix_arg = prefix_arg
self.always_args = always_args self.always_args = always_args
self.machine = None # type: T.Optional[str] self.machine: T.Optional[str] = None
def __repr__(self) -> str: def __repr__(self) -> str:
return '<{}: v{} `{}`>'.format(type(self).__name__, self.version, ' '.join(self.exelist)) 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]: 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.') 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)''' '''Name of debug file written out (see below)'''
return None return None
@ -479,7 +479,7 @@ class DynamicLinker(metaclass=abc.ABCMeta):
f'Linker {self.id} does not support allow undefined') f'Linker {self.id} does not support allow undefined')
@abc.abstractmethod @abc.abstractmethod
def get_output_args(self, outname: str) -> T.List[str]: def get_output_args(self, outputname: str) -> T.List[str]:
pass pass
def get_coverage_args(self) -> T.List[str]: def get_coverage_args(self) -> T.List[str]:
@ -560,8 +560,8 @@ class PosixDynamicLinkerMixin:
GNU-like that it makes sense to split this out. GNU-like that it makes sense to split this out.
""" """
def get_output_args(self, outname: str) -> T.List[str]: def get_output_args(self, outputname: str) -> T.List[str]:
return ['-o', outname] return ['-o', outputname]
def get_std_shared_lib_args(self) -> T.List[str]: def get_std_shared_lib_args(self) -> T.List[str]:
return ['-shared'] return ['-shared']
@ -582,16 +582,16 @@ class GnuLikeDynamicLinkerMixin:
for_machine = MachineChoice.HOST for_machine = MachineChoice.HOST
def _apply_prefix(self, arg: T.Union[str, T.List[str]]) -> T.List[str]: ... 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': [], 'plain': [],
'debug': [], 'debug': [],
'debugoptimized': [], 'debugoptimized': [],
'release': ['-O1'], 'release': ['-O1'],
'minsize': [], 'minsize': [],
'custom': [], 'custom': [],
} # type: T.Dict[str, T.List[str]] }
_SUBSYSTEMS = { _SUBSYSTEMS: T.Dict[str, str] = {
"native": "1", "native": "1",
"windows": "windows", "windows": "windows",
"console": "console", "console": "console",
@ -601,7 +601,7 @@ class GnuLikeDynamicLinkerMixin:
"efi_runtime_driver": "12", "efi_runtime_driver": "12",
"efi_rom": "13", "efi_rom": "13",
"boot_application": "16", "boot_application": "16",
} # type: T.Dict[str, str] }
def get_buildtype_args(self, buildtype: str) -> T.List[str]: def get_buildtype_args(self, buildtype: str) -> T.List[str]:
# We can override these in children by just overriding the # We can override these in children by just overriding the
@ -670,14 +670,14 @@ class GnuLikeDynamicLinkerMixin:
return ([], set()) return ([], set())
if not rpath_paths and not install_rpath and not build_rpath: if not rpath_paths and not install_rpath and not build_rpath:
return ([], set()) return ([], set())
args = [] args: T.List[str] = []
origin_placeholder = '$ORIGIN' origin_placeholder = '$ORIGIN'
processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir)
# Need to deduplicate rpaths, as macOS's install_name_tool # Need to deduplicate rpaths, as macOS's install_name_tool
# is *very* allergic to duplicate -delete_rpath arguments # is *very* allergic to duplicate -delete_rpath arguments
# when calling depfixer on installation. # when calling depfixer on installation.
all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths]) 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: for p in all_paths:
rpath_dirs_to_remove.add(p.encode('utf8')) rpath_dirs_to_remove.add(p.encode('utf8'))
# Build_rpath is used as-is (it is usually absolute). # Build_rpath is used as-is (it is usually absolute).
@ -769,7 +769,7 @@ class AppleDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):
return [] return []
def get_link_whole_for(self, args: T.List[str]) -> T.List[str]: 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: for a in args:
result.extend(self._apply_prefix('-force_load')) result.extend(self._apply_prefix('-force_load'))
result.append(a) result.append(a)
@ -812,7 +812,7 @@ class AppleDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):
install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
if not rpath_paths and not install_rpath and not build_rpath: if not rpath_paths and not install_rpath and not build_rpath:
return ([], set()) return ([], set())
args = [] args: T.List[str] = []
# @loader_path is the equivalent of $ORIGIN on macOS # @loader_path is the equivalent of $ORIGIN on macOS
# https://stackoverflow.com/q/26280738 # https://stackoverflow.com/q/26280738
origin_placeholder = '@loader_path' origin_placeholder = '@loader_path'
@ -1152,7 +1152,7 @@ class NAGDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):
install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]:
if not rpath_paths and not install_rpath and not build_rpath: if not rpath_paths and not install_rpath and not build_rpath:
return ([], set()) return ([], set())
args = [] args: T.List[str] = []
origin_placeholder = '$ORIGIN' origin_placeholder = '$ORIGIN'
processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) 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]) 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 for_machine = MachineChoice.HOST
def _apply_prefix(self, arg: T.Union[str, T.List[str]]) -> T.List[str]: ... 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': [], 'plain': [],
'debug': [], 'debug': [],
'debugoptimized': [], 'debugoptimized': [],
@ -1234,7 +1234,7 @@ class VisualStudioLikeLinkerMixin:
'release': ['/OPT:REF'], 'release': ['/OPT:REF'],
'minsize': ['/INCREMENTAL:NO', '/OPT:REF'], 'minsize': ['/INCREMENTAL:NO', '/OPT:REF'],
'custom': [], 'custom': [],
} # type: T.Dict[str, T.List[str]] }
def __init__(self, exelist: T.List[str], for_machine: mesonlib.MachineChoice, def __init__(self, exelist: T.List[str], for_machine: mesonlib.MachineChoice,
prefix_arg: T.Union[str, T.List[str]], always_args: T.List[str], *, 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]: def get_link_whole_for(self, args: T.List[str]) -> T.List[str]:
# Only since VS2015 # Only since VS2015
args = mesonlib.listify(args) args = mesonlib.listify(args)
l = [] # T.List[str] l: T.List[str] = []
for a in args: for a in args:
l.extend(self._apply_prefix('/WHOLEARCHIVE:' + a)) l.extend(self._apply_prefix('/WHOLEARCHIVE:' + a))
return l return l
@ -1409,7 +1409,7 @@ class SolarisDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):
return ([], set()) return ([], set())
processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir)
all_paths = mesonlib.OrderedSet([os.path.join('$ORIGIN', p) for p in processed_rpaths]) 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: for p in all_paths:
rpath_dirs_to_remove.add(p.encode('utf8')) rpath_dirs_to_remove.add(p.encode('utf8'))
if build_rpath != '': if build_rpath != '':
@ -1473,7 +1473,7 @@ class AIXDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):
def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str, def build_rpath_args(self, env: 'Environment', build_dir: str, from_dir: str,
rpath_paths: T.Tuple[str, ...], build_rpath: str, rpath_paths: T.Tuple[str, ...], build_rpath: str,
install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: 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 # install_rpath first, followed by other paths, and the system path last
if install_rpath != '': if install_rpath != '':
all_paths.add(install_rpath) all_paths.add(install_rpath)
@ -1596,8 +1596,8 @@ class MetrowerksLinker(DynamicLinker):
def get_linker_always_args(self) -> T.List[str]: def get_linker_always_args(self) -> T.List[str]:
return [] return []
def get_output_args(self, target: str) -> T.List[str]: def get_output_args(self, outputname: str) -> T.List[str]:
return ['-o', target] return ['-o', outputname]
def get_search_args(self, dirname: str) -> T.List[str]: def get_search_args(self, dirname: str) -> T.List[str]:
return self._apply_prefix('-L' + dirname) return self._apply_prefix('-L' + dirname)

@ -41,7 +41,7 @@ if T.TYPE_CHECKING:
from .._typing import ImmutableListProtocol from .._typing import ImmutableListProtocol
from ..build import ConfigurationData from ..build import ConfigurationData
from ..coredata import KeyedOptionDictType, UserOption from ..coredata import KeyedOptionDictType, UserOption, StrOrBytesPath
from ..environment import Environment from ..environment import Environment
from ..compilers.compilers import Compiler from ..compilers.compilers import Compiler
from ..interpreterbase.baseobjects import SubProject 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 # TODO: this is such a hack, this really should be either in coredata or in the
# interpreter # interpreter
# {subproject: project_meson_version} # {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 from glob import glob
@ -194,14 +194,15 @@ class GitException(MesonException):
self.output = output.strip() if output else '' self.output = output.strip() if output else ''
GIT = shutil.which('git') 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]: def git(cmd: T.List[str], workingdir: StrOrBytesPath, check: bool = False, **kwargs: T.Any) -> T.Tuple[subprocess.Popen[str], str, str]:
cmd = [GIT] + cmd assert GIT is not None, 'Callers should make sure it exists'
cmd = [GIT, *cmd]
p, o, e = Popen_safe(cmd, cwd=workingdir, **kwargs) p, o, e = Popen_safe(cmd, cwd=workingdir, **kwargs)
if check and p.returncode != 0: if check and p.returncode != 0:
raise GitException('Git command failed: ' + str(cmd), e) raise GitException('Git command failed: ' + str(cmd), e)
return p, o, 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: if not GIT:
m = 'Git program not found.' m = 'Git program not found.'
if check: 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 False, e
return True, o 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: if not GIT:
m = 'Git program not found.' m = 'Git program not found.'
if check: if check:
@ -514,7 +515,7 @@ class PerMachine(T.Generic[_T]):
machines, we can elaborate the original and then redefault them and thus machines, we can elaborate the original and then redefault them and thus
avoid repeating the elaboration explicitly. avoid repeating the elaboration explicitly.
""" """
unfreeze = PerMachineDefaultable() # type: PerMachineDefaultable[T.Optional[_T]] unfreeze: PerMachineDefaultable[T.Optional[_T]] = PerMachineDefaultable()
unfreeze.build = self.build unfreeze.build = self.build
unfreeze.host = self.host unfreeze.host = self.host
if unfreeze.host == unfreeze.build: 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 machines, we can elaborate the original and then redefault them and thus
avoid repeating the elaboration explicitly. avoid repeating the elaboration explicitly.
""" """
unfreeze = PerThreeMachineDefaultable() # type: PerThreeMachineDefaultable[T.Optional[_T]] unfreeze: PerThreeMachineDefaultable[T.Optional[_T]] = PerThreeMachineDefaultable()
unfreeze.build = self.build unfreeze.build = self.build
unfreeze.host = self.host unfreeze.host = self.host
unfreeze.target = self.target unfreeze.target = self.target
@ -595,7 +596,7 @@ class PerMachineDefaultable(PerMachine[T.Optional[_T]]):
return m.default_missing() 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. """Extends `PerThreeMachine` with the ability to default from `None`s.
""" """
def __init__(self) -> None: 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]]: 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): if isinstance(conditions, str):
conditions = [conditions] conditions = [conditions]
found = [] found: T.List[str] = []
not_found = [] not_found: T.List[str] = []
for req in conditions: for req in conditions:
if not version_compare(vstr1, req): if not version_compare(vstr1, req):
not_found.append(req) not_found.append(req)
@ -1131,7 +1132,7 @@ if is_windows():
return result return result
def split_args(cmd: str) -> T.List[str]: def split_args(cmd: str) -> T.List[str]:
result = [] result: T.List[str] = []
arg = '' arg = ''
num_backslashes = 0 num_backslashes = 0
num_quotes = 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, def do_replacement(regex: T.Pattern[str], line: str,
variable_format: Literal['meson', 'cmake', 'cmake@'], 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]]: 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': if variable_format == 'cmake':
start_tag = '${' start_tag = '${'
backslash_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: variable_format: Literal['meson', 'cmake', 'cmake@'], subproject: T.Optional[SubProject] = None) -> str:
def get_cmake_define(line: str, confdata: 'ConfigurationData') -> str: def get_cmake_define(line: str, confdata: 'ConfigurationData') -> str:
arr = line.split() arr = line.split()
define_value = [] define_value: T.List[str] = []
for token in arr[2:]: for token in arr[2:]:
try: try:
(v, desc) = confdata.get(token) v, _ = confdata.get(token)
define_value += [str(v)] define_value += [str(v)]
except KeyError: except KeyError:
define_value += [token] define_value += [token]
@ -1237,7 +1238,7 @@ def do_define(regex: T.Pattern[str], line: str, confdata: 'ConfigurationData',
varname = arr[1] varname = arr[1]
try: try:
(v, desc) = confdata.get(varname) v, _ = confdata.get(varname)
except KeyError: except KeyError:
return '/* #undef %s */\n' % varname return '/* #undef %s */\n' % varname
if isinstance(v, bool): if isinstance(v, bool):
@ -1253,7 +1254,7 @@ def do_define(regex: T.Pattern[str], line: str, confdata: 'ConfigurationData',
else: else:
result = get_cmake_define(line, confdata) result = get_cmake_define(line, confdata)
result = f'#define {varname} {result}\n' 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 return result
else: else:
raise MesonException('#mesondefine argument "%s" is of unknown type.' % varname) 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_]+)}') regex = re.compile(r'(?:\\\\)+(?=\\?\$)|\\\${|\${([-a-zA-Z0-9_]+)}')
return regex 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@'], 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: def line_is_valid(line: str, variable_format: str) -> bool:
if variable_format == 'meson': if variable_format == 'meson':
if '#cmakedefine' in line: if '#cmakedefine' in line:
@ -1285,8 +1286,8 @@ def do_conf_str(src: str, data: list, confdata: 'ConfigurationData',
if variable_format != 'meson': if variable_format != 'meson':
search_token = '#cmakedefine' search_token = '#cmakedefine'
result = [] result: T.List[str] = []
missing_variables = set() missing_variables: T.Set[str] = set()
# Detect when the configuration data is empty and no tokens were found # 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. # during substitution so we can warn the user to use the `copy:` kwarg.
confdata_useless = not confdata.keys() confdata_useless = not confdata.keys()
@ -1314,7 +1315,7 @@ def do_conf_file(src: str, dst: str, confdata: 'ConfigurationData',
except Exception as e: except Exception as e:
raise MesonException(f'Could not read input file {src}: {e!s}') 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 + '~' dst_tmp = dst + '~'
try: try:
with open(dst_tmp, 'w', encoding=encoding, newline='') as f: 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): if not isinstance(item, list):
return [item] return [item]
result = [] # type: T.List[T.Any] result: T.List[T.Any] = []
for i in item: for i in item:
if flatten and isinstance(i, list): if flatten and isinstance(i, list):
result += listify(i, flatten=True) 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]]: 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: for arg in args:
if not arg.startswith('@'): if not arg.startswith('@'):
expended_args.append(arg) 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: def _substitute_values_check_errors(command: T.List[str], values: T.Dict[str, T.Union[str, T.List[str]]]) -> None:
# Error checking # Error checking
inregex = ['@INPUT([0-9]+)?@', '@PLAINNAME@', '@BASENAME@'] # type: T.List[str] inregex: T.List[str] = ['@INPUT([0-9]+)?@', '@PLAINNAME@', '@BASENAME@']
outregex = ['@OUTPUT([0-9]+)?@', '@OUTDIR@'] # type: T.List[str] outregex: T.List[str] = ['@OUTPUT([0-9]+)?@', '@OUTDIR@']
if '@INPUT@' not in values: if '@INPUT@' not in values:
# Error out if any input-derived templates are present in the command # Error out if any input-derived templates are present in the command
match = iter_regexin_iter(inregex, 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) _substitute_values_check_errors(command, values)
# Substitution # 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@')] 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 value_rx = re.compile('|'.join(rx_keys)) if rx_keys else None
for vv in command: 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 @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 # Gather values derived from the input
if inputs: if inputs:
# We want to substitute all the inputs. # We want to substitute all the inputs.
@ -1964,7 +1965,7 @@ try:
from tqdm import tqdm from tqdm import tqdm
except ImportError: except ImportError:
# ideally we would use a typing.Protocol here, but it's part of typing_extensions until 3.8 # 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: else:
class ProgressBarTqdm(tqdm): class ProgressBarTqdm(tqdm):
def __init__(self, *args: T.Any, bar_type: T.Optional[str] = None, **kwargs: T.Any) -> None: 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) super().__init__(option_strings, dest, nargs=None, default=default, **kwargs)
def __call__(self, parser: argparse.ArgumentParser, namespace: argparse.Namespace, 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) assert isinstance(values, str)
setattr(namespace, self.dest, os.path.abspath(os.path.realpath(values))) 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 return wine_path
# Check paths that can be reduced by making them relative to workdir. # Check paths that can be reduced by making them relative to workdir.
rel_paths = [] rel_paths: T.List[str] = []
if workdir: if workdir:
abs_paths = [] abs_paths: T.List[str] = []
for p in wine_paths: for p in wine_paths:
try: try:
rel = Path(p).relative_to(workdir) 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]: def run_once(func: T.Callable[..., _T]) -> T.Callable[..., _T]:
ret = [] # type: T.List[_T] ret: T.List[_T] = []
@wraps(func) @wraps(func)
def wrapper(*args: T.Any, **kwargs: T.Any) -> _T: def wrapper(*args: T.Any, **kwargs: T.Any) -> _T:

Loading…
Cancel
Save