# SPDX-License-Identifier: Apache-2.0
# Copyright 2013-2021 The Meson development team

from __future__ import annotations

from pathlib import Path

from .base import ExternalDependency, DependencyException, sort_libpaths, DependencyTypeName
from ..mesonlib import (EnvironmentVariables, OrderedSet, PerMachine, Popen_safe, Popen_safe_logged, MachineChoice,
                        join_args, MesonException, path_has_root)
from ..options import OptionKey
from ..programs import find_external_program, ExternalProgram
from .. import mlog
from pathlib import PurePath
from functools import lru_cache
import re
import os
import shlex
import typing as T

if T.TYPE_CHECKING:
    from typing_extensions import Literal
    from .._typing import ImmutableListProtocol

    from ..environment import Environment
    from ..utils.core import EnvironOrDict
    from ..interpreter.type_checking import PkgConfigDefineType
    from .base import DependencyObjectKWs

class PkgConfigInterface:
    '''Base class wrapping a pkg-config implementation'''

    # keyed on machine and extra_paths
    class_impl: PerMachine[T.Dict[T.Optional[T.Tuple[str, ...]], T.Union[Literal[False], T.Optional[PkgConfigInterface]]]] = PerMachine({}, {})
    class_cli_impl: PerMachine[T.Dict[T.Optional[T.Tuple[str, ...]], T.Union[Literal[False], T.Optional[PkgConfigCLI]]]] = PerMachine({}, {})
    pkg_bin_per_machine: PerMachine[T.Optional[ExternalProgram]] = PerMachine(None, None)

    @staticmethod
    def set_program_override(pkg_bin: ExternalProgram, for_machine: MachineChoice) -> None:
        if PkgConfigInterface.class_impl[for_machine]:
            raise MesonException(f'Tried to override pkg-config for machine {for_machine} but it was already initialized.\n'
                                 'pkg-config must be overridden before it\'s used.')
        PkgConfigInterface.pkg_bin_per_machine[for_machine] = pkg_bin

    @staticmethod
    def instance(env: Environment, for_machine: MachineChoice, silent: bool,
                 extra_paths: T.Optional[T.List[str]] = None) -> T.Optional[PkgConfigInterface]:
        '''Return a pkg-config implementation singleton'''
        extra_paths_key = tuple(extra_paths) if extra_paths is not None else None
        impl = PkgConfigInterface.class_impl[for_machine].get(extra_paths_key, False)
        if impl is False:
            impl = PkgConfigCLI(env, for_machine, silent, PkgConfigInterface.pkg_bin_per_machine[for_machine], extra_paths)
            if not impl.found():
                impl = None
            if not impl and not silent:
                mlog.log('Found pkg-config:', mlog.red('NO'))
            PkgConfigInterface.class_impl[for_machine][extra_paths_key] = impl
        return impl

    @staticmethod
    def _cli(env: Environment, for_machine: MachineChoice,
             extra_paths: T.Optional[T.List[str]] = None,
             silent: bool = False) -> T.Optional[PkgConfigCLI]:
        '''Return the CLI pkg-config implementation singleton
        Even when we use another implementation internally, external tools might
        still need the CLI implementation.
        '''
        impl: T.Union[Literal[False], T.Optional[PkgConfigInterface]] # Help confused mypy
        impl = PkgConfigInterface.instance(env, for_machine, silent)
        if impl and not isinstance(impl, PkgConfigCLI):
            extra_paths_key = tuple(extra_paths) if extra_paths is not None else None
            impl = PkgConfigInterface.class_cli_impl[for_machine].get(extra_paths_key, False)
            if impl is False:
                impl = PkgConfigCLI(env, for_machine, silent, PkgConfigInterface.pkg_bin_per_machine[for_machine], extra_paths)
                if not impl.found():
                    impl = None
                PkgConfigInterface.class_cli_impl[for_machine][extra_paths_key] = impl
        return T.cast('T.Optional[PkgConfigCLI]', impl) # Trust me, mypy

    @staticmethod
    def get_env(env: Environment, for_machine: MachineChoice, uninstalled: bool = False,
                extra_paths: T.Optional[T.List[str]] = None) -> EnvironmentVariables:
        cli = PkgConfigInterface._cli(env, for_machine, extra_paths)
        return cli._get_env(uninstalled) if cli else EnvironmentVariables()

    @staticmethod
    def setup_env(environ: EnvironOrDict, env: Environment, for_machine: MachineChoice,
                  uninstalled: bool = False) -> EnvironOrDict:
        cli = PkgConfigInterface._cli(env, for_machine)
        return cli._setup_env(environ, uninstalled) if cli else environ

    def __init__(self, env: Environment, for_machine: MachineChoice) -> None:
        self.env = env
        self.for_machine = for_machine

    def found(self) -> bool:
        '''Return whether pkg-config is supported'''
        raise NotImplementedError

    def version(self, name: str) -> T.Optional[str]:
        '''Return module version or None if not found'''
        raise NotImplementedError

    def cflags(self, name: str, static: bool = False, allow_system: bool = False,
               define_variable: PkgConfigDefineType = None) -> ImmutableListProtocol[str]:
        '''Return module cflags
           @allow_system: If False, remove default system include paths
        '''
        raise NotImplementedError

    def libs(self, name: str, static: bool = False, allow_system: bool = False,
             define_variable: PkgConfigDefineType = None) -> ImmutableListProtocol[str]:
        '''Return module libs
           @static: If True, also include private libraries
           @allow_system: If False, remove default system libraries search paths
        '''
        raise NotImplementedError

    def variable(self, name: str, variable_name: str,
                 define_variable: PkgConfigDefineType) -> T.Optional[str]:
        '''Return module variable or None if variable is not defined'''
        raise NotImplementedError

    def list_all(self) -> ImmutableListProtocol[str]:
        '''Return all available pkg-config modules'''
        raise NotImplementedError

class PkgConfigCLI(PkgConfigInterface):
    '''pkg-config CLI implementation'''

    def __init__(self, env: Environment, for_machine: MachineChoice, silent: bool,
                 pkgbin: T.Optional[ExternalProgram] = None,
                 extra_paths: T.Optional[T.List[str]] = None) -> None:
        super().__init__(env, for_machine)
        self._detect_pkgbin(pkgbin)
        if self.pkgbin and not silent:
            mlog.log('Found pkg-config:', mlog.green('YES'), mlog.bold(f'({self.pkgbin.get_path()})'), mlog.blue(self.pkgbin_version))
        self.extra_paths = extra_paths or []

    def found(self) -> bool:
        return bool(self.pkgbin)

    @lru_cache(maxsize=None)
    def version(self, name: str) -> T.Optional[str]:
        mlog.debug(f'Determining dependency {name!r} with pkg-config executable {self.pkgbin.get_path()!r}')
        ret, version, _ = self._call_pkgbin(['--modversion', name])
        return version if ret == 0 else None

    @staticmethod
    def _define_variable_args(define_variable: PkgConfigDefineType) -> T.List[str]:
        ret = []
        if define_variable:
            for pair in define_variable:
                ret.append('--define-variable=' + '='.join(pair))
        return ret

    @lru_cache(maxsize=None)
    def cflags(self, name: str, static: bool = False, allow_system: bool = False,
               define_variable: PkgConfigDefineType = None) -> ImmutableListProtocol[str]:
        env = None
        if allow_system:
            env = os.environ.copy()
            env['PKG_CONFIG_ALLOW_SYSTEM_CFLAGS'] = '1'
        args: T.List[str] = []
        args += self._define_variable_args(define_variable)
        if static:
            args.append('--static')
        args += ['--cflags', name]
        ret, out, err = self._call_pkgbin(args, env=env)
        if ret != 0:
            raise DependencyException(f'Could not generate cflags for {name}:\n{err}\n')
        return self._split_args(out)

    @lru_cache(maxsize=None)
    def libs(self, name: str, static: bool = False, allow_system: bool = False,
             define_variable: PkgConfigDefineType = None) -> ImmutableListProtocol[str]:
        env = None
        if allow_system:
            env = os.environ.copy()
            env['PKG_CONFIG_ALLOW_SYSTEM_LIBS'] = '1'
        args: T.List[str] = []
        args += self._define_variable_args(define_variable)
        if static:
            args.append('--static')
        args += ['--libs', name]
        ret, out, err = self._call_pkgbin(args, env=env)
        if ret != 0:
            raise DependencyException(f'Could not generate libs for {name}:\n{err}\n')
        return self._split_args(out)

    @lru_cache(maxsize=None)
    def variable(self, name: str, variable_name: str,
                 define_variable: PkgConfigDefineType) -> T.Optional[str]:
        args: T.List[str] = []
        args += self._define_variable_args(define_variable)
        args += ['--variable=' + variable_name, name]
        ret, out, err = self._call_pkgbin(args)
        if ret != 0:
            raise DependencyException(f'Could not get variable for {name}:\n{err}\n')
        variable = out.strip()
        # pkg-config doesn't distinguish between empty and nonexistent variables
        # use the variable list to check for variable existence
        if not variable:
            ret, out, _ = self._call_pkgbin(['--print-variables', name])
            if not re.search(rf'^{variable_name}$', out, re.MULTILINE):
                return None
        mlog.debug(f'Got pkg-config variable {variable_name} : {variable}')
        return variable

    @lru_cache(maxsize=None)
    def list_all(self) -> ImmutableListProtocol[str]:
        ret, out, err = self._call_pkgbin(['--list-all'])
        if ret != 0:
            raise DependencyException(f'could not list modules:\n{err}\n')
        return [i.split(' ', 1)[0] for i in out.splitlines()]

    @staticmethod
    def _split_args(cmd: str) -> T.List[str]:
        # pkg-config paths follow Unix conventions, even on Windows; split the
        # output using shlex.split rather than mesonlib.split_args
        return shlex.split(cmd)

    def _detect_pkgbin(self, pkgbin: T.Optional[ExternalProgram] = None) -> None:
        def validate(potential_pkgbin: ExternalProgram) -> bool:
            version_if_ok = self._check_pkgconfig(potential_pkgbin)
            if version_if_ok:
                self.pkgbin = potential_pkgbin
                self.pkgbin_version = version_if_ok
                return True
            return False

        if pkgbin and validate(pkgbin):
            return

        for potential_pkgbin in find_external_program(self.env, self.for_machine, "pkg-config", "Pkg-config",
                                                      self.env.default_pkgconfig, allow_default_for_cross=False):
            if validate(potential_pkgbin):
                return
        self.pkgbin = None

    def _check_pkgconfig(self, pkgbin: ExternalProgram) -> T.Optional[str]:
        if not pkgbin.found():
            mlog.log(f'Did not find pkg-config by name {pkgbin.name!r}')
            return None
        command_as_string = ' '.join(pkgbin.get_command())
        try:
            helptext = Popen_safe(pkgbin.get_command() + ['--help'])[1]
            if 'Pure-Perl' in helptext:
                mlog.log(f'Found pkg-config {command_as_string!r} but it is Strawberry Perl and thus broken. Ignoring...')
                return None
            p, out = Popen_safe(pkgbin.get_command() + ['--version'])[0:2]
            if p.returncode != 0:
                mlog.warning(f'Found pkg-config {command_as_string!r} but it failed when ran')
                return None
        except FileNotFoundError:
            mlog.warning(f'We thought we found pkg-config {command_as_string!r} but now it\'s not there. How odd!')
            return None
        except PermissionError:
            msg = f'Found pkg-config {command_as_string!r} but didn\'t have permissions to run it.'
            if not self.env.machines.build.is_windows():
                msg += '\n\nOn Unix-like systems this is often caused by scripts that are not executable.'
            mlog.warning(msg)
            return None
        return out.strip()

    def _get_env(self, uninstalled: bool = False) -> EnvironmentVariables:
        env = EnvironmentVariables()
        key = OptionKey('pkg_config_path', machine=self.for_machine)
        pathlist = self.env.coredata.optstore.get_value_for(key)
        assert isinstance(pathlist, list)
        extra_paths: T.List[str] = pathlist + self.extra_paths
        if uninstalled:
            bpath = self.env.get_build_dir()
            if bpath is not None:
                # uninstalled can only be used if a build dir exists.
                uninstalled_path = Path(bpath, 'meson-uninstalled').as_posix()
                if uninstalled_path not in extra_paths:
                    extra_paths.insert(0, uninstalled_path)
        env.set('PKG_CONFIG_PATH', extra_paths)
        sysroot = self.env.properties[self.for_machine].get_sys_root()
        if sysroot:
            env.set('PKG_CONFIG_SYSROOT_DIR', [sysroot])
        pkg_config_libdir_prop = self.env.properties[self.for_machine].get_pkg_config_libdir()
        if pkg_config_libdir_prop:
            env.set('PKG_CONFIG_LIBDIR', pkg_config_libdir_prop)
        env.set('PKG_CONFIG', [join_args(self.pkgbin.get_command())])
        return env

    def _setup_env(self, env: EnvironOrDict, uninstalled: bool = False) -> T.Dict[str, str]:
        envvars = self._get_env(uninstalled)
        env = envvars.get_env(env)
        # Dump all PKG_CONFIG environment variables
        for key, value in env.items():
            if key.startswith('PKG_'):
                mlog.debug(f'env[{key}]: {value}')
        return env

    def _call_pkgbin(self, args: T.List[str], env: T.Optional[EnvironOrDict] = None) -> T.Tuple[int, str, str]:
        assert isinstance(self.pkgbin, ExternalProgram)
        env = env or os.environ
        env = self._setup_env(env)
        cmd = self.pkgbin.get_command() + args
        p, out, err = Popen_safe_logged(cmd, env=env)
        return p.returncode, out.strip(), err.strip()


class PkgConfigDependency(ExternalDependency):

    type_name = DependencyTypeName('pkgconfig')

    def __init__(self, name: str, environment: Environment, kwargs: DependencyObjectKWs,
                 extra_paths: T.Optional[T.List[str]] = None) -> None:
        super().__init__(name, environment, kwargs)
        self.is_libtool = False
        self.extra_paths = extra_paths or []
        pkgconfig = PkgConfigInterface.instance(self.env, self.for_machine, self.silent, self.extra_paths)
        if not pkgconfig:
            msg = f'Pkg-config for machine {self.for_machine} not found. Giving up.'
            if self.required:
                raise DependencyException(msg)
            mlog.debug(msg)
            return
        self.pkgconfig = pkgconfig

        version = self.pkgconfig.version(name)
        if version is None:
            return

        self.version = version
        self.is_found = True

        try:
            # Fetch cargs to be used while using this dependency
            self._set_cargs()
            # Fetch the libraries and library paths needed for using this
            self._set_libs()
        except DependencyException as e:
            mlog.warning(f"Pkg-config error with '{name}': {e}")
            if self.required:
                raise
            else:
                self.compile_args = []
                self.link_args = []
                self.is_found = False
                self.reason = e

    def __repr__(self) -> str:
        s = '<{0} {1}: {2} {3}>'
        return s.format(self.__class__.__name__, self.name, self.is_found,
                        self.version_reqs)

    def _convert_mingw_paths(self, args: ImmutableListProtocol[str]) -> T.List[str]:
        '''
        Both MSVC and native Python on Windows cannot handle MinGW-esque /c/foo
        paths so convert them to C:/foo. We cannot resolve other paths starting
        with / like /home/foo so leave them as-is so that the user gets an
        error/warning from the compiler/linker.
        '''
        if not self.env.machines.build.is_windows():
            return args.copy()
        converted = []
        for arg in args:
            pargs: T.Tuple[str, ...] = tuple()
            # Library search path
            if arg.startswith('-L/'):
                pargs = PurePath(arg[2:]).parts
                tmpl = '-L{}:/{}'
            elif arg.startswith('-I/'):
                pargs = PurePath(arg[2:]).parts
                tmpl = '-I{}:/{}'
            # Full path to library or .la file
            elif arg.startswith('/'):
                pargs = PurePath(arg).parts
                tmpl = '{}:/{}'
            elif arg.startswith(('-L', '-I')) or (len(arg) > 2 and arg[1] == ':'):
                # clean out improper '\\ ' as comes from some Windows pkg-config files
                arg = arg.replace('\\ ', ' ')
            if len(pargs) > 1 and len(pargs[1]) == 1:
                arg = tmpl.format(pargs[1], '/'.join(pargs[2:]))
            converted.append(arg)
        return converted

    def _set_cargs(self) -> None:
        allow_system = False
        if self.language == 'fortran':
            # gfortran doesn't appear to look in system paths for INCLUDE files,
            # so don't allow pkg-config to suppress -I flags for system paths
            allow_system = True
        cflags = self.pkgconfig.cflags(self.name, self.static, allow_system)
        self.compile_args = self._convert_mingw_paths(cflags)

    def _search_libs(self, libs_in: ImmutableListProtocol[str], raw_libs_in: ImmutableListProtocol[str]) -> T.Tuple[T.List[str], T.List[str]]:
        '''
        @libs_in: PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 pkg-config --libs
        @raw_libs_in: pkg-config --libs

        We always look for the file ourselves instead of depending on the
        compiler to find it with -lfoo or foo.lib (if possible) because:
        1. We want to be able to select static or shared
        2. We need the full path of the library to calculate RPATH values
        3. De-dup of libraries is easier when we have absolute paths

        Libraries that are provided by the toolchain or are not found by
        find_library() will be added with -L -l pairs.
        '''
        # Library paths should be safe to de-dup
        #
        # First, figure out what library paths to use. Originally, we were
        # doing this as part of the loop, but due to differences in the order
        # of -L values between pkg-config and pkgconf, we need to do that as
        # a separate step. See:
        # https://github.com/mesonbuild/meson/issues/3951
        # https://github.com/mesonbuild/meson/issues/4023
        #
        # Separate system and prefix paths, and ensure that prefix paths are
        # always searched first.
        prefix_libpaths: OrderedSet[str] = OrderedSet()
        # We also store this raw_link_args on the object later
        raw_link_args = self._convert_mingw_paths(raw_libs_in)
        for arg in raw_link_args:
            if arg.startswith('-L') and not arg.startswith(('-L-l', '-L-L')):
                path = arg[2:]
                if not path_has_root(path):
                    # Resolve the path as a compiler in the build directory would
                    path = os.path.join(self.env.get_build_dir(), path)
                prefix_libpaths.add(path)
        # Library paths are not always ordered in a meaningful way
        #
        # Instead of relying on pkg-config or pkgconf to provide -L flags in a
        # specific order, we reorder library paths ourselves, according to th
        # order specified in PKG_CONFIG_PATH. See:
        # https://github.com/mesonbuild/meson/issues/4271
        #
        # Only prefix_libpaths are reordered here because there should not be
        # too many system_libpaths to cause library version issues.
        pkg_config_path: T.List[str] = self.env.coredata.optstore.get_value_for(OptionKey('pkg_config_path', machine=self.for_machine)) # type: ignore[assignment]
        pkg_config_path = self._convert_mingw_paths(pkg_config_path)
        prefix_libpaths = OrderedSet(sort_libpaths(list(prefix_libpaths), pkg_config_path))
        system_libpaths: OrderedSet[str] = OrderedSet()
        full_args = self._convert_mingw_paths(libs_in)
        for arg in full_args:
            if arg.startswith(('-L-l', '-L-L')):
                # These are D language arguments, not library paths
                continue
            if arg.startswith('-L') and arg[2:] not in prefix_libpaths:
                system_libpaths.add(arg[2:])
        # Use this re-ordered path list for library resolution
        libpaths = list(prefix_libpaths) + list(system_libpaths)
        # Track -lfoo libraries to avoid duplicate work
        libs_found: OrderedSet[str] = OrderedSet()
        # Track not-found libraries to know whether to add library paths
        libs_notfound = []
        # Generate link arguments for this library
        link_args = []
        for lib in full_args:
            if lib.startswith(('-L-l', '-L-L')):
                # These are D language arguments, add them as-is
                pass
            elif lib.startswith('-L'):
                # We already handled library paths above
                continue
            elif lib.startswith('-l:'):
                # see: https://stackoverflow.com/questions/48532868/gcc-library-option-with-a-colon-llibevent-a
                # also : See the documentation of -lnamespec | --library=namespec in the linker manual
                #                     https://sourceware.org/binutils/docs-2.18/ld/Options.html

                # Don't resolve the same -l:libfoo.a argument again
                if lib in libs_found:
                    continue
                libfilename = lib[3:]
                foundname = None
                for libdir in libpaths:
                    target = os.path.join(libdir, libfilename)
                    if os.path.exists(target):
                        foundname = target
                        break
                if foundname is None:
                    if lib in libs_notfound:
                        continue
                    else:
                        mlog.warning('Library {!r} not found for dependency {!r}, may '
                                     'not be successfully linked'.format(libfilename, self.name))
                    libs_notfound.append(lib)
                else:
                    lib = foundname
            elif lib.startswith('-l'):
                # Don't resolve the same -lfoo argument again
                if lib in libs_found:
                    continue
                if self.clib_compiler:
                    # Libraries from pkg-config are trusted to be linkable, so
                    # we skip the potentially expensive link check for
                    # performance reasons.
                    args = self.clib_compiler.find_library(
                        lib[2:], libpaths, self.libtype, lib_prefix_warning=False,
                        skip_link_check=True)
                # If the project only uses a non-clib language such as D, Rust,
                # C#, Python, etc, all we can do is limp along by adding the
                # arguments as-is and then adding the libpaths at the end.
                else:
                    args = None
                if args is not None:
                    libs_found.add(lib)
                    # Replace -l arg with full path to library if available
                    # else, library is either to be ignored, or is provided by
                    # the compiler, can't be resolved, and should be used as-is
                    if args:
                        if not args[0].startswith('-l'):
                            lib = args[0]
                    else:
                        continue
                else:
                    # Library wasn't found, maybe we're looking in the wrong
                    # places or the library will be provided with LDFLAGS or
                    # LIBRARY_PATH from the environment (on macOS), and many
                    # other edge cases that we can't account for.
                    #
                    # Add all -L paths and use it as -lfoo
                    if lib in libs_notfound:
                        continue
                    if self.static:
                        mlog.warning('Static library {!r} not found for dependency {!r}, may '
                                     'not be statically linked'.format(lib[2:], self.name))
                    libs_notfound.append(lib)
            elif lib.endswith(".la"):
                shared_libname = self.extract_libtool_shlib(lib)
                shared_lib = os.path.join(os.path.dirname(lib), shared_libname)
                if not os.path.exists(shared_lib):
                    shared_lib = os.path.join(os.path.dirname(lib), ".libs", shared_libname)

                if not os.path.exists(shared_lib):
                    raise DependencyException(f'Got a libtools specific "{lib}" dependencies'
                                              'but we could not compute the actual shared'
                                              'library path')
                self.is_libtool = True
                lib = shared_lib
                if lib in link_args:
                    continue
            link_args.append(lib)
        # Add all -Lbar args if we have -lfoo args in link_args
        if libs_notfound:
            # Order of -L flags doesn't matter with ld, but it might with other
            # linkers such as MSVC, so prepend them.
            link_args = ['-L' + lp for lp in prefix_libpaths] + link_args
        return link_args, raw_link_args

    def _set_libs(self) -> None:
        # Force pkg-config to output -L fields even if they are system
        # paths so we can do manual searching with cc.find_library() later.
        libs = self.pkgconfig.libs(self.name, self.static, allow_system=True)
        # Also get the 'raw' output without -Lfoo system paths for adding -L
        # args with -lfoo when a library can't be found, and also in
        # gnome.generate_gir + gnome.gtkdoc which need -L -l arguments.
        raw_libs = self.pkgconfig.libs(self.name, self.static, allow_system=False)
        self.link_args, self.raw_link_args = self._search_libs(libs, raw_libs)

    def extract_field(self, la_file: str, fieldname: str) -> T.Optional[str]:
        with open(la_file, encoding='utf-8') as f:
            for line in f:
                arr = line.strip().split('=', 1)
                if arr[0] == fieldname:
                    return arr[1][1:-1]
        return None

    def extract_dlname_field(self, la_file: str) -> T.Optional[str]:
        return self.extract_field(la_file, 'dlname')

    def extract_libdir_field(self, la_file: str) -> T.Optional[str]:
        return self.extract_field(la_file, 'libdir')

    def extract_libtool_shlib(self, la_file: str) -> T.Optional[str]:
        '''
        Returns the path to the shared library
        corresponding to this .la file
        '''
        dlname = self.extract_dlname_field(la_file)
        if dlname is None:
            return None

        # Darwin uses absolute paths where possible; since the libtool files never
        # contain absolute paths, use the libdir field
        if self.env.machines[self.for_machine].is_darwin():
            dlbasename = os.path.basename(dlname)
            libdir = self.extract_libdir_field(la_file)
            if libdir is None:
                return dlbasename
            return os.path.join(libdir, dlbasename)
        # From the comments in extract_libtool(), older libtools had
        # a path rather than the raw dlname
        return os.path.basename(dlname)

    def get_variable(self, *, cmake: T.Optional[str] = None, pkgconfig: T.Optional[str] = None,
                     configtool: T.Optional[str] = None, internal: T.Optional[str] = None,
                     system: T.Optional[str] = None, default_value: T.Optional[str] = None,
                     pkgconfig_define: PkgConfigDefineType = None) -> str:
        if pkgconfig:
            try:
                variable = self.pkgconfig.variable(self.name, pkgconfig, pkgconfig_define)
                if variable is not None:
                    return variable
            except DependencyException:
                pass
        if default_value is not None:
            return default_value
        raise DependencyException(f'Could not get pkg-config variable and no default provided for {self!r}')
