diff options
author | Dylan Baker <dylan@pnwbakers.com> | 2020-09-28 12:53:15 -0700 |
---|---|---|
committer | Dylan Baker <dylan@pnwbakers.com> | 2020-10-01 15:05:01 -0700 |
commit | 8291e947f5c2a69ea1aad75109c692ee6f8f4540 (patch) | |
tree | 8e9ff7358591e532b08cb75261b13659b31e6377 | |
parent | e039727e63561b0ecf75eff853579ee85f498a11 (diff) | |
download | meson-8291e947f5c2a69ea1aad75109c692ee6f8f4540.zip meson-8291e947f5c2a69ea1aad75109c692ee6f8f4540.tar.gz meson-8291e947f5c2a69ea1aad75109c692ee6f8f4540.tar.bz2 |
compilers: move get_compile_check_args() to Compiler
This is groundwork to put _build_wrapper in the base Compiler, which is
needed to make the D compilers truly type safe.
-rw-r--r-- | mesonbuild/compilers/compilers.py | 34 | ||||
-rw-r--r-- | mesonbuild/compilers/cpp.py | 15 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/clike.py | 24 |
3 files changed, 47 insertions, 26 deletions
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 0a53529..42bc251 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -14,6 +14,7 @@ import abc import contextlib, os.path, re, tempfile +import enum import itertools import typing as T from functools import lru_cache @@ -165,6 +166,14 @@ def is_known_suffix(fname: 'mesonlib.FileOrString') -> bool: return suffix in all_suffixes + +class CompileCheckMode(enum.Enum): + + PREPROCESS = 'preprocess' + COMPILE = 'compile' + LINK = 'link' + + cuda_buildtype_args = {'plain': [], 'debug': [], 'debugoptimized': [], @@ -716,14 +725,16 @@ class Compiler(metaclass=abc.ABCMeta): suffix = 'obj' return os.path.join(dirname, 'output.' + suffix) - def get_compiler_args_for_mode(self, mode: str) -> T.List[str]: + def get_compiler_args_for_mode(self, mode: CompileCheckMode) -> T.List[str]: # TODO: mode should really be an enum args = [] # type: T.List[str] args += self.get_always_args() - if mode == 'compile': + if mode is CompileCheckMode.COMPILE: args += self.get_compile_only_args() - if mode == 'preprocess': + elif mode is CompileCheckMode.PREPROCESS: args += self.get_preprocess_only_args() + else: + assert mode is CompileCheckMode.LINK return args def compiler_args(self, args: T.Optional[T.Iterable[str]] = None) -> CompilerArgs: @@ -761,7 +772,7 @@ class Compiler(metaclass=abc.ABCMeta): if mode != 'preprocess': output = self._get_compile_output(tmpdirname, mode) commands += self.get_output_args(output) - commands.extend(self.get_compiler_args_for_mode(mode)) + commands.extend(self.get_compiler_args_for_mode(CompileCheckMode(mode))) # extra_args must be last because it could contain '/link' to # pass args to VisualStudio's linker. In that case everything # in the command line after '/link' is given to the linker. @@ -1106,6 +1117,21 @@ class Compiler(metaclass=abc.ABCMeta): def module_name_to_filename(self, module_name: str) -> str: raise EnvironmentError('{} does not implement module_name_to_filename'.format(self.id)) + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: + """Arguments to pass the compiler and/or linker for checks. + + The default implementation turns off optimizations. mode should be + one of: + + Examples of things that go here: + - extra arguments for error checking + """ + return self.get_no_optimization_args() + + def get_no_optimization_args(self) -> T.List[str]: + """Arguments to the compiler to turn off all optimizations.""" + return [] + def get_args_from_envvars(lang: str, for_machine: MachineChoice, diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 4ef13e8..d934fa8 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 @@ -90,11 +91,11 @@ class CPPCompiler(CLikeCompiler, Compiler): code = 'class breakCCompiler;int main(void) { return 0; }\n' return self._sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code) - def get_compiler_check_args(self) -> T.List[str]: + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: # -fpermissive allows non-conforming code to compile which is necessary # for many C++ checks. Particularly, the has_header_symbol check is # too strict without this and always fails. - return super().get_compiler_check_args() + ['-fpermissive'] + return super().get_compiler_check_args(mode) + ['-fpermissive'] def has_header_symbol(self, hname: str, symbol: str, prefix: str, env: 'Environment', *, @@ -605,9 +606,9 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase): return args - def get_compiler_check_args(self) -> T.List[str]: + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: # XXX: this is a hack because so much GnuLike stuff is in the base CPPCompiler class. - return CLikeCompiler.get_compiler_check_args(self) + return Compiler.get_compiler_check_args(self, mode) class CPP11AsCPP14Mixin(CompilerMixinBase): @@ -739,7 +740,7 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler): def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return [] - def get_compiler_check_args(self) -> T.List[str]: + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: return [] @@ -768,7 +769,7 @@ class CcrxCPPCompiler(CcrxCompiler, CPPCompiler): def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return [] - def get_compiler_check_args(self) -> T.List[str]: + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: return [] class C2000CPPCompiler(C2000Compiler, CPPCompiler): @@ -802,5 +803,5 @@ class C2000CPPCompiler(C2000Compiler, CPPCompiler): def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]: return [] - def get_compiler_check_args(self) -> T.List[str]: + def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: return [] diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 7cac7dc..9de715c 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -37,6 +37,7 @@ from ... import mlog from ...linkers import GnuLikeDynamicLinkerMixin, SolarisDynamicLinker, CompCertDynamicLinker from ...mesonlib import LibType from .. import compilers +from ..compilers import CompileCheckMode from .visualstudio import VisualStudioLikeCompiler if T.TYPE_CHECKING: @@ -184,13 +185,6 @@ class CLikeCompiler(Compiler): def get_no_optimization_args(self) -> T.List[str]: return ['-O0'] - def get_compiler_check_args(self) -> T.List[str]: - ''' - Get arguments useful for compiler checks such as being permissive in - the code quality and not doing any optimization. - ''' - return self.get_no_optimization_args() - def get_output_args(self, target: str) -> T.List[str]: return ['-o', target] @@ -296,7 +290,7 @@ class CLikeCompiler(Compiler): source_name = os.path.join(work_dir, sname) binname = sname.rsplit('.', 1)[0] - mode = 'link' + mode = CompileCheckMode.LINK if self.is_cross: binname += '_cross' if self.exe_wrapper is None: @@ -305,7 +299,7 @@ class CLikeCompiler(Compiler): # on OSX the compiler binary is the same but you need # a ton of compiler flags to differentiate between # arm and x86_64. So just compile. - mode = 'compile' + mode = CompileCheckMode.COMPILE cargs, largs = self._get_basic_compiler_args(environment, mode) extra_flags = cargs + self.linker_to_compiler_args(largs) @@ -432,7 +426,7 @@ class CLikeCompiler(Compiler): def _get_compiler_check_args(self, env: 'Environment', extra_args: T.Union[None, arglist.CompilerArgs, T.List[str]], dependencies: T.Optional[T.List['Dependency']], - mode: str = 'compile') -> arglist.CompilerArgs: + mode: CompileCheckMode = CompileCheckMode.COMPILE) -> arglist.CompilerArgs: # TODO: the caller should handle the listfing of these arguments if extra_args is None: extra_args = [] @@ -460,7 +454,7 @@ class CLikeCompiler(Compiler): cargs += ca largs += la - cargs += self.get_compiler_check_args() + cargs += self.get_compiler_check_args(mode) # on MSVC compiler and linker flags must be separated by the "/link" argument # at this point, the '/link' argument may already be part of extra_args, otherwise, it is added here @@ -482,10 +476,10 @@ class CLikeCompiler(Compiler): def _build_wrapper(self, code: str, env: 'Environment', extra_args: T.Union[None, arglist.CompilerArgs, T.List[str]] = None, dependencies: T.Optional[T.List['Dependency']] = None, - mode: str = 'compile', want_output: bool = False, + mode: str = CompileCheckMode.COMPILE, want_output: bool = False, disable_cache: bool = False, temp_dir: str = None) -> T.Iterator[T.Optional[compilers.CompileResult]]: - args = self._get_compiler_check_args(env, extra_args, dependencies, mode) + args = self._get_compiler_check_args(env, extra_args, dependencies, CompileCheckMode(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 @@ -720,7 +714,7 @@ class CLikeCompiler(Compiler): #endif {delim}\n{define}''' args = self._get_compiler_check_args(env, extra_args, dependencies, - mode='preprocess').to_native() + mode=CompileCheckMode.PREPROCESS).to_native() func = functools.partial(self.cached_compile, code.format(**fargs), env.coredata, extra_args=args, mode='preprocess') if disable_cache: func = functools.partial(self.compile, code.format(**fargs), extra_args=args, mode='preprocess', temp_dir=env.scratch_dir) @@ -966,7 +960,7 @@ class CLikeCompiler(Compiler): } #endif ''' - args = self.get_compiler_check_args() + args = self.get_compiler_check_args(CompileCheckMode.COMPILE) n = 'symbols_have_underscore_prefix' with self._build_wrapper(code, env, extra_args=args, mode='compile', want_output=True, temp_dir=env.scratch_dir) as p: if p.returncode != 0: |