aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/dependencies/base.py101
-rw-r--r--mesonbuild/dependencies/misc.py100
-rw-r--r--mesonbuild/dependencies/ui.py201
3 files changed, 209 insertions, 193 deletions
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 15dbd62..c34146f 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -16,6 +16,7 @@
# Custom logic for several other packages are in separate files.
import copy
+import functools
import os
import re
import stat
@@ -1279,47 +1280,79 @@ def find_external_dependency(name, env, kwargs):
raise DependencyException('Keyword "required" must be a boolean.')
if not isinstance(kwargs.get('method', ''), str):
raise DependencyException('Keyword "method" must be a string.')
- method = kwargs.get('method', '')
+ if name.lower() not in _packages_accept_language and 'language' in kwargs:
+ raise DependencyException('%s dependency does not accept "language" keyword argument' % (name, ))
+
+ # build a list of dependency methods to try
+ candidates = _build_external_dependency_list(name, env, kwargs)
+
+ pkg_exc = None
+ pkgdep = []
+ for c in candidates:
+ # try this dependency method
+ try:
+ d = c()
+ pkgdep.append(d)
+ except Exception as e:
+ mlog.debug(str(e))
+ # store the first exception we see
+ if not pkg_exc:
+ pkg_exc = e
+ else:
+ # if the dependency was found
+ if d.found():
+ return d
+
+ # otherwise, the dependency could not be found
+ if required:
+ # if exception(s) occurred, re-raise the first one (on the grounds that
+ # it came from a preferred dependency detection method)
+ if pkg_exc:
+ raise pkg_exc
+
+ # we have a list of failed ExternalDependency objects, so we can report
+ # the methods we tried to find the dependency
+ tried_methods = ','.join([d.type_name for d in pkgdep])
+ raise DependencyException('Dependency "%s" not found, tried %s' % (name, tried_methods))
+
+ # return the last failed dependency object
+ if pkgdep:
+ return pkgdep[-1]
+
+ # this should never happen
+ raise DependencyException('Dependency "%s" not found, but no dependency object to return' % (name))
+
+
+def _build_external_dependency_list(name, env, kwargs):
+ # Is there a specific dependency detector for this dependency?
lname = name.lower()
if lname in packages:
- if lname not in _packages_accept_language and 'language' in kwargs:
- raise DependencyException('%s dependency does not accept "language" keyword argument' % (lname, ))
- # Create the dependency object using a factory class method, if one
- # exists, otherwise it is just constructed directly.
+ # Create the list of dependency object constructors using a factory
+ # class method, if one exists, otherwise the list just consists of the
+ # constructor
if getattr(packages[lname], '_factory', None):
dep = packages[lname]._factory(env, kwargs)
else:
- dep = packages[lname](env, kwargs)
- if required and not dep.found():
- raise DependencyException('Dependency "%s" not found' % name)
+ dep = [functools.partial(packages[lname], env, kwargs)]
return dep
- if 'language' in kwargs:
- # Remove check when PkgConfigDependency supports language.
- raise DependencyException('%s dependency does not accept "language" keyword argument' % (lname, ))
- if 'dub' == method:
- dubdep = DubDependency(name, env, kwargs)
- if required and not dubdep.found():
- mlog.log('Dependency', mlog.bold(name), 'found:', mlog.red('NO'))
- return dubdep
- pkg_exc = None
- pkgdep = None
- try:
- pkgdep = PkgConfigDependency(name, env, kwargs)
- if pkgdep.found():
- return pkgdep
- except Exception as e:
- pkg_exc = e
+
+ candidates = []
+
+ # If it's explicitly requested, use the dub detection method (only)
+ if 'dub' == kwargs.get('method', ''):
+ candidates.append(functools.partial(DubDependency, name, env, kwargs))
+ return candidates
+ # TBD: other values of method should control what method(s) are used
+
+ # Otherwise, just use the pkgconfig dependency detector
+ candidates.append(functools.partial(PkgConfigDependency, name, env, kwargs))
+
+ # On OSX, also try framework dependency detector
if mesonlib.is_osx():
- fwdep = ExtraFrameworkDependency(name, False, None, env, None, kwargs)
- if required and not fwdep.found():
- m = 'Dependency {!r} not found, tried Extra Frameworks ' \
- 'and Pkg-Config:\n\n' + str(pkg_exc)
- raise DependencyException(m.format(name))
- return fwdep
- if pkg_exc is not None:
- raise pkg_exc
- mlog.log('Dependency', mlog.bold(name), 'found:', mlog.red('NO'))
- return pkgdep
+ candidates.append(functools.partial(ExtraFrameworkDependency, name,
+ False, None, env, None, kwargs))
+
+ return candidates
def strip_system_libdirs(environment, link_args):
diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py
index 19874fc..6076433 100644
--- a/mesonbuild/dependencies/misc.py
+++ b/mesonbuild/dependencies/misc.py
@@ -14,6 +14,7 @@
# This file contains the detection logic for miscellaneous external dependencies.
+import functools
import os
import re
import shlex
@@ -436,26 +437,21 @@ class PcapDependency(ExternalDependency):
@classmethod
def _factory(cls, environment, kwargs):
methods = cls._process_method_kw(kwargs)
+ candidates = []
+
if DependencyMethods.PKGCONFIG in methods:
- try:
- pcdep = PkgConfigDependency('pcap', environment, kwargs)
- if pcdep.found():
- return pcdep
- except Exception as e:
- mlog.debug('Pcap not found via pkgconfig. Trying next, error was:', str(e))
+ candidates.append(functools.partial(PkgConfigDependency, 'pcap', environment, kwargs))
+
if DependencyMethods.CONFIG_TOOL in methods:
- try:
- ctdep = ConfigToolDependency.factory(
- 'pcap', environment, None, kwargs, ['pcap-config'], 'pcap-config')
- if ctdep.found():
- ctdep.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
- ctdep.link_args = ctdep.get_config_value(['--libs'], 'link_args')
- ctdep.version = cls.get_pcap_lib_version(ctdep)
- return ctdep
- except Exception as e:
- mlog.debug('Pcap not found via pcap-config. Trying next, error was:', str(e))
-
- return PcapDependency(environment, kwargs)
+ candidates.append(functools.partial(ConfigToolDependency.factory,
+ 'pcap', environment, None, kwargs, ['pcap-config'], 'pcap-config'))
+# if ctdep.found():
+# ctdep.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
+# ctdep.link_args = ctdep.get_config_value(['--libs'], 'link_args')
+# ctdep.version = cls.get_pcap_lib_version(ctdep)
+# return ctdep
+
+ return candidates
@staticmethod
def get_methods():
@@ -474,32 +470,27 @@ class CupsDependency(ExternalDependency):
@classmethod
def _factory(cls, environment, kwargs):
methods = cls._process_method_kw(kwargs)
+ candidates = []
+
if DependencyMethods.PKGCONFIG in methods:
- try:
- pcdep = PkgConfigDependency('cups', environment, kwargs)
- if pcdep.found():
- return pcdep
- except Exception as e:
- mlog.debug('cups not found via pkgconfig. Trying next, error was:', str(e))
+ candidates.append(functools.partial(PkgConfigDependency, 'cups', environment, kwargs))
+
if DependencyMethods.CONFIG_TOOL in methods:
- try:
- ctdep = ConfigToolDependency.factory(
- 'cups', environment, None, kwargs, ['cups-config'], 'cups-config')
- if ctdep.found():
- ctdep.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
- ctdep.link_args = ctdep.get_config_value(['--ldflags', '--libs'], 'link_args')
- return ctdep
- except Exception as e:
- mlog.debug('cups not found via cups-config. Trying next, error was:', str(e))
+ candidates.append(functools.partial(ConfigToolDependency.factory,
+ 'cups', environment, None,
+ kwargs, ['cups-config'],
+ 'cups-config'))
+# if ctdep.found():
+# ctdep.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
+# ctdep.link_args = ctdep.get_config_value(['--ldflags', '--libs'], 'link_args')
+
if DependencyMethods.EXTRAFRAMEWORK in methods:
if mesonlib.is_osx():
- fwdep = ExtraFrameworkDependency('cups', False, None, environment,
- kwargs.get('language', None), kwargs)
- if fwdep.found():
- return fwdep
- mlog.log('Dependency', mlog.bold('cups'), 'found:', mlog.red('NO'))
+ candidates.append(functools.partial(
+ ExtraFrameworkDependency, 'cups', False, None, environment,
+ kwargs.get('language', None), kwargs))
- return CupsDependency(environment, kwargs)
+ return candidates
@staticmethod
def get_methods():
@@ -516,26 +507,21 @@ class LibWmfDependency(ExternalDependency):
@classmethod
def _factory(cls, environment, kwargs):
methods = cls._process_method_kw(kwargs)
+ candidates = []
+
if DependencyMethods.PKGCONFIG in methods:
- try:
- kwargs['required'] = False
- pcdep = PkgConfigDependency('libwmf', environment, kwargs)
- if pcdep.found():
- return pcdep
- except Exception as e:
- mlog.debug('LibWmf not found via pkgconfig. Trying next, error was:', str(e))
+ candidates.append(functools.partial(PkgConfigDependency, 'libwmf', environment, kwargs))
+
if DependencyMethods.CONFIG_TOOL in methods:
- try:
- ctdep = ConfigToolDependency.factory(
- 'libwmf', environment, None, kwargs, ['libwmf-config'], 'libwmf-config')
- if ctdep.found():
- ctdep.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
- ctdep.link_args = ctdep.get_config_value(['--libs'], 'link_args')
- return ctdep
- except Exception as e:
- mlog.debug('cups not found via libwmf-config. Trying next, error was:', str(e))
-
- return LibWmfDependency(environment, kwargs)
+ candidates.append(functools.partial(ConfigToolDependency.factory,
+ 'libwmf', environment, None, kwargs, ['libwmf-config'], 'libwmf-config'))
+
+# if ctdep.found():
+# ctdep.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
+# ctdep.link_args = ctdep.get_config_value(['--libs'], 'link_args')
+# return ctdep
+
+ return candidates
@staticmethod
def get_methods():
diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py
index 197d22c..e25d135 100644
--- a/mesonbuild/dependencies/ui.py
+++ b/mesonbuild/dependencies/ui.py
@@ -15,6 +15,7 @@
# This file contains the detection logic for external dependencies that
# are UI-related.
+import functools
import os
import re
import subprocess
@@ -37,32 +38,34 @@ from .base import ConfigToolDependency
class GLDependency(ExternalDependency):
def __init__(self, environment, kwargs):
super().__init__('gl', environment, None, kwargs)
- if DependencyMethods.SYSTEM in self.methods:
- if mesonlib.is_osx():
- self.is_found = True
- # FIXME: Use AppleFrameworks dependency
- self.link_args = ['-framework', 'OpenGL']
- # FIXME: Detect version using self.clib_compiler
- self.version = '1'
- return
- if mesonlib.is_windows():
- self.is_found = True
- # FIXME: Use self.clib_compiler.find_library()
- self.link_args = ['-lopengl32']
- # FIXME: Detect version using self.clib_compiler
- self.version = '1'
- return
+
+ if mesonlib.is_osx():
+ self.is_found = True
+ # FIXME: Use AppleFrameworks dependency
+ self.link_args = ['-framework', 'OpenGL']
+ # FIXME: Detect version using self.clib_compiler
+ self.version = '1'
+ return
+ if mesonlib.is_windows():
+ self.is_found = True
+ # FIXME: Use self.clib_compiler.find_library()
+ self.link_args = ['-lopengl32']
+ # FIXME: Detect version using self.clib_compiler
+ self.version = '1'
+ return
@classmethod
def _factory(cls, environment, kwargs):
- if DependencyMethods.PKGCONFIG in cls._process_method_kw(kwargs):
- try:
- pcdep = PkgConfigDependency('gl', environment, kwargs)
- if pcdep.found():
- return pcdep
- except Exception:
- pass
- return GLDependency(environment, kwargs)
+ methods = cls._process_method_kw(kwargs)
+ candidates = []
+
+ if DependencyMethods.PKGCONFIG in methods:
+ candidates.append(functools.partial(PkgConfigDependency, 'gl', environment, kwargs))
+
+ if DependencyMethods.SYSTEM in methods:
+ candidates.append(functools.partial(GLDependency), environment, kwargs)
+
+ return candidates
@staticmethod
def get_methods():
@@ -452,33 +455,27 @@ class SDL2Dependency(ExternalDependency):
@classmethod
def _factory(cls, environment, kwargs):
methods = cls._process_method_kw(kwargs)
+ candidates = []
+
if DependencyMethods.PKGCONFIG in methods:
- try:
- pcdep = PkgConfigDependency('sdl2', environment, kwargs)
- if pcdep.found():
- return pcdep
- except Exception as e:
- mlog.debug('SDL 2 not found via pkgconfig. Trying next, error was:', str(e))
+ candidates.append(functools.partial(PkgConfigDependency, 'sdl2', environment, kwargs))
+
if DependencyMethods.CONFIG_TOOL in methods:
- try:
- ctdep = ConfigToolDependency.factory(
- 'sdl2', environment, None, kwargs, ['sdl2-config'], 'sdl2-config')
- if ctdep.found():
- ctdep.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
- ctdep.link_args = ctdep.get_config_value(['--libs'], 'link_args')
- return ctdep
- except Exception as e:
- mlog.debug('SDL 2 not found via sdl2-config. Trying next, error was:', str(e))
+ candidates.append(functools.partial(ConfigToolDependency.factory,
+ 'sdl2', environment, None,
+ kwargs, ['sdl2-config'],
+ 'sdl2-config'))
+# if ctdep.found():
+# ctdep.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
+# ctdep.link_args = ctdep.get_config_value(['--libs'], 'link_args')
+
if DependencyMethods.EXTRAFRAMEWORK in methods:
if mesonlib.is_osx():
- fwdep = ExtraFrameworkDependency('sdl2', False, None, environment,
- kwargs.get('language', None), kwargs)
- if fwdep.found():
- fwdep.version = '2' # FIXME
- return fwdep
- mlog.log('Dependency', mlog.bold('sdl2'), 'found:', mlog.red('NO'))
-
- return SDL2Dependency(environment, kwargs)
+ candidates.append(functools.partial(ExtraFrameworkDependency,
+ 'sdl2', False, None, environment,
+ kwargs.get('language', None), kwargs))
+ # fwdep.version = '2' # FIXME
+ return candidates
@staticmethod
def get_methods():
@@ -518,73 +515,73 @@ class VulkanDependency(ExternalDependency):
def __init__(self, environment, kwargs):
super().__init__('vulkan', environment, None, kwargs)
- if DependencyMethods.SYSTEM in self.methods:
- try:
- self.vulkan_sdk = os.environ['VULKAN_SDK']
- if not os.path.isabs(self.vulkan_sdk):
- raise DependencyException('VULKAN_SDK must be an absolute path.')
- except KeyError:
- self.vulkan_sdk = None
-
- if self.vulkan_sdk:
- # TODO: this config might not work on some platforms, fix bugs as reported
- # we should at least detect other 64-bit platforms (e.g. armv8)
+ try:
+ self.vulkan_sdk = os.environ['VULKAN_SDK']
+ if not os.path.isabs(self.vulkan_sdk):
+ raise DependencyException('VULKAN_SDK must be an absolute path.')
+ except KeyError:
+ self.vulkan_sdk = None
+
+ if self.vulkan_sdk:
+ # TODO: this config might not work on some platforms, fix bugs as reported
+ # we should at least detect other 64-bit platforms (e.g. armv8)
+ lib_name = 'vulkan'
+ if mesonlib.is_windows():
+ lib_name = 'vulkan-1'
+ lib_dir = 'Lib32'
+ inc_dir = 'Include'
+ if detect_cpu({}) == 'x86_64':
+ lib_dir = 'Lib'
+ else:
lib_name = 'vulkan'
- if mesonlib.is_windows():
- lib_name = 'vulkan-1'
- lib_dir = 'Lib32'
- inc_dir = 'Include'
- if detect_cpu({}) == 'x86_64':
- lib_dir = 'Lib'
- else:
- lib_name = 'vulkan'
- lib_dir = 'lib'
- inc_dir = 'include'
+ lib_dir = 'lib'
+ inc_dir = 'include'
- # make sure header and lib are valid
- inc_path = os.path.join(self.vulkan_sdk, inc_dir)
- header = os.path.join(inc_path, 'vulkan', 'vulkan.h')
- lib_path = os.path.join(self.vulkan_sdk, lib_dir)
- find_lib = self.clib_compiler.find_library(lib_name, environment, lib_path)
+ # make sure header and lib are valid
+ inc_path = os.path.join(self.vulkan_sdk, inc_dir)
+ header = os.path.join(inc_path, 'vulkan', 'vulkan.h')
+ lib_path = os.path.join(self.vulkan_sdk, lib_dir)
+ find_lib = self.clib_compiler.find_library(lib_name, environment, lib_path)
- if not find_lib:
- raise DependencyException('VULKAN_SDK point to invalid directory (no lib)')
+ if not find_lib:
+ raise DependencyException('VULKAN_SDK point to invalid directory (no lib)')
- if not os.path.isfile(header):
- raise DependencyException('VULKAN_SDK point to invalid directory (no include)')
+ if not os.path.isfile(header):
+ raise DependencyException('VULKAN_SDK point to invalid directory (no include)')
- self.type_name = 'vulkan_sdk'
- self.is_found = True
- self.compile_args.append('-I' + inc_path)
- self.link_args.append('-L' + lib_path)
- self.link_args.append('-l' + lib_name)
+ self.type_name = 'vulkan_sdk'
+ self.is_found = True
+ self.compile_args.append('-I' + inc_path)
+ self.link_args.append('-L' + lib_path)
+ self.link_args.append('-l' + lib_name)
- # TODO: find a way to retrieve the version from the sdk?
- # Usually it is a part of the path to it (but does not have to be)
- self.version = '1'
+ # TODO: find a way to retrieve the version from the sdk?
+ # Usually it is a part of the path to it (but does not have to be)
+ self.version = '1'
+ return
+ else:
+ # simply try to guess it, usually works on linux
+ libs = self.clib_compiler.find_library('vulkan', environment, [])
+ if libs is not None and self.clib_compiler.has_header('vulkan/vulkan.h', '', environment):
+ self.type_name = 'system'
+ self.is_found = True
+ self.version = 1 # TODO
+ for lib in libs:
+ self.link_args.append(lib)
return
- else:
- # simply try to guess it, usually works on linux
- libs = self.clib_compiler.find_library('vulkan', environment, [])
- if libs is not None and self.clib_compiler.has_header('vulkan/vulkan.h', '', environment):
- self.type_name = 'system'
- self.is_found = True
- self.version = 1 # TODO
- for lib in libs:
- self.link_args.append(lib)
- return
@classmethod
def _factory(cls, environment, kwargs):
- if DependencyMethods.PKGCONFIG in cls._process_method_kw(kwargs):
- try:
- pcdep = PkgConfigDependency('vulkan', environment, kwargs)
- if pcdep.found():
- return pcdep
- except Exception:
- pass
+ methods = cls._process_method_kw(kwargs)
+ candidates = []
- return VulkanDependency(environment, kwargs)
+ if DependencyMethods.PKGCONFIG in methods:
+ candidates.append(functools.partial(PkgConfigDependency, 'vulkan', environment, kwargs))
+
+ if DependencyMethods.PKGCONFIG in methods:
+ candidates.append(functools.partial(VulkanDependency, environment, kwargs))
+
+ return candidates
@staticmethod
def get_methods():