diff options
Diffstat (limited to 'mesonbuild/modules/gnome.py')
-rw-r--r-- | mesonbuild/modules/gnome.py | 162 |
1 files changed, 132 insertions, 30 deletions
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 6764133..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 @@ -137,6 +136,8 @@ if T.TYPE_CHECKING: install_header: bool install_dir: T.Optional[str] docbook: T.Optional[str] + rst: T.Optional[str] + markdown: T.Optional[str] autocleanup: Literal['all', 'none', 'objects', 'default'] class GenMarshal(TypedDict): @@ -196,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 @@ -253,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 @@ -307,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', @@ -320,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', @@ -634,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: @@ -773,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 @@ -789,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 @@ -865,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) @@ -957,8 +963,8 @@ class GnomeModule(ExtensionModule): return gir_filelist_filename - @staticmethod def _make_gir_target( + self, state: 'ModuleState', girfile: str, scan_command: T.Sequence[T.Union['FileOrString', Executable, ExternalProgram, OverrideProgram]], @@ -988,6 +994,11 @@ class GnomeModule(ExtensionModule): run_env.set('CFLAGS', [quote_arg(x) for x in env_flags], ' ') run_env.merge(kwargs['env']) + giscanner, _ = self._get_gi(state) + + # response file supported? + rspable = self._giscanner_version_compare(state, '>= 1.85.0') + return GirTarget( girfile, state.subdir, @@ -1002,6 +1013,7 @@ class GnomeModule(ExtensionModule): install_dir=[install_dir], install_tag=['devel'], env=run_env, + rspable=rspable, ) @staticmethod @@ -1137,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'] @@ -1148,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 @@ -1168,13 +1179,13 @@ class GnomeModule(ExtensionModule): scan_cflags += list(self._get_scanner_cflags(self._get_external_args_for_langs(state, [lc[0] for lc in langs_compilers]))) scan_internal_ldflags = [] scan_external_ldflags = [] - scan_env_ldflags = [] + scan_env_ldflags = state.environment.coredata.get_external_link_args(MachineChoice.HOST, 'c') for cli_flags, env_flags in (self._get_scanner_ldflags(internal_ldflags), self._get_scanner_ldflags(dep_internal_ldflags)): scan_internal_ldflags += cli_flags - scan_env_ldflags = env_flags + scan_env_ldflags += env_flags for cli_flags, env_flags in (self._get_scanner_ldflags(external_ldflags), self._get_scanner_ldflags(dep_external_ldflags)): scan_external_ldflags += cli_flags - scan_env_ldflags = env_flags + scan_env_ldflags += env_flags girtargets_inc_dirs = self._get_gir_targets_inc_dirs(girtargets) inc_dirs = kwargs['include_directories'] @@ -1182,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'] @@ -1619,6 +1656,8 @@ class GnomeModule(ExtensionModule): ), KwargInfo('install_header', bool, default=False, since='0.46.0'), KwargInfo('docbook', (str, NoneType)), + KwargInfo('rst', (str, NoneType), since='1.9.0'), + KwargInfo('markdown', (str, NoneType), since='1.9.0'), KwargInfo( 'autocleanup', str, default='default', since='0.47.0', validator=in_set_validator({'all', 'none', 'objects'})), @@ -1675,6 +1714,26 @@ class GnomeModule(ExtensionModule): cmd += ['--generate-docbook', docbook] + if kwargs['rst'] is not None: + if not mesonlib.version_compare(glib_version, '>= 2.71.1'): + mlog.error(f'Glib version ({glib_version}) is too old to ' + 'support the \'rst\' kwarg, need 2.71.1 or ' + 'newer') + + rst = kwargs['rst'] + + cmd += ['--generate-rst', rst] + + if kwargs['markdown'] is not None: + if not mesonlib.version_compare(glib_version, '>= 2.75.2'): + mlog.error(f'Glib version ({glib_version}) is too old to ' + 'support the \'markdown\' kwarg, need 2.75.2 ' + 'or newer') + + markdown = kwargs['markdown'] + + cmd += ['--generate-md', markdown] + # https://git.gnome.org/browse/glib/commit/?id=ee09bb704fe9ccb24d92dd86696a0e6bb8f0dc1a if mesonlib.version_compare(glib_version, '>= 2.51.3'): cmd += ['--output-directory', '@OUTDIR@', '--generate-c-code', namebase, '@INPUT@'] @@ -1750,6 +1809,48 @@ class GnomeModule(ExtensionModule): ) targets.append(docbook_custom_target) + if kwargs['rst'] is not None: + rst = kwargs['rst'] + # The rst output is always ${rst}-${name_of_xml_file} + output = namebase + '-rst' + outputs = [] + for f in xml_files: + outputs.append('{}-{}'.format(rst, os.path.basename(str(f)))) + + rst_custom_target = CustomTarget( + output, + state.subdir, + state.subproject, + state.environment, + cmd + ['--output-directory', '@OUTDIR@', '--generate-rst', rst, '@INPUT@'], + xml_files, + outputs, + build_by_default=build_by_default, + description='Generating gdbus reStructuredText {}', + ) + targets.append(rst_custom_target) + + if kwargs['markdown'] is not None: + markdown = kwargs['markdown'] + # The markdown output is always ${markdown}-${name_of_xml_file} + output = namebase + '-markdown' + outputs = [] + for f in xml_files: + outputs.append('{}-{}'.format(markdown, os.path.basename(str(f)))) + + markdown_custom_target = CustomTarget( + output, + state.subdir, + state.subproject, + state.environment, + cmd + ['--output-directory', '@OUTDIR@', '--generate-md', markdown, '@INPUT@'], + xml_files, + outputs, + build_by_default=build_by_default, + description='Generating gdbus markdown {}', + ) + targets.append(markdown_custom_target) + return ModuleReturnValue(targets, targets) @typed_pos_args('gnome.mkenums', str) @@ -1991,6 +2092,7 @@ class GnomeModule(ExtensionModule): extra_depends=depends, # https://github.com/mesonbuild/meson/issues/973 absolute_paths=True, + rspable=mesonlib.is_windows() or mesonlib.is_cygwin(), description='Generating GObject enum file {}', ) |