From 1624354f33bf0a33f0e715ba1ca391ae0154ad19 Mon Sep 17 00:00:00 2001 From: Tristan Partin Date: Wed, 12 Jul 2023 15:12:36 -0500 Subject: [PATCH] Use CompileCheckMode enum There were a ton of naked strings with TODOs telling us to use the enum. --- mesonbuild/compilers/compilers.py | 27 +++++++++------------ mesonbuild/compilers/cpp.py | 4 +-- mesonbuild/compilers/d.py | 4 +-- mesonbuild/compilers/fortran.py | 4 +-- mesonbuild/compilers/mixins/clike.py | 22 ++++++++--------- mesonbuild/compilers/mixins/emscripten.py | 7 +++--- mesonbuild/compilers/mixins/gnu.py | 5 ++-- mesonbuild/compilers/mixins/visualstudio.py | 11 +++++---- mesonbuild/compilers/vala.py | 6 ++--- mesonbuild/coredata.py | 4 +-- 10 files changed, 47 insertions(+), 47 deletions(-) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 286406d77..22865d849 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.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.""" diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 2605670f6..f17b0d2f2 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -26,6 +26,7 @@ from .compilers import ( gnu_winlibs, msvc_winlibs, Compiler, + CompileCheckMode, ) from .c_function_attributes import CXX_FUNC_ATTRIBUTES, C_FUNC_ATTRIBUTES from .mixins.clike import CLikeCompiler @@ -43,7 +44,6 @@ from .mixins.metrowerks import MetrowerksCompiler from .mixins.metrowerks import mwccarm_instruction_set_args, mwcceppc_instruction_set_args if T.TYPE_CHECKING: - from .compilers import CompileCheckMode from ..coredata import MutableKeyedOptionDictType, KeyedOptionDictType from ..dependencies import Dependency from ..envconfig import MachineInfo @@ -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(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 diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index c6e70b252..d7edbe947 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -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): diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index 7c836b74a..06f8cb44c 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -20,6 +20,7 @@ from .. import coredata from .compilers import ( clike_debug_args, Compiler, + CompileCheckMode, ) from .mixins.clike import CLikeCompiler from .mixins.gnu import ( @@ -43,7 +44,6 @@ if T.TYPE_CHECKING: from ..linkers.linkers import DynamicLinker from ..mesonlib import MachineChoice from ..programs import ExternalProgram - from .compilers import CompileCheckMode class FortranCompiler(CLikeCompiler, Compiler): @@ -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): diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index cec6b758f..fe39ef17a 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -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 diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py index 22b76559b..f95e63ff9 100644 --- a/mesonbuild/compilers/mixins/emscripten.py +++ b/mesonbuild/compilers/mixins/emscripten.py @@ -22,6 +22,7 @@ from ... import coredata from ... import mesonlib from ...mesonlib import OptionKey from ...mesonlib import LibType +from mesonbuild.compilers.compilers import CompileCheckMode if T.TYPE_CHECKING: from ...environment import Environment @@ -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' diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py index 93b367b2c..6517a3e91 100644 --- a/mesonbuild/compilers/mixins/gnu.py +++ b/mesonbuild/compilers/mixins/gnu.py @@ -27,6 +27,7 @@ import typing as T from ... import mesonlib from ... import mlog from ...mesonlib import OptionKey +from mesonbuild.compilers.compilers import CompileCheckMode if T.TYPE_CHECKING: from ..._typing import ImmutableListProtocol @@ -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 diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py index acf475a1d..cc52538ea 100644 --- a/mesonbuild/compilers/mixins/visualstudio.py +++ b/mesonbuild/compilers/mixins/visualstudio.py @@ -24,6 +24,7 @@ import typing as T from ... import arglist from ... import mesonlib from ... import mlog +from mesonbuild.compilers.compilers import CompileCheckMode if T.TYPE_CHECKING: from ...environment import Environment @@ -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) diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py index 40cfc146e..e1477b965 100644 --- a/mesonbuild/compilers/vala.py +++ b/mesonbuild/compilers/vala.py @@ -19,7 +19,7 @@ import typing as T from .. import mlog from ..mesonlib import EnvironmentException, version_compare, OptionKey -from .compilers import Compiler, LibType +from .compilers import CompileCheckMode, Compiler, LibType if T.TYPE_CHECKING: from ..envconfig import MachineInfo @@ -100,7 +100,7 @@ class ValaCompiler(Compiler): extra_flags += self.get_compile_only_args() else: extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language) - with self.cached_compile(code, environment.coredata, extra_args=extra_flags, mode='compile') as p: + with self.cached_compile(code, environment.coredata, extra_args=extra_flags, mode=CompileCheckMode.COMPILE) as p: if p.returncode != 0: msg = f'Vala compiler {self.name_string()!r} cannot compile programs' raise EnvironmentException(msg) @@ -122,7 +122,7 @@ class ValaCompiler(Compiler): args += env.coredata.get_external_args(self.for_machine, self.language) vapi_args = ['--pkg', libname] args += vapi_args - with self.cached_compile(code, env.coredata, extra_args=args, mode='compile') as p: + with self.cached_compile(code, env.coredata, extra_args=args, mode=CompileCheckMode.COMPILE) as p: if p.returncode == 0: return vapi_args # Not found? Try to find the vapi file itself. diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 48541d7db..c921d648d 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -39,7 +39,7 @@ import typing as T if T.TYPE_CHECKING: from . import dependencies - from .compilers.compilers import Compiler, CompileResult, RunResult + from .compilers.compilers import Compiler, CompileResult, RunResult, CompileCheckMode from .dependencies.detect import TV_DepID from .environment import Environment from .mesonlib import OptionOverrideProxy, FileOrString @@ -48,7 +48,7 @@ if T.TYPE_CHECKING: OptionDictType = T.Union[T.Dict[str, 'UserOption[T.Any]'], OptionOverrideProxy] MutableKeyedOptionDictType = T.Dict['OptionKey', 'UserOption[T.Any]'] KeyedOptionDictType = T.Union[MutableKeyedOptionDictType, OptionOverrideProxy] - CompilerCheckCacheKey = T.Tuple[T.Tuple[str, ...], str, FileOrString, T.Tuple[str, ...], str] + CompilerCheckCacheKey = T.Tuple[T.Tuple[str, ...], str, FileOrString, T.Tuple[str, ...], CompileCheckMode] # code, args RunCheckCacheKey = T.Tuple[str, T.Tuple[str, ...]]