aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/modules
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/modules')
-rw-r--r--mesonbuild/modules/__init__.py18
-rw-r--r--mesonbuild/modules/fs.py121
-rw-r--r--mesonbuild/modules/gnome.py85
-rw-r--r--mesonbuild/modules/pkgconfig.py8
-rw-r--r--mesonbuild/modules/python.py3
-rw-r--r--mesonbuild/modules/rust.py4
6 files changed, 151 insertions, 88 deletions
diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py
index 87892e6..3938101 100644
--- a/mesonbuild/modules/__init__.py
+++ b/mesonbuild/modules/__init__.py
@@ -82,19 +82,21 @@ class ModuleState:
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[build.OverrideExecutable, 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
+ wanted: T.Optional[str] = None, for_machine: MachineChoice = MachineChoice.HOST) -> T.Union[build.OverrideExecutable, ExternalProgram, 'OverrideProgram']:
+ if for_machine is MachineChoice.HOST:
+ # 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)
+ prog_list = self.environment.lookup_binary_entry(for_machine, 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)
+ dep = self.dependency(depname, native=for_machine is MachineChoice.BUILD,
+ required=False, wanted=wanted)
if dep.found() and dep.type_name == 'pkgconfig':
value = dep.get_variable(pkgconfig=varname)
if value:
@@ -106,7 +108,7 @@ class ModuleState:
return progobj
# Normal program lookup
- return self.find_program(name, required=required, wanted=wanted)
+ return self.find_program(name, required=required, wanted=wanted, for_machine=for_machine)
def dependency(self, depname: str, native: bool = False, required: bool = True,
wanted: T.Optional[str] = None) -> 'Dependency':
diff --git a/mesonbuild/modules/fs.py b/mesonbuild/modules/fs.py
index 1fa368e..57a6b6d 100644
--- a/mesonbuild/modules/fs.py
+++ b/mesonbuild/modules/fs.py
@@ -2,7 +2,9 @@
# Copyright 2019 The Meson development team
from __future__ import annotations
-from pathlib import Path, PurePath, PureWindowsPath
+from ntpath import sep as ntsep
+from pathlib import Path
+from posixpath import sep as posixsep
import hashlib
import os
import typing as T
@@ -12,7 +14,7 @@ from .. import mlog
from ..build import BuildTarget, CustomTarget, CustomTargetIndex, InvalidArguments
from ..interpreter.type_checking import INSTALL_KW, INSTALL_MODE_KW, INSTALL_TAG_KW, NoneType
from ..interpreterbase import FeatureNew, KwargInfo, typed_kwargs, typed_pos_args, noKwargs
-from ..mesonlib import File, MesonException, has_path_sep, path_is_in_root, relpath
+from ..mesonlib import File, MesonException, has_path_sep, is_windows, path_is_in_root, relpath
if T.TYPE_CHECKING:
from . import ModuleState
@@ -42,7 +44,7 @@ class FSModule(ExtensionModule):
INFO = ModuleInfo('fs', '0.53.0')
- def __init__(self, interpreter: 'Interpreter') -> None:
+ def __init__(self, interpreter: Interpreter) -> None:
super().__init__(interpreter)
self.methods.update({
'as_posix': self.as_posix,
@@ -62,29 +64,30 @@ class FSModule(ExtensionModule):
'replace_suffix': self.replace_suffix,
'size': self.size,
'stem': self.stem,
+ 'suffix': self.suffix,
})
- def _absolute_dir(self, state: 'ModuleState', arg: 'FileOrString') -> Path:
+ def _absolute_dir(self, state: ModuleState, arg: FileOrString) -> str:
"""
make an absolute path from a relative path, WITHOUT resolving symlinks
"""
if isinstance(arg, File):
- return Path(arg.absolute_path(state.source_root, state.environment.get_build_dir()))
- return Path(state.source_root) / Path(state.subdir) / Path(arg).expanduser()
+ return arg.absolute_path(state.source_root, state.environment.get_build_dir())
+ return os.path.join(state.source_root, state.subdir, os.path.expanduser(arg))
@staticmethod
- def _obj_to_path(feature_new_prefix: str, obj: T.Union[FileOrString, BuildTargetTypes], state: ModuleState) -> PurePath:
+ def _obj_to_pathstr(feature_new_prefix: str, obj: T.Union[FileOrString, BuildTargetTypes], state: ModuleState) -> str:
if isinstance(obj, str):
- return PurePath(obj)
+ return obj
if isinstance(obj, File):
FeatureNew(f'{feature_new_prefix} with file', '0.59.0').use(state.subproject, location=state.current_node)
- return PurePath(str(obj))
+ return str(obj)
FeatureNew(f'{feature_new_prefix} with build_tgt, custom_tgt, and custom_idx', '1.4.0').use(state.subproject, location=state.current_node)
- return PurePath(state.backend.get_target_filename(obj))
+ return state.backend.get_target_filename(obj)
- def _resolve_dir(self, state: 'ModuleState', arg: 'FileOrString') -> Path:
+ def _resolve_dir(self, state: ModuleState, arg: FileOrString) -> str:
"""
resolves symlinks and makes absolute a directory relative to calling meson.build,
if not already absolute
@@ -92,7 +95,7 @@ class FSModule(ExtensionModule):
path = self._absolute_dir(state, arg)
try:
# accommodate unresolvable paths e.g. symlink loops
- path = path.resolve()
+ path = os.path.realpath(path)
except Exception:
# return the best we could do
pass
@@ -101,123 +104,139 @@ class FSModule(ExtensionModule):
@noKwargs
@FeatureNew('fs.expanduser', '0.54.0')
@typed_pos_args('fs.expanduser', str)
- def expanduser(self, state: 'ModuleState', args: T.Tuple[str], kwargs: T.Dict[str, T.Any]) -> str:
- return str(Path(args[0]).expanduser())
+ def expanduser(self, state: ModuleState, args: T.Tuple[str], kwargs: T.Dict[str, T.Any]) -> str:
+ return os.path.expanduser(args[0])
@noKwargs
@FeatureNew('fs.is_absolute', '0.54.0')
@typed_pos_args('fs.is_absolute', (str, File))
- def is_absolute(self, state: 'ModuleState', args: T.Tuple['FileOrString'], kwargs: T.Dict[str, T.Any]) -> bool:
- if isinstance(args[0], File):
+ def is_absolute(self, state: ModuleState, args: T.Tuple[FileOrString], kwargs: T.Dict[str, T.Any]) -> bool:
+ path = args[0]
+ if isinstance(path, File):
FeatureNew('fs.is_absolute with file', '0.59.0').use(state.subproject, location=state.current_node)
- return PurePath(str(args[0])).is_absolute()
+ path = str(path)
+ if is_windows():
+ # os.path.isabs was broken for Windows before Python 3.13, so we implement it ourselves
+ path = path[:3].replace(posixsep, ntsep)
+ return path.startswith(ntsep * 2) or path.startswith(':' + ntsep, 1)
+ return path.startswith(posixsep)
@noKwargs
@FeatureNew('fs.as_posix', '0.54.0')
@typed_pos_args('fs.as_posix', str)
- def as_posix(self, state: 'ModuleState', args: T.Tuple[str], kwargs: T.Dict[str, T.Any]) -> str:
+ def as_posix(self, state: ModuleState, args: T.Tuple[str], kwargs: T.Dict[str, T.Any]) -> str:
r"""
this function assumes you are passing a Windows path, even if on a Unix-like system
and so ALL '\' are turned to '/', even if you meant to escape a character
"""
- return PureWindowsPath(args[0]).as_posix()
+ return args[0].replace(ntsep, posixsep)
@noKwargs
@typed_pos_args('fs.exists', str)
- def exists(self, state: 'ModuleState', args: T.Tuple[str], kwargs: T.Dict[str, T.Any]) -> bool:
- return self._resolve_dir(state, args[0]).exists()
+ def exists(self, state: ModuleState, args: T.Tuple[str], kwargs: T.Dict[str, T.Any]) -> bool:
+ return os.path.exists(self._resolve_dir(state, args[0]))
@noKwargs
@typed_pos_args('fs.is_symlink', (str, File))
- def is_symlink(self, state: 'ModuleState', args: T.Tuple['FileOrString'], kwargs: T.Dict[str, T.Any]) -> bool:
+ def is_symlink(self, state: ModuleState, args: T.Tuple[FileOrString], kwargs: T.Dict[str, T.Any]) -> bool:
if isinstance(args[0], File):
FeatureNew('fs.is_symlink with file', '0.59.0').use(state.subproject, location=state.current_node)
- return self._absolute_dir(state, args[0]).is_symlink()
+ return os.path.islink(self._absolute_dir(state, args[0]))
@noKwargs
@typed_pos_args('fs.is_file', str)
- def is_file(self, state: 'ModuleState', args: T.Tuple[str], kwargs: T.Dict[str, T.Any]) -> bool:
- return self._resolve_dir(state, args[0]).is_file()
+ def is_file(self, state: ModuleState, args: T.Tuple[str], kwargs: T.Dict[str, T.Any]) -> bool:
+ return os.path.isfile(self._resolve_dir(state, args[0]))
@noKwargs
@typed_pos_args('fs.is_dir', str)
- def is_dir(self, state: 'ModuleState', args: T.Tuple[str], kwargs: T.Dict[str, T.Any]) -> bool:
- return self._resolve_dir(state, args[0]).is_dir()
+ def is_dir(self, state: ModuleState, args: T.Tuple[str], kwargs: T.Dict[str, T.Any]) -> bool:
+ return os.path.isdir(self._resolve_dir(state, args[0]))
@noKwargs
@typed_pos_args('fs.hash', (str, File), str)
- def hash(self, state: 'ModuleState', args: T.Tuple['FileOrString', str], kwargs: T.Dict[str, T.Any]) -> str:
+ def hash(self, state: ModuleState, args: T.Tuple[FileOrString, str], kwargs: T.Dict[str, T.Any]) -> str:
if isinstance(args[0], File):
FeatureNew('fs.hash with file', '0.59.0').use(state.subproject, location=state.current_node)
file = self._resolve_dir(state, args[0])
- if not file.is_file():
+ if not os.path.isfile(file):
raise MesonException(f'{file} is not a file and therefore cannot be hashed')
try:
h = hashlib.new(args[1])
except ValueError:
raise MesonException('hash algorithm {} is not available'.format(args[1]))
- mlog.debug('computing {} sum of {} size {} bytes'.format(args[1], file, file.stat().st_size))
- h.update(file.read_bytes())
+ mlog.debug('computing {} sum of {} size {} bytes'.format(args[1], file, os.stat(file).st_size))
+ with open(file, mode='rb', buffering=0) as f:
+ h.update(f.read())
return h.hexdigest()
@noKwargs
@typed_pos_args('fs.size', (str, File))
- def size(self, state: 'ModuleState', args: T.Tuple['FileOrString'], kwargs: T.Dict[str, T.Any]) -> int:
+ def size(self, state: ModuleState, args: T.Tuple[FileOrString], kwargs: T.Dict[str, T.Any]) -> int:
if isinstance(args[0], File):
FeatureNew('fs.size with file', '0.59.0').use(state.subproject, location=state.current_node)
file = self._resolve_dir(state, args[0])
- if not file.is_file():
+ if not os.path.isfile(file):
raise MesonException(f'{file} is not a file and therefore cannot be sized')
try:
- return file.stat().st_size
+ return os.stat(file).st_size
except ValueError:
raise MesonException('{} size could not be determined'.format(args[0]))
@noKwargs
@typed_pos_args('fs.is_samepath', (str, File), (str, File))
- def is_samepath(self, state: 'ModuleState', args: T.Tuple['FileOrString', 'FileOrString'], kwargs: T.Dict[str, T.Any]) -> bool:
+ def is_samepath(self, state: ModuleState, args: T.Tuple[FileOrString, FileOrString], kwargs: T.Dict[str, T.Any]) -> bool:
if isinstance(args[0], File) or isinstance(args[1], File):
FeatureNew('fs.is_samepath with file', '0.59.0').use(state.subproject, location=state.current_node)
file1 = self._resolve_dir(state, args[0])
file2 = self._resolve_dir(state, args[1])
- if not file1.exists():
+ if not os.path.exists(file1):
return False
- if not file2.exists():
+ if not os.path.exists(file2):
return False
try:
- return file1.samefile(file2)
+ return os.path.samefile(file1, file2)
except OSError:
return False
@noKwargs
@typed_pos_args('fs.replace_suffix', (str, File, CustomTarget, CustomTargetIndex, BuildTarget), str)
- def replace_suffix(self, state: 'ModuleState', args: T.Tuple[T.Union[FileOrString, BuildTargetTypes], str], kwargs: T.Dict[str, T.Any]) -> str:
- path = self._obj_to_path('fs.replace_suffix', args[0], state)
- return str(path.with_suffix(args[1]))
+ def replace_suffix(self, state: ModuleState, args: T.Tuple[T.Union[FileOrString, BuildTargetTypes], str], kwargs: T.Dict[str, T.Any]) -> str:
+ if args[1] and not args[1].startswith('.'):
+ raise ValueError(f"Invalid suffix {args[1]!r}")
+ path = self._obj_to_pathstr('fs.replace_suffix', args[0], state)
+ return os.path.splitext(path)[0] + args[1]
@noKwargs
@typed_pos_args('fs.parent', (str, File, CustomTarget, CustomTargetIndex, BuildTarget))
- def parent(self, state: 'ModuleState', args: T.Tuple[T.Union[FileOrString, BuildTargetTypes]], kwargs: T.Dict[str, T.Any]) -> str:
- path = self._obj_to_path('fs.parent', args[0], state)
- return str(path.parent)
+ def parent(self, state: ModuleState, args: T.Tuple[T.Union[FileOrString, BuildTargetTypes]], kwargs: T.Dict[str, T.Any]) -> str:
+ path = self._obj_to_pathstr('fs.parent', args[0], state)
+ return os.path.split(path)[0] or '.'
@noKwargs
@typed_pos_args('fs.name', (str, File, CustomTarget, CustomTargetIndex, BuildTarget))
- def name(self, state: 'ModuleState', args: T.Tuple[T.Union[FileOrString, BuildTargetTypes]], kwargs: T.Dict[str, T.Any]) -> str:
- path = self._obj_to_path('fs.name', args[0], state)
- return str(path.name)
+ def name(self, state: ModuleState, args: T.Tuple[T.Union[FileOrString, BuildTargetTypes]], kwargs: T.Dict[str, T.Any]) -> str:
+ path = self._obj_to_pathstr('fs.name', args[0], state)
+ return os.path.basename(path)
@noKwargs
@typed_pos_args('fs.stem', (str, File, CustomTarget, CustomTargetIndex, BuildTarget))
@FeatureNew('fs.stem', '0.54.0')
- def stem(self, state: 'ModuleState', args: T.Tuple[T.Union[FileOrString, BuildTargetTypes]], kwargs: T.Dict[str, T.Any]) -> str:
- path = self._obj_to_path('fs.stem', args[0], state)
- return str(path.stem)
+ def stem(self, state: ModuleState, args: T.Tuple[T.Union[FileOrString, BuildTargetTypes]], kwargs: T.Dict[str, T.Any]) -> str:
+ path = self._obj_to_pathstr('fs.name', args[0], state)
+ return os.path.splitext(os.path.basename(path))[0]
+
+ @noKwargs
+ @typed_pos_args('fs.suffix', (str, File, CustomTarget, CustomTargetIndex, BuildTarget))
+ @FeatureNew('fs.suffix', '1.9.0')
+ def suffix(self, state: ModuleState, args: T.Tuple[T.Union[FileOrString, BuildTargetTypes]], kwargs: T.Dict[str, T.Any]) -> str:
+ path = self._obj_to_pathstr('fs.suffix', args[0], state)
+ return os.path.splitext(path)[1]
@FeatureNew('fs.read', '0.57.0')
@typed_pos_args('fs.read', (str, File))
@typed_kwargs('fs.read', KwargInfo('encoding', str, default='utf-8'))
- def read(self, state: 'ModuleState', args: T.Tuple['FileOrString'], kwargs: 'ReadKwArgs') -> str:
+ def read(self, state: ModuleState, args: T.Tuple[FileOrString], kwargs: ReadKwArgs) -> str:
"""Read a file from the source tree and return its value as a decoded
string.
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index 9f955ae..53919bc 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -22,7 +22,7 @@ from .. import build
from .. import interpreter
from .. import mesonlib
from .. import mlog
-from ..build import CustomTarget, CustomTargetIndex, Executable, GeneratedList, InvalidArguments
+from ..build import CustomTarget, CustomTargetIndex, Executable, GeneratedList, InvalidArguments, OverrideExecutable
from ..dependencies import Dependency, InternalDependency
from ..dependencies.pkgconfig import PkgConfigDependency, PkgConfigInterface
from ..interpreter.type_checking import DEPENDS_KW, DEPEND_FILES_KW, ENV_KW, INSTALL_DIR_KW, INSTALL_KW, NoneType, DEPENDENCY_SOURCES_KW, in_set_validator
@@ -33,11 +33,11 @@ from ..mesonlib import (
MachineChoice, MesonException, OrderedSet, Popen_safe, join_args, quote_arg
)
from ..options import OptionKey
-from ..programs import OverrideProgram
+from ..programs import ExternalProgram, OverrideProgram
from ..scripts.gettext import read_linguas
if T.TYPE_CHECKING:
- from typing_extensions import Literal, TypedDict
+ from typing_extensions import Literal, TypeAlias, TypedDict
from . import ModuleState
from ..build import BuildTarget
@@ -45,7 +45,6 @@ if T.TYPE_CHECKING:
from ..interpreter import Interpreter
from ..interpreterbase import TYPE_var, TYPE_kwargs
from ..mesonlib import FileOrString
- from ..programs import ExternalProgram
class PostInstall(TypedDict):
glib_compile_schemas: bool
@@ -198,7 +197,7 @@ if T.TYPE_CHECKING:
vtail: T.Optional[str]
depends: T.List[T.Union[BuildTarget, CustomTarget, CustomTargetIndex]]
- ToolType = T.Union[Executable, ExternalProgram, OverrideProgram]
+ ToolType: TypeAlias = T.Union[OverrideExecutable, ExternalProgram, OverrideProgram]
# Differs from the CustomTarget version in that it straight defaults to True
@@ -255,9 +254,8 @@ class GnomeModule(ExtensionModule):
def __init__(self, interpreter: 'Interpreter') -> None:
super().__init__(interpreter)
- self.gir_dep: T.Optional[Dependency] = None
- self.giscanner: T.Optional[T.Union[ExternalProgram, Executable, OverrideProgram]] = None
- self.gicompiler: T.Optional[T.Union[ExternalProgram, Executable, OverrideProgram]] = None
+ self.giscanner: T.Optional[ToolType] = None
+ self.gicompiler: T.Optional[ToolType] = None
self.install_glib_compile_schemas = False
self.install_gio_querymodules: T.List[str] = []
self.install_gtk_update_icon_cache = False
@@ -309,7 +307,7 @@ class GnomeModule(ExtensionModule):
once=True, fatal=False)
@staticmethod
- def _find_tool(state: 'ModuleState', tool: str) -> 'ToolType':
+ def _find_tool(state: 'ModuleState', tool: str, for_machine: MachineChoice = MachineChoice.HOST) -> 'ToolType':
tool_map = {
'gio-querymodules': 'gio-2.0',
'glib-compile-schemas': 'gio-2.0',
@@ -322,7 +320,7 @@ class GnomeModule(ExtensionModule):
}
depname = tool_map[tool]
varname = tool.replace('-', '_')
- return state.find_tool(tool, depname, varname)
+ return state.find_tool(tool, depname, varname, for_machine=for_machine)
@typed_kwargs(
'gnome.post_install',
@@ -636,7 +634,7 @@ class GnomeModule(ExtensionModule):
# https://github.com/mesonbuild/meson/issues/1911
# However, g-ir-scanner does not understand -Wl,-rpath
# so we need to use -L instead
- for d in state.backend.determine_rpath_dirs(lib):
+ for d in lib.determine_rpath_dirs():
d = os.path.join(state.environment.get_build_dir(), d)
link_command.append('-L' + d)
if include_rpath:
@@ -775,9 +773,7 @@ class GnomeModule(ExtensionModule):
STATIC_BUILD_REQUIRED_VERSION = ">=1.58.1"
if isinstance(girtarget, (build.StaticLibrary)) and \
- not mesonlib.version_compare(
- self._get_gir_dep(state)[0].get_version(),
- STATIC_BUILD_REQUIRED_VERSION):
+ not self._giscanner_version_compare(state, STATIC_BUILD_REQUIRED_VERSION):
raise MesonException('Static libraries can only be introspected with GObject-Introspection ' + STATIC_BUILD_REQUIRED_VERSION)
return girtarget
@@ -791,18 +787,26 @@ class GnomeModule(ExtensionModule):
if self.devenv is not None:
b.devenv.append(self.devenv)
- def _get_gir_dep(self, state: 'ModuleState') -> T.Tuple[Dependency, T.Union[Executable, 'ExternalProgram', 'OverrideProgram'],
- T.Union[Executable, 'ExternalProgram', 'OverrideProgram']]:
- if not self.gir_dep:
- self.gir_dep = state.dependency('gobject-introspection-1.0')
- self.giscanner = self._find_tool(state, 'g-ir-scanner')
- self.gicompiler = self._find_tool(state, 'g-ir-compiler')
- return self.gir_dep, self.giscanner, self.gicompiler
+ def _get_gi(self, state: 'ModuleState') -> T.Tuple[ToolType, ToolType]:
+ if not self.giscanner:
+ self.giscanner = self._find_tool(state, 'g-ir-scanner', for_machine=MachineChoice.BUILD)
+ self.gicompiler = self._find_tool(state, 'g-ir-compiler', for_machine=MachineChoice.HOST)
+ return self.giscanner, self.gicompiler
+
+ def _giscanner_version_compare(self, state: 'ModuleState', cmp: str) -> bool:
+ # Support for --version was introduced in g-i 1.58, but Ubuntu
+ # Bionic shipped 1.56.1. As all our version checks are greater
+ # than 1.58, we can just return False if get_version fails.
+ try:
+ giscanner, _ = self._get_gi(state)
+ return mesonlib.version_compare(giscanner.get_version(), cmp)
+ except MesonException:
+ return False
@functools.lru_cache(maxsize=None)
def _gir_has_option(self, option: str) -> bool:
exe = self.giscanner
- if isinstance(exe, OverrideProgram):
+ if isinstance(exe, (Executable, OverrideProgram)):
# Handle overridden g-ir-scanner
assert option in {'--extra-library', '--sources-top-dirs'}
return True
@@ -867,7 +871,7 @@ class GnomeModule(ExtensionModule):
# https://github.com/mesonbuild/meson/issues/1911
# However, g-ir-scanner does not understand -Wl,-rpath
# so we need to use -L instead
- for d in state.backend.determine_rpath_dirs(girtarget):
+ for d in girtarget.determine_rpath_dirs():
d = os.path.join(state.environment.get_build_dir(), d)
ret.append('-L' + d)
@@ -990,10 +994,10 @@ class GnomeModule(ExtensionModule):
run_env.set('CFLAGS', [quote_arg(x) for x in env_flags], ' ')
run_env.merge(kwargs['env'])
- gir_dep, _, _ = self._get_gir_dep(state)
+ giscanner, _ = self._get_gi(state)
# response file supported?
- rspable = mesonlib.version_compare(gir_dep.get_version(), '>= 1.85.0')
+ rspable = self._giscanner_version_compare(state, '>= 1.85.0')
return GirTarget(
girfile,
@@ -1145,7 +1149,7 @@ class GnomeModule(ExtensionModule):
if len(girtargets) > 1 and any(isinstance(el, Executable) for el in girtargets):
raise MesonException('generate_gir only accepts a single argument when one of the arguments is an executable')
- gir_dep, giscanner, gicompiler = self._get_gir_dep(state)
+ giscanner, gicompiler = self._get_gi(state)
ns = kwargs['namespace']
nsversion = kwargs['nsversion']
@@ -1156,14 +1160,13 @@ class GnomeModule(ExtensionModule):
builddir = os.path.join(state.environment.get_build_dir(), state.subdir)
depends: T.List[T.Union['FileOrString', 'build.GeneratedTypes', build.BuildTarget, build.StructuredSources]] = []
- depends.extend(gir_dep.sources)
depends.extend(girtargets)
langs_compilers = self._get_girtargets_langs_compilers(girtargets)
cflags, internal_ldflags, external_ldflags = self._get_langs_compilers_flags(state, langs_compilers)
deps = self._get_gir_targets_deps(girtargets)
deps += kwargs['dependencies']
- deps += [gir_dep]
+ deps += [state.dependency('glib-2.0'), state.dependency('gobject-2.0'), state.dependency('gmodule-2.0'), state.dependency('gio-2.0')]
typelib_includes, depends = self._gather_typelib_includes_and_update_depends(state, deps, depends)
# ldflags will be misinterpreted by gir scanner (showing
# spurious dependencies) but building GStreamer fails if they
@@ -1190,6 +1193,32 @@ class GnomeModule(ExtensionModule):
scan_command: T.List[T.Union[str, Executable, 'ExternalProgram', 'OverrideProgram']] = [giscanner]
scan_command += ['--quiet']
+
+ if state.environment.is_cross_build() and state.environment.need_exe_wrapper():
+ if not state.environment.has_exe_wrapper():
+ mlog.error('generate_gir requires exe_wrapper')
+
+ binary_wrapper = state.environment.get_exe_wrapper().get_command()
+ ldd = state.environment.lookup_binary_entry(MachineChoice.HOST, 'ldd')
+ if ldd is None:
+ ldd_wrapper = ['ldd']
+ else:
+ ldd_wrapper = ExternalProgram.from_bin_list(state.environment, MachineChoice.HOST, 'ldd').get_command()
+
+ WRAPPER_ARGS_REQUIRED_VERSION = ">=1.85.0"
+ if not self._giscanner_version_compare(state, WRAPPER_ARGS_REQUIRED_VERSION):
+ msg = ('Use of gnome.generate_gir during cross compilation requires'
+ f'g-ir-scanner {WRAPPER_ARGS_REQUIRED_VERSION}')
+ raise MesonException(msg)
+ else:
+ scan_command += ['--use-binary-wrapper', binary_wrapper[0]]
+ if len(binary_wrapper) > 1:
+ scan_command += ['--binary-wrapper-args-begin', *binary_wrapper[1:], '--binary-wrapper-args-end']
+
+ scan_command += ['--use-ldd-wrapper', ldd_wrapper[0]]
+ if len(ldd_wrapper) > 1:
+ scan_command += ['--ldd-wrapper-args-begin', *ldd_wrapper[1:], '--ldd-wrapper-args-end']
+
scan_command += ['--no-libtool']
scan_command += ['--namespace=' + ns, '--nsversion=' + nsversion]
scan_command += ['--warn-all']
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index e3f7a97..bef14e9 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -156,6 +156,14 @@ class DependenciesHelper:
pass
elif isinstance(obj, dependencies.ExternalDependency) and obj.name == 'threads':
pass
+ elif isinstance(obj, dependencies.InternalDependency) and all(lib.get_id() in self.metadata for lib in obj.libraries):
+ # Ensure BothLibraries are resolved:
+ if self.pub_libs and isinstance(self.pub_libs[0], build.StaticLibrary):
+ obj = obj.get_as_static(recursive=True)
+ else:
+ obj = obj.get_as_shared(recursive=True)
+ for lib in obj.libraries:
+ processed_reqs.append(self.metadata[lib.get_id()].filebase)
else:
raise mesonlib.MesonException('requires argument not a string, '
'library with pkgconfig-generated file '
diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py
index 8d82a33..3c07960 100644
--- a/mesonbuild/modules/python.py
+++ b/mesonbuild/modules/python.py
@@ -16,7 +16,7 @@ from ..dependencies.detect import get_dep_identifier, find_external_dependency
from ..dependencies.python import BasicPythonExternalProgram, python_factory, _PythonDependencyBase
from ..interpreter import extract_required_kwarg, permitted_dependency_kwargs, primitives as P_OBJ
from ..interpreter.interpreterobjects import _ExternalProgramHolder
-from ..interpreter.type_checking import NoneType, PRESERVE_PATH_KW, SHARED_MOD_KWS
+from ..interpreter.type_checking import NoneType, DEPENDENCY_KWS, PRESERVE_PATH_KW, SHARED_MOD_KWS
from ..interpreterbase import (
noPosargs, noKwargs, permittedKwargs, ContainerTypeInfo,
InvalidArguments, typed_pos_args, typed_kwargs, KwargInfo,
@@ -256,6 +256,7 @@ class PythonInstallation(_ExternalProgramHolder['PythonExternalProgram']):
@permittedKwargs(permitted_dependency_kwargs | {'embed'})
@FeatureNewKwargs('python_installation.dependency', '0.53.0', ['embed'])
@noPosargs
+ @typed_kwargs('python_installation.dependency', *DEPENDENCY_KWS, allow_unknown=True)
@InterpreterObject.method('dependency')
def dependency_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> 'Dependency':
disabled, required, feature = extract_required_kwarg(kwargs, self.subproject)
diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py
index c5f18e8..d0e8091 100644
--- a/mesonbuild/modules/rust.py
+++ b/mesonbuild/modules/rust.py
@@ -242,6 +242,10 @@ class RustModule(ExtensionModule):
def doctest(self, state: ModuleState, args: T.Tuple[str, T.Union[SharedLibrary, StaticLibrary]], kwargs: FuncDoctest) -> ModuleReturnValue:
name, base_target = args
+ if not base_target.uses_rust():
+ raise MesonException('doc tests are only supported for Rust targets')
+ if not base_target.uses_rust_abi():
+ raise MesonException("doc tests are not supported for rust_abi: 'c'")
if state.environment.is_cross_build() and state.environment.need_exe_wrapper(base_target.for_machine):
mlog.notice('skipping Rust doctests due to cross compilation', once=True)
return ModuleReturnValue(None, [])