diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index ef4b2996f..54abc43c7 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -20,14 +20,16 @@ import typing as T from .. import mesonlib from ..mesonlib import relpath, HoldableObject, MachineChoice from ..interpreterbase.decorators import noKwargs, noPosargs +from ..programs import ExternalProgram if T.TYPE_CHECKING: from ..interpreter import Interpreter from ..interpreter.interpreterobjects import MachineHolder from ..interpreterbase import TYPE_var, TYPE_kwargs - from ..programs import ExternalProgram + from ..programs import OverrideProgram from ..wrap import WrapMode - from ..build import EnvironmentVariables + from ..build import EnvironmentVariables, Executable + from ..dependencies import Dependency class ModuleState: """Object passed to all module methods. @@ -87,6 +89,38 @@ class ModuleState: return self._interpreter.find_program_impl(prog, required=required, version_func=version_func, wanted=wanted, silent=silent, for_machine=for_machine) + def find_tool(self, name: str, depname: str, varname: str, required: bool = True, + wanted: T.Optional[str] = None) -> T.Union['Executable', ExternalProgram, 'OverrideProgram']: + # Look in overrides in case it's built as subproject + progobj = self._interpreter.program_from_overrides([name], []) + if progobj is not None: + return progobj + + # Look in machine file + prog_list = self.environment.lookup_binary_entry(MachineChoice.HOST, name) + if prog_list is not None: + return ExternalProgram.from_entry(name, prog_list) + + # Check if pkgconfig has a variable + dep = self.dependency(depname, native=True, required=False, wanted=wanted) + if dep.found() and dep.type_name == 'pkgconfig': + value = dep.get_variable(pkgconfig=varname) + if value: + return ExternalProgram(name, [value]) + + # Normal program lookup + return self.find_program(name, required=required, wanted=wanted) + + def dependency(self, depname: str, native: bool = False, required: bool = True, + wanted: T.Optional[str] = None) -> 'Dependency': + kwargs = {'native': native, 'required': required} + if wanted: + kwargs['version'] = wanted + # FIXME: Even if we fix the function, mypy still can't figure out what's + # going on here. And we really dont want to call interpreter + # implementations of meson functions anyway. + return self._interpreter.func_dependency(self.current_node, [depname], kwargs) # type: ignore + def test(self, args: T.Tuple[str, T.Union[build.Executable, build.Jar, 'ExternalProgram', mesonlib.File]], workdir: T.Optional[str] = None, env: T.Union[T.List[str], T.Dict[str, str], str] = None, diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 1f4f140ed..4cfbe2640 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -325,36 +325,6 @@ class GnomeModule(ExtensionModule): mlog.bold('https://github.com/mesonbuild/meson/issues/1387'), once=True) - def _get_dep(self, state: 'ModuleState', depname: str, native: bool = False, - required: bool = True) -> Dependency: - kwargs = {'native': native, 'required': required} - # FIXME: Even if we fix the function, mypy still can't figure out what's - # going on here. And we really dont want to call interpreter - # implementations of meson functions anyway. - return self.interpreter.func_dependency(state.current_node, [depname], kwargs) # type: ignore - - def _get_native_binary(self, state: 'ModuleState', name: str, depname: str, - varname: str, required: bool = True) -> T.Union[ExternalProgram, OverrideProgram, 'build.Executable']: - # Look in overrides in case glib/gtk/etc are built as subproject - prog = self.interpreter.program_from_overrides([name], []) - if prog is not None: - return prog - - # Look in machine file - prog_list = state.environment.lookup_binary_entry(MachineChoice.HOST, name) - if prog_list is not None: - return ExternalProgram.from_entry(name, prog_list) - - # Check if pkgconfig has a variable - dep = self._get_dep(state, depname, native=True, required=False) - if dep.found() and dep.type_name == 'pkgconfig': - value = dep.get_pkgconfig_variable(varname, [], None) - if value: - return ExternalProgram(name, [value]) - - # Normal program lookup - return state.find_program(name, required=required) - @typed_kwargs( 'gnome.post_install', KwargInfo('glib_compile_schemas', bool, default=False), @@ -369,7 +339,7 @@ class GnomeModule(ExtensionModule): datadir_abs = os.path.join(state.environment.get_prefix(), state.environment.get_datadir()) if kwargs['glib_compile_schemas'] and not self.install_glib_compile_schemas: self.install_glib_compile_schemas = True - prog = self._get_native_binary(state, 'glib-compile-schemas', 'gio-2.0', 'glib_compile_schemas') + prog = state.find_tool('glib-compile-schemas', 'gio-2.0', 'glib_compile_schemas') schemasdir = os.path.join(datadir_abs, 'glib-2.0', 'schemas') script = state.backend.get_executable_serialisation([prog, schemasdir]) script.skip_if_destdir = True @@ -377,7 +347,7 @@ class GnomeModule(ExtensionModule): for d in kwargs['gio_querymodules']: if d not in self.install_gio_querymodules: self.install_gio_querymodules.append(d) - prog = self._get_native_binary(state, 'gio-querymodules', 'gio-2.0', 'gio_querymodules') + prog = state.find_tool('gio-querymodules', 'gio-2.0', 'gio_querymodules') moduledir = os.path.join(state.environment.get_prefix(), d) script = state.backend.get_executable_serialisation([prog, moduledir]) script.skip_if_destdir = True @@ -798,9 +768,9 @@ class GnomeModule(ExtensionModule): def _get_gir_dep(self, state: 'ModuleState') -> T.Tuple[Dependency, T.Union[build.Executable, 'ExternalProgram', 'OverrideProgram'], T.Union[build.Executable, 'ExternalProgram', 'OverrideProgram']]: if not self.gir_dep: - self.gir_dep = self._get_dep(state, 'gobject-introspection-1.0') - self.giscanner = self._get_native_binary(state, 'g-ir-scanner', 'gobject-introspection-1.0', 'g_ir_scanner') - self.gicompiler = self._get_native_binary(state, 'g-ir-compiler', 'gobject-introspection-1.0', 'g_ir_compiler') + self.gir_dep = state.dependency('gobject-introspection-1.0') + self.giscanner = state.find_tool('g-ir-scanner', 'gobject-introspection-1.0', 'g_ir_scanner') + self.gicompiler = state.find_tool('g-ir-compiler', 'gobject-introspection-1.0', 'g_ir_compiler') return self.gir_dep, self.giscanner, self.gicompiler @functools.lru_cache(maxsize=None) diff --git a/mesonbuild/modules/unstable_wayland.py b/mesonbuild/modules/unstable_wayland.py index 79f768562..a0a796568 100644 --- a/mesonbuild/modules/unstable_wayland.py +++ b/mesonbuild/modules/unstable_wayland.py @@ -18,7 +18,7 @@ from . import ExtensionModule, ModuleReturnValue from ..build import CustomTarget from ..interpreter.type_checking import NoneType, in_set_validator from ..interpreterbase import FeatureNew, typed_pos_args, typed_kwargs, KwargInfo -from ..mesonlib import File, MesonException, MachineChoice +from ..mesonlib import File, MesonException class WaylandModule(ExtensionModule): @@ -47,10 +47,9 @@ class WaylandModule(ExtensionModule): if self.scanner_bin is None: # wayland-scanner from BUILD machine must have same version as wayland # libraries from HOST machine. - dep = self.interpreter.func_dependency(state.current_node, ['wayland-client'], {}) - self.scanner_bin = state.find_program('wayland-scanner', - for_machine=MachineChoice.BUILD, - wanted=dep.version) + dep = state.dependency('wayland-client') + self.scanner_bin = state.find_tool('wayland-scanner', 'wayland-scanner', 'wayland_scanner', + wanted=dep.version) scope = 'public' if kwargs['public'] else 'private' sides = [i for i in ['client', 'server'] if kwargs[i]] @@ -107,7 +106,7 @@ class WaylandModule(ExtensionModule): raise MesonException('stable protocols do not require a version number.') if self.protocols_dep is None: - self.protocols_dep = self.interpreter.func_dependency(state.current_node, ['wayland-protocols'], {}) + self.protocols_dep = state.dependency('wayland-protocols') if self.pkgdatadir is None: self.pkgdatadir = self.protocols_dep.get_variable(pkgconfig='pkgdatadir', internal='pkgdatadir')