compilers: Every compiler can run code

Compiling and linking code is part of the Compiler base class, there is
no reason it cannot also run executables.
pull/12983/head
Xavier Claessens 1 year ago committed by Xavier Claessens
parent 3afbe042af
commit f41a95ddf2
  1. 4
      docs/markdown/snippets/compiler_run.md
  2. 25
      mesonbuild/compilers/compilers.py
  3. 26
      mesonbuild/compilers/d.py
  4. 26
      mesonbuild/compilers/mixins/clike.py
  5. 3
      mesonbuild/interpreter/compiler.py
  6. 3
      test cases/rust/1 basic/meson.build

@ -0,0 +1,4 @@
## compiler.run() method is now available for all languages
It used to be only implemented for C-like and D languages, but it is now available
for all languages.

@ -623,10 +623,31 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
dependencies: T.Optional[T.List['Dependency']] = None) -> T.Tuple[bool, bool]:
raise EnvironmentException('Language %s does not support header symbol checks.' % self.get_display_language())
def run(self, code: 'mesonlib.FileOrString', env: 'Environment', *,
def run(self, code: 'mesonlib.FileOrString', env: 'Environment',
extra_args: T.Union[T.List[str], T.Callable[[CompileCheckMode], T.List[str]], None] = None,
dependencies: T.Optional[T.List['Dependency']] = None) -> RunResult:
raise EnvironmentException('Language %s does not support run checks.' % self.get_display_language())
need_exe_wrapper = env.need_exe_wrapper(self.for_machine)
if need_exe_wrapper and self.exe_wrapper is None:
raise CrossNoRunException('Can not run test applications in this cross environment.')
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 RunResult(False)
if need_exe_wrapper:
cmdlist = self.exe_wrapper.get_command() + [p.output_name]
else:
cmdlist = [p.output_name]
try:
pe, so, se = mesonlib.Popen_safe(cmdlist)
except Exception as e:
mlog.debug(f'Could not run: {cmdlist} (error: {e})\n')
return RunResult(False)
mlog.debug('Program stdout:\n')
mlog.debug(so)
mlog.debug('Program stderr:\n')
mlog.debug(se)
return RunResult(True, pe.returncode, so, se)
# Caching run() in general seems too risky (no way to know what the program
# depends on), but some callers know more about the programs they intend to

@ -9,7 +9,6 @@ import subprocess
import typing as T
from .. import mesonlib
from .. import mlog
from ..arglist import CompilerArgs
from ..linkers import RSPFileSyntax
from ..mesonlib import (
@ -571,32 +570,11 @@ class DCompiler(Compiler):
args.append(extra_args)
return args
def run(self, code: 'mesonlib.FileOrString', env: 'Environment', *,
def run(self, code: 'mesonlib.FileOrString', env: 'Environment',
extra_args: T.Union[T.List[str], T.Callable[[CompileCheckMode], T.List[str]], None] = None,
dependencies: T.Optional[T.List['Dependency']] = None) -> compilers.RunResult:
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.')
extra_args = self._get_compile_extra_args(extra_args)
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)
if need_exe_wrapper:
cmdlist = self.exe_wrapper.get_command() + [p.output_name]
else:
cmdlist = [p.output_name]
try:
pe, so, se = mesonlib.Popen_safe(cmdlist)
except Exception as e:
mlog.debug(f'Could not run: {cmdlist} (error: {e})\n')
return compilers.RunResult(False)
mlog.debug('Program stdout:\n')
mlog.debug(so)
mlog.debug('Program stderr:\n')
mlog.debug(se)
return compilers.RunResult(True, pe.returncode, so, se)
return super().run(code, env, extra_args, dependencies)
def sizeof(self, typename: str, prefix: str, env: 'Environment', *,
extra_args: T.Union[None, T.List[str], T.Callable[[CompileCheckMode], T.List[str]]] = None,

@ -459,32 +459,6 @@ class CLikeCompiler(Compiler):
args = cargs + extra_args + largs
return args
def run(self, code: 'mesonlib.FileOrString', env: 'Environment', *,
extra_args: T.Union[T.List[str], T.Callable[[CompileCheckMode], T.List[str]], None] = None,
dependencies: T.Optional[T.List['Dependency']] = None) -> compilers.RunResult:
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=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)
if need_exe_wrapper:
cmdlist = self.exe_wrapper.get_command() + [p.output_name]
else:
cmdlist = [p.output_name]
try:
pe, so, se = mesonlib.Popen_safe(cmdlist)
except Exception as e:
mlog.debug(f'Could not run: {cmdlist} (error: {e})\n')
return compilers.RunResult(False)
mlog.debug('Program stdout:\n')
mlog.debug(so)
mlog.debug('Program stderr:\n')
mlog.debug(se)
return compilers.RunResult(True, pe.returncode, so, se)
def _compile_int(self, expression: str, prefix: str, env: 'Environment',
extra_args: T.Union[None, T.List[str], T.Callable[[CompileCheckMode], T.List[str]]],
dependencies: T.Optional[T.List['Dependency']]) -> bool:

@ -302,6 +302,9 @@ class CompilerHolder(ObjectHolder['Compiler']):
@typed_pos_args('compiler.run', (str, mesonlib.File))
@typed_kwargs('compiler.run', *_COMPILES_KWS)
def run_method(self, args: T.Tuple['mesonlib.FileOrString'], kwargs: 'CompileKW') -> 'RunResult':
if self.compiler.language not in {'d', 'c', 'cpp', 'objc', 'objcpp'}:
FeatureNew.single_use(f'compiler.run for {self.compiler.get_display_language()} language',
'1.5.0', self.subproject, location=self.current_node)
code = args[0]
if isinstance(code, mesonlib.File):
self.interpreter.add_build_def_file(code)

@ -18,3 +18,6 @@ test(
),
should_fail : true,
)
rustc = meson.get_compiler('rust')
assert(rustc.run('fn main(){}').returncode() == 0)

Loading…
Cancel
Save