compilers: introduce common helper for sanity checks
Avoid reinventing the wheel and instead use a single helper, taking care of logging and cross compilation. Fixes: #14373 Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
8909a09d2a
commit
8e564f16ae
|
@ -1200,6 +1200,23 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta):
|
|||
is good enough here.
|
||||
"""
|
||||
|
||||
def run_sanity_check(self, environment: Environment, cmdlist: T.List[str], work_dir: str, use_exe_wrapper_for_cross: bool = True) -> T.Tuple[str, str]:
|
||||
# Run sanity check
|
||||
if self.is_cross and use_exe_wrapper_for_cross:
|
||||
if not environment.has_exe_wrapper():
|
||||
# Can't check if the binaries run so we have to assume they do
|
||||
return ('', '')
|
||||
cmdlist = environment.exe_wrapper.get_command() + cmdlist
|
||||
mlog.debug('Running test binary command: ', mesonlib.join_args(cmdlist))
|
||||
try:
|
||||
pe, stdo, stde = Popen_safe_logged(cmdlist, 'Sanity check', cwd=work_dir)
|
||||
except Exception as e:
|
||||
raise mesonlib.EnvironmentException(f'Could not invoke sanity check executable: {e!s}.')
|
||||
|
||||
if pe.returncode != 0:
|
||||
raise mesonlib.EnvironmentException(f'Executables created by {self.language} compiler {self.name_string()} are not runnable.')
|
||||
return stdo, stde
|
||||
|
||||
def split_shlib_to_parts(self, fname: str) -> T.Tuple[T.Optional[str], str]:
|
||||
return None, fname
|
||||
|
||||
|
|
|
@ -102,10 +102,7 @@ class CsCompiler(BasicLinkerIsCompilerMixin, Compiler):
|
|||
cmdlist = [self.runner, obj]
|
||||
else:
|
||||
cmdlist = [os.path.join(work_dir, obj)]
|
||||
pe = subprocess.Popen(cmdlist, cwd=work_dir)
|
||||
pe.wait()
|
||||
if pe.returncode != 0:
|
||||
raise EnvironmentException('Executables created by Mono compiler %s are not runnable.' % self.name_string())
|
||||
self.run_sanity_check(environment, cmdlist, work_dir, use_exe_wrapper_for_cross=False)
|
||||
|
||||
def needs_static_linker(self) -> bool:
|
||||
return False
|
||||
|
|
|
@ -577,21 +577,12 @@ class CudaCompiler(Compiler):
|
|||
|
||||
# Run sanity check (if possible)
|
||||
if self.is_cross:
|
||||
if not env.has_exe_wrapper():
|
||||
return
|
||||
else:
|
||||
cmdlist = env.exe_wrapper.get_command() + [binary_name]
|
||||
else:
|
||||
cmdlist = self.exelist + ['--run', '"' + binary_name + '"']
|
||||
mlog.debug('Sanity check run command line: ', ' '.join(cmdlist))
|
||||
pe, stdo, stde = Popen_safe(cmdlist, cwd=work_dir)
|
||||
mlog.debug('Sanity check run stdout: ')
|
||||
mlog.debug(stdo)
|
||||
mlog.debug('-----\nSanity check run stderr:')
|
||||
mlog.debug(stde)
|
||||
mlog.debug('-----')
|
||||
pe.wait()
|
||||
if pe.returncode != 0:
|
||||
return
|
||||
|
||||
cmdlist = self.exelist + ['--run', f'"{binary_name}"']
|
||||
try:
|
||||
stdo, stde = self.run_sanity_check(env, cmdlist, work_dir)
|
||||
except EnvironmentException:
|
||||
raise EnvironmentException(f'Executables created by {self.language} compiler {self.name_string()} are not runnable.')
|
||||
|
||||
# Interpret the result of the sanity test.
|
||||
|
@ -599,8 +590,6 @@ class CudaCompiler(Compiler):
|
|||
# architecture detection test.
|
||||
if stde == '':
|
||||
self.detected_cc = stdo
|
||||
else:
|
||||
mlog.debug('cudaGetDeviceCount() returned ' + stde)
|
||||
|
||||
def has_header_symbol(self, hname: str, symbol: str, prefix: str,
|
||||
env: 'Environment', *,
|
||||
|
|
|
@ -456,15 +456,7 @@ class DCompiler(Compiler):
|
|||
if pc.returncode != 0:
|
||||
raise EnvironmentException('D compiler %s cannot compile programs.' % self.name_string())
|
||||
|
||||
if self.is_cross:
|
||||
if not environment.has_exe_wrapper():
|
||||
# Can't check if the binaries run so we have to assume they do
|
||||
return
|
||||
cmdlist = environment.exe_wrapper.get_command() + [output_name]
|
||||
else:
|
||||
cmdlist = [output_name]
|
||||
if subprocess.call(cmdlist) != 0:
|
||||
raise EnvironmentException('Executables created by D compiler %s are not runnable.' % self.name_string())
|
||||
stdo, stde = self.run_sanity_check(environment, [output_name], work_dir)
|
||||
|
||||
def needs_static_linker(self) -> bool:
|
||||
return True
|
||||
|
|
|
@ -91,10 +91,7 @@ class JavaCompiler(BasicLinkerIsCompilerMixin, Compiler):
|
|||
runner = shutil.which(self.javarunner)
|
||||
if runner:
|
||||
cmdlist = [runner, '-cp', '.', obj]
|
||||
pe = subprocess.Popen(cmdlist, cwd=work_dir)
|
||||
pe.wait()
|
||||
if pe.returncode != 0:
|
||||
raise EnvironmentException(f'Executables created by Java compiler {self.name_string()} are not runnable.')
|
||||
self.run_sanity_check(environment, cmdlist, work_dir, use_exe_wrapper_for_cross=False)
|
||||
else:
|
||||
m = "Java Virtual Machine wasn't found, but it's needed by Meson. " \
|
||||
"Please install a JRE.\nIf you have specific needs where this " \
|
||||
|
|
|
@ -307,21 +307,7 @@ class CLikeCompiler(Compiler):
|
|||
mlog.debug('-----')
|
||||
if pc.returncode != 0:
|
||||
raise mesonlib.EnvironmentException(f'Compiler {self.name_string()} cannot compile programs.')
|
||||
# Run sanity check
|
||||
if self.is_cross:
|
||||
if not environment.has_exe_wrapper():
|
||||
# Can't check if the binaries run so we have to assume they do
|
||||
return
|
||||
cmdlist = environment.exe_wrapper.get_command() + [binary_name]
|
||||
else:
|
||||
cmdlist = [binary_name]
|
||||
mlog.debug('Running test binary command: ', mesonlib.join_args(cmdlist))
|
||||
try:
|
||||
pe, _, _ = Popen_safe_logged(cmdlist, 'Sanity check', cwd=work_dir)
|
||||
except Exception as e:
|
||||
raise mesonlib.EnvironmentException(f'Could not invoke sanity test executable: {e!s}.')
|
||||
if pe.returncode != 0:
|
||||
raise mesonlib.EnvironmentException(f'Executables created by {self.language} compiler {self.name_string()} are not runnable.')
|
||||
self.run_sanity_check(environment, [binary_name], work_dir)
|
||||
|
||||
def sanity_check(self, work_dir: str, environment: 'Environment') -> None:
|
||||
code = 'int main(void) { int class=0; return class; }\n'
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import functools
|
||||
import subprocess, os.path
|
||||
import os.path
|
||||
import textwrap
|
||||
import re
|
||||
import typing as T
|
||||
|
@ -141,17 +141,7 @@ class RustCompiler(Compiler):
|
|||
if pc.returncode != 0:
|
||||
raise EnvironmentException(f'Rust compiler {self.name_string()} cannot compile programs.')
|
||||
self._native_static_libs(work_dir, source_name)
|
||||
if self.is_cross:
|
||||
if not environment.has_exe_wrapper():
|
||||
# Can't check if the binaries run so we have to assume they do
|
||||
return
|
||||
cmdlist = environment.exe_wrapper.get_command() + [output_name]
|
||||
else:
|
||||
cmdlist = [output_name]
|
||||
pe = subprocess.Popen(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
pe.wait()
|
||||
if pe.returncode != 0:
|
||||
raise EnvironmentException(f'Executables created by Rust compiler {self.name_string()} are not runnable.')
|
||||
self.run_sanity_check(environment, [output_name], work_dir)
|
||||
|
||||
def _native_static_libs(self, work_dir: str, source_name: str) -> None:
|
||||
# Get libraries needed to link with a Rust staticlib
|
||||
|
|
|
@ -8,7 +8,7 @@ import subprocess, os.path
|
|||
import typing as T
|
||||
|
||||
from .. import mlog, options
|
||||
from ..mesonlib import EnvironmentException, MesonException, version_compare
|
||||
from ..mesonlib import MesonException, version_compare
|
||||
from .compilers import Compiler, clike_debug_args
|
||||
|
||||
|
||||
|
@ -170,13 +170,7 @@ class SwiftCompiler(Compiler):
|
|||
''')
|
||||
pc = subprocess.Popen(self.exelist + extra_flags + ['-emit-executable', '-o', output_name, src], cwd=work_dir)
|
||||
pc.wait()
|
||||
if pc.returncode != 0:
|
||||
raise EnvironmentException('Swift compiler %s cannot compile programs.' % self.name_string())
|
||||
if self.is_cross:
|
||||
# Can't check if the binaries run so we have to assume they do
|
||||
return
|
||||
if subprocess.call(output_name) != 0:
|
||||
raise EnvironmentException('Executables created by Swift compiler %s are not runnable.' % self.name_string())
|
||||
self.run_sanity_check(environment, [output_name], work_dir)
|
||||
|
||||
def get_debug_args(self, is_debug: bool) -> T.List[str]:
|
||||
return clike_debug_args[is_debug]
|
||||
|
|
Loading…
Reference in New Issue