# Copyright 2015-2016 The Meson development team

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

'''This module provides helper functions for Gnome/GLib related
functionality such as gobject-introspection, gresources and gtk-doc'''
from __future__ import annotations

import copy
import itertools
import functools
import os
import subprocess
import textwrap
import typing as T

from . import ExtensionModule
from . import GResourceTarget, GResourceHeaderTarget, GirTarget, TypelibTarget, VapiTarget
from . import ModuleReturnValue
from .. import build
from .. import interpreter
from .. import mesonlib
from .. import mlog
from ..build import CustomTarget, CustomTargetIndex, Executable, GeneratedList, InvalidArguments
from ..dependencies import Dependency, PkgConfigDependency, InternalDependency
from ..interpreter.type_checking import DEPENDS_KW, DEPEND_FILES_KW, INSTALL_KW, NoneType, in_set_validator
from ..interpreterbase import noPosargs, noKwargs, FeatureNew, FeatureDeprecated
from ..interpreterbase import typed_kwargs, KwargInfo, ContainerTypeInfo
from ..interpreterbase.decorators import typed_pos_args
from ..mesonlib import (
    MachineChoice, MesonException, OrderedSet, Popen_safe, join_args,
)
from ..programs import ExternalProgram, OverrideProgram, EmptyExternalProgram
from ..scripts.gettext import read_linguas

if T.TYPE_CHECKING:
    from typing_extensions import Literal, TypedDict

    from . import ModuleState
    from ..build import BuildTarget
    from ..compilers import Compiler
    from ..interpreter import Interpreter
    from ..interpreterbase import TYPE_var, TYPE_kwargs
    from ..mesonlib import FileOrString

    class PostInstall(TypedDict):
        glib_compile_schemas: bool
        gio_querymodules: T.List[str]
        gtk_update_icon_cache: bool
        update_desktop_database: bool

    class CompileSchemas(TypedDict):

        build_by_default: bool
        depend_files: T.List[FileOrString]

    class Yelp(TypedDict):

        languages: T.List[str]
        media: T.List[str]
        sources: T.List[str]
        symlink_media: bool

    class CompileResources(TypedDict):

        build_by_default: bool
        c_name: T.Optional[str]
        dependencies: T.List[T.Union[mesonlib.File, build.CustomTarget, build.CustomTargetIndex]]
        export: bool
        extra_args: T.List[str]
        gresource_bundle: bool
        install: bool
        install_dir: T.Optional[str]
        install_header: bool
        source_dir: T.List[str]

    class GenerateGir(TypedDict):

        build_by_default: bool
        dependencies: T.List[Dependency]
        export_packages: T.List[str]
        extra_args: T.List[str]
        fatal_warnings: bool
        header: T.List[str]
        identifier_prefix: T.List[str]
        include_directories: T.List[T.Union[build.IncludeDirs, str]]
        includes: T.List[T.Union[str, GirTarget]]
        install: bool
        install_dir_gir: T.Optional[str]
        install_dir_typelib: T.Optional[str]
        link_with: T.List[T.Union[build.SharedLibrary, build.StaticLibrary]]
        namespace: str
        nsversion: str
        sources: T.List[T.Union[FileOrString, build.GeneratedTypes]]
        symbol_prefix: T.List[str]

    class GtkDoc(TypedDict):

        src_dir: T.List[T.Union[str, build.IncludeDirs]]
        main_sgml: str
        main_xml: str
        module_version: str
        namespace: str
        mode: Literal['xml', 'smgl', 'auto', 'none']
        html_args: T.List[str]
        scan_args: T.List[str]
        scanobjs_args: T.List[str]
        fixxref_args: T.List[str]
        mkdb_args: T.List[str]
        content_files: T.List[T.Union[build.GeneratedTypes, FileOrString]]
        ignore_headers: T.List[str]
        install_dir: T.List[str]
        check: bool
        install: bool
        gobject_typesfile: T.List[FileOrString]
        html_assets: T.List[FileOrString]
        expand_content_files: T.List[FileOrString]
        c_args: T.List[str]
        include_directories: T.List[T.Union[str, build.IncludeDirs]]
        dependencies: T.List[T.Union[Dependency, build.SharedLibrary, build.StaticLibrary]]

    class GdbusCodegen(TypedDict):

        sources: T.List[FileOrString]
        extra_args: T.List[str]
        interface_prefix: T.Optional[str]
        namespace: T.Optional[str]
        object_manager: bool
        build_by_default: bool
        annotations: T.List[T.List[str]]
        install_header: bool
        install_dir: T.Optional[str]
        docbook: T.Optional[str]
        autocleanup: Literal['all', 'none', 'objects', 'default']

    class GenMarshal(TypedDict):

        build_always: T.Optional[str]
        build_always_stale: T.Optional[bool]
        build_by_default: T.Optional[bool]
        depend_files: T.List[mesonlib.File]
        extra_args: T.List[str]
        install_dir: T.Union[str, bool]
        install_header: bool
        internal: bool
        nostdinc: bool
        prefix: T.Optional[str]
        skip_source: bool
        sources: T.List[FileOrString]
        stdinc: bool
        valist_marshallers: bool

    class GenerateVapi(TypedDict):

        sources: T.List[T.Union[str, GirTarget]]
        install_dir: T.Optional[str]
        install: bool
        vapi_dirs: T.List[str]
        metadata_dirs: T.List[str]
        gir_dirs: T.List[str]
        packages: T.List[T.Union[str, InternalDependency]]

    class _MkEnumsCommon(TypedDict):

        sources: T.List[T.Union[FileOrString, build.GeneratedTypes]]
        install_header: bool
        install_dir: T.Optional[str]
        identifier_prefix: T.Optional[str]
        symbol_prefix: T.Optional[str]

    class MkEnumsSimple(_MkEnumsCommon):

        header_prefix: str
        decorator: str
        function_prefix: str
        body_prefix: str

    class MkEnums(_MkEnumsCommon):

        c_template: T.Optional[FileOrString]
        h_template: T.Optional[FileOrString]
        comments: T.Optional[str]
        eprod: T.Optional[str]
        fhead: T.Optional[str]
        fprod: T.Optional[str]
        ftail: T.Optional[str]
        vhead: T.Optional[str]
        vprod: T.Optional[str]
        vtail: T.Optional[str]
        depends: T.List[T.Union[BuildTarget, CustomTarget, CustomTargetIndex]]


# Differs from the CustomTarget version in that it straight defaults to True
_BUILD_BY_DEFAULT: KwargInfo[bool] = KwargInfo(
    'build_by_default', bool, default=True,
)

_EXTRA_ARGS_KW: KwargInfo[T.List[str]] = KwargInfo(
    'extra_args',
    ContainerTypeInfo(list, str),
    default=[],
    listify=True,
)

_MK_ENUMS_COMMON_KWS: T.List[KwargInfo] = [
    INSTALL_KW.evolve(name='install_header'),
    KwargInfo(
        'sources',
        ContainerTypeInfo(list, (str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList)),
        listify=True,
        required=True,
    ),
    KwargInfo('install_dir', (str, NoneType)),
    KwargInfo('identifier_prefix', (str, NoneType)),
    KwargInfo('symbol_prefix', (str, NoneType)),
]

def annotations_validator(annotations: T.List[T.Union[str, T.List[str]]]) -> T.Optional[str]:
    """Validate gdbus-codegen annotations argument"""

    badlist = 'must be made up of 3 strings for ELEMENT, KEY, and VALUE'

    if not annotations:
        return None
    elif all(isinstance(annot, str) for annot in annotations):
        if len(annotations) == 3:
            return None
        else:
            return badlist
    elif not all(isinstance(annot, list) for annot in annotations):
        for c, annot in enumerate(annotations):
            if not isinstance(annot, list):
                return f'element {c+1} must be a list'
    else:
        for c, annot in enumerate(annotations):
            if len(annot) != 3 or not all(isinstance(i, str) for i in annot):
                return f'element {c+1} {badlist}'
    return None

# gresource compilation is broken due to the way
# the resource compiler and Ninja clash about it
#
# https://github.com/ninja-build/ninja/issues/1184
# https://bugzilla.gnome.org/show_bug.cgi?id=774368
gresource_dep_needed_version = '>= 2.51.1'

native_glib_version = None

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, build.Executable, OverrideProgram]] = None
        self.gicompiler: T.Optional[T.Union[ExternalProgram, build.Executable, OverrideProgram]] = None
        self.install_glib_compile_schemas = False
        self.install_gio_querymodules: T.List[str] = []
        self.install_gtk_update_icon_cache = False
        self.install_update_desktop_database = False
        self.devenv: T.Optional[build.EnvironmentVariables] = None
        self.methods.update({
            'post_install': self.post_install,
            'compile_resources': self.compile_resources,
            'generate_gir': self.generate_gir,
            'compile_schemas': self.compile_schemas,
            'yelp': self.yelp,
            'gtkdoc': self.gtkdoc,
            'gtkdoc_html_dir': self.gtkdoc_html_dir,
            'gdbus_codegen': self.gdbus_codegen,
            'mkenums': self.mkenums,
            'mkenums_simple': self.mkenums_simple,
            'genmarshal': self.genmarshal,
            'generate_vapi': self.generate_vapi,
        })

    @staticmethod
    def _get_native_glib_version(state: 'ModuleState') -> str:
        global native_glib_version
        if native_glib_version is None:
            glib_dep = PkgConfigDependency('glib-2.0', state.environment,
                                           {'native': True, 'required': False})
            if glib_dep.found():
                native_glib_version = glib_dep.get_version()
            else:
                mlog.warning('Could not detect glib version, assuming 2.54. '
                             'You may get build errors if your glib is older.')
                native_glib_version = '2.54'
        return native_glib_version

    @mesonlib.run_once
    def __print_gresources_warning(self, state: 'ModuleState') -> None:
        if not mesonlib.version_compare(self._get_native_glib_version(state),
                                        gresource_dep_needed_version):
            mlog.warning('GLib compiled dependencies do not work reliably with \n'
                         'the current version of GLib. See the following upstream issue:',
                         mlog.bold('https://bugzilla.gnome.org/show_bug.cgi?id=774368'))

    @staticmethod
    def _print_gdbus_warning() -> None:
        mlog.warning('Code generated with gdbus_codegen() requires the root directory be added to\n'
                     '  include_directories of targets with GLib < 2.51.3:',
                     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),
        KwargInfo('gio_querymodules', ContainerTypeInfo(list, str), default=[], listify=True),
        KwargInfo('gtk_update_icon_cache', bool, default=False),
        KwargInfo('update_desktop_database', bool, default=False, since='0.59.0'),
    )
    @noPosargs
    @FeatureNew('gnome.post_install', '0.57.0')
    def post_install(self, state: 'ModuleState', args: T.List['TYPE_var'], kwargs: 'PostInstall') -> ModuleReturnValue:
        rv: T.List['build.ExecutableSerialisation'] = []
        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')
            schemasdir = os.path.join(datadir_abs, 'glib-2.0', 'schemas')
            script = state.backend.get_executable_serialisation([prog, schemasdir])
            script.skip_if_destdir = True
            rv.append(script)
        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')
                moduledir = os.path.join(state.environment.get_prefix(), d)
                script = state.backend.get_executable_serialisation([prog, moduledir])
                script.skip_if_destdir = True
                rv.append(script)
        if kwargs['gtk_update_icon_cache'] and not self.install_gtk_update_icon_cache:
            self.install_gtk_update_icon_cache = True
            prog = state.find_program('gtk4-update-icon-cache', required=False)
            found = isinstance(prog, build.Executable) or prog.found()
            if not found:
                prog = state.find_program('gtk-update-icon-cache')
            icondir = os.path.join(datadir_abs, 'icons', 'hicolor')
            script = state.backend.get_executable_serialisation([prog, '-q', '-t', '-f', icondir])
            script.skip_if_destdir = True
            rv.append(script)
        if kwargs['update_desktop_database'] and not self.install_update_desktop_database:
            self.install_update_desktop_database = True
            prog = state.find_program('update-desktop-database')
            appdir = os.path.join(datadir_abs, 'applications')
            script = state.backend.get_executable_serialisation([prog, '-q', appdir])
            script.skip_if_destdir = True
            rv.append(script)
        return ModuleReturnValue(None, rv)

    @typed_pos_args('gnome.compile_resources', str, (str, mesonlib.File))
    @typed_kwargs(
        'gnome.compile_resources',
        _BUILD_BY_DEFAULT,
        _EXTRA_ARGS_KW,
        INSTALL_KW,
        INSTALL_KW.evolve(name='install_header', since='0.37.0'),
        KwargInfo('c_name', (str, NoneType)),
        KwargInfo('dependencies', ContainerTypeInfo(list, (mesonlib.File, build.CustomTarget, build.CustomTargetIndex)), default=[], listify=True),
        KwargInfo('export', bool, default=False, since='0.37.0'),
        KwargInfo('gresource_bundle', bool, default=False, since='0.37.0'),
        KwargInfo('install_dir', (str, NoneType)),
        KwargInfo('source_dir', ContainerTypeInfo(list, str), default=[], listify=True),
    )
    def compile_resources(self, state: 'ModuleState', args: T.Tuple[str, 'FileOrString'],
                          kwargs: 'CompileResources') -> 'ModuleReturnValue':
        self.__print_gresources_warning(state)
        glib_version = self._get_native_glib_version(state)

        glib_compile_resources = state.find_program('glib-compile-resources')
        cmd: T.List[T.Union[ExternalProgram, str]] = [glib_compile_resources, '@INPUT@']

        source_dirs = kwargs['source_dir']
        dependencies = kwargs['dependencies']

        target_name, input_file = args

        # Validate dependencies
        subdirs: T.List[str] = []
        depends: T.List[T.Union[build.CustomTarget, build.CustomTargetIndex]] = []
        for dep in dependencies:
            if isinstance(dep, mesonlib.File):
                subdirs.append(dep.subdir)
            else:
                depends.append(dep)
                subdirs.append(dep.get_subdir())
                if not mesonlib.version_compare(glib_version, gresource_dep_needed_version):
                    m = 'The "dependencies" argument of gnome.compile_resources() can not\n' \
                        'be used with the current version of glib-compile-resources due to\n' \
                        '<https://bugzilla.gnome.org/show_bug.cgi?id=774368>'
                    raise MesonException(m)

        if not mesonlib.version_compare(glib_version, gresource_dep_needed_version):
            # Resource xml files generated at build-time cannot be used with
            # gnome.compile_resources() because we need to scan the xml for
            # dependencies. Use configure_file() instead to generate it at
            # configure-time
            if isinstance(input_file, mesonlib.File):
                # glib-compile-resources will be run inside the source dir,
                # so we need either 'src_to_build' or the absolute path.
                # Absolute path is the easiest choice.
                if input_file.is_built:
                    ifile = os.path.join(state.environment.get_build_dir(), input_file.subdir, input_file.fname)
                else:
                    ifile = os.path.join(input_file.subdir, input_file.fname)
            else:
                ifile = os.path.join(state.subdir, input_file)

            depend_files, depends, subdirs = self._get_gresource_dependencies(
                state, ifile, source_dirs, dependencies)

        # Make source dirs relative to build dir now
        source_dirs = [os.path.join(state.build_to_src, state.subdir, d) for d in source_dirs]
        # Ensure build directories of generated deps are included
        source_dirs += subdirs
        # Always include current directory, but after paths set by user
        source_dirs.append(os.path.join(state.build_to_src, state.subdir))

        for source_dir in OrderedSet(source_dirs):
            cmd += ['--sourcedir', source_dir]

        if kwargs['c_name']:
            cmd += ['--c-name', kwargs['c_name']]
        if not kwargs['export']:
            cmd += ['--internal']

        cmd += ['--generate', '--target', '@OUTPUT@']
        cmd += kwargs['extra_args']

        gresource = kwargs['gresource_bundle']
        if gresource:
            output = f'{target_name}.gresource'
            name = f'{target_name}_gresource'
        else:
            if 'c' in state.environment.coredata.compilers.host:
                output = f'{target_name}.c'
                name = f'{target_name}_c'
            elif 'cpp' in state.environment.coredata.compilers.host:
                output = f'{target_name}.cpp'
                name = f'{target_name}_cpp'
            else:
                raise MesonException('Compiling GResources into code is only supported in C and C++ projects')

        if kwargs['install'] and not gresource:
            raise MesonException('The install kwarg only applies to gresource bundles, see install_header')

        install_header = kwargs['install_header']
        if install_header and gresource:
            raise MesonException('The install_header kwarg does not apply to gresource bundles')
        if install_header and not kwargs['export']:
            raise MesonException('GResource header is installed yet export is not enabled')

        depfile: T.Optional[str] = None
        target_cmd: T.List[T.Union[ExternalProgram, str]]
        if not mesonlib.version_compare(glib_version, gresource_dep_needed_version):
            # This will eventually go out of sync if dependencies are added
            target_cmd = cmd
        else:
            depfile = f'{output}.d'
            depend_files = []
            target_cmd = copy.copy(cmd) + ['--dependency-file', '@DEPFILE@']
        target_c = GResourceTarget(
            name,
            state.subdir,
            state.subproject,
            state.environment,
            target_cmd,
            [input_file],
            [output],
            build_by_default=kwargs['build_by_default'],
            depfile=depfile,
            depend_files=depend_files,
            extra_depends=depends,
            install=kwargs['install'],
            install_dir=[kwargs['install_dir']] if kwargs['install_dir'] else [],
        )

        if gresource: # Only one target for .gresource files
            return ModuleReturnValue(target_c, [target_c])

        install_dir = kwargs['install_dir'] or state.environment.coredata.get_option(mesonlib.OptionKey('includedir'))
        assert isinstance(install_dir, str), 'for mypy'
        target_h = GResourceHeaderTarget(
            f'{target_name}_h',
            state.subdir,
            state.subproject,
            state.environment,
            cmd,
            [input_file],
            [f'{target_name}.h'],
            build_by_default=kwargs['build_by_default'],
            extra_depends=depends,
            install=install_header,
            install_dir=[install_dir],
        )
        rv = [target_c, target_h]
        return ModuleReturnValue(rv, rv)

    @staticmethod
    def _get_gresource_dependencies(
            state: 'ModuleState', input_file: str, source_dirs: T.List[str],
            dependencies: T.Sequence[T.Union[mesonlib.File, build.CustomTarget, build.CustomTargetIndex]]
            ) -> T.Tuple[T.List[mesonlib.FileOrString], T.List[T.Union[build.CustomTarget, build.CustomTargetIndex]], T.List[str]]:

        cmd = ['glib-compile-resources',
               input_file,
               '--generate-dependencies']

        # Prefer generated files over source files
        cmd += ['--sourcedir', state.subdir] # Current build dir
        for source_dir in source_dirs:
            cmd += ['--sourcedir', os.path.join(state.subdir, source_dir)]

        try:
            pc, stdout, stderr = Popen_safe(cmd, cwd=state.environment.get_source_dir())
        except (FileNotFoundError, PermissionError):
            raise MesonException('Could not execute glib-compile-resources.')
        if pc.returncode != 0:
            m = f'glib-compile-resources failed to get dependencies for {cmd[1]}:\n{stderr}'
            mlog.warning(m)
            raise subprocess.CalledProcessError(pc.returncode, cmd)

        raw_dep_files: T.List[str] = stdout.split('\n')[:-1]

        depends: T.List[T.Union[build.CustomTarget, build.CustomTargetIndex]] = []
        subdirs: T.List[str] = []
        dep_files: T.List[mesonlib.FileOrString] = []
        for resfile in raw_dep_files.copy():
            resbasename = os.path.basename(resfile)
            for dep in dependencies:
                if isinstance(dep, mesonlib.File):
                    if dep.fname != resbasename:
                        continue
                    raw_dep_files.remove(resfile)
                    dep_files.append(dep)
                    subdirs.append(dep.subdir)
                    break
                elif isinstance(dep, (build.CustomTarget, build.CustomTargetIndex)):
                    fname = None
                    outputs = {(o, os.path.basename(o)) for o in dep.get_outputs()}
                    for o, baseo in outputs:
                        if baseo == resbasename:
                            fname = o
                            break
                    if fname is not None:
                        raw_dep_files.remove(resfile)
                        depends.append(dep)
                        subdirs.append(dep.get_subdir())
                        break
            else:
                # In generate-dependencies mode, glib-compile-resources doesn't raise
                # an error for missing resources but instead prints whatever filename
                # was listed in the input file.  That's good because it means we can
                # handle resource files that get generated as part of the build, as
                # follows.
                #
                # If there are multiple generated resource files with the same basename
                # then this code will get confused.
                try:
                    f = mesonlib.File.from_source_file(state.environment.get_source_dir(),
                                                       ".", resfile)
                except MesonException:
                    raise MesonException(
                        f'Resource "{resfile}" listed in "{input_file}" was not found. '
                        'If this is a generated file, pass the target that generates '
                        'it to gnome.compile_resources() using the "dependencies" '
                        'keyword argument.')
                raw_dep_files.remove(resfile)
                dep_files.append(f)
        dep_files.extend(raw_dep_files)
        return dep_files, depends, subdirs

    def _get_link_args(self, state: 'ModuleState',
                       lib: T.Union[build.SharedLibrary, build.StaticLibrary],
                       depends: T.Sequence[T.Union[build.BuildTarget, 'build.GeneratedTypes', 'FileOrString', build.StructuredSources]],
                       include_rpath: bool = False,
                       use_gir_args: bool = False
                       ) -> T.Tuple[T.List[str], T.List[T.Union[build.BuildTarget, 'build.GeneratedTypes', 'FileOrString', build.StructuredSources]]]:
        link_command: T.List[str] = []
        new_depends = list(depends)
        # Construct link args
        if isinstance(lib, build.SharedLibrary):
            libdir = os.path.join(state.environment.get_build_dir(), state.backend.get_target_dir(lib))
            link_command.append('-L' + libdir)
            if include_rpath:
                link_command.append('-Wl,-rpath,' + libdir)
            new_depends.append(lib)
            # Needed for the following binutils bug:
            # 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):
                d = os.path.join(state.environment.get_build_dir(), d)
                link_command.append('-L' + d)
                if include_rpath:
                    link_command.append('-Wl,-rpath,' + d)
        if use_gir_args and self._gir_has_option('--extra-library'):
            link_command.append('--extra-library=' + lib.name)
        else:
            link_command.append('-l' + lib.name)
        return link_command, new_depends

    def _get_dependencies_flags_raw(
            self, deps: T.Sequence[T.Union['Dependency', build.BuildTarget, build.CustomTarget, build.CustomTargetIndex]],
            state: 'ModuleState',
            depends: T.Sequence[T.Union[build.BuildTarget, 'build.GeneratedTypes', 'FileOrString', build.StructuredSources]],
            include_rpath: bool,
            use_gir_args: bool,
            ) -> T.Tuple[OrderedSet[str], OrderedSet[T.Union[str, T.Tuple[str, str]]], OrderedSet[T.Union[str, T.Tuple[str, str]]], OrderedSet[str],
                         T.List[T.Union[build.BuildTarget, 'build.GeneratedTypes', 'FileOrString', build.StructuredSources]]]:
        cflags: OrderedSet[str] = OrderedSet()
        # External linker flags that can't be de-duped reliably because they
        # require two args in order, such as -framework AVFoundation will be stored as a tuple.
        internal_ldflags: OrderedSet[T.Union[str, T.Tuple[str, str]]] = OrderedSet()
        external_ldflags: OrderedSet[T.Union[str, T.Tuple[str, str]]] = OrderedSet()
        gi_includes: OrderedSet[str] = OrderedSet()
        deps = mesonlib.listify(deps)
        depends = list(depends)

        for dep in deps:
            if isinstance(dep, Dependency):
                girdir = dep.get_variable(pkgconfig='girdir', internal='girdir', default_value='')
                if girdir:
                    assert isinstance(girdir, str), 'for mypy'
                    gi_includes.update([girdir])
            if isinstance(dep, InternalDependency):
                cflags.update(dep.get_compile_args())
                cflags.update(state.get_include_args(dep.include_directories))
                for lib in dep.libraries:
                    if isinstance(lib, build.SharedLibrary):
                        _ld, depends = self._get_link_args(state, lib, depends, include_rpath)
                        internal_ldflags.update(_ld)
                        libdepflags = self._get_dependencies_flags_raw(lib.get_external_deps(), state, depends, include_rpath,
                                                                   use_gir_args)
                        cflags.update(libdepflags[0])
                        internal_ldflags.update(libdepflags[1])
                        external_ldflags.update(libdepflags[2])
                        gi_includes.update(libdepflags[3])
                        depends.extend(libdepflags[4])
                extdepflags = self._get_dependencies_flags_raw(dep.ext_deps, state, depends, include_rpath,
                                                               use_gir_args)
                cflags.update(extdepflags[0])
                internal_ldflags.update(extdepflags[1])
                external_ldflags.update(extdepflags[2])
                gi_includes.update(extdepflags[3])
                depends.extend(extdepflags[4])
                for source in dep.sources:
                    if isinstance(source, GirTarget):
                        gi_includes.update([os.path.join(state.environment.get_build_dir(),
                                            source.get_subdir())])
            # This should be any dependency other than an internal one.
            elif isinstance(dep, Dependency):
                cflags.update(dep.get_compile_args())
                ldflags = iter(dep.get_link_args(raw=True))
                for flag in ldflags:
                    if (os.path.isabs(flag) and
                            # For PkgConfigDependency only:
                            getattr(dep, 'is_libtool', False)):
                        lib_dir = os.path.dirname(flag)
                        external_ldflags.update([f'-L{lib_dir}'])
                        if include_rpath:
                            external_ldflags.update([f'-Wl,-rpath {lib_dir}'])
                        libname = os.path.basename(flag)
                        if libname.startswith("lib"):
                            libname = libname[3:]
                        libname = libname.split(".so")[0]
                        flag = f"-l{libname}"
                    # FIXME: Hack to avoid passing some compiler options in
                    if flag.startswith("-W"):
                        continue
                    # If it's a framework arg, slurp the framework name too
                    # to preserve the order of arguments
                    if flag == '-framework':
                        external_ldflags.update([(flag, next(ldflags))])
                    else:
                        external_ldflags.update([flag])
            elif isinstance(dep, (build.StaticLibrary, build.SharedLibrary)):
                cflags.update(state.get_include_args(dep.get_include_dirs()))
                depends.append(dep)
            else:
                mlog.log(f'dependency {dep!r} not handled to build gir files')
                continue

        if use_gir_args and self._gir_has_option('--extra-library'):
            def fix_ldflags(ldflags: T.Iterable[T.Union[str, T.Tuple[str, str]]]) -> OrderedSet[T.Union[str, T.Tuple[str, str]]]:
                fixed_ldflags: OrderedSet[T.Union[str, T.Tuple[str, str]]] = OrderedSet()
                for ldflag in ldflags:
                    if isinstance(ldflag, str) and ldflag.startswith("-l"):
                        ldflag = ldflag.replace('-l', '--extra-library=', 1)
                    fixed_ldflags.add(ldflag)
                return fixed_ldflags
            internal_ldflags = fix_ldflags(internal_ldflags)
            external_ldflags = fix_ldflags(external_ldflags)
        return cflags, internal_ldflags, external_ldflags, gi_includes, depends

    def _get_dependencies_flags(
            self, deps: T.Sequence[T.Union['Dependency', build.BuildTarget, build.CustomTarget, build.CustomTargetIndex]],
            state: 'ModuleState',
            depends: T.Sequence[T.Union[build.BuildTarget, 'build.GeneratedTypes', 'FileOrString', build.StructuredSources]],
            include_rpath: bool = False,
            use_gir_args: bool = False,
            ) -> T.Tuple[OrderedSet[str], T.List[str], T.List[str], OrderedSet[str],
                         T.List[T.Union[build.BuildTarget, 'build.GeneratedTypes', 'FileOrString', build.StructuredSources]]]:

        cflags, internal_ldflags_raw, external_ldflags_raw, gi_includes, depends = self._get_dependencies_flags_raw(deps, state, depends, include_rpath, use_gir_args)
        internal_ldflags: T.List[str] = []
        external_ldflags: T.List[str] = []

        # Extract non-deduplicable argument groups out of the tuples.
        for ldflag in internal_ldflags_raw:
            if isinstance(ldflag, str):
                internal_ldflags.append(ldflag)
            else:
                internal_ldflags.extend(ldflag)
        for ldflag in external_ldflags_raw:
            if isinstance(ldflag, str):
                external_ldflags.append(ldflag)
            else:
                external_ldflags.extend(ldflag)

        return cflags, internal_ldflags, external_ldflags, gi_includes, depends
    def _unwrap_gir_target(self, girtarget: T.Union[build.Executable, build.StaticLibrary, build.SharedLibrary], state: 'ModuleState'
                           ) -> T.Union[build.Executable, build.StaticLibrary, build.SharedLibrary]:
        if not isinstance(girtarget, (build.Executable, build.SharedLibrary,
                                      build.StaticLibrary)):
            raise MesonException(f'Gir target must be an executable or library but is "{girtarget}" of type {type(girtarget).__name__}')

        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):
            raise MesonException('Static libraries can only be introspected with GObject-Introspection ' + STATIC_BUILD_REQUIRED_VERSION)

        return girtarget

    def _devenv_prepend(self, varname: str, value: str) -> None:
        if self.devenv is None:
            self.devenv = build.EnvironmentVariables()
        self.devenv.prepend(varname, [value])

    def get_devenv(self) -> T.Optional[build.EnvironmentVariables]:
        return self.devenv

    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')
        return self.gir_dep, self.giscanner, self.gicompiler

    @functools.lru_cache(maxsize=None)
    def _gir_has_option(self, option: str) -> bool:
        exe = self.giscanner
        if isinstance(exe, OverrideProgram):
            # Handle overridden g-ir-scanner
            assert option in {'--extra-library', '--sources-top-dirs'}
            return True
        p, o, _ = Popen_safe(exe.get_command() + ['--help'], stderr=subprocess.STDOUT)
        return p.returncode == 0 and option in o

    # May mutate depends and gir_inc_dirs
    @staticmethod
    def _scan_include(state: 'ModuleState', includes: T.List[T.Union[str, GirTarget]]
                      ) -> T.Tuple[T.List[str], T.List[str], T.List[GirTarget]]:
        ret: T.List[str] = []
        gir_inc_dirs: T.List[str] = []
        depends: T.List[GirTarget] = []

        for inc in includes:
            if isinstance(inc, str):
                ret += [f'--include={inc}']
            elif isinstance(inc, GirTarget):
                gir_inc_dirs .append(os.path.join(state.environment.get_build_dir(), inc.get_subdir()))
                ret.append(f"--include-uninstalled={os.path.join(inc.get_subdir(), inc.get_basename())}")
                depends.append(inc)

        return ret, gir_inc_dirs, depends

    @staticmethod
    def _scan_langs(state: 'ModuleState', langs: T.Iterable[str]) -> T.List[str]:
        ret: T.List[str] = []

        for lang in langs:
            link_args = state.environment.coredata.get_external_link_args(MachineChoice.HOST, lang)
            for link_arg in link_args:
                if link_arg.startswith('-L'):
                    ret.append(link_arg)

        return ret

    @staticmethod
    def _scan_gir_targets(state: 'ModuleState', girtargets: T.Sequence[build.BuildTarget]) -> T.List[T.Union[str, build.Executable]]:
        ret: T.List[T.Union[str, build.Executable]] = []

        for girtarget in girtargets:
            if isinstance(girtarget, build.Executable):
                ret += ['--program', girtarget]
            else:
                # Because of https://gitlab.gnome.org/GNOME/gobject-introspection/merge_requests/72
                # we can't use the full path until this is merged.
                libpath = os.path.join(girtarget.get_subdir(), girtarget.get_filename())
                # Must use absolute paths here because g-ir-scanner will not
                # add them to the runtime path list if they're relative. This
                # means we cannot use @BUILD_ROOT@
                build_root = state.environment.get_build_dir()
                if isinstance(girtarget, build.SharedLibrary):
                    # need to put our output directory first as we need to use the
                    # generated libraries instead of any possibly installed system/prefix
                    # ones.
                    ret += ["-L{}/{}".format(build_root, os.path.dirname(libpath))]
                    libname = girtarget.get_basename()
                else:
                    libname = os.path.join(f"{build_root}/{libpath}")
                ret += ['--library', libname]
                # Needed for the following binutils bug:
                # 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):
                    d = os.path.join(state.environment.get_build_dir(), d)
                    ret.append('-L' + d)

        return ret

    @staticmethod
    def _get_girtargets_langs_compilers(girtargets: T.Sequence[build.BuildTarget]) -> T.List[T.Tuple[str, 'Compiler']]:
        ret: T.List[T.Tuple[str, 'Compiler']] = []
        for girtarget in girtargets:
            for lang, compiler in girtarget.compilers.items():
                # XXX: Can you use g-i with any other language?
                if lang in ('c', 'cpp', 'objc', 'objcpp', 'd'):
                    ret.append((lang, compiler))
                    break

        return ret

    @staticmethod
    def _get_gir_targets_deps(girtargets: T.Sequence[build.BuildTarget]
                              ) -> T.List[T.Union[build.BuildTarget, build.CustomTarget, build.CustomTargetIndex, Dependency]]:
        ret: T.List[T.Union[build.BuildTarget, build.CustomTarget, build.CustomTargetIndex, Dependency]] = []
        for girtarget in girtargets:
            ret += girtarget.get_all_link_deps()
            ret += girtarget.get_external_deps()
        return ret

    @staticmethod
    def _get_gir_targets_inc_dirs(girtargets: T.Sequence[build.BuildTarget]) -> T.List[build.IncludeDirs]:
        ret: T.List[build.IncludeDirs] = []
        for girtarget in girtargets:
            ret += girtarget.get_include_dirs()
        return ret

    @staticmethod
    def _get_langs_compilers_flags(state: 'ModuleState', langs_compilers: T.List[T.Tuple[str, 'Compiler']]
                                   ) -> T.Tuple[T.List[str], T.List[str], T.List[str]]:
        cflags: T.List[str] = []
        internal_ldflags: T.List[str] = []
        external_ldflags: T.List[str] = []

        for lang, compiler in langs_compilers:
            if state.global_args.get(lang):
                cflags += state.global_args[lang]
            if state.project_args.get(lang):
                cflags += state.project_args[lang]
            if mesonlib.OptionKey('b_sanitize') in compiler.base_options:
                sanitize = state.environment.coredata.options[mesonlib.OptionKey('b_sanitize')].value
                cflags += compiler.sanitizer_compile_args(sanitize)
                sanitize = sanitize.split(',')
                # These must be first in ldflags
                if 'address' in sanitize:
                    internal_ldflags += ['-lasan']
                if 'thread' in sanitize:
                    internal_ldflags += ['-ltsan']
                if 'undefined' in sanitize:
                    internal_ldflags += ['-lubsan']
                # FIXME: Linking directly to lib*san is not recommended but g-ir-scanner
                # does not understand -f LDFLAGS. https://bugzilla.gnome.org/show_bug.cgi?id=783892
                # ldflags += compiler.sanitizer_link_args(sanitize)

        return cflags, internal_ldflags, external_ldflags

    @staticmethod
    def _make_gir_filelist(state: 'ModuleState', srcdir: str, ns: str,
                           nsversion: str, girtargets: T.Sequence[build.BuildTarget],
                           libsources: T.Sequence[T.Union[
                               str, mesonlib.File, build.GeneratedList,
                               build.CustomTarget, build.CustomTargetIndex]]
                           ) -> str:
        gir_filelist_dir = state.backend.get_target_private_dir_abs(girtargets[0])
        if not os.path.isdir(gir_filelist_dir):
            os.mkdir(gir_filelist_dir)
        gir_filelist_filename = os.path.join(gir_filelist_dir, f'{ns}_{nsversion}_gir_filelist')

        with open(gir_filelist_filename, 'w', encoding='utf-8') as gir_filelist:
            for s in libsources:
                if isinstance(s, (build.CustomTarget, build.CustomTargetIndex)):
                    for custom_output in s.get_outputs():
                        gir_filelist.write(os.path.join(state.environment.get_build_dir(),
                                                        state.backend.get_target_dir(s),
                                                        custom_output) + '\n')
                elif isinstance(s, mesonlib.File):
                    gir_filelist.write(s.rel_to_builddir(state.build_to_src) + '\n')
                elif isinstance(s, build.GeneratedList):
                    for gen_src in s.get_outputs():
                        gir_filelist.write(os.path.join(srcdir, gen_src) + '\n')
                else:
                    gir_filelist.write(os.path.join(srcdir, s) + '\n')

        return gir_filelist_filename

    @staticmethod
    def _make_gir_target(
            state: 'ModuleState',
            girfile: str,
            scan_command: T.Sequence[T.Union['FileOrString', Executable, ExternalProgram, OverrideProgram]],
            generated_files: T.Sequence[T.Union[str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]],
            depends: T.Sequence[T.Union['FileOrString', build.BuildTarget, 'build.GeneratedTypes', build.StructuredSources]],
            kwargs: T.Dict[str, T.Any]) -> GirTarget:
        install = kwargs['install_gir']
        if install is None:
            install = kwargs['install']

        install_dir = kwargs['install_dir_gir']
        if install_dir is None:
            install_dir = os.path.join(state.environment.get_datadir(), 'gir-1.0')
        elif install_dir is False:
            install = False

        return GirTarget(
            girfile,
            state.subdir,
            state.subproject,
            state.environment,
            scan_command,
            generated_files,
            [girfile],
            build_by_default=kwargs['build_by_default'],
            extra_depends=depends,
            install=install,
            install_dir=[install_dir],
            install_tag=['devel'],
        )

    @staticmethod
    def _make_typelib_target(state: 'ModuleState', typelib_output: str,
                             typelib_cmd: T.Sequence[T.Union[str, build.Executable, ExternalProgram, build.CustomTarget]],
                             generated_files: T.Sequence[T.Union[str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]],
                             kwargs: T.Dict[str, T.Any]) -> TypelibTarget:
        install = kwargs['install_typelib']
        if install is None:
            install = kwargs['install']

        install_dir = kwargs['install_dir_typelib']
        if install_dir is None:
            install_dir = os.path.join(state.environment.get_libdir(), 'girepository-1.0')
        elif install_dir is False:
            install = False

        return TypelibTarget(
            typelib_output,
            state.subdir,
            state.subproject,
            state.environment,
            typelib_cmd,
            generated_files,
            [typelib_output],
            install=install,
            install_dir=[install_dir],
            install_tag=['typelib'],
            build_by_default=kwargs['build_by_default'],
        )

    @staticmethod
    def _gather_typelib_includes_and_update_depends(
            state: 'ModuleState',
            deps: T.Sequence[T.Union[Dependency, build.BuildTarget, build.CustomTarget, build.CustomTargetIndex]],
            depends: T.Sequence[T.Union[build.BuildTarget, 'build.GeneratedTypes', 'FileOrString', build.StructuredSources]]
            ) -> T.Tuple[T.List[str], T.List[T.Union[build.BuildTarget, 'build.GeneratedTypes', 'FileOrString', build.StructuredSources]]]:
        # Need to recursively add deps on GirTarget sources from our
        # dependencies and also find the include directories needed for the
        # typelib generation custom target below.
        typelib_includes: T.List[str] = []
        new_depends = list(depends)
        for dep in deps:
            # Add a dependency on each GirTarget listed in dependencies and add
            # the directory where it will be generated to the typelib includes
            if isinstance(dep, InternalDependency):
                for source in dep.sources:
                    if isinstance(source, GirTarget) and source not in depends:
                        new_depends.append(source)
                        subdir = os.path.join(state.environment.get_build_dir(),
                                              source.get_subdir())
                        if subdir not in typelib_includes:
                            typelib_includes.append(subdir)
            # Do the same, but for dependencies of dependencies. These are
            # stored in the list of generated sources for each link dep (from
            # girtarget.get_all_link_deps() above).
            # FIXME: Store this in the original form from declare_dependency()
            # so it can be used here directly.
            elif isinstance(dep, build.SharedLibrary):
                for g_source in dep.generated:
                    if isinstance(g_source, GirTarget):
                        subdir = os.path.join(state.environment.get_build_dir(),
                                              g_source.get_subdir())
                        if subdir not in typelib_includes:
                            typelib_includes.append(subdir)
            if isinstance(dep, Dependency):
                girdir = dep.get_variable(pkgconfig='girdir', internal='girdir', default_value='')
                assert isinstance(girdir, str), 'for mypy'
                if girdir and girdir not in typelib_includes:
                    typelib_includes.append(girdir)
        return typelib_includes, new_depends

    @staticmethod
    def _get_external_args_for_langs(state: 'ModuleState', langs: T.Sequence[str]) -> T.List[str]:
        ret: T.List[str] = []
        for lang in langs:
            ret += mesonlib.listify(state.environment.coredata.get_external_args(MachineChoice.HOST, lang))
        return ret

    @staticmethod
    def _get_scanner_cflags(cflags: T.Iterable[str]) -> T.Iterable[str]:
        'g-ir-scanner only accepts -I/-D/-U; must ignore all other flags'
        for f in cflags:
            # _FORTIFY_SOURCE depends on / works together with -O, on the other hand this
            # just invokes the preprocessor anyway
            if f.startswith(('-D', '-U', '-I')) and not f.startswith('-D_FORTIFY_SOURCE'):
                yield f

    @staticmethod
    def _get_scanner_ldflags(ldflags: T.Iterable[str]) -> T.Iterable[str]:
        'g-ir-scanner only accepts -L/-l; must ignore -F and other linker flags'
        for f in ldflags:
            if f.startswith(('-L', '-l', '--extra-library')):
                yield f

    @typed_pos_args('gnome.generate_gir', varargs=(build.Executable, build.SharedLibrary, build.StaticLibrary), min_varargs=1)
    @typed_kwargs(
        'gnome.generate_gir',
        INSTALL_KW,
        _BUILD_BY_DEFAULT.evolve(since='0.40.0'),
        _EXTRA_ARGS_KW,
        KwargInfo('dependencies', ContainerTypeInfo(list, Dependency), default=[], listify=True),
        KwargInfo('export_packages', ContainerTypeInfo(list, str), default=[], listify=True),
        KwargInfo('fatal_warnings', bool, default=False, since='0.55.0'),
        KwargInfo('header', ContainerTypeInfo(list, str), default=[], listify=True),
        KwargInfo('identifier_prefix', ContainerTypeInfo(list, str), default=[], listify=True),
        KwargInfo('include_directories', ContainerTypeInfo(list, (str, build.IncludeDirs)), default=[], listify=True),
        KwargInfo('includes', ContainerTypeInfo(list, (str, GirTarget)), default=[], listify=True),
        KwargInfo('install_gir', (bool, NoneType), since='0.61.0'),
        KwargInfo('install_dir_gir', (str, bool, NoneType),
                  deprecated_values={False: ('0.61.0', 'Use install_gir to disable installation')},
                  validator=lambda x: 'as boolean can only be false' if x is True else None),
        KwargInfo('install_typelib', (bool, NoneType), since='0.61.0'),
        KwargInfo('install_dir_typelib', (str, bool, NoneType),
                  deprecated_values={False: ('0.61.0', 'Use install_typelib to disable installation')},
                  validator=lambda x: 'as boolean can only be false' if x is True else None),
        KwargInfo('link_with', ContainerTypeInfo(list, (build.SharedLibrary, build.StaticLibrary)), default=[], listify=True),
        KwargInfo('namespace', str, required=True),
        KwargInfo('nsversion', str, required=True),
        KwargInfo('sources', ContainerTypeInfo(list, (str, mesonlib.File, build.GeneratedList, build.CustomTarget, build.CustomTargetIndex)), default=[], listify=True),
        KwargInfo('symbol_prefix', ContainerTypeInfo(list, str), default=[], listify=True),
    )
    def generate_gir(self, state: 'ModuleState', args: T.Tuple[T.List[T.Union[build.Executable, build.SharedLibrary, build.StaticLibrary]]],
                     kwargs: 'GenerateGir') -> ModuleReturnValue:
        girtargets = [self._unwrap_gir_target(arg, state) for arg in args[0]]
        if len(girtargets) > 1 and any([isinstance(el, build.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)

        ns = kwargs['namespace']
        nsversion = kwargs['nsversion']
        libsources = kwargs['sources']

        girfile = f'{ns}-{nsversion}.gir'
        srcdir = os.path.join(state.environment.get_source_dir(), state.subdir)
        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]
        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
        # are not used here.
        dep_cflags, dep_internal_ldflags, dep_external_ldflags, gi_includes, depends = \
            self._get_dependencies_flags(deps, state, depends, use_gir_args=True)
        scan_cflags = []
        scan_cflags += list(self._get_scanner_cflags(cflags))
        scan_cflags += list(self._get_scanner_cflags(dep_cflags))
        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_internal_ldflags += list(self._get_scanner_ldflags(internal_ldflags))
        scan_internal_ldflags += list(self._get_scanner_ldflags(dep_internal_ldflags))
        scan_external_ldflags = []
        scan_external_ldflags += list(self._get_scanner_ldflags(external_ldflags))
        scan_external_ldflags += list(self._get_scanner_ldflags(dep_external_ldflags))
        girtargets_inc_dirs = self._get_gir_targets_inc_dirs(girtargets)
        inc_dirs = kwargs['include_directories']

        gir_inc_dirs: T.List[str] = []

        scan_command: T.List[T.Union[str, build.Executable, 'ExternalProgram', 'OverrideProgram']] = [giscanner]
        scan_command += ['--no-libtool']
        scan_command += ['--namespace=' + ns, '--nsversion=' + nsversion]
        scan_command += ['--warn-all']
        scan_command += ['--output', '@OUTPUT@']
        scan_command += [f'--c-include={h}' for h in kwargs['header']]
        scan_command += kwargs['extra_args']
        scan_command += ['-I' + srcdir, '-I' + builddir]
        scan_command += state.get_include_args(girtargets_inc_dirs)
        scan_command += ['--filelist=' + self._make_gir_filelist(state, srcdir, ns, nsversion, girtargets, libsources)]
        for l in kwargs['link_with']:
            _cflags, depends = self._get_link_args(state, l, depends, use_gir_args=True)
            scan_command.extend(_cflags)
        _cmd, _ginc, _deps = self._scan_include(state, kwargs['includes'])
        scan_command.extend(_cmd)
        gir_inc_dirs.extend(_ginc)
        depends.extend(_deps)

        scan_command += [f'--symbol-prefix={p}' for p in kwargs['symbol_prefix']]
        scan_command += [f'--identifier-prefix={p}' for p in kwargs['identifier_prefix']]
        scan_command += [f'--pkg-export={p}' for p in kwargs['export_packages']]
        scan_command += ['--cflags-begin']
        scan_command += scan_cflags
        scan_command += ['--cflags-end']
        scan_command += state.get_include_args(inc_dirs)
        scan_command += state.get_include_args(itertools.chain(gi_includes, gir_inc_dirs, inc_dirs), prefix='--add-include-path=')
        scan_command += list(scan_internal_ldflags)
        scan_command += self._scan_gir_targets(state, girtargets)
        scan_command += self._scan_langs(state, [lc[0] for lc in langs_compilers])
        scan_command += list(scan_external_ldflags)

        if self._gir_has_option('--sources-top-dirs'):
            scan_command += ['--sources-top-dirs', os.path.join(state.environment.get_source_dir(), self.interpreter.subproject_dir, state.subproject)]
            scan_command += ['--sources-top-dirs', os.path.join(state.environment.get_build_dir(), self.interpreter.subproject_dir, state.subproject)]

        if '--warn-error' in scan_command:
            FeatureDeprecated.single_use('gnome.generate_gir argument --warn-error', '0.55.0',
                                         state.subproject, 'Use "fatal_warnings" keyword argument', state.current_node)
        if kwargs['fatal_warnings']:
            scan_command.append('--warn-error')

        generated_files = [f for f in libsources if isinstance(f, (GeneratedList, CustomTarget, CustomTargetIndex))]

        scan_target = self._make_gir_target(
            state, girfile, scan_command, generated_files, depends,
            # We have to cast here because mypy can't figure this out
            T.cast('T.Dict[str, T.Any]', kwargs))

        typelib_output = f'{ns}-{nsversion}.typelib'
        typelib_cmd = [gicompiler, scan_target, '--output', '@OUTPUT@']
        typelib_cmd += state.get_include_args(gir_inc_dirs, prefix='--includedir=')

        for incdir in typelib_includes:
            typelib_cmd += ["--includedir=" + incdir]

        typelib_target = self._make_typelib_target(state, typelib_output, typelib_cmd, generated_files, T.cast('T.Dict[str, T.Any]', kwargs))

        self._devenv_prepend('GI_TYPELIB_PATH', os.path.join(state.environment.get_build_dir(), state.subdir))

        rv = [scan_target, typelib_target]

        return ModuleReturnValue(rv, rv)

    @noPosargs
    @typed_kwargs('gnome.compile_schemas', _BUILD_BY_DEFAULT.evolve(since='0.40.0'), DEPEND_FILES_KW)
    def compile_schemas(self, state: 'ModuleState', args: T.List['TYPE_var'], kwargs: 'CompileSchemas') -> ModuleReturnValue:
        srcdir = os.path.join(state.build_to_src, state.subdir)
        outdir = state.subdir

        cmd: T.List[T.Union[ExternalProgram, str]] = [state.find_program('glib-compile-schemas'), '--targetdir', outdir, srcdir]
        if state.subdir == '':
            targetname = 'gsettings-compile'
        else:
            targetname = 'gsettings-compile-' + state.subdir.replace('/', '_')
        target_g = build.CustomTarget(
            targetname,
            state.subdir,
            state.subproject,
            state.environment,
            cmd,
            [],
            ['gschemas.compiled'],
            build_by_default=kwargs['build_by_default'],
            depend_files=kwargs['depend_files'],
        )
        self._devenv_prepend('GSETTINGS_SCHEMA_DIR', os.path.join(state.environment.get_build_dir(), state.subdir))
        return ModuleReturnValue(target_g, [target_g])

    @typed_pos_args('gnome.yelp', str, varargs=str)
    @typed_kwargs(
        'gnome.yelp',
        KwargInfo(
            'languages', ContainerTypeInfo(list, str),
            listify=True, default=[],
            deprecated='0.43.0',
            deprecated_message='Use a LINGUAS file in the source directory instead',
        ),
        KwargInfo('media', ContainerTypeInfo(list, str), listify=True, default=[]),
        KwargInfo('sources', ContainerTypeInfo(list, str), listify=True, default=[]),
        KwargInfo('symlink_media', bool, default=True),
    )
    def yelp(self, state: 'ModuleState', args: T.Tuple[str, T.List[str]], kwargs: 'Yelp') -> ModuleReturnValue:
        project_id = args[0]
        sources = kwargs['sources']
        if args[1]:
            FeatureDeprecated.single_use('gnome.yelp more than one positional argument', '0.60.0',
                                         state.subproject, 'use the "sources" keyword argument instead.', state.current_node)
        if not sources:
            sources = args[1]
            if not sources:
                raise MesonException('Yelp requires a list of sources')
        elif args[1]:
            mlog.warning('"gnome.yelp" ignores positional sources arguments when the "sources" keyword argument is set')
        sources_files = [mesonlib.File.from_source_file(state.environment.source_dir,
                                                        os.path.join(state.subdir, 'C'),
                                                        s) for s in sources]

        langs = kwargs['languages']
        if not langs:
            langs = read_linguas(os.path.join(state.environment.source_dir, state.subdir))

        media = kwargs['media']
        symlinks = kwargs['symlink_media']
        targets: T.List[T.Union['build.Target', build.Data, build.SymlinkData]] = []
        potargets: T.List[build.RunTarget] = []

        itstool = state.find_program('itstool')
        msgmerge = state.find_program('msgmerge')
        msgfmt = state.find_program('msgfmt')

        install_dir = os.path.join(state.environment.get_datadir(), 'help')
        c_install_dir = os.path.join(install_dir, 'C', project_id)
        c_data = build.Data(sources_files, c_install_dir, c_install_dir,
                            mesonlib.FileMode(), state.subproject)
        targets.append(c_data)

        media_files: T.List[mesonlib.File] = []
        for m in media:
            f = mesonlib.File.from_source_file(state.environment.source_dir,
                                               os.path.join(state.subdir, 'C'), m)
            media_files.append(f)
            m_install_dir = os.path.join(c_install_dir, os.path.dirname(m))
            m_data = build.Data([f], m_install_dir, m_install_dir,
                                mesonlib.FileMode(), state.subproject)
            targets.append(m_data)

        pot_file = os.path.join('@SOURCE_ROOT@', state.subdir, 'C', project_id + '.pot')
        pot_sources = [os.path.join('@SOURCE_ROOT@', state.subdir, 'C', s) for s in sources]
        pot_args: T.List[T.Union['ExternalProgram', str]] = [itstool, '-o', pot_file]
        pot_args.extend(pot_sources)
        pottarget = build.RunTarget(f'help-{project_id}-pot', pot_args, [],
                                    os.path.join(state.subdir, 'C'), state.subproject,
                                    state.environment)
        targets.append(pottarget)

        for l in langs:
            l_subdir = os.path.join(state.subdir, l)
            l_install_dir = os.path.join(install_dir, l, project_id)

            for i, m in enumerate(media):
                m_dir = os.path.dirname(m)
                m_install_dir = os.path.join(l_install_dir, m_dir)
                l_data: T.Union[build.Data, build.SymlinkData]
                if symlinks:
                    link_target = os.path.join(os.path.relpath(c_install_dir, start=m_install_dir), m)
                    l_data = build.SymlinkData(link_target, os.path.basename(m),
                                               m_install_dir, state.subproject)
                else:
                    try:
                        m_file = mesonlib.File.from_source_file(state.environment.source_dir, l_subdir, m)
                    except MesonException:
                        m_file = media_files[i]
                    l_data = build.Data([m_file], m_install_dir, m_install_dir,
                                        mesonlib.FileMode(), state.subproject)
                targets.append(l_data)

            po_file = l + '.po'
            po_args: T.List[T.Union['ExternalProgram', str]] = [
                msgmerge, '-q', '-o',
                os.path.join('@SOURCE_ROOT@', l_subdir, po_file),
                os.path.join('@SOURCE_ROOT@', l_subdir, po_file), pot_file]
            potarget = build.RunTarget(f'help-{project_id}-{l}-update-po',
                                       po_args, [pottarget], l_subdir, state.subproject,
                                       state.environment)
            targets.append(potarget)
            potargets.append(potarget)

            gmo_file = project_id + '-' + l + '.gmo'
            gmotarget = build.CustomTarget(
                f'help-{project_id}-{l}-gmo',
                l_subdir,
                state.subproject,
                state.environment,
                [msgfmt, '@INPUT@', '-o', '@OUTPUT@'],
                [po_file],
                [gmo_file],
            )
            targets.append(gmotarget)

            mergetarget = build.CustomTarget(
                f'help-{project_id}-{l}',
                l_subdir,
                state.subproject,
                state.environment,
                [itstool, '-m', os.path.join(l_subdir, gmo_file), '-o', '@OUTDIR@', '@INPUT@'],
                sources_files,
                sources,
                extra_depends=[gmotarget],
                install=True,
                install_dir=[l_install_dir],
            )
            targets.append(mergetarget)

        allpotarget = build.AliasTarget(f'help-{project_id}-update-po', potargets,
                                        state.subdir, state.subproject, state.environment)
        targets.append(allpotarget)

        return ModuleReturnValue(None, targets)

    @typed_pos_args('gnome.gtkdoc', str)
    @typed_kwargs(
        'gnome.gtkdoc',
        KwargInfo('c_args', ContainerTypeInfo(list, str), since='0.48.0', default=[], listify=True),
        KwargInfo('check', bool, default=False, since='0.52.0'),
        KwargInfo('content_files', ContainerTypeInfo(list, (str, mesonlib.File, build.GeneratedList, build.CustomTarget, build.CustomTargetIndex)), default=[], listify=True),
        KwargInfo(
            'dependencies',
            ContainerTypeInfo(list, (Dependency, build.SharedLibrary, build.StaticLibrary)),
            listify=True, default=[]),
        KwargInfo('expand_content_files', ContainerTypeInfo(list, (str, mesonlib.File)), default=[], listify=True),
        KwargInfo('fixxref_args', ContainerTypeInfo(list, str), default=[], listify=True),
        KwargInfo('gobject_typesfile', ContainerTypeInfo(list, (str, mesonlib.File)), default=[], listify=True),
        KwargInfo('html_args', ContainerTypeInfo(list, str), default=[], listify=True),
        KwargInfo('html_assets', ContainerTypeInfo(list, (str, mesonlib.File)), default=[], listify=True),
        KwargInfo('ignore_headers', ContainerTypeInfo(list, str), default=[], listify=True),
        KwargInfo(
            'include_directories',
            ContainerTypeInfo(list, (str, build.IncludeDirs)),
            listify=True, default=[]),
        KwargInfo('install', bool, default=True),
        KwargInfo('install_dir', ContainerTypeInfo(list, str), default=[], listify=True),
        KwargInfo('main_sgml', (str, NoneType)),
        KwargInfo('main_xml', (str, NoneType)),
        KwargInfo('mkdb_args', ContainerTypeInfo(list, str), default=[], listify=True),
        KwargInfo(
            'mode', str, default='auto', since='0.37.0',
            validator=in_set_validator({'xml', 'sgml', 'none', 'auto'})),
        KwargInfo('module_version', str, default='', since='0.48.0'),
        KwargInfo('namespace', str, default='', since='0.37.0'),
        KwargInfo('scan_args', ContainerTypeInfo(list, str), default=[], listify=True),
        KwargInfo('scanobjs_args', ContainerTypeInfo(list, str), default=[], listify=True),
        KwargInfo('src_dir', ContainerTypeInfo(list, (str, build.IncludeDirs)), listify=True, required=True),
    )
    def gtkdoc(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'GtkDoc') -> ModuleReturnValue:
        modulename = args[0]
        main_file = kwargs['main_sgml']
        main_xml = kwargs['main_xml']
        if main_xml is not None:
            if main_file is not None:
                raise InvalidArguments('gnome.gtkdoc: main_xml and main_sgml are exclusive arguments')
            main_file = main_xml
        moduleversion = kwargs['module_version']
        targetname = modulename + ('-' + moduleversion if moduleversion else '') + '-doc'
        command = state.environment.get_build_command()

        namespace = kwargs['namespace']

        def abs_filenames(files: T.Iterable['FileOrString']) -> T.Iterator[str]:
            for f in files:
                if isinstance(f, mesonlib.File):
                    yield f.absolute_path(state.environment.get_source_dir(), state.environment.get_build_dir())
                else:
                    yield os.path.join(state.environment.get_source_dir(), state.subdir, f)

        src_dirs = kwargs['src_dir']
        header_dirs: T.List[str] = []
        for src_dir in src_dirs:
            if isinstance(src_dir, build.IncludeDirs):
                header_dirs.extend(src_dir.to_string_list(state.environment.get_source_dir(),
                                                          state.environment.get_build_dir()))
            else:
                header_dirs.append(src_dir)

        t_args: T.List[str] = [
            '--internal', 'gtkdoc',
            '--sourcedir=' + state.environment.get_source_dir(),
            '--builddir=' + state.environment.get_build_dir(),
            '--subdir=' + state.subdir,
            '--headerdirs=' + '@@'.join(header_dirs),
            '--mainfile=' + main_file,
            '--modulename=' + modulename,
            '--moduleversion=' + moduleversion,
            '--mode=' + kwargs['mode']]
        for tool in ['scan', 'scangobj', 'mkdb', 'mkhtml', 'fixxref']:
            program_name = 'gtkdoc-' + tool
            program = state.find_program(program_name)
            path = program.get_path()
            t_args.append(f'--{program_name}={path}')
        if namespace:
            t_args.append('--namespace=' + namespace)
        # if not need_exe_wrapper, we get an EmptyExternalProgram. If none provided, we get NoneType
        exe_wrapper = state.environment.get_exe_wrapper()
        if not isinstance(exe_wrapper, (NoneType, EmptyExternalProgram)):
            t_args.append('--run=' + ' '.join(exe_wrapper.get_command()))
        t_args.append(f'--htmlargs={"@@".join(kwargs["html_args"])}')
        t_args.append(f'--scanargs={"@@".join(kwargs["scan_args"])}')
        t_args.append(f'--scanobjsargs={"@@".join(kwargs["scanobjs_args"])}')
        t_args.append(f'--gobjects-types-file={"@@".join(abs_filenames(kwargs["gobject_typesfile"]))}')
        t_args.append(f'--fixxrefargs={"@@".join(kwargs["fixxref_args"])}')
        t_args.append(f'--mkdbargs={"@@".join(kwargs["mkdb_args"])}')
        t_args.append(f'--html-assets={"@@".join(abs_filenames(kwargs["html_assets"]))}')

        depends: T.List['build.GeneratedTypes'] = []
        content_files = []
        for s in kwargs['content_files']:
            if isinstance(s, (build.CustomTarget, build.CustomTargetIndex)):
                depends.append(s)
                for o in s.get_outputs():
                    content_files.append(os.path.join(state.environment.get_build_dir(),
                                                      state.backend.get_target_dir(s),
                                                      o))
            elif isinstance(s, mesonlib.File):
                content_files.append(s.absolute_path(state.environment.get_source_dir(),
                                                     state.environment.get_build_dir()))
            elif isinstance(s, build.GeneratedList):
                depends.append(s)
                for gen_src in s.get_outputs():
                    content_files.append(os.path.join(state.environment.get_source_dir(),
                                                      state.subdir,
                                                      gen_src))
            else:
                content_files.append(os.path.join(state.environment.get_source_dir(),
                                                  state.subdir,
                                                  s))
        t_args += ['--content-files=' + '@@'.join(content_files)]

        t_args.append(f'--expand-content-files={"@@".join(abs_filenames(kwargs["expand_content_files"]))}')
        t_args.append(f'--ignore-headers={"@@".join(kwargs["ignore_headers"])}')
        t_args.append(f'--installdir={"@@".join(kwargs["install_dir"])}')
        build_args, new_depends = self._get_build_args(kwargs['c_args'], kwargs['include_directories'],
                                                       kwargs['dependencies'], state, depends)
        t_args.extend(build_args)
        new_depends.extend(depends)
        custom_target = build.CustomTarget(
            targetname,
            state.subdir,
            state.subproject,
            state.environment,
            command + t_args,
            [],
            [f'{modulename}-decl.txt'],
            build_always_stale=True,
            extra_depends=new_depends,
        )
        alias_target = build.AliasTarget(targetname, [custom_target], state.subdir, state.subproject, state.environment)
        if kwargs['check']:
            check_cmd = state.find_program('gtkdoc-check')
            check_env = ['DOC_MODULE=' + modulename,
                         'DOC_MAIN_SGML_FILE=' + main_file]
            check_args = (targetname + '-check', check_cmd)
            check_workdir = os.path.join(state.environment.get_build_dir(), state.subdir)
            state.test(check_args, env=check_env, workdir=check_workdir, depends=[custom_target])
        res: T.List[T.Union[build.Target, build.ExecutableSerialisation]] = [custom_target, alias_target]
        if kwargs['install']:
            res.append(state.backend.get_executable_serialisation(command + t_args, tag='doc'))
        return ModuleReturnValue(custom_target, res)

    def _get_build_args(self, c_args: T.List[str], inc_dirs: T.List[T.Union[str, build.IncludeDirs]],
                        deps: T.List[T.Union[Dependency, build.SharedLibrary, build.StaticLibrary]],
                        state: 'ModuleState',
                        depends: T.Sequence[T.Union[build.BuildTarget, 'build.GeneratedTypes']]) -> T.Tuple[
                                T.List[str], T.List[T.Union[build.BuildTarget, 'build.GeneratedTypes', 'FileOrString', build.StructuredSources]]]:
        args: T.List[str] = []
        cflags = c_args.copy()
        deps_cflags, internal_ldflags, external_ldflags, _gi_includes, new_depends = \
            self._get_dependencies_flags(deps, state, depends, include_rpath=True)

        cflags.extend(deps_cflags)
        cflags.extend(state.get_include_args(inc_dirs))
        ldflags: T.List[str] = []
        ldflags.extend(internal_ldflags)
        ldflags.extend(external_ldflags)

        cflags.extend(state.environment.coredata.get_external_args(MachineChoice.HOST, 'c'))
        ldflags.extend(state.environment.coredata.get_external_link_args(MachineChoice.HOST, 'c'))
        compiler = state.environment.coredata.compilers[MachineChoice.HOST]['c']

        compiler_flags = self._get_langs_compilers_flags(state, [('c', compiler)])
        cflags.extend(compiler_flags[0])
        ldflags.extend(compiler_flags[1])
        ldflags.extend(compiler_flags[2])
        if compiler:
            args += ['--cc=%s' % join_args(compiler.get_exelist())]
            args += ['--ld=%s' % join_args(compiler.get_linker_exelist())]
        if cflags:
            args += ['--cflags=%s' % join_args(cflags)]
        if ldflags:
            args += ['--ldflags=%s' % join_args(ldflags)]

        return args, new_depends

    @noKwargs
    @typed_pos_args('gnome.gtkdoc_html_dir', str)
    def gtkdoc_html_dir(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'TYPE_kwargs') -> str:
        return os.path.join('share/gtk-doc/html', args[0])

    @typed_pos_args('gnome.gdbus_codegen', str, optargs=[(str, mesonlib.File)])
    @typed_kwargs(
        'gnome.gdbus_codegen',
        _BUILD_BY_DEFAULT.evolve(since='0.40.0'),
        KwargInfo('sources', ContainerTypeInfo(list, (str, mesonlib.File)), since='0.46.0', default=[], listify=True),
        KwargInfo('extra_args', ContainerTypeInfo(list, str), since='0.47.0', default=[], listify=True),
        KwargInfo('interface_prefix', (str, NoneType)),
        KwargInfo('namespace', (str, NoneType)),
        KwargInfo('object_manager', bool, default=False),
        KwargInfo(
            'annotations', ContainerTypeInfo(list, (list, str)),
            default=[],
            validator=annotations_validator,
            convertor=lambda x: [x] if x and isinstance(x[0], str) else x,
        ),
        KwargInfo('install_header', bool, default=False, since='0.46.0'),
        KwargInfo('install_dir', (str, NoneType), since='0.46.0'),
        KwargInfo('docbook', (str, NoneType)),
        KwargInfo(
            'autocleanup', str, default='default', since='0.47.0',
            validator=in_set_validator({'all', 'none', 'objects'})),
    )
    def gdbus_codegen(self, state: 'ModuleState', args: T.Tuple[str, T.Optional['FileOrString']],
                      kwargs: 'GdbusCodegen') -> ModuleReturnValue:
        namebase = args[0]
        xml_files: T.List['FileOrString'] = [args[1]] if args[1] else []
        cmd: T.List[T.Union['ExternalProgram', str]] = [state.find_program('gdbus-codegen')]
        cmd.extend(kwargs['extra_args'])

        # Autocleanup supported?
        glib_version = self._get_native_glib_version(state)
        if not mesonlib.version_compare(glib_version, '>= 2.49.1'):
            # Warn if requested, silently disable if not
            if kwargs['autocleanup'] != 'default':
                mlog.warning(f'Glib version ({glib_version}) is too old to support the \'autocleanup\' '
                             'kwarg, need 2.49.1 or newer')
        else:
            # Handle legacy glib versions that don't have autocleanup
            ac = kwargs['autocleanup']
            if ac == 'default':
                ac = 'all'
            cmd.extend(['--c-generate-autocleanup', ac])

        if kwargs['interface_prefix'] is not None:
            cmd.extend(['--interface-prefix', kwargs['interface_prefix']])
        if kwargs['namespace'] is not None:
            cmd.extend(['--c-namespace', kwargs['namespace']])
        if kwargs['object_manager']:
            cmd.extend(['--c-generate-object-manager'])
        xml_files.extend(kwargs['sources'])
        build_by_default = kwargs['build_by_default']

        # Annotations are a bit ugly in that they are a list of lists of strings...
        for annot in kwargs['annotations']:
            cmd.append('--annotate')
            cmd.extend(annot)

        targets = []
        install_header = kwargs['install_header']
        install_dir = kwargs['install_dir'] or state.environment.coredata.get_option(mesonlib.OptionKey('includedir'))
        assert isinstance(install_dir, str), 'for mypy'

        output = namebase + '.c'
        # Added in https://gitlab.gnome.org/GNOME/glib/commit/e4d68c7b3e8b01ab1a4231bf6da21d045cb5a816 (2.55.2)
        # Fixed in https://gitlab.gnome.org/GNOME/glib/commit/cd1f82d8fc741a2203582c12cc21b4dacf7e1872 (2.56.2)
        if mesonlib.version_compare(glib_version, '>= 2.56.2'):
            c_cmd = cmd + ['--body', '--output', '@OUTPUT@', '@INPUT@']
        else:
            if kwargs['docbook'] is not None:
                docbook = kwargs['docbook']

                cmd += ['--generate-docbook', docbook]

            # 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@']
            else:
                self._print_gdbus_warning()
                cmd += ['--generate-c-code', '@OUTDIR@/' + namebase, '@INPUT@']
            c_cmd = cmd

        cfile_custom_target = build.CustomTarget(
            output,
            state.subdir,
            state.subproject,
            state.environment,
            c_cmd,
            xml_files,
            [output],
            build_by_default=build_by_default,
        )
        targets.append(cfile_custom_target)

        output = namebase + '.h'
        if mesonlib.version_compare(glib_version, '>= 2.56.2'):
            hfile_cmd = cmd + ['--header', '--output', '@OUTPUT@', '@INPUT@']
            depends = []
        else:
            hfile_cmd = cmd
            depends = [cfile_custom_target]

        hfile_custom_target = build.CustomTarget(
            output,
            state.subdir,
            state.subproject,
            state.environment,
            hfile_cmd,
            xml_files,
            [output],
            build_by_default=build_by_default,
            extra_depends=depends,
            install=install_header,
            install_dir=[install_dir],
        )
        targets.append(hfile_custom_target)

        if kwargs['docbook'] is not None:
            docbook = kwargs['docbook']
            # The docbook output is always ${docbook}-${name_of_xml_file}
            output = namebase + '-docbook'
            outputs = []
            for f in xml_files:
                outputs.append('{}-{}'.format(docbook, os.path.basename(str(f))))

            if mesonlib.version_compare(glib_version, '>= 2.56.2'):
                docbook_cmd = cmd + ['--output-directory', '@OUTDIR@', '--generate-docbook', docbook, '@INPUT@']
                depends = []
            else:
                docbook_cmd = cmd
                depends = [cfile_custom_target]

            docbook_custom_target = build.CustomTarget(
                output,
                state.subdir,
                state.subproject,
                state.environment,
                docbook_cmd,
                xml_files,
                outputs,
                build_by_default=build_by_default,
                extra_depends=depends,
            )
            targets.append(docbook_custom_target)

        return ModuleReturnValue(targets, targets)

    @typed_pos_args('gnome.mkenums', str)
    @typed_kwargs(
        'gnome.mkenums',
        *_MK_ENUMS_COMMON_KWS,
        DEPENDS_KW,
        KwargInfo('c_template', (str, mesonlib.File, NoneType)),
        KwargInfo('h_template', (str, mesonlib.File, NoneType)),
        KwargInfo('comments', (str, NoneType)),
        KwargInfo('eprod', (str, NoneType)),
        KwargInfo('fhead', (str, NoneType)),
        KwargInfo('fprod', (str, NoneType)),
        KwargInfo('ftail', (str, NoneType)),
        KwargInfo('vhead', (str, NoneType)),
        KwargInfo('vprod', (str, NoneType)),
        KwargInfo('vtail', (str, NoneType)),
    )
    def mkenums(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'MkEnums') -> ModuleReturnValue:
        basename = args[0]

        c_template = kwargs['c_template']
        if isinstance(c_template, mesonlib.File):
            c_template = c_template.absolute_path(state.environment.source_dir, state.environment.build_dir)
        h_template = kwargs['h_template']
        if isinstance(h_template, mesonlib.File):
            h_template = h_template.absolute_path(state.environment.source_dir, state.environment.build_dir)

        cmd: T.List[str] = []
        known_kwargs = ['comments', 'eprod', 'fhead', 'fprod', 'ftail',
                        'identifier_prefix', 'symbol_prefix',
                        'vhead', 'vprod', 'vtail']
        for arg in known_kwargs:
            # mypy can't figure this out
            if kwargs[arg]:                                         # type: ignore
                cmd += ['--' + arg.replace('_', '-'), kwargs[arg]]  # type: ignore

        targets: T.List[CustomTarget] = []

        h_target: T.Optional[CustomTarget] = None
        if h_template is not None:
            h_output = os.path.basename(os.path.splitext(h_template)[0])
            # We always set template as the first element in the source array
            # so --template consumes it.
            h_cmd = cmd + ['--template', '@INPUT@']
            h_sources: T.List[T.Union[FileOrString, 'build.GeneratedTypes']] = [h_template]
            h_sources.extend(kwargs['sources'])
            h_target = self._make_mkenum_impl(
                state, h_sources, h_output, h_cmd, install=kwargs['install_header'],
                install_dir=kwargs['install_dir'])
            targets.append(h_target)

        if c_template is not None:
            c_output = os.path.basename(os.path.splitext(c_template)[0])
            # We always set template as the first element in the source array
            # so --template consumes it.
            c_cmd = cmd + ['--template', '@INPUT@']
            c_sources: T.List[T.Union[FileOrString, 'build.GeneratedTypes']] = [c_template]
            c_sources.extend(kwargs['sources'])

            depends = kwargs['depends'].copy()
            if h_target is not None:
                depends.append(h_target)
            c_target = self._make_mkenum_impl(
                state, c_sources, c_output, c_cmd, depends=depends)
            targets.insert(0, c_target)

        if c_template is None and h_template is None:
            generic_cmd = cmd + ['@INPUT@']
            target = self._make_mkenum_impl(
                state, kwargs['sources'], basename, generic_cmd,
                install=kwargs['install_header'],
                install_dir=kwargs['install_dir'])
            return ModuleReturnValue(target, [target])
        else:
            return ModuleReturnValue(targets, targets)

    @FeatureNew('gnome.mkenums_simple', '0.42.0')
    @typed_pos_args('gnome.mkenums_simple', str)
    @typed_kwargs(
        'gnome.mkenums_simple',
        *_MK_ENUMS_COMMON_KWS,
        KwargInfo('header_prefix', str, default=''),
        KwargInfo('function_prefix', str, default=''),
        KwargInfo('body_prefix', str, default=''),
        KwargInfo('decorator', str, default=''),
    )
    def mkenums_simple(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'MkEnumsSimple') -> ModuleReturnValue:
        hdr_filename = f'{args[0]}.h'
        body_filename = f'{args[0]}.c'

        header_prefix = kwargs['header_prefix']
        decl_decorator = kwargs['decorator']
        func_prefix = kwargs['function_prefix']
        body_prefix = kwargs['body_prefix']

        cmd: T.List[str] = []
        if kwargs['identifier_prefix']:
            cmd.extend(['--identifier-prefix', kwargs['identifier_prefix']])
        if kwargs['symbol_prefix']:
            cmd.extend(['--symbol-prefix', kwargs['symbol_prefix']])

        c_cmd = cmd.copy()
        # Maybe we should write our own template files into the build dir
        # instead, but that seems like much more work, nice as it would be.
        fhead = ''
        if body_prefix != '':
            fhead += '%s\n' % body_prefix
        fhead += '#include "%s"\n' % hdr_filename
        for hdr in kwargs['sources']:
            fhead += '#include "{}"\n'.format(os.path.basename(str(hdr)))
        fhead += textwrap.dedent(
            '''
            #define C_ENUM(v) ((gint) v)
            #define C_FLAGS(v) ((guint) v)
            ''')
        c_cmd.extend(['--fhead', fhead])

        c_cmd.append('--fprod')
        c_cmd.append(textwrap.dedent(
            '''
            /* enumerations from "@basename@" */
            '''))

        c_cmd.append('--vhead')
        c_cmd.append(textwrap.dedent(
            f'''
            GType
            {func_prefix}@enum_name@_get_type (void)
            {{
            static gsize gtype_id = 0;
            static const G@Type@Value values[] = {{'''))

        c_cmd.extend(['--vprod', '    { C_@TYPE@(@VALUENAME@), "@VALUENAME@", "@valuenick@" },'])

        c_cmd.append('--vtail')
        c_cmd.append(textwrap.dedent(
            '''    { 0, NULL, NULL }
            };
            if (g_once_init_enter (&gtype_id)) {
                GType new_type = g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
                g_once_init_leave (&gtype_id, new_type);
            }
            return (GType) gtype_id;
            }'''))
        c_cmd.append('@INPUT@')

        c_file = self._make_mkenum_impl(state, kwargs['sources'], body_filename, c_cmd)

        # .h file generation
        h_cmd = cmd.copy()

        h_cmd.append('--fhead')
        h_cmd.append(textwrap.dedent(
            f'''#pragma once

            #include <glib-object.h>
            {header_prefix}

            G_BEGIN_DECLS
            '''))

        h_cmd.append('--fprod')
        h_cmd.append(textwrap.dedent(
            '''
            /* enumerations from "@basename@" */
            '''))

        h_cmd.append('--vhead')
        h_cmd.append(textwrap.dedent(
            f'''
            {decl_decorator}
            GType {func_prefix}@enum_name@_get_type (void);
            #define @ENUMPREFIX@_TYPE_@ENUMSHORT@ ({func_prefix}@enum_name@_get_type())'''))

        h_cmd.append('--ftail')
        h_cmd.append(textwrap.dedent(
            '''
            G_END_DECLS'''))
        h_cmd.append('@INPUT@')

        h_file = self._make_mkenum_impl(
            state, kwargs['sources'], hdr_filename, h_cmd,
            install=kwargs['install_header'],
            install_dir=kwargs['install_dir'])

        return ModuleReturnValue([c_file, h_file], [c_file, h_file])

    @staticmethod
    def _make_mkenum_impl(
            state: 'ModuleState',
            sources: T.Sequence[T.Union[str, mesonlib.File, build.CustomTarget, build.CustomTargetIndex, build.GeneratedList]],
            output: str,
            cmd: T.List[str],
            *,
            install: bool = False,
            install_dir: T.Optional[T.Sequence[T.Union[str, bool]]] = None,
            depends: T.Optional[T.Sequence[T.Union[CustomTarget, CustomTargetIndex, BuildTarget]]] = None
            ) -> build.CustomTarget:
        real_cmd: T.List[T.Union[str, ExternalProgram]] = [state.find_program(['glib-mkenums', 'mkenums'])]
        real_cmd.extend(cmd)
        _install_dir = install_dir or state.environment.coredata.get_option(mesonlib.OptionKey('includedir'))
        assert isinstance(_install_dir, str), 'for mypy'

        return build.CustomTarget(
            output,
            state.subdir,
            state.subproject,
            state.environment,
            real_cmd,
            sources,
            [output],
            capture=True,
            install=install,
            install_dir=[_install_dir],
            extra_depends=depends,
            # https://github.com/mesonbuild/meson/issues/973
            absolute_paths=True,
        )

    @typed_pos_args('gnome.genmarshal', str)
    @typed_kwargs(
        'gnome.genmarshal',
        DEPEND_FILES_KW.evolve(since='0.61.0'),
        DEPENDS_KW.evolve(since='0.61.0'),
        INSTALL_KW.evolve(name='install_header'),
        KwargInfo('extra_args', ContainerTypeInfo(list, str), listify=True, default=[]),
        KwargInfo('install_dir', (str, NoneType)),
        KwargInfo('internal', bool, default=False),
        KwargInfo('nostdinc', bool, default=False),
        KwargInfo('prefix', (str, NoneType)),
        KwargInfo('skip_source', bool, default=False),
        KwargInfo('sources', ContainerTypeInfo(list, (str, mesonlib.File), allow_empty=False), listify=True, required=True),
        KwargInfo('stdinc', bool, default=False),
        KwargInfo('valist_marshallers', bool, default=False),
    )
    def genmarshal(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'GenMarshal') -> ModuleReturnValue:
        output = args[0]
        sources = kwargs['sources']

        new_genmarshal = mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.53.3')

        cmd: T.List[T.Union['ExternalProgram', str]] = [state.find_program('glib-genmarshal')]
        if kwargs['prefix']:
            cmd.extend(['--prefix', kwargs['prefix']])
        if kwargs['extra_args']:
            if new_genmarshal:
                cmd.extend(kwargs['extra_args'])
            else:
                mlog.warning('The current version of GLib does not support extra arguments \n'
                             'for glib-genmarshal. You need at least GLib 2.53.3. See ',
                             mlog.bold('https://github.com/mesonbuild/meson/pull/2049'))
        for k in ['internal', 'nostdinc', 'skip_source', 'stdinc', 'valist_marshallers']:
            # Mypy can't figure out that this is correct
            if kwargs[k]:                                            # type: ignore
                cmd.append(f'--{k.replace("_", "-")}')

        install_header = kwargs['install_header']
        capture = False

        # https://github.com/GNOME/glib/commit/0fbc98097fac4d3e647684f344e508abae109fdf
        if mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.51.0'):
            cmd += ['--output', '@OUTPUT@']
        else:
            capture = True

        header_file = output + '.h'
        h_cmd = cmd + ['--header', '@INPUT@']
        if new_genmarshal:
            h_cmd += ['--pragma-once']
        header = build.CustomTarget(
            output + '_h',
            state.subdir,
            state.subproject,
            state.environment,
            h_cmd,
            sources,
            [header_file],
            install=install_header,
            install_dir=[kwargs['install_dir']] if kwargs['install_dir'] else [],
            capture=capture,
            depend_files=kwargs['depend_files'],
        )

        c_cmd = cmd + ['--body', '@INPUT@']
        extra_deps: T.List[build.CustomTarget] = []
        if mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.53.4'):
            # Silence any warnings about missing prototypes
            c_cmd += ['--include-header', header_file]
            extra_deps.append(header)
        body = build.CustomTarget(
            output + '_c',
            state.subdir,
            state.subproject,
            state.environment,
            c_cmd,
            sources,
            [f'{output}.c'],
            capture=capture,
            depend_files=kwargs['depend_files'],
            extra_depends=extra_deps,
        )

        rv = [body, header]
        return ModuleReturnValue(rv, rv)

    def _extract_vapi_packages(self, state: 'ModuleState', packages: T.List[T.Union[InternalDependency, str]],
                               ) -> T.Tuple[T.List[str], T.List[VapiTarget], T.List[str], T.List[str], T.List[str]]:
        '''
        Packages are special because we need to:
        - Get a list of packages for the .deps file
        - Get a list of depends for any VapiTargets
        - Get package name from VapiTargets
        - Add include dirs for any VapiTargets
        '''
        if not packages:
            return [], [], [], [], []
        vapi_depends: T.List[VapiTarget] = []
        vapi_packages: T.List[str] = []
        vapi_includes: T.List[str] = []
        vapi_args: T.List[str] = []
        remaining_args = []
        for arg in packages:
            if isinstance(arg, InternalDependency):
                targets = [t for t in arg.sources if isinstance(t, VapiTarget)]
                for target in targets:
                    srcdir = os.path.join(state.environment.get_source_dir(),
                                          target.get_subdir())
                    outdir = os.path.join(state.environment.get_build_dir(),
                                          target.get_subdir())
                    outfile = target.get_outputs()[0][:-5] # Strip .vapi
                    vapi_args.append('--vapidir=' + outdir)
                    vapi_args.append('--girdir=' + outdir)
                    vapi_args.append('--pkg=' + outfile)
                    vapi_depends.append(target)
                    vapi_packages.append(outfile)
                    vapi_includes.append(srcdir)
            else:
                assert isinstance(arg, str), 'for mypy'
                vapi_args.append(f'--pkg={arg}')
                vapi_packages.append(arg)
                remaining_args.append(arg)

        # TODO: this is supposed to take IncludeDirs, but it never worked
        return vapi_args, vapi_depends, vapi_packages, vapi_includes, remaining_args

    def _generate_deps(self, state: 'ModuleState', library: str, packages: T.List[str], install_dir: str) -> build.Data:
        outdir = state.environment.scratch_dir
        fname = os.path.join(outdir, library + '.deps')
        with open(fname, 'w', encoding='utf-8') as ofile:
            for package in packages:
                ofile.write(package + '\n')
        return build.Data([mesonlib.File(True, outdir, fname)], install_dir, install_dir, mesonlib.FileMode(), state.subproject)

    def _get_vapi_link_with(self, target: build.CustomTarget) -> T.List[T.Union[build.BuildTarget, build.CustomTarget]]:
        link_with: T.List[T.Union[build.BuildTarget, build.CustomTarget]] = []
        for dep in target.get_target_dependencies():
            if isinstance(dep, build.SharedLibrary):
                link_with.append(dep)
            elif isinstance(dep, GirTarget):
                link_with += self._get_vapi_link_with(dep)
        return link_with

    @typed_pos_args('gnome.generate_vapi', str)
    @typed_kwargs(
        'gnome.generate_vapi',
        INSTALL_KW,
        KwargInfo(
            'sources',
            ContainerTypeInfo(list, (str, GirTarget), allow_empty=False),
            listify=True,
            required=True,
        ),
        KwargInfo('install_dir', (str, NoneType)),
        KwargInfo('vapi_dirs', ContainerTypeInfo(list, str), listify=True, default=[]),
        KwargInfo('metadata_dirs', ContainerTypeInfo(list, str), listify=True, default=[]),
        KwargInfo('gir_dirs', ContainerTypeInfo(list, str), listify=True, default=[]),
        KwargInfo('packages', ContainerTypeInfo(list, (str, InternalDependency)), listify=True, default=[]),
    )
    def generate_vapi(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'GenerateVapi') -> ModuleReturnValue:
        created_values: T.List[T.Union[Dependency, build.Data]] = []
        library = args[0]
        build_dir = os.path.join(state.environment.get_build_dir(), state.subdir)
        source_dir = os.path.join(state.environment.get_source_dir(), state.subdir)
        pkg_cmd, vapi_depends, vapi_packages, vapi_includes, packages = self._extract_vapi_packages(state, kwargs['packages'])
        cmd: T.List[T.Union[str, 'ExternalProgram']]
        cmd = [state.find_program('vapigen'), '--quiet', f'--library={library}', f'--directory={build_dir}']
        cmd.extend([f'--vapidir={d}' for d in kwargs['vapi_dirs']])
        cmd.extend([f'--metadatadir={d}' for d in kwargs['metadata_dirs']])
        cmd.extend([f'--girdir={d}' for d in kwargs['gir_dirs']])
        cmd += pkg_cmd
        cmd += ['--metadatadir=' + source_dir]

        inputs = kwargs['sources']

        link_with = []
        for i in inputs:
            if isinstance(i, str):
                cmd.append(os.path.join(source_dir, i))
            elif isinstance(i, GirTarget):
                link_with += self._get_vapi_link_with(i)
                subdir = os.path.join(state.environment.get_build_dir(),
                                      i.get_subdir())
                gir_file = os.path.join(subdir, i.get_outputs()[0])
                cmd.append(gir_file)

        vapi_output = library + '.vapi'
        datadir = state.environment.coredata.get_option(mesonlib.OptionKey('datadir'))
        assert isinstance(datadir, str), 'for mypy'
        install_dir = kwargs['install_dir'] or os.path.join(datadir, 'vala', 'vapi')

        if kwargs['install']:
            # We shouldn't need this locally but we install it
            deps_target = self._generate_deps(state, library, vapi_packages, install_dir)
            created_values.append(deps_target)
        vapi_target = VapiTarget(
            vapi_output,
            state.subdir,
            state.subproject,
            state.environment,
            command=cmd,
            sources=inputs,
            outputs=[vapi_output],
            extra_depends=vapi_depends,
            install=kwargs['install'],
            install_dir=[install_dir],
        )

        # So to try our best to get this to just work we need:
        # - link with with the correct library
        # - include the vapi and dependent vapi files in sources
        # - add relevant directories to include dirs
        incs = [build.IncludeDirs(state.subdir, ['.'] + vapi_includes, False)]
        sources = [vapi_target] + vapi_depends
        rv = InternalDependency(None, incs, [], [], link_with, [], sources, [], {}, [], [])
        created_values.append(rv)
        return ModuleReturnValue(rv, created_values)

def initialize(interp: 'Interpreter') -> GnomeModule:
    mod = GnomeModule(interp)
    mod.interpreter.append_holder_map(GResourceTarget, interpreter.CustomTargetHolder)
    mod.interpreter.append_holder_map(GResourceHeaderTarget, interpreter.CustomTargetHolder)
    mod.interpreter.append_holder_map(GirTarget, interpreter.CustomTargetHolder)
    mod.interpreter.append_holder_map(TypelibTarget, interpreter.CustomTargetHolder)
    mod.interpreter.append_holder_map(VapiTarget, interpreter.CustomTargetHolder)
    return mod
