summaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2025-09-25 14:43:06 -0700
committerDylan Baker <dylan@pnwbakers.com>2025-10-06 09:03:07 -0700
commit08221c6d1fc4a6afe780a479bbc7e40899242601 (patch)
treede1c550b47d3ca617ebdd4a1ab52ba2fc9f08a14 /mesonbuild
parent8847c938dd1c9e2c6e64e3050eb58f7ec54fccb3 (diff)
downloadmeson-08221c6d1fc4a6afe780a479bbc7e40899242601.tar.gz
compilers/asm: Implement infrastructure for sanity checking
ASM has some special concerns because it has to be implemented in terms of assembling an object, and then linking the object with a linker or linker driver. That makes the implementation somewhat complex. There is a bit of a hack going on here with the `_run_sanity_check` method and the mro. I'm still thinking about how best to handle that.
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/compilers/asm.py56
1 files changed, 54 insertions, 2 deletions
diff --git a/mesonbuild/compilers/asm.py b/mesonbuild/compilers/asm.py
index 813c87fe6..df96c2eee 100644
--- a/mesonbuild/compilers/asm.py
+++ b/mesonbuild/compilers/asm.py
@@ -3,7 +3,8 @@ from __future__ import annotations
import os
import typing as T
-from ..mesonlib import EnvironmentException, get_meson_command
+from .. import mlog
+from ..mesonlib import EnvironmentException, Popen_safe, join_args, get_meson_command
from ..options import OptionKey
from .compilers import Compiler
from .mixins.metrowerks import MetrowerksCompiler, mwasmarm_instruction_set_args, mwasmeppc_instruction_set_args
@@ -25,6 +26,10 @@ nasm_optimization_args: T.Dict[str, T.List[str]] = {
}
+class _CheckUnimplementedException(Exception):
+ pass
+
+
class ASMCompiler(Compiler):
"""Shared base class for all ASM Compilers (Assemblers)"""
@@ -41,10 +46,57 @@ class ASMCompiler(Compiler):
self._compiler = compiler
def _sanity_check_compile_args(self, env: Environment, sourcename: str, binname: str) -> T.List[str]:
+ # TODO: fallback back to this is always wrong, it means that the
+ # concrete implementation is missing the sanity check implementation
return []
+ def _sanity_check_filenames(self) -> T.Tuple[str, str]:
+ src, bin = super()._sanity_check_filenames()
+ bin = '{}.obj'.format(os.path.splitext(bin)[0])
+ return src, bin
+
def _sanity_check_source_code(self) -> str:
- return ''
+ raise _CheckUnimplementedException()
+
+ def _run_sanity_check(self, env: Environment, cmdlist: T.List[str], work_dir: str) -> None:
+ # This is a bit of a hack
+ return
+
+ def sanity_check(self, work_dir: str, env: Environment) -> None:
+ try:
+ super().sanity_check(work_dir, env)
+ except _CheckUnimplementedException:
+ if self.info.kernel:
+ name = self.info.kernel
+ if self.info.subsystem:
+ name = f'{name} {self.info.subsystem}'
+ else:
+ name = self.info.system
+ mlog.warning(
+ f'Missing {self.id} sanity check code for {name}.',
+ 'You can help by providing such an implementation',
+ fatal=False, once=True)
+ return
+
+ # This is the object from the compilation
+ src = self._sanity_check_filenames()[1]
+ bin = self._compiler._sanity_check_filenames()[1]
+
+ cmdlist = self._compiler._sanity_check_compile_args(env, src, bin)
+
+ pc, stdo, stde = Popen_safe(cmdlist, cwd=work_dir)
+ mlog.debug('Sanity check linker command line:', join_args(cmdlist))
+ mlog.debug('Sanity check linker stdout:')
+ mlog.debug(stdo)
+ mlog.debug('-----\nSanity check linker stderr:')
+ mlog.debug(stde)
+ mlog.debug('-----')
+ if pc.returncode != 0:
+ raise EnvironmentError(
+ f'Compiler {self._compiler.name_string()} could not link an object from the {self.name_string()} assembler')
+
+ # This is also a hack
+ return super()._run_sanity_check(env, [os.path.join(work_dir, bin)], work_dir)
class NasmCompiler(ASMCompiler):