Fix crash when toolchain is missing

Add a MissingCompiler class returned by compiler detecting methods
intead of None - accessing such an object raises a DependencyException

Fixes #10586

Co-authored-by: duckflyer <duckflyer@gmail.com>
pull/11115/head
SmallWood-D 2 years ago committed by Jussi Pakkanen
parent 23fcea16e5
commit d32ee583ad
  1. 5
      mesonbuild/cmake/tracetargets.py
  2. 3
      mesonbuild/dependencies/__init__.py
  3. 19
      mesonbuild/dependencies/base.py
  4. 2
      mesonbuild/dependencies/cuda.py
  5. 5
      mesonbuild/dependencies/dev.py
  6. 2
      mesonbuild/dependencies/misc.py
  7. 2
      mesonbuild/dependencies/mpi.py
  8. 3
      mesonbuild/dependencies/qt.py

@ -12,6 +12,7 @@ if T.TYPE_CHECKING:
from .traceparser import CMakeTraceParser
from ..environment import Environment
from ..compilers import Compiler
from ..dependencies import MissingCompiler
class ResolvedTarget:
def __init__(self) -> None:
@ -24,7 +25,7 @@ def resolve_cmake_trace_targets(target_name: str,
trace: 'CMakeTraceParser',
env: 'Environment',
*,
clib_compiler: T.Optional['Compiler'] = None,
clib_compiler: T.Union['MissingCompiler', 'Compiler'] = None,
not_found_warning: T.Callable[[str], None] = lambda x: None) -> ResolvedTarget:
res = ResolvedTarget()
targets = [target_name]
@ -48,7 +49,7 @@ def resolve_cmake_trace_targets(target_name: str,
res.libraries += [curr]
elif Path(curr).is_absolute() and Path(curr).exists():
res.libraries += [curr]
elif env.machines.build.is_windows() and reg_is_maybe_bare_lib.match(curr) and clib_compiler is not None:
elif env.machines.build.is_windows() and reg_is_maybe_bare_lib.match(curr) and clib_compiler:
# On Windows, CMake library dependencies can be passed as bare library names,
# CMake brute-forces a combination of prefix/suffix combinations to find the
# right library. Assume any bare argument passed which is not also a CMake

@ -15,7 +15,7 @@
from .boost import BoostDependency
from .cuda import CudaDependency
from .hdf5 import hdf5_factory
from .base import Dependency, InternalDependency, ExternalDependency, NotFoundDependency
from .base import Dependency, InternalDependency, ExternalDependency, NotFoundDependency, MissingCompiler
from .base import (
ExternalLibrary, DependencyException, DependencyMethods,
BuiltinDependency, SystemDependency, get_leaf_external_dependencies)
@ -52,6 +52,7 @@ __all__ = [
'ExternalLibrary',
'DependencyException',
'DependencyMethods',
'MissingCompiler',
'CMakeDependency',
'ConfigToolDependency',

@ -46,6 +46,19 @@ class DependencyException(MesonException):
'''Exceptions raised while trying to find dependencies'''
class MissingCompiler:
"""Represent a None Compiler - when no tool chain is found.
replacing AttributeError with DependencyException"""
def __getattr__(self, item: str) -> T.Any:
if item.startswith('__'):
raise AttributeError()
raise DependencyException('no toolchain found')
def __bool__(self) -> bool:
return False
class DependencyMethods(Enum):
# Auto means to use whatever dependency checking mechanisms in whatever order meson thinks is best.
AUTO = 'auto'
@ -361,7 +374,7 @@ class ExternalDependency(Dependency, HasNativeKwarg):
HasNativeKwarg.__init__(self, kwargs)
self.clib_compiler = detect_compiler(self.name, environment, self.for_machine, self.language)
def get_compiler(self) -> 'Compiler':
def get_compiler(self) -> T.Union['MissingCompiler', 'Compiler']:
return self.clib_compiler
def get_partial_dependency(self, *, compile_args: bool = False,
@ -573,7 +586,7 @@ def process_method_kw(possible: T.Iterable[DependencyMethods], kwargs: T.Dict[st
return methods
def detect_compiler(name: str, env: 'Environment', for_machine: MachineChoice,
language: T.Optional[str]) -> T.Optional['Compiler']:
language: T.Optional[str]) -> T.Union['MissingCompiler', 'Compiler']:
"""Given a language and environment find the compiler used."""
compilers = env.coredata.compilers[for_machine]
@ -591,7 +604,7 @@ def detect_compiler(name: str, env: 'Environment', for_machine: MachineChoice,
return compilers[lang]
except KeyError:
continue
return None
return MissingCompiler()
class SystemDependency(ExternalDependency):

@ -283,7 +283,7 @@ class CudaDependency(SystemDependency):
return candidates
def get_link_args(self, language: T.Optional[str] = None, raw: bool = False) -> T.List[str]:
args = []
args: T.List[str] = []
if self.libdir:
args += self.clib_compiler.get_linker_search_args(self.libdir)
for lib in self.requested_modules:

@ -499,11 +499,6 @@ class ZlibSystemDependency(SystemDependency):
self.is_found = True
self.link_args = ['-lz']
else:
# Without a clib_compiler we can't find zlib, so just give up.
if self.clib_compiler is None:
self.is_found = False
return
if self.clib_compiler.get_argument_syntax() == 'msvc':
libs = ['zlib1' 'zlib']
else:

@ -145,7 +145,7 @@ class ThreadDependency(SystemDependency):
self.is_found = True
# Happens if you are using a language with threads
# concept without C, such as plain Cuda.
if self.clib_compiler is None:
if not self.clib_compiler:
self.compile_args = []
self.link_args = []
else:

@ -40,7 +40,7 @@ def mpi_factory(env: 'Environment',
candidates: T.List['DependencyGenerator'] = []
compiler = detect_compiler('mpi', env, for_machine, language)
if compiler is None:
if not compiler:
return []
compiler_is_intel = compiler.get_id() in {'intel', 'intel-cl'}

@ -33,6 +33,7 @@ if T.TYPE_CHECKING:
from ..compilers import Compiler
from ..envconfig import MachineInfo
from ..environment import Environment
from ..dependencies import MissingCompiler
def _qt_get_private_includes(mod_inc_dir: str, module: str, mod_version: str) -> T.List[str]:
@ -122,7 +123,7 @@ class _QtBase:
"""Mixin class for shared components between PkgConfig and Qmake."""
link_args: T.List[str]
clib_compiler: 'Compiler'
clib_compiler: T.Union['MissingCompiler', 'Compiler']
env: 'Environment'
libexecdir: T.Optional[str] = None

Loading…
Cancel
Save