# 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

from .. import build
from .. import mlog
from .. import mesonlib
from .. import interpreter
from . import GResourceTarget, GResourceHeaderTarget, GirTarget, TypelibTarget, VapiTarget
from . import get_include_args
from . import ExtensionModule
from . import ModuleReturnValue
from ..mesonlib import (
    MachineChoice, MesonException, OrderedSet, Popen_safe, extract_as_list,
    join_args, unholder,
)
from ..dependencies import Dependency, PkgConfigDependency, InternalDependency, ExternalProgram
from ..interpreterbase import noKwargs, permittedKwargs, FeatureNew, FeatureNewKwargs, FeatureDeprecatedKwargs

# 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):
    gir_dep = None

    @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)

    @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 = self.interpreter.find_program_impl('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(unholder(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('Invalid file argument: {!r}'.format(ifile))
            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_builtin_option('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 unholder(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.unholder(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(get_include_args(dep.include_directories))
                for lib in unholder(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 unholder(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(['-Wl,-rpath {}'.format(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(get_include_args(dep.get_include_dirs()))
                depends.append(dep)
            else:
                mlog.log('dependency {!r} not handled to build gir files'.format(dep))
                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):
        while hasattr(girtarget, 'held_object'):
            girtarget = girtarget.held_object

        if not isinstance(girtarget, (build.Executable, build.SharedLibrary,
                                      build.StaticLibrary)):
            raise MesonException('Gir target must be an executable or library')

        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 _get_gir_dep(self, state):
        if not self.gir_dep:
            kwargs = {'native': True, 'required': True}
            holder = self.interpreter.func_dependency(state.current_node, ['gobject-introspection-1.0'], kwargs)
            self.gir_dep = holder.held_object
            giscanner = state.environment.lookup_binary_entry(MachineChoice.HOST, 'g-ir-scanner')
            if giscanner is not None:
                self.giscanner = ExternalProgram.from_entry('g-ir-scanner', giscanner)
            elif self.gir_dep.type_name == 'pkgconfig':
                self.giscanner = ExternalProgram('g_ir_scanner', self.gir_dep.get_pkgconfig_variable('g_ir_scanner', {}))
            else:
                self.giscanner = self.interpreter.find_program_impl('g-ir-scanner')
            gicompiler = state.environment.lookup_binary_entry(MachineChoice.HOST, 'g-ir-compiler')
            if gicompiler is not None:
                self.gicompiler = ExternalProgram.from_entry('g-ir-compiler', gicompiler)
            elif self.gir_dep.type_name == 'pkgconfig':
                self.gicompiler = ExternalProgram('g_ir_compiler', self.gir_dep.get_pkgconfig_variable('g_ir_compiler', {}))
            else:
                self.gicompiler = self.interpreter.find_program_impl('g-ir-compiler')
        return self.gir_dep, self.giscanner, self.gicompiler

    @functools.lru_cache(maxsize=None)
    def _gir_has_option(self, option):
        exe = self.giscanner
        if hasattr(exe, 'held_object'):
            exe = exe.held_object
        if isinstance(exe, interpreter.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.held_object, 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 unholder(includes):
                if isinstance(inc, str):
                    ret += ['--include=%s' % (inc, )]
                elif isinstance(inc, GirTarget):
                    gir_inc_dirs += [
                        os.path.join(state.environment.get_build_dir(),
                                     inc.get_subdir()),
                    ]
                    ret += [
                        "--include-uninstalled=%s" % (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.held_object, (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())
                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@BUILD_ROOT@/{}".format(os.path.dirname(libpath))]
                    libname = girtarget.get_basename()
                else:
                    libname = os.path.join("@BUILD_ROOT@/{}".format(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):
        ret = []
        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):
        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 'b_sanitize' in compiler.base_options:
                sanitize = state.environment.coredata.base_options['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, '%s_%s_gir_filelist' % (ns, nsversion))

        with open(gir_filelist_filename, 'w', encoding='utf-8') as gir_filelist:
            for s in unholder(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, depends, kwargs):
        scankwargs = {'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'))

        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, kwargs):
        typelib_kwargs = {
            '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'))

        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 unholder(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 unholder(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):
        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 = '%s-%s.gir' % (ns, nsversion)
        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 += mesonlib.unholder(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)
        cflags += list(self._get_scanner_cflags(dep_cflags))
        cflags += list(self._get_scanner_cflags(self._get_external_args_for_langs(state, [lc[0] for lc in langs_compilers])))
        internal_ldflags += list(self._get_scanner_ldflags(dep_internal_ldflags))
        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 += 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 += cflags
        scan_command += ['--cflags-end']
        scan_command += get_include_args(inc_dirs)
        scan_command += get_include_args(list(gi_includes) + gir_inc_dirs + inc_dirs, prefix='--add-include-path=')
        scan_command += list(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(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')

        scan_target = self._make_gir_target(state, girfile, scan_command, depends, kwargs)

        typelib_output = '%s-%s.typelib' % (ns, nsversion)
        typelib_cmd = [gicompiler, scan_target, '--output', '@OUTPUT@']
        typelib_cmd += 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, kwargs)

        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 = [self.interpreter.find_program_impl('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)
        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 = build.RunScript(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[0],
                                    potargs[1:], [], 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[0],
                                   poargs[1:], [], 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('gtkdoc: Mode {} is not a valid mode: {}'.format(mode, VALID_MODES))

        src_dirs = mesonlib.extract_as_list(kwargs, 'src_dir')
        header_dirs = []
        for src_dir in src_dirs:
            if hasattr(src_dir, 'held_object'):
                src_dir = src_dir.held_object
                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 = self.interpreter.find_program_impl(program_name)
            path = program.held_object.get_path()
            args.append('--{}={}'.format(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 unholder(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(
                    'Invalid object type: {!r}'.format(s.__class__.__name__))
        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 = self.interpreter.find_program_impl('gtkdoc-check')
            check_env = ['DOC_MODULE=' + modulename,
                         'DOC_MAIN_SGML_FILE=' + main_file]
            check_args = [targetname + '-check', check_cmd]
            check_kwargs = {'env': check_env,
                            'workdir': os.path.join(state.environment.get_build_dir(), state.subdir),
                            'depends': custom_target}
            self.interpreter.add_test(state.current_node, check_args, check_kwargs, True)
        res = [custom_target, alias_target]
        if kwargs.get('install', True):
            res.append(build.RunScript(command, args))
        return ModuleReturnValue(custom_target, res)

    def _get_build_args(self, kwargs, state, depends):
        args = []
        deps = mesonlib.unholder(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.held_object, (str, build.IncludeDirs)):
                raise MesonException(
                    'Gir include dirs should be include_directories().')

        cflags.extend(deps_cflags)
        cflags.extend(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 ModuleReturnValue(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 = [self.interpreter.find_program_impl('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_builtin_option('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(
                    'Mkenums does not take a %s keyword argument.' % (arg, ))
        cmd = [self.interpreter.find_program_impl(['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_builtin_option('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_builtin_option('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('mkenums_simple() does not take a %s keyword argument' % (arg, ))

        # 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 = [self.interpreter.find_program_impl('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 %s keyword argument.' % (
                        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('All {} must be {}'.format(variable, 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 unholder(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') as ofile:
            for package in packages:
                ofile.write(package + '\n')
        return build.Data(mesonlib.File(True, outdir, fname), install_dir)

    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 = [self.interpreter.find_program_impl(os.environ['VAPIGEN'])]
        else:
            cmd = [self.interpreter.find_program_impl('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 hasattr(i, 'held_object') and isinstance(i.held_object, GirTarget):
                link_with += self._get_vapi_link_with(i.held_object)
                subdir = os.path.join(state.environment.get_build_dir(),
                                      i.held_object.get_subdir())
                gir_file = os.path.join(subdir, i.held_object.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_builtin_option('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):
    return GnomeModule(*args, **kwargs)
