Use CompileCheckMode enum

There were a ton of naked strings with TODOs telling us to use the enum.
pull/11976/head
Tristan Partin 1 year ago
parent ab21dc0384
commit 1624354f33
  1. 27
      mesonbuild/compilers/compilers.py
  2. 4
      mesonbuild/compilers/cpp.py
  3. 4
      mesonbuild/compilers/d.py
  4. 4
      mesonbuild/compilers/fortran.py
  5. 22
      mesonbuild/compilers/mixins/clike.py
  6. 7
      mesonbuild/compilers/mixins/emscripten.py
  7. 5
      mesonbuild/compilers/mixins/gnu.py
  8. 11
      mesonbuild/compilers/mixins/visualstudio.py
  9. 6
      mesonbuild/compilers/vala.py
  10. 4
      mesonbuild/coredata.py

@ -516,7 +516,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
language: str
id: str
warn_args: T.Dict[str, T.List[str]]
mode: str = 'COMPILER'
mode = CompileCheckMode.COMPILE
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str,
for_machine: MachineChoice, info: 'MachineInfo',
@ -790,21 +790,19 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]:
return self.linker.has_multi_arguments(args, env)
def _get_compile_output(self, dirname: str, mode: str) -> str:
# TODO: mode should really be an enum
def _get_compile_output(self, dirname: str, mode: CompileCheckMode) -> str:
# In pre-processor mode, the output is sent to stdout and discarded
if mode == 'preprocess':
if mode == CompileCheckMode.PREPROCESS:
return None
# Extension only matters if running results; '.exe' is
# guaranteed to be executable on every platform.
if mode == 'link':
if mode == CompileCheckMode.LINK:
suffix = 'exe'
else:
suffix = 'obj'
return os.path.join(dirname, 'output.' + suffix)
def get_compiler_args_for_mode(self, mode: CompileCheckMode) -> T.List[str]:
# TODO: mode should really be an enum
args: T.List[str] = []
args += self.get_always_args()
if mode is CompileCheckMode.COMPILE:
@ -822,7 +820,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
@contextlib.contextmanager
def compile(self, code: 'mesonlib.FileOrString',
extra_args: T.Union[None, CompilerArgs, T.List[str]] = None,
*, mode: str = 'link', want_output: bool = False,
*, mode: CompileCheckMode = CompileCheckMode.LINK, want_output: bool = False,
temp_dir: T.Optional[str] = None) -> T.Iterator[T.Optional[CompileResult]]:
# TODO: there isn't really any reason for this to be a contextmanager
if extra_args is None:
@ -852,7 +850,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
# Preprocess mode outputs to stdout, so no output args
output = self._get_compile_output(tmpdirname, mode)
if mode != 'preprocess':
if mode != CompileCheckMode.PREPROCESS:
commands += self.get_output_args(output)
commands.extend(self.get_compiler_args_for_mode(CompileCheckMode(mode)))
@ -880,7 +878,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
@contextlib.contextmanager
def cached_compile(self, code: 'mesonlib.FileOrString', cdata: coredata.CoreData, *,
extra_args: T.Union[None, T.List[str], CompilerArgs] = None,
mode: str = 'link',
mode: CompileCheckMode = CompileCheckMode.LINK,
temp_dir: T.Optional[str] = None) -> T.Iterator[T.Optional[CompileResult]]:
# TODO: There's isn't really any reason for this to be a context manager
@ -1289,7 +1287,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
def _build_wrapper(self, code: 'mesonlib.FileOrString', env: 'Environment',
extra_args: T.Union[None, CompilerArgs, T.List[str], T.Callable[[CompileCheckMode], T.List[str]]] = None,
dependencies: T.Optional[T.List['Dependency']] = None,
mode: str = 'compile', want_output: bool = False,
mode: CompileCheckMode = CompileCheckMode.COMPILE, want_output: bool = False,
disable_cache: bool = False,
temp_dir: str = None) -> T.Iterator[T.Optional[CompileResult]]:
"""Helper for getting a cached value when possible.
@ -1297,7 +1295,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
This method isn't meant to be called externally, it's mean to be
wrapped by other methods like compiles() and links().
"""
args = self.build_wrapper_args(env, extra_args, dependencies, CompileCheckMode(mode))
args = self.build_wrapper_args(env, extra_args, dependencies, mode)
if disable_cache or want_output:
with self.compile(code, extra_args=args, mode=mode, want_output=want_output, temp_dir=env.scratch_dir) as r:
yield r
@ -1308,7 +1306,7 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
def compiles(self, code: 'mesonlib.FileOrString', env: 'Environment', *,
extra_args: T.Union[None, T.List[str], CompilerArgs, T.Callable[[CompileCheckMode], T.List[str]]] = None,
dependencies: T.Optional[T.List['Dependency']] = None,
mode: str = 'compile',
mode: CompileCheckMode = CompileCheckMode.COMPILE,
disable_cache: bool = False) -> T.Tuple[bool, bool]:
with self._build_wrapper(code, env, extra_args, dependencies, mode, disable_cache=disable_cache) as p:
return p.returncode == 0, p.cached
@ -1317,16 +1315,15 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
compiler: T.Optional['Compiler'] = None,
extra_args: T.Union[None, T.List[str], CompilerArgs, T.Callable[[CompileCheckMode], T.List[str]]] = None,
dependencies: T.Optional[T.List['Dependency']] = None,
mode: str = 'compile',
disable_cache: bool = False) -> T.Tuple[bool, bool]:
if compiler:
with compiler._build_wrapper(code, env, dependencies=dependencies, want_output=True) as r:
objfile = mesonlib.File.from_absolute_file(r.output_name)
return self.compiles(objfile, env, extra_args=extra_args,
dependencies=dependencies, mode='link', disable_cache=True)
dependencies=dependencies, mode=CompileCheckMode.LINK, disable_cache=True)
return self.compiles(code, env, extra_args=extra_args,
dependencies=dependencies, mode='link', disable_cache=disable_cache)
dependencies=dependencies, mode=CompileCheckMode.LINK, disable_cache=disable_cache)
def get_feature_args(self, kwargs: T.Dict[str, T.Any], build_to_src: str) -> T.List[str]:
"""Used by D for extra language features."""

@ -26,6 +26,7 @@ from .compilers import (
gnu_winlibs,
msvc_winlibs,
Compiler,
CompileCheckMode,
)
from .c_function_attributes import CXX_FUNC_ATTRIBUTES, C_FUNC_ATTRIBUTES
from .mixins.clike import CLikeCompiler
@ -43,7 +44,6 @@ from .mixins.metrowerks import MetrowerksCompiler
from .mixins.metrowerks import mwccarm_instruction_set_args, mwcceppc_instruction_set_args
if T.TYPE_CHECKING:
from .compilers import CompileCheckMode
from ..coredata import MutableKeyedOptionDictType, KeyedOptionDictType
from ..dependencies import Dependency
from ..envconfig import MachineInfo
@ -129,7 +129,7 @@ class CPPCompiler(CLikeCompiler, Compiler):
# 2. even if it did have an env object, that might contain another more
# recent -std= argument, which might lead to a cascaded failure.
CPP_TEST = 'int i = static_cast<int>(0);'
with self.compile(CPP_TEST, extra_args=[cpp_std_value], mode='compile') as p:
with self.compile(CPP_TEST, extra_args=[cpp_std_value], mode=CompileCheckMode.COMPILE) as p:
if p.returncode == 0:
mlog.debug(f'Compiler accepts {cpp_std_value}:', 'YES')
return True

@ -713,7 +713,7 @@ class DCompiler(Compiler):
if need_exe_wrapper and self.exe_wrapper is None:
raise compilers.CrossNoRunException('Can not run test applications in this cross environment.')
extra_args = self._get_compile_extra_args(extra_args)
with self._build_wrapper(code, env, extra_args, dependencies, mode='link', want_output=True) as p:
with self._build_wrapper(code, env, extra_args, dependencies, mode=CompileCheckMode.LINK, want_output=True) as p:
if p.returncode != 0:
mlog.debug(f'Could not compile test file {p.input_name}: {p.returncode}\n')
return compilers.RunResult(False)
@ -786,7 +786,7 @@ class DCompiler(Compiler):
import {hname};
'''
return self.compiles(code, env, extra_args=extra_args,
dependencies=dependencies, mode='compile', disable_cache=disable_cache)
dependencies=dependencies, mode=CompileCheckMode.COMPILE, disable_cache=disable_cache)
class GnuDCompiler(GnuCompiler, DCompiler):

@ -20,6 +20,7 @@ from .. import coredata
from .compilers import (
clike_debug_args,
Compiler,
CompileCheckMode,
)
from .mixins.clike import CLikeCompiler
from .mixins.gnu import (
@ -43,7 +44,6 @@ if T.TYPE_CHECKING:
from ..linkers.linkers import DynamicLinker
from ..mesonlib import MachineChoice
from ..programs import ExternalProgram
from .compilers import CompileCheckMode
class FortranCompiler(CLikeCompiler, Compiler):
@ -207,7 +207,7 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler):
'''
code = f'{prefix}\n#include <{hname}>'
return self.compiles(code, env, extra_args=extra_args,
dependencies=dependencies, mode='preprocess', disable_cache=disable_cache)
dependencies=dependencies, mode=CompileCheckMode.PREPROCESS, disable_cache=disable_cache)
class ElbrusFortranCompiler(ElbrusCompiler, FortranCompiler):

@ -370,7 +370,7 @@ class CLikeCompiler(Compiler):
#include <{hname}>
#endif'''
return self.compiles(code, env, extra_args=extra_args,
dependencies=dependencies, mode='preprocess', disable_cache=disable_cache)
dependencies=dependencies, mode=CompileCheckMode.PREPROCESS, disable_cache=disable_cache)
def has_header_symbol(self, hname: str, symbol: str, prefix: str,
env: 'Environment', *,
@ -475,7 +475,7 @@ class CLikeCompiler(Compiler):
need_exe_wrapper = env.need_exe_wrapper(self.for_machine)
if need_exe_wrapper and self.exe_wrapper is None:
raise compilers.CrossNoRunException('Can not run test applications in this cross environment.')
with self._build_wrapper(code, env, extra_args, dependencies, mode='link', want_output=True) as p:
with self._build_wrapper(code, env, extra_args, dependencies, mode=CompileCheckMode.LINK, want_output=True) as p:
if p.returncode != 0:
mlog.debug(f'Could not compile test file {p.input_name}: {p.returncode}\n')
return compilers.RunResult(False)
@ -678,9 +678,9 @@ class CLikeCompiler(Compiler):
{delim}\n{dname}'''
args = self.build_wrapper_args(env, extra_args, dependencies,
mode=CompileCheckMode.PREPROCESS).to_native()
func = functools.partial(self.cached_compile, code, env.coredata, extra_args=args, mode='preprocess')
func = functools.partial(self.cached_compile, code, env.coredata, extra_args=args, mode=CompileCheckMode.PREPROCESS)
if disable_cache:
func = functools.partial(self.compile, code, extra_args=args, mode='preprocess', temp_dir=env.scratch_dir)
func = functools.partial(self.compile, code, extra_args=args, mode=CompileCheckMode.PREPROCESS, temp_dir=env.scratch_dir)
with func() as p:
cached = p.cached
if p.returncode != 0:
@ -919,7 +919,7 @@ class CLikeCompiler(Compiler):
'''
args = self.get_compiler_check_args(CompileCheckMode.COMPILE)
n = '_symbols_have_underscore_prefix_searchbin'
with self._build_wrapper(code, env, extra_args=args, mode='compile', want_output=True, temp_dir=env.scratch_dir) as p:
with self._build_wrapper(code, env, extra_args=args, mode=CompileCheckMode.COMPILE, want_output=True, temp_dir=env.scratch_dir) as p:
if p.returncode != 0:
raise RuntimeError(f'BUG: Unable to compile {n!r} check: {p.stderr}')
if not os.path.isfile(p.output_name):
@ -954,7 +954,7 @@ class CLikeCompiler(Compiler):
#endif
{delim}MESON_UNDERSCORE_PREFIX
'''
with self._build_wrapper(code, env, mode='preprocess', want_output=False, temp_dir=env.scratch_dir) as p:
with self._build_wrapper(code, env, mode=CompileCheckMode.PREPROCESS, want_output=False, temp_dir=env.scratch_dir) as p:
if p.returncode != 0:
raise RuntimeError(f'BUG: Unable to preprocess _symbols_have_underscore_prefix_define check: {p.stdout}')
symbol_prefix = p.stdout.partition(delim)[-1].rstrip()
@ -1269,7 +1269,7 @@ class CLikeCompiler(Compiler):
return args.copy()
def has_arguments(self, args: T.List[str], env: 'Environment', code: str,
mode: str) -> T.Tuple[bool, bool]:
mode: CompileCheckMode) -> T.Tuple[bool, bool]:
return self.compiles(code, env, extra_args=args, mode=mode)
def _has_multi_arguments(self, args: T.List[str], env: 'Environment', code: str) -> T.Tuple[bool, bool]:
@ -1289,7 +1289,7 @@ class CLikeCompiler(Compiler):
'the compiler you are using. has_link_argument or '
'other similar method can be used instead.')
new_args.append(arg)
return self.has_arguments(new_args, env, code, mode='compile')
return self.has_arguments(new_args, env, code, mode=CompileCheckMode.COMPILE)
def has_multi_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]:
return self._has_multi_arguments(args, env, 'extern int i;\nint i;\n')
@ -1300,7 +1300,7 @@ class CLikeCompiler(Compiler):
# false positive.
args = self.linker.fatal_warnings() + args
args = self.linker_to_compiler_args(args)
return self.has_arguments(args, env, code, mode='link')
return self.has_arguments(args, env, code, mode=CompileCheckMode.LINK)
def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]:
return self._has_multi_link_arguments(args, env, 'int main(void) { return 0; }\n')
@ -1340,7 +1340,7 @@ class CLikeCompiler(Compiler):
@functools.lru_cache(maxsize=None)
def can_compile(self, src: 'mesonlib.FileOrString') -> bool:
# Files we preprocess can be anything, e.g. .in
if self.mode == 'PREPROCESSOR':
if self.mode == CompileCheckMode.PREPROCESS:
return True
return super().can_compile(src)
@ -1348,6 +1348,6 @@ class CLikeCompiler(Compiler):
if not self.preprocessor:
self.preprocessor = copy.copy(self)
self.preprocessor.exelist = self.exelist + self.get_preprocess_to_file_args()
self.preprocessor.mode = 'PREPROCESSOR'
self.preprocessor.mode = CompileCheckMode.PREPROCESS
self.modes.append(self.preprocessor)
return self.preprocessor

@ -22,6 +22,7 @@ from ... import coredata
from ... import mesonlib
from ...mesonlib import OptionKey
from ...mesonlib import LibType
from mesonbuild.compilers.compilers import CompileCheckMode
if T.TYPE_CHECKING:
from ...environment import Environment
@ -46,14 +47,14 @@ def wrap_js_includes(args: T.List[str]) -> T.List[str]:
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
if mode == 'preprocess':
if mode == CompileCheckMode.PREPROCESS:
return None
# Unlike sane toolchains, emcc infers the kind of output from its name.
# This is the only reason why this method is overridden; compiler tests
# do not work well with the default exe/obj suffices.
if mode == 'link':
if mode == CompileCheckMode.LINK:
suffix = 'js'
else:
suffix = 'o'

@ -27,6 +27,7 @@ import typing as T
from ... import mesonlib
from ... import mlog
from ...mesonlib import OptionKey
from mesonbuild.compilers.compilers import CompileCheckMode
if T.TYPE_CHECKING:
from ..._typing import ImmutableListProtocol
@ -464,7 +465,7 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta):
def _get_search_dirs(self, env: 'Environment') -> str:
extra_args = ['--print-search-dirs']
with self._build_wrapper('', env, extra_args=extra_args,
dependencies=None, mode='compile',
dependencies=None, mode=CompileCheckMode.COMPILE,
want_output=True) as p:
return p.stdout
@ -613,7 +614,7 @@ class GnuCompiler(GnuLikeCompiler):
return ['-fopenmp']
def has_arguments(self, args: T.List[str], env: 'Environment', code: str,
mode: str) -> T.Tuple[bool, bool]:
mode: CompileCheckMode) -> T.Tuple[bool, bool]:
# For some compiler command line arguments, the GNU compilers will
# emit a warning on stderr indicating that an option is valid for a
# another language, but still complete with exit_success

@ -24,6 +24,7 @@ import typing as T
from ... import arglist
from ... import mesonlib
from ... import mlog
from mesonbuild.compilers.compilers import CompileCheckMode
if T.TYPE_CHECKING:
from ...environment import Environment
@ -181,7 +182,7 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
return ['/fsanitize=address']
def get_output_args(self, target: str) -> T.List[str]:
if self.mode == 'PREPROCESSOR':
if self.mode == CompileCheckMode.PREPROCESS:
return ['/Fi' + target]
if target.endswith('.exe'):
return ['/Fe' + target]
@ -307,8 +308,8 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
# Visual Studio is special. It ignores some arguments it does not
# understand and you can't tell it to error out on those.
# http://stackoverflow.com/questions/15259720/how-can-i-make-the-microsoft-c-compiler-treat-unknown-flags-as-errors-rather-t
def has_arguments(self, args: T.List[str], env: 'Environment', code: str, mode: str) -> T.Tuple[bool, bool]:
warning_text = '4044' if mode == 'link' else '9002'
def has_arguments(self, args: T.List[str], env: 'Environment', code: str, mode: CompileCheckMode) -> T.Tuple[bool, bool]:
warning_text = '4044' if mode == CompileCheckMode.LINK else '9002'
with self._build_wrapper(code, env, extra_args=args, mode=mode) as p:
if p.returncode != 0:
return False, p.cached
@ -471,8 +472,8 @@ class ClangClCompiler(VisualStudioLikeCompiler):
self.can_compile_suffixes.add('s')
self.can_compile_suffixes.add('sx')
def has_arguments(self, args: T.List[str], env: 'Environment', code: str, mode: str) -> T.Tuple[bool, bool]:
if mode != 'link':
def has_arguments(self, args: T.List[str], env: 'Environment', code: str, mode: CompileCheckMode) -> T.Tuple[bool, bool]:
if mode != CompileCheckMode.LINK:
args = args + ['-Werror=unknown-argument', '-Werror=unknown-warning-option']
return super().has_arguments(args, env, code, mode)

@ -19,7 +19,7 @@ import typing as T
from .. import mlog
from ..mesonlib import EnvironmentException, version_compare, OptionKey
from .compilers import Compiler, LibType
from .compilers import CompileCheckMode, Compiler, LibType
if T.TYPE_CHECKING:
from ..envconfig import MachineInfo
@ -100,7 +100,7 @@ class ValaCompiler(Compiler):
extra_flags += self.get_compile_only_args()
else:
extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language)
with self.cached_compile(code, environment.coredata, extra_args=extra_flags, mode='compile') as p:
with self.cached_compile(code, environment.coredata, extra_args=extra_flags, mode=CompileCheckMode.COMPILE) as p:
if p.returncode != 0:
msg = f'Vala compiler {self.name_string()!r} cannot compile programs'
raise EnvironmentException(msg)
@ -122,7 +122,7 @@ class ValaCompiler(Compiler):
args += env.coredata.get_external_args(self.for_machine, self.language)
vapi_args = ['--pkg', libname]
args += vapi_args
with self.cached_compile(code, env.coredata, extra_args=args, mode='compile') as p:
with self.cached_compile(code, env.coredata, extra_args=args, mode=CompileCheckMode.COMPILE) as p:
if p.returncode == 0:
return vapi_args
# Not found? Try to find the vapi file itself.

@ -39,7 +39,7 @@ import typing as T
if T.TYPE_CHECKING:
from . import dependencies
from .compilers.compilers import Compiler, CompileResult, RunResult
from .compilers.compilers import Compiler, CompileResult, RunResult, CompileCheckMode
from .dependencies.detect import TV_DepID
from .environment import Environment
from .mesonlib import OptionOverrideProxy, FileOrString
@ -48,7 +48,7 @@ if T.TYPE_CHECKING:
OptionDictType = T.Union[T.Dict[str, 'UserOption[T.Any]'], OptionOverrideProxy]
MutableKeyedOptionDictType = T.Dict['OptionKey', 'UserOption[T.Any]']
KeyedOptionDictType = T.Union[MutableKeyedOptionDictType, OptionOverrideProxy]
CompilerCheckCacheKey = T.Tuple[T.Tuple[str, ...], str, FileOrString, T.Tuple[str, ...], str]
CompilerCheckCacheKey = T.Tuple[T.Tuple[str, ...], str, FileOrString, T.Tuple[str, ...], CompileCheckMode]
# code, args
RunCheckCacheKey = T.Tuple[str, T.Tuple[str, ...]]

Loading…
Cancel
Save