# 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'''

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

from .. import build
from .. import mlog
from .. import mesonlib
from .. import interpreter
from . import GResourceTarget, GResourceHeaderTarget, GirTarget, TypelibTarget, VapiTarget
from . import ExtensionModule
from . import ModuleReturnValue
from ..mesonlib import (
    MachineChoice, MesonException, OrderedSet, Popen_safe, extract_as_list,
    join_args, HoldableObject
)
from ..dependencies import Dependency, PkgConfigDependency, InternalDependency
from ..interpreterbase import noPosargs, noKwargs, permittedKwargs, FeatureNew, FeatureNewKwargs, FeatureDeprecatedKwargs
from ..interpreterbase import typed_kwargs, KwargInfo, ContainerTypeInfo
from ..programs import ExternalProgram, OverrideProgram
from ..build import CustomTarget, CustomTargetIndex, GeneratedList

if T.TYPE_CHECKING:
    from ..compilers import Compiler
    from ..interpreter import Interpreter

# 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 = None
        self.install_glib_compile_schemas = False
        self.install_gio_querymodules = []
        self.install_gtk_update_icon_cache = False
        self.install_update_desktop_database = False
        self.devenv = 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):
        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):
        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():
        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, depname, native=False, required=True):
        kwargs = {'native': native, 'required': required}
        return self.interpreter.func_dependency(state.current_node, [depname], kwargs)

    def _get_native_binary(self, state, name, depname, varname, required=True):
        # 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 = state.environment.lookup_binary_entry(MachineChoice.HOST, name)
        if prog is not None:
            return ExternalProgram.from_entry(name, prog)

        # 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, {})
            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, args, kwargs):
        rv = []
        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 = self._get_native_binary(state, 'gtk4-update-icon-cache', 'gtk-4.0', 'gtk4_update_icon_cache', required=False)
            found = isinstance(prog, build.Executable) or prog.found()
            if not found:
                prog = self._get_native_binary(state, 'gtk-update-icon-cache', 'gtk+-3.0', '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 = self._get_native_binary(state, 'update-desktop-database', 'desktop-file-utils', '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)

    @FeatureNewKwargs('gnome.compile_resources', '0.37.0', ['gresource_bundle', 'export', 'install_header'])
    @permittedKwargs({'source_dir', 'c_name', 'dependencies', 'export', 'gresource_bundle', 'install_header',
                      'install', 'install_dir', 'extra_args', 'build_by_default'})
    def compile_resources(self, state, args, kwargs):
        self.__print_gresources_warning(state)
        glib_version = self._get_native_glib_version(state)

        glib_compile_resources = state.find_program('glib-compile-resources')
        cmd = [glib_compile_resources, '@INPUT@']

        source_dirs, dependencies = [mesonlib.extract_as_list(kwargs, c, pop=True) for c in  ['source_dir', 'dependencies']]

        if len(args) < 2:
            raise MesonException('Not enough arguments; the name of the resource '
                                 'and the path to the XML file are required')

        # Validate dependencies
        subdirs = []
        depends = []
        for (ii, dep) in enumerate(dependencies):
            if isinstance(dep, mesonlib.File):
                subdirs.append(dep.subdir)
            elif isinstance(dep, (build.CustomTarget, build.CustomTargetIndex)):
                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)
            else:
                m = 'Unexpected dependency type {!r} for gnome.compile_resources() ' \
                    '"dependencies" argument.\nPlease pass the return value of ' \
                    'custom_target() or configure_file()'
                raise MesonException(m.format(dep))

        if not mesonlib.version_compare(glib_version, gresource_dep_needed_version):
            ifile = args[1]
            if isinstance(ifile, 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 ifile.is_built:
                    ifile = os.path.join(state.environment.get_build_dir(), ifile.subdir, ifile.fname)
                else:
                    ifile = os.path.join(ifile.subdir, ifile.fname)
            elif isinstance(ifile, str):
                ifile = os.path.join(state.subdir, ifile)
            elif isinstance(ifile, (interpreter.CustomTargetHolder,
                                    interpreter.CustomTargetIndexHolder,
                                    interpreter.GeneratedObjectsHolder)):
                m = '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.'
                raise MesonException(m)
            else:
                raise MesonException(f'Invalid file argument: {ifile!r}')
            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 'c_name' in kwargs:
            cmd += ['--c-name', kwargs.pop('c_name')]
        export = kwargs.pop('export', False)
        if not export:
            cmd += ['--internal']

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

        cmd += mesonlib.stringlistify(kwargs.pop('extra_args', []))

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

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

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

        kwargs['input'] = args[1]
        kwargs['output'] = output
        kwargs['depends'] = depends
        if not mesonlib.version_compare(glib_version, gresource_dep_needed_version):
            # This will eventually go out of sync if dependencies are added
            kwargs['depend_files'] = depend_files
            kwargs['command'] = cmd
        else:
            depfile = kwargs['output'] + '.d'
            kwargs['depfile'] = depfile
            kwargs['command'] = copy.copy(cmd) + ['--dependency-file', '@DEPFILE@']
        target_c = GResourceTarget(name, state.subdir, state.subproject, kwargs)

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

        h_kwargs = {
            'command': cmd,
            'input': args[1],
            'output': args[0] + '.h',
            # The header doesn't actually care about the files yet it errors if missing
            'depends': depends
        }
        if 'build_by_default' in kwargs:
            h_kwargs['build_by_default'] = kwargs['build_by_default']
        if install_header:
            h_kwargs['install'] = install_header
            h_kwargs['install_dir'] = kwargs.get('install_dir',
                                                 state.environment.coredata.get_option(mesonlib.OptionKey('includedir')))
        target_h = GResourceHeaderTarget(args[0] + '_h', state.subdir, state.subproject, h_kwargs)
        rv = [target_c, target_h]
        return ModuleReturnValue(rv, rv)

    def _get_gresource_dependencies(self, state, input_file, source_dirs, dependencies):

        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 = 'glib-compile-resources failed to get dependencies for {}:\n{}'
            mlog.warning(m.format(cmd[1], stderr))
            raise subprocess.CalledProcessError(pc.returncode, cmd)

        dep_files = stdout.split('\n')[:-1]

        depends = []
        subdirs = []
        for resfile in dep_files[:]:
            resbasename = os.path.basename(resfile)
            for dep in dependencies:
                if isinstance(dep, mesonlib.File):
                    if dep.fname != resbasename:
                        continue
                    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:
                        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(
                        'Resource "%s" listed in "%s" was not found. If this is a '
                        'generated file, pass the target that generates it to '
                        'gnome.compile_resources() using the "dependencies" '
                        'keyword argument.' % (resfile, input_file))
                dep_files.remove(resfile)
                dep_files.append(f)
        return dep_files, depends, subdirs

    def _get_link_args(self, state, lib, depends, include_rpath=False,
                       use_gir_args=False):
        link_command = []
        # 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)
            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

    def _get_dependencies_flags(self, deps, state, depends, include_rpath=False,
                                use_gir_args=False, separate_nodedup=False):
        cflags = OrderedSet()
        internal_ldflags = OrderedSet()
        external_ldflags = OrderedSet()
        # External linker flags that can't be de-duped reliably because they
        # require two args in order, such as -framework AVFoundation
        external_ldflags_nodedup = []
        gi_includes = OrderedSet()
        deps = mesonlib.listify(deps)

        for dep in deps:
            if isinstance(dep, Dependency):
                girdir = dep.get_variable(pkgconfig='girdir', internal='girdir', default_value='')
                if girdir:
                    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):
                        internal_ldflags.update(self._get_link_args(state, lib, depends, include_rpath))
                        libdepflags = self._get_dependencies_flags(lib.get_external_deps(), state, depends, include_rpath,
                                                                   use_gir_args, True)
                        cflags.update(libdepflags[0])
                        internal_ldflags.update(libdepflags[1])
                        external_ldflags.update(libdepflags[2])
                        external_ldflags_nodedup += libdepflags[3]
                        gi_includes.update(libdepflags[4])
                extdepflags = self._get_dependencies_flags(dep.ext_deps, state, depends, include_rpath,
                                                           use_gir_args, True)
                cflags.update(extdepflags[0])
                internal_ldflags.update(extdepflags[1])
                external_ldflags.update(extdepflags[2])
                external_ldflags_nodedup += extdepflags[3]
                gi_includes.update(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 lib in ldflags:
                    if (os.path.isabs(lib) and
                            # For PkgConfigDependency only:
                            getattr(dep, 'is_libtool', False)):
                        lib_dir = os.path.dirname(lib)
                        external_ldflags.update(["-L%s" % lib_dir])
                        if include_rpath:
                            external_ldflags.update([f'-Wl,-rpath {lib_dir}'])
                        libname = os.path.basename(lib)
                        if libname.startswith("lib"):
                            libname = libname[3:]
                        libname = libname.split(".so")[0]
                        lib = "-l%s" % libname
                    # FIXME: Hack to avoid passing some compiler options in
                    if lib.startswith("-W"):
                        continue
                    # If it's a framework arg, slurp the framework name too
                    # to preserve the order of arguments
                    if lib == '-framework':
                        external_ldflags_nodedup += [lib, next(ldflags)]
                    else:
                        external_ldflags.update([lib])
            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):
                fixed_ldflags = OrderedSet()
                for ldflag in ldflags:
                    if 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)
        if not separate_nodedup:
            external_ldflags.update(external_ldflags_nodedup)
            return cflags, internal_ldflags, external_ldflags, gi_includes
        else:
            return cflags, internal_ldflags, external_ldflags, external_ldflags_nodedup, gi_includes

    def _unwrap_gir_target(self, girtarget, state):
        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_append(self, varname: str, value: str) -> None:
        if self.devenv is None:
            self.devenv = build.EnvironmentVariables()
            self.interpreter.build.devenv.append(self.devenv)
        self.devenv.append(varname, [value])

    def _get_gir_dep(self, state):
        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) -> 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, e = Popen_safe(exe.get_command() + ['--help'], stderr=subprocess.STDOUT)
        return p.returncode == 0 and option in o

    def _scan_header(self, kwargs):
        ret = []
        header = kwargs.pop('header', None)
        if header:
            if not isinstance(header, str):
                raise MesonException('header must be a string')
            ret = ['--c-include=' + header]
        return ret

    def _scan_extra_args(self, kwargs):
        return mesonlib.stringlistify(kwargs.pop('extra_args', []))

    def _scan_link_withs(self, state, depends, kwargs):
        ret = []
        if 'link_with' in kwargs:
            link_with = mesonlib.extract_as_list(kwargs, 'link_with', pop = True)

            for link in link_with:
                ret += self._get_link_args(state, link, depends,
                                           use_gir_args=True)
        return ret

    # May mutate depends and gir_inc_dirs
    def _scan_include(self, state, depends, gir_inc_dirs, kwargs):
        ret = []

        if 'includes' in kwargs:
            includes = mesonlib.extract_as_list(kwargs, 'includes', pop = True)
            for inc in includes:
                if isinstance(inc, str):
                    ret += [f'--include={inc}']
                elif isinstance(inc, GirTarget):
                    gir_inc_dirs += [
                        os.path.join(state.environment.get_build_dir(),
                                     inc.get_subdir()),
                    ]
                    ret += [
                        "--include-uninstalled={}".format(os.path.join(inc.get_subdir(), inc.get_basename()))
                    ]
                    depends += [inc]
                else:
                    raise MesonException(
                        'Gir includes must be str, GirTarget, or list of them. '
                        'Got %s.' % type(inc).__name__)

        return ret

    def _scan_symbol_prefix(self, kwargs):
        ret = []

        if 'symbol_prefix' in kwargs:
            sym_prefixes = mesonlib.stringlistify(kwargs.pop('symbol_prefix', []))
            ret += ['--symbol-prefix=%s' % sym_prefix for sym_prefix in sym_prefixes]

        return ret

    def _scan_identifier_prefix(self, kwargs):
        ret = []

        if 'identifier_prefix' in kwargs:
            identifier_prefix = kwargs.pop('identifier_prefix')
            if not isinstance(identifier_prefix, str):
                raise MesonException('Gir identifier prefix must be str')
            ret += ['--identifier-prefix=%s' % identifier_prefix]

        return ret

    def _scan_export_packages(self, kwargs):
        ret = []

        if 'export_packages' in kwargs:
            pkgs = kwargs.pop('export_packages')
            if isinstance(pkgs, str):
                ret += ['--pkg-export=%s' % pkgs]
            elif isinstance(pkgs, list):
                ret += ['--pkg-export=%s' % pkg for pkg in pkgs]
            else:
                raise MesonException('Gir export packages must be str or list')

        return ret

    def _scan_inc_dirs(self, kwargs):
        ret = mesonlib.extract_as_list(kwargs, 'include_directories', pop = True)
        for incd in ret:
            if not isinstance(incd, (str, build.IncludeDirs)):
                raise MesonException(
                    'Gir include dirs should be include_directories().')
        return ret

    def _scan_langs(self, state, langs):
        ret = []

        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

    def _scan_gir_targets(self, state, girtargets):
        ret = []

        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

    def _get_girtargets_langs_compilers(self, girtargets: T.List[GirTarget]) -> 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

    def _get_gir_targets_deps(self, girtargets):
        ret = []
        for girtarget in girtargets:
            ret += girtarget.get_all_link_deps()
            ret += girtarget.get_external_deps()
        return ret

    def _get_gir_targets_inc_dirs(self, girtargets):
        ret = []
        for girtarget in girtargets:
            ret += girtarget.get_include_dirs()
        return ret

    def _get_langs_compilers_flags(self, state, langs_compilers: T.List[T.Tuple[str, 'Compiler']]):
        cflags = []
        internal_ldflags = []
        external_ldflags = []

        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

    def _make_gir_filelist(self, state, srcdir, ns, nsversion, girtargets, libsources):
        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

    def _make_gir_target(self, state, girfile, scan_command, generated_files, depends, kwargs):
        scankwargs = {'input': generated_files,
                      'output': girfile,
                      'command': scan_command,
                      'depends': depends}

        if 'install' in kwargs:
            scankwargs['install'] = kwargs['install']
            scankwargs['install_dir'] = kwargs.get('install_dir_gir',
                                                   os.path.join(state.environment.get_datadir(), 'gir-1.0'))
            scankwargs['install_tag'] = 'devel'

        if 'build_by_default' in kwargs:
            scankwargs['build_by_default'] = kwargs['build_by_default']

        return GirTarget(girfile, state.subdir, state.subproject, scankwargs)

    def _make_typelib_target(self, state, typelib_output, typelib_cmd, generated_files, kwargs):
        typelib_kwargs = {
            'input': generated_files,
            'output': typelib_output,
            'command': typelib_cmd,
        }

        if 'install' in kwargs:
            typelib_kwargs['install'] = kwargs['install']
            typelib_kwargs['install_dir'] = kwargs.get('install_dir_typelib',
                                                       os.path.join(state.environment.get_libdir(), 'girepository-1.0'))
            typelib_kwargs['install_tag'] = 'typelib'

        if 'build_by_default' in kwargs:
            typelib_kwargs['build_by_default'] = kwargs['build_by_default']

        return TypelibTarget(typelib_output, state.subdir, state.subproject, typelib_kwargs)

    # May mutate depends
    def _gather_typelib_includes_and_update_depends(self, state, deps, depends):
        # 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 = []
        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:
                        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 source in dep.generated:
                    if isinstance(source, GirTarget):
                        subdir = os.path.join(state.environment.get_build_dir(),
                                              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='')
                if girdir and girdir not in typelib_includes:
                    typelib_includes.append(girdir)
        return typelib_includes

    def _get_external_args_for_langs(self, state, langs):
        ret = []
        for lang in langs:
            ret += state.environment.coredata.get_external_args(MachineChoice.HOST, lang)
        return ret

    @staticmethod
    def _get_scanner_cflags(cflags):
        'g-ir-scanner only accepts -I/-D/-U; must ignore all other flags'
        for f in cflags:
            if f.startswith(('-D', '-U', '-I')):
                yield f

    @staticmethod
    def _get_scanner_ldflags(ldflags):
        '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

    @FeatureNewKwargs('generate_gir', '0.55.0', ['fatal_warnings'])
    @FeatureNewKwargs('generate_gir', '0.40.0', ['build_by_default'])
    @permittedKwargs({'sources', 'nsversion', 'namespace', 'symbol_prefix', 'identifier_prefix',
                      'export_packages', 'includes', 'dependencies', 'link_with', 'include_directories',
                      'install', 'install_dir_gir', 'install_dir_typelib', 'extra_args',
                      'packages', 'header', 'build_by_default', 'fatal_warnings'})
    def generate_gir(self, state, args, kwargs: T.Dict[str, T.Any]):
        if not args:
            raise MesonException('generate_gir takes at least one argument')
        if kwargs.get('install_dir'):
            raise MesonException('install_dir is not supported with generate_gir(), see "install_dir_gir" and "install_dir_typelib"')

        girtargets = [self._unwrap_gir_target(arg, state) for arg in args]

        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.get('namespace')
        if not ns:
            raise MesonException('Missing "namespace" keyword argument')
        nsversion = kwargs.get('nsversion')
        if not nsversion:
            raise MesonException('Missing "nsversion" keyword argument')
        libsources = mesonlib.extract_as_list(kwargs, 'sources', pop=True)
        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 = gir_dep.sources + girtargets
        gir_inc_dirs = []
        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 += extract_as_list(kwargs, 'dependencies', pop=True)
        deps += [gir_dep]
        typelib_includes = 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 = \
            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 = self._scan_inc_dirs(kwargs)

        scan_command = [giscanner]
        scan_command += ['--no-libtool']
        scan_command += ['--namespace=' + ns, '--nsversion=' + nsversion]
        scan_command += ['--warn-all']
        scan_command += ['--output', '@OUTPUT@']
        scan_command += self._scan_header(kwargs)
        scan_command += self._scan_extra_args(kwargs)
        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)]
        scan_command += self._scan_link_withs(state, depends, kwargs)
        scan_command += self._scan_include(state, depends, gir_inc_dirs, kwargs)
        scan_command += self._scan_symbol_prefix(kwargs)
        scan_command += self._scan_identifier_prefix(kwargs)
        scan_command += self._scan_export_packages(kwargs)
        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(list(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:
            mlog.deprecation('Passing --warn-error is deprecated in favor of "fatal_warnings" keyword argument since v0.55')
        fatal_warnings = kwargs.get('fatal_warnings', False)
        if not isinstance(fatal_warnings, bool):
            raise MesonException('fatal_warnings keyword argument must be a boolean')
        if 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, 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, kwargs)

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

        rv = [scan_target, typelib_target]

        return ModuleReturnValue(rv, rv)

    @FeatureNewKwargs('build target', '0.40.0', ['build_by_default'])
    @permittedKwargs({'build_by_default', 'depend_files'})
    def compile_schemas(self, state, args, kwargs):
        if args:
            raise MesonException('Compile_schemas does not take positional arguments.')
        srcdir = os.path.join(state.build_to_src, state.subdir)
        outdir = state.subdir

        cmd = [state.find_program('glib-compile-schemas')]
        cmd += ['--targetdir', outdir, srcdir]
        kwargs['command'] = cmd
        kwargs['input'] = []
        kwargs['output'] = 'gschemas.compiled'
        if state.subdir == '':
            targetname = 'gsettings-compile'
        else:
            targetname = 'gsettings-compile-' + state.subdir.replace('/', '_')
        target_g = build.CustomTarget(targetname, state.subdir, state.subproject, kwargs)
        self._devenv_append('GSETTINGS_SCHEMA_DIR', os.path.join(state.environment.get_build_dir(), state.subdir))
        return ModuleReturnValue(target_g, [target_g])

    @permittedKwargs({'sources', 'media', 'symlink_media', 'languages'})
    @FeatureDeprecatedKwargs('gnome.yelp', '0.43.0', ['languages'],
                             'Use a LINGUAS file in the source directory instead')
    def yelp(self, state, args, kwargs):
        if len(args) < 1:
            raise MesonException('Yelp requires a project id')

        project_id = args[0]
        sources = mesonlib.stringlistify(kwargs.pop('sources', []))
        if not sources:
            if len(args) > 1:
                sources = mesonlib.stringlistify(args[1:])
            if not sources:
                raise MesonException('Yelp requires a list of sources')
        source_str = '@@'.join(sources)

        langs = mesonlib.stringlistify(kwargs.pop('languages', []))
        media = mesonlib.stringlistify(kwargs.pop('media', []))
        symlinks = kwargs.pop('symlink_media', True)

        if not isinstance(symlinks, bool):
            raise MesonException('symlink_media must be a boolean')

        if kwargs:
            raise MesonException('Unknown arguments passed: {}'.format(', '.join(kwargs.keys())))

        script = state.environment.get_build_command()
        args = ['--internal',
                'yelphelper',
                'install',
                '--subdir=' + state.subdir,
                '--id=' + project_id,
                '--installdir=' + os.path.join(state.environment.get_datadir(), 'help'),
                '--sources=' + source_str]
        if symlinks:
            args.append('--symlinks=true')
        if media:
            args.append('--media=' + '@@'.join(media))
        if langs:
            args.append('--langs=' + '@@'.join(langs))
        inscript = state.backend.get_executable_serialisation(script + args)

        potargs = state.environment.get_build_command() + [
            '--internal', 'yelphelper', 'pot',
            '--subdir=' + state.subdir,
            '--id=' + project_id,
            '--sources=' + source_str,
        ]
        pottarget = build.RunTarget('help-' + project_id + '-pot', potargs,
                                    [], state.subdir, state.subproject)

        poargs = state.environment.get_build_command() + [
            '--internal', 'yelphelper', 'update-po',
            '--subdir=' + state.subdir,
            '--id=' + project_id,
            '--sources=' + source_str,
            '--langs=' + '@@'.join(langs),
        ]
        potarget = build.RunTarget('help-' + project_id + '-update-po', poargs,
                                   [], state.subdir, state.subproject)

        rv = [inscript, pottarget, potarget]
        return ModuleReturnValue(None, rv)

    @FeatureNewKwargs('gnome.gtkdoc', '0.52.0', ['check'])
    @FeatureNewKwargs('gnome.gtkdoc', '0.48.0', ['c_args'])
    @FeatureNewKwargs('gnome.gtkdoc', '0.48.0', ['module_version'])
    @FeatureNewKwargs('gnome.gtkdoc', '0.37.0', ['namespace', 'mode'])
    @permittedKwargs({'main_xml', 'main_sgml', 'src_dir', 'dependencies', 'install',
                      'install_dir', 'scan_args', 'scanobjs_args', 'gobject_typesfile',
                      'fixxref_args', 'html_args', 'html_assets', 'content_files',
                      'mkdb_args', 'ignore_headers', 'include_directories',
                      'namespace', 'mode', 'expand_content_files', 'module_version',
                      'c_args', 'check'})
    def gtkdoc(self, state, args, kwargs):
        if len(args) != 1:
            raise MesonException('Gtkdoc must have one positional argument.')
        modulename = args[0]
        if not isinstance(modulename, str):
            raise MesonException('Gtkdoc arg must be string.')
        if 'src_dir' not in kwargs:
            raise MesonException('Keyword argument src_dir missing.')
        main_file = kwargs.get('main_sgml', '')
        if not isinstance(main_file, str):
            raise MesonException('Main sgml keyword argument must be a string.')
        main_xml = kwargs.get('main_xml', '')
        if not isinstance(main_xml, str):
            raise MesonException('Main xml keyword argument must be a string.')
        moduleversion = kwargs.get('module_version', '')
        if not isinstance(moduleversion, str):
            raise MesonException('Module version keyword argument must be a string.')
        if main_xml != '':
            if main_file != '':
                raise MesonException('You can only specify main_xml or main_sgml, not both.')
            main_file = main_xml
        targetname = modulename + ('-' + moduleversion if moduleversion else '') + '-doc'
        command = state.environment.get_build_command()

        namespace = kwargs.get('namespace', '')
        mode = kwargs.get('mode', 'auto')
        VALID_MODES = ('xml', 'sgml', 'none', 'auto')
        if mode not in VALID_MODES:
            raise MesonException(f'gtkdoc: Mode {mode} is not a valid mode: {VALID_MODES}')

        src_dirs = mesonlib.extract_as_list(kwargs, 'src_dir')
        header_dirs = []
        for src_dir in src_dirs:
            if isinstance(src_dir, HoldableObject):
                if not isinstance(src_dir, build.IncludeDirs):
                    raise MesonException('Invalid keyword argument for src_dir.')
                for inc_dir in src_dir.get_incdirs():
                    header_dirs.append(os.path.join(state.environment.get_source_dir(),
                                                    src_dir.get_curdir(), inc_dir))
                    header_dirs.append(os.path.join(state.environment.get_build_dir(),
                                                    src_dir.get_curdir(), inc_dir))
            else:
                header_dirs.append(src_dir)

        args = ['--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=' + mode]
        for tool in ['scan', 'scangobj', 'mkdb', 'mkhtml', 'fixxref']:
            program_name = 'gtkdoc-' + tool
            program = state.find_program(program_name)
            path = program.get_path()
            args.append(f'--{program_name}={path}')
        if namespace:
            args.append('--namespace=' + namespace)
        args += self._unpack_args('--htmlargs=', 'html_args', kwargs)
        args += self._unpack_args('--scanargs=', 'scan_args', kwargs)
        args += self._unpack_args('--scanobjsargs=', 'scanobjs_args', kwargs)
        args += self._unpack_args('--gobjects-types-file=', 'gobject_typesfile', kwargs, state)
        args += self._unpack_args('--fixxrefargs=', 'fixxref_args', kwargs)
        args += self._unpack_args('--mkdbargs=', 'mkdb_args', kwargs)
        args += self._unpack_args('--html-assets=', 'html_assets', kwargs, state)

        depends = []
        content_files = []
        for s in mesonlib.extract_as_list(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))
            elif isinstance(s, str):
                content_files.append(os.path.join(state.environment.get_source_dir(),
                                                  state.subdir,
                                                  s))
            else:
                raise MesonException(
                    f'Invalid object type: {s.__class__.__name__!r}')
        args += ['--content-files=' + '@@'.join(content_files)]

        args += self._unpack_args('--expand-content-files=', 'expand_content_files', kwargs, state)
        args += self._unpack_args('--ignore-headers=', 'ignore_headers', kwargs)
        args += self._unpack_args('--installdir=', 'install_dir', kwargs)
        args += self._get_build_args(kwargs, state, depends)
        custom_kwargs = {'output': modulename + '-decl.txt',
                         'command': command + args,
                         'depends': depends,
                         'build_always_stale': True,
                         }
        custom_target = build.CustomTarget(targetname, state.subdir, state.subproject, custom_kwargs)
        alias_target = build.AliasTarget(targetname, [custom_target], state.subdir, state.subproject)
        if kwargs.get('check', False):
            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 = [custom_target, alias_target]
        if kwargs.get('install', True):
            res.append(state.backend.get_executable_serialisation(command + args, tag='doc'))
        return ModuleReturnValue(custom_target, res)

    def _get_build_args(self, kwargs, state, depends):
        args = []
        deps = extract_as_list(kwargs, 'dependencies')
        cflags = []
        cflags.extend(mesonlib.stringlistify(kwargs.pop('c_args', [])))
        deps_cflags, internal_ldflags, external_ldflags, gi_includes = \
            self._get_dependencies_flags(deps, state, depends, include_rpath=True)
        inc_dirs = mesonlib.extract_as_list(kwargs, 'include_directories')
        for incd in inc_dirs:
            if not isinstance(incd, (str, build.IncludeDirs)):
                raise MesonException(
                    'Gir include dirs should be include_directories().')

        cflags.extend(deps_cflags)
        cflags.extend(state.get_include_args(inc_dirs))
        ldflags = []
        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

    @noKwargs
    def gtkdoc_html_dir(self, state, args, kwargs):
        if len(args) != 1:
            raise MesonException('Must have exactly one argument.')
        modulename = args[0]
        if not isinstance(modulename, str):
            raise MesonException('Argument must be a string')
        return os.path.join('share/gtk-doc/html', modulename)

    @staticmethod
    def _unpack_args(arg, kwarg_name, kwargs, expend_file_state=None):
        if kwarg_name not in kwargs:
            return []

        new_args = mesonlib.extract_as_list(kwargs, kwarg_name)
        args = []
        for i in new_args:
            if expend_file_state and isinstance(i, mesonlib.File):
                i = i.absolute_path(expend_file_state.environment.get_source_dir(), expend_file_state.environment.get_build_dir())
            elif expend_file_state and isinstance(i, str):
                i = os.path.join(expend_file_state.environment.get_source_dir(), expend_file_state.subdir, i)
            elif not isinstance(i, str):
                raise MesonException(kwarg_name + ' values must be strings.')
            args.append(i)

        if args:
            return [arg + '@@'.join(args)]

        return []

    def _get_autocleanup_args(self, kwargs, glib_version):
        if not mesonlib.version_compare(glib_version, '>= 2.49.1'):
            # Warn if requested, silently disable if not
            if 'autocleanup' in kwargs:
                mlog.warning('Glib version ({}) is too old to support the \'autocleanup\' '
                             'kwarg, need 2.49.1 or newer'.format(glib_version))
            return []
        autocleanup = kwargs.pop('autocleanup', 'all')
        values = ('none', 'objects', 'all')
        if autocleanup not in values:
            raise MesonException('gdbus_codegen does not support {!r} as an autocleanup value, '
                                 'must be one of: {!r}'.format(autocleanup, ', '.join(values)))
        return ['--c-generate-autocleanup', autocleanup]

    @FeatureNewKwargs('build target', '0.46.0', ['install_header', 'install_dir', 'sources'])
    @FeatureNewKwargs('build target', '0.40.0', ['build_by_default'])
    @FeatureNewKwargs('build target', '0.47.0', ['extra_args', 'autocleanup'])
    @permittedKwargs({'interface_prefix', 'namespace', 'extra_args', 'autocleanup', 'object_manager', 'build_by_default',
                      'annotations', 'docbook', 'install_header', 'install_dir', 'sources'})
    def gdbus_codegen(self, state, args, kwargs):
        if len(args) not in (1, 2):
            raise MesonException('gdbus_codegen takes at most two arguments, name and xml file.')
        namebase = args[0]
        xml_files = args[1:]
        cmd = [state.find_program('gdbus-codegen')]
        extra_args = mesonlib.stringlistify(kwargs.pop('extra_args', []))
        cmd += extra_args
        # Autocleanup supported?
        glib_version = self._get_native_glib_version(state)
        cmd += self._get_autocleanup_args(kwargs, glib_version)
        if 'interface_prefix' in kwargs:
            cmd += ['--interface-prefix', kwargs.pop('interface_prefix')]
        if 'namespace' in kwargs:
            cmd += ['--c-namespace', kwargs.pop('namespace')]
        if kwargs.get('object_manager', False):
            cmd += ['--c-generate-object-manager']
        if 'sources' in kwargs:
            xml_files += mesonlib.listify(kwargs.pop('sources'))
        build_by_default = kwargs.get('build_by_default', False)

        # Annotations are a bit ugly in that they are a list of lists of strings...
        annotations = kwargs.pop('annotations', [])
        if not isinstance(annotations, list):
            raise MesonException('annotations takes a list')
        if annotations and isinstance(annotations, list) and not isinstance(annotations[0], list):
            annotations = [annotations]

        for annotation in annotations:
            if len(annotation) != 3 or not all(isinstance(i, str) for i in annotation):
                raise MesonException('Annotations must be made up of 3 strings for ELEMENT, KEY, and VALUE')
            cmd += ['--annotate'] + annotation

        targets = []
        install_header = kwargs.get('install_header', False)
        install_dir = kwargs.get('install_dir', state.environment.coredata.get_option(mesonlib.OptionKey('includedir')))

        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'):
            custom_kwargs = {'input': xml_files,
                             'output': output,
                             'command': cmd + ['--body', '--output', '@OUTPUT@', '@INPUT@'],
                             'build_by_default': build_by_default
                             }
        else:
            if 'docbook' in kwargs:
                docbook = kwargs['docbook']
                if not isinstance(docbook, str):
                    raise MesonException('docbook value must be a string.')

                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@']

            custom_kwargs = {'input': xml_files,
                             'output': output,
                             'command': cmd,
                             'build_by_default': build_by_default
                             }

        cfile_custom_target = build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs)
        targets.append(cfile_custom_target)

        output = namebase + '.h'
        if mesonlib.version_compare(glib_version, '>= 2.56.2'):
            custom_kwargs = {'input': xml_files,
                             'output': output,
                             'command': cmd + ['--header', '--output', '@OUTPUT@', '@INPUT@'],
                             'build_by_default': build_by_default,
                             'install': install_header,
                             'install_dir': install_dir
                             }
        else:
            custom_kwargs = {'input': xml_files,
                             'output': output,
                             'command': cmd,
                             'build_by_default': build_by_default,
                             'install': install_header,
                             'install_dir': install_dir,
                             'depends': cfile_custom_target
                             }

        hfile_custom_target = build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs)
        targets.append(hfile_custom_target)

        if 'docbook' in kwargs:
            docbook = kwargs['docbook']
            if not isinstance(docbook, str):
                raise MesonException('docbook value must be a string.')

            docbook_cmd = cmd + ['--output-directory', '@OUTDIR@', '--generate-docbook', docbook, '@INPUT@']

            # 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'):
                custom_kwargs = {'input': xml_files,
                                 'output': outputs,
                                 'command': docbook_cmd,
                                 'build_by_default': build_by_default
                                 }
            else:
                custom_kwargs = {'input': xml_files,
                                 'output': outputs,
                                 'command': cmd,
                                 'build_by_default': build_by_default,
                                 'depends': cfile_custom_target
                                 }

            docbook_custom_target = build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs)
            targets.append(docbook_custom_target)

        return ModuleReturnValue(targets, targets)

    @permittedKwargs({'sources', 'c_template', 'h_template', 'install_header', 'install_dir',
                      'comments', 'identifier_prefix', 'symbol_prefix', 'eprod', 'vprod',
                      'fhead', 'fprod', 'ftail', 'vhead', 'vtail', 'depends'})
    def mkenums(self, state, args, kwargs):
        if len(args) != 1:
            raise MesonException('Mkenums requires one positional argument.')
        basename = args[0]

        if 'sources' not in kwargs:
            raise MesonException('Missing keyword argument "sources".')
        sources = kwargs.pop('sources')
        if isinstance(sources, str):
            sources = [sources]
        elif not isinstance(sources, list):
            raise MesonException(
                'Sources keyword argument must be a string or array.')

        cmd = []
        known_kwargs = ['comments', 'eprod', 'fhead', 'fprod', 'ftail',
                        'identifier_prefix', 'symbol_prefix', 'template',
                        'vhead', 'vprod', 'vtail']
        known_custom_target_kwargs = ['install_dir', 'build_always',
                                      'depends', 'depend_files']
        c_template = h_template = None
        install_header = False
        for arg, value in kwargs.items():
            if arg == 'sources':
                raise AssertionError("sources should've already been handled")
            elif arg == 'c_template':
                c_template = value
                if isinstance(c_template, mesonlib.File):
                    c_template = c_template.absolute_path(state.environment.source_dir, state.environment.build_dir)
                if 'template' in kwargs:
                    raise MesonException('Mkenums does not accept both '
                                         'c_template and template keyword '
                                         'arguments at the same time.')
            elif arg == 'h_template':
                h_template = value
                if isinstance(h_template, mesonlib.File):
                    h_template = h_template.absolute_path(state.environment.source_dir, state.environment.build_dir)
                if 'template' in kwargs:
                    raise MesonException('Mkenums does not accept both '
                                         'h_template and template keyword '
                                         'arguments at the same time.')
            elif arg == 'install_header':
                install_header = value
            elif arg in known_kwargs:
                cmd += ['--' + arg.replace('_', '-'), value]
            elif arg not in known_custom_target_kwargs:
                raise MesonException(
                    f'Mkenums does not take a {arg} keyword argument.')
        cmd = [state.find_program(['glib-mkenums', 'mkenums'])] + cmd
        custom_kwargs = {}
        for arg in known_custom_target_kwargs:
            if arg in kwargs:
                custom_kwargs[arg] = kwargs[arg]

        targets = []

        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 = [h_template] + sources
            custom_kwargs['install'] = install_header
            if 'install_dir' not in custom_kwargs:
                custom_kwargs['install_dir'] = \
                    state.environment.coredata.get_option(mesonlib.OptionKey('includedir'))
            h_target = self._make_mkenum_custom_target(state, h_sources,
                                                       h_output, h_cmd,
                                                       custom_kwargs)
            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 = [c_template] + sources
            # Never install the C file. Complain on bug tracker if you need it.
            custom_kwargs['install'] = False
            if h_template is not None:
                if 'depends' in custom_kwargs:
                    custom_kwargs['depends'] += [h_target]
                else:
                    custom_kwargs['depends'] = h_target
            c_target = self._make_mkenum_custom_target(state, c_sources,
                                                       c_output, c_cmd,
                                                       custom_kwargs)
            targets.insert(0, c_target)

        if c_template is None and h_template is None:
            generic_cmd = cmd + ['@INPUT@']
            custom_kwargs['install'] = install_header
            if 'install_dir' not in custom_kwargs:
                custom_kwargs['install_dir'] = \
                    state.environment.coredata.get_option(mesonlib.OptionKey('includedir'))
            target = self._make_mkenum_custom_target(state, sources, basename,
                                                     generic_cmd, custom_kwargs)
            return ModuleReturnValue(target, [target])
        elif len(targets) == 1:
            return ModuleReturnValue(targets[0], [targets[0]])
        else:
            return ModuleReturnValue(targets, targets)

    @FeatureNew('gnome.mkenums_simple', '0.42.0')
    def mkenums_simple(self, state, args, kwargs):
        hdr_filename = args[0] + '.h'
        body_filename = args[0] + '.c'

        # not really needed, just for sanity checking
        forbidden_kwargs = ['c_template', 'h_template', 'eprod', 'fhead',
                            'fprod', 'ftail', 'vhead', 'vtail', 'comments']
        for arg in forbidden_kwargs:
            if arg in kwargs:
                raise MesonException(f'mkenums_simple() does not take a {arg} keyword argument')

        # kwargs to pass as-is from mkenums_simple() to mkenums()
        shared_kwargs = ['sources', 'install_header', 'install_dir',
                         'identifier_prefix', 'symbol_prefix']
        mkenums_kwargs = {}
        for arg in shared_kwargs:
            if arg in kwargs:
                mkenums_kwargs[arg] = kwargs[arg]

        # .c file generation
        c_file_kwargs = copy.deepcopy(mkenums_kwargs)
        if 'sources' not in kwargs:
            raise MesonException('Missing keyword argument "sources".')
        sources = kwargs['sources']
        if isinstance(sources, str):
            sources = [sources]
        elif not isinstance(sources, list):
            raise MesonException(
                'Sources keyword argument must be a string or array.')

        # The `install_header` argument will be used by mkenums() when
        # not using template files, so we need to forcibly unset it
        # when generating the C source file, otherwise we will end up
        # installing it
        c_file_kwargs['install_header'] = False

        header_prefix = kwargs.get('header_prefix', '')
        decl_decorator = kwargs.get('decorator', '')
        func_prefix = kwargs.get('function_prefix', '')
        body_prefix = kwargs.get('body_prefix', '')

        # 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 sources:
            fhead += '#include "%s"\n' % os.path.basename(str(hdr))
        fhead += '''
#define C_ENUM(v) ((gint) v)
#define C_FLAGS(v) ((guint) v)
'''
        c_file_kwargs['fhead'] = fhead

        c_file_kwargs['fprod'] = '''
/* enumerations from "@basename@" */
'''

        c_file_kwargs['vhead'] = '''
GType
%s@enum_name@_get_type (void)
{
  static gsize gtype_id = 0;
  static const G@Type@Value values[] = {''' % func_prefix

        c_file_kwargs['vprod'] = '    { C_@TYPE@(@VALUENAME@), "@VALUENAME@", "@valuenick@" },'

        c_file_kwargs['vtail'] = '''    { 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;
}'''

        rv = self.mkenums(state, [body_filename], c_file_kwargs)
        c_file = rv.return_value

        # .h file generation
        h_file_kwargs = copy.deepcopy(mkenums_kwargs)

        h_file_kwargs['fhead'] = '''#pragma once

#include <glib-object.h>
{}

G_BEGIN_DECLS
'''.format(header_prefix)

        h_file_kwargs['fprod'] = '''
/* enumerations from "@basename@" */
'''

        h_file_kwargs['vhead'] = '''
{}
GType {}@enum_name@_get_type (void);
#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ ({}@enum_name@_get_type())'''.format(decl_decorator, func_prefix, func_prefix)

        h_file_kwargs['ftail'] = '''
G_END_DECLS'''

        rv = self.mkenums(state, [hdr_filename], h_file_kwargs)
        h_file = rv.return_value

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

    @staticmethod
    def _make_mkenum_custom_target(state, sources, output, cmd, kwargs):
        custom_kwargs = {
            'input': sources,
            'output': output,
            'capture': True,
            'command': cmd
        }
        custom_kwargs.update(kwargs)
        return build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs,
                                  # https://github.com/mesonbuild/meson/issues/973
                                  absolute_paths=True)

    @permittedKwargs({'sources', 'prefix', 'install_header', 'install_dir', 'stdinc',
                      'nostdinc', 'internal', 'skip_source', 'valist_marshallers',
                      'extra_args'})
    def genmarshal(self, state, args, kwargs):
        if len(args) != 1:
            raise MesonException(
                'Genmarshal requires one positional argument.')
        output = args[0]

        if 'sources' not in kwargs:
            raise MesonException('Missing keyword argument "sources".')
        sources = kwargs.pop('sources')
        if isinstance(sources, str):
            sources = [sources]
        elif not isinstance(sources, list):
            raise MesonException(
                'Sources keyword argument must be a string or array.')

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

        cmd = [state.find_program('glib-genmarshal')]
        known_kwargs = ['internal', 'nostdinc', 'skip_source', 'stdinc',
                        'valist_marshallers', 'extra_args']
        known_custom_target_kwargs = ['build_always', 'depends',
                                      'depend_files', 'install_dir',
                                      'install_header']
        for arg, value in kwargs.items():
            if arg == 'prefix':
                cmd += ['--prefix', value]
            elif arg == 'extra_args':
                if new_genmarshal:
                    cmd += mesonlib.stringlistify(value)
                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'))
            elif arg in known_kwargs and value:
                cmd += ['--' + arg.replace('_', '-')]
            elif arg not in known_custom_target_kwargs:
                raise MesonException(
                    'Genmarshal does not take a {} keyword argument.'.format(
                        arg))

        install_header = kwargs.pop('install_header', False)
        install_dir = kwargs.pop('install_dir', None)

        custom_kwargs = {
            'input': sources,
        }

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

        for arg in known_custom_target_kwargs:
            if arg in kwargs:
                custom_kwargs[arg] = kwargs[arg]

        header_file = output + '.h'
        custom_kwargs['command'] = cmd + ['--body', '@INPUT@']
        if mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.53.4'):
            # Silence any warnings about missing prototypes
            custom_kwargs['command'] += ['--include-header', header_file]
        custom_kwargs['output'] = output + '.c'
        body = build.CustomTarget(output + '_c', state.subdir, state.subproject, custom_kwargs)

        custom_kwargs['install'] = install_header
        if install_dir is not None:
            custom_kwargs['install_dir'] = install_dir
        if new_genmarshal:
            cmd += ['--pragma-once']
        custom_kwargs['command'] = cmd + ['--header', '@INPUT@']
        custom_kwargs['output'] = header_file
        header = build.CustomTarget(output + '_h', state.subdir, state.subproject, custom_kwargs)

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

    @staticmethod
    def _vapi_args_to_command(prefix, variable, kwargs, accept_vapi=False):
        arg_list = mesonlib.extract_as_list(kwargs, variable)
        ret = []
        for arg in arg_list:
            if not isinstance(arg, str):
                types = 'strings' + ' or InternalDependencys' if accept_vapi else ''
                raise MesonException(f'All {variable} must be {types}')
            ret.append(prefix + arg)
        return ret

    def _extract_vapi_packages(self, state, kwargs):
        '''
        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
        '''
        arg_list = kwargs.get('packages')
        if not arg_list:
            return [], [], [], []
        arg_list = mesonlib.listify(arg_list)
        vapi_depends = []
        vapi_packages = []
        vapi_includes = []
        ret = []
        remaining_args = []
        for arg in arg_list:
            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
                    ret.append('--vapidir=' + outdir)
                    ret.append('--girdir=' + outdir)
                    ret.append('--pkg=' + outfile)
                    vapi_depends.append(target)
                    vapi_packages.append(outfile)
                    vapi_includes.append(srcdir)
            else:
                vapi_packages.append(arg)
                remaining_args.append(arg)

        kwargs['packages'] = remaining_args
        vapi_args = ret + self._vapi_args_to_command('--pkg=', 'packages', kwargs, accept_vapi=True)
        return vapi_args, vapi_depends, vapi_packages, vapi_includes

    def _generate_deps(self, state, library, packages, install_dir):
        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, None, state.subproject)

    def _get_vapi_link_with(self, target):
        link_with = []
        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

    @permittedKwargs({'sources', 'packages', 'metadata_dirs', 'gir_dirs',
                      'vapi_dirs', 'install', 'install_dir'})
    def generate_vapi(self, state, args, kwargs):
        if len(args) != 1:
            raise MesonException('The library name is required')

        if not isinstance(args[0], str):
            raise MesonException('The first argument must be the name of the library')
        created_values = []

        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 = self._extract_vapi_packages(state, kwargs)
        if 'VAPIGEN' in os.environ:
            cmd = [state.find_program(os.environ['VAPIGEN'])]
        else:
            cmd = [state.find_program('vapigen')]
        cmd += ['--quiet', '--library=' + library, '--directory=' + build_dir]
        cmd += self._vapi_args_to_command('--vapidir=', 'vapi_dirs', kwargs)
        cmd += self._vapi_args_to_command('--metadatadir=', 'metadata_dirs', kwargs)
        cmd += self._vapi_args_to_command('--girdir=', 'gir_dirs', kwargs)
        cmd += pkg_cmd
        cmd += ['--metadatadir=' + source_dir]

        if 'sources' not in kwargs:
            raise MesonException('sources are required to generate the vapi file')

        inputs = mesonlib.extract_as_list(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)
            else:
                raise MesonException('Input must be a str or GirTarget')

        vapi_output = library + '.vapi'
        custom_kwargs = {
            'command': cmd,
            'input': inputs,
            'output': vapi_output,
            'depends': vapi_depends,
        }
        install_dir = kwargs.get('install_dir',
                                 os.path.join(state.environment.coredata.get_option(mesonlib.OptionKey('datadir')),
                                              'vala', 'vapi'))
        if kwargs.get('install'):
            custom_kwargs['install'] = kwargs['install']
            custom_kwargs['install_dir'] = install_dir

            # 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, custom_kwargs)

        # 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(*args, **kwargs):
    mod = GnomeModule(*args, **kwargs)
    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
