Merge pull request #2926 from jon-turney/dependency-factory

Fix dependency object types returned by custom dependency detection
pull/3043/head
Jussi Pakkanen 7 years ago committed by GitHub
commit 1b7b7fedb9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 57
      mesonbuild/dependencies/base.py
  2. 118
      mesonbuild/dependencies/misc.py
  3. 104
      mesonbuild/dependencies/ui.py
  4. 51
      test cases/common/174 dependency factory/meson.build

@ -61,21 +61,14 @@ class DependencyMethods(Enum):
class Dependency:
def __init__(self, type_name, kwargs):
self.name = "null"
self.version = 'none'
self.language = None # None means C-like
self.is_found = False
self.type_name = type_name
self.compile_args = []
self.link_args = []
self.sources = []
@classmethod
def _process_method_kw(cls, kwargs):
method = kwargs.get('method', 'auto')
if method not in [e.value for e in DependencyMethods]:
raise DependencyException('method {!r} is invalid'.format(method))
method = DependencyMethods(method)
# This sets per-too config methods which are deprecated to to the new
# This sets per-tool config methods which are deprecated to to the new
# generic CONFIG_TOOL value.
if method in [DependencyMethods.SDLCONFIG, DependencyMethods.CUPSCONFIG,
DependencyMethods.PCAPCONFIG, DependencyMethods.LIBWMFCONFIG]:
@ -88,14 +81,27 @@ class Dependency:
# Set the detection method. If the method is set to auto, use any available method.
# If method is set to a specific string, allow only that detection method.
if method == DependencyMethods.AUTO:
self.methods = self.get_methods()
elif method in self.get_methods():
self.methods = [method]
methods = cls.get_methods()
elif method in cls.get_methods():
methods = [method]
else:
raise DependencyException(
'Unsupported detection method: {}, allowed methods are {}'.format(
method.value,
mlog.format_list([x.value for x in [DependencyMethods.AUTO] + self.get_methods()])))
mlog.format_list([x.value for x in [DependencyMethods.AUTO] + cls.get_methods()])))
return methods
def __init__(self, type_name, kwargs):
self.name = "null"
self.version = 'none'
self.language = None # None means C-like
self.is_found = False
self.type_name = type_name
self.compile_args = []
self.link_args = []
self.sources = []
self.methods = self._process_method_kw(kwargs)
def __repr__(self):
s = '<{0} {1}: {2}>'
@ -115,7 +121,8 @@ class Dependency:
As an example, gtest-all.cc when using GTest."""
return self.sources
def get_methods(self):
@staticmethod
def get_methods():
return [DependencyMethods.AUTO]
def get_name(self):
@ -246,14 +253,17 @@ class ConfigToolDependency(ExternalDependency):
# instantiated and returned. The reduce function (method) is also
# attached, since python's pickle module won't be able to do anything
# with this dynamically generated class otherwise.
def reduce(_):
return (cls.factory,
(name, environment, language, kwargs, tools, tool_name))
def reduce(self):
return (cls._unpickle, (), self.__dict__)
sub = type('{}Dependency'.format(name.capitalize()), (cls, ),
{'tools': tools, 'tool_name': tool_name, '__reduce__': reduce})
return sub(name, environment, language, kwargs)
@classmethod
def _unpickle(cls):
return cls.__new__(cls)
def find_config(self, versions=None):
"""Helper method that searchs for config tool binaries in PATH and
returns the one that best matches the given version requirements.
@ -331,7 +341,8 @@ class ConfigToolDependency(ExternalDependency):
return []
return shlex.split(out)
def get_methods(self):
@staticmethod
def get_methods():
return [DependencyMethods.AUTO, DependencyMethods.CONFIG_TOOL]
def get_configtool_variable(self, variable_name):
@ -569,7 +580,8 @@ class PkgConfigDependency(ExternalDependency):
mlog.debug('Got pkgconfig variable %s : %s' % (variable_name, variable))
return variable
def get_methods(self):
@staticmethod
def get_methods():
return [DependencyMethods.PKGCONFIG]
def check_pkgconfig(self):
@ -918,6 +930,11 @@ def find_external_dependency(name, env, kwargs):
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.
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)

@ -795,7 +795,8 @@ class Python3Dependency(ExternalDependency):
self.version = sysconfig.get_config_var('py_version')
self.is_found = True
def get_methods(self):
@staticmethod
def get_methods():
if mesonlib.is_windows():
return [DependencyMethods.PKGCONFIG, DependencyMethods.SYSCONFIG]
elif mesonlib.is_osx():
@ -813,90 +814,80 @@ class Python3Dependency(ExternalDependency):
class PcapDependency(ExternalDependency):
def __init__(self, environment, kwargs):
super().__init__('pcap', environment, None, kwargs)
kwargs['required'] = False
if DependencyMethods.PKGCONFIG in self.methods:
@classmethod
def _factory(cls, environment, kwargs):
methods = cls._process_method_kw(kwargs)
if DependencyMethods.PKGCONFIG in methods:
try:
pcdep = PkgConfigDependency('pcap', environment, kwargs)
if pcdep.found():
self.type_name = 'pkgconfig'
self.is_found = True
self.compile_args = pcdep.get_compile_args()
self.link_args = pcdep.get_link_args()
self.version = pcdep.get_version()
self.pcdep = pcdep
return
return pcdep
except Exception as e:
mlog.debug('Pcap not found via pkgconfig. Trying next, error was:', str(e))
if DependencyMethods.CONFIG_TOOL in self.methods:
if DependencyMethods.CONFIG_TOOL in methods:
try:
ctdep = ConfigToolDependency.factory(
'pcap', environment, None, kwargs, ['pcap-config'], 'pcap-config')
if ctdep.found():
self.config = ctdep.config
self.type_name = 'config-tool'
self.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
self.link_args = ctdep.get_config_value(['--libs'], 'link_args')
self.version = self.get_pcap_lib_version()
self.is_found = True
return
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))
def get_methods(self):
return PcapDependency(environment, kwargs)
@staticmethod
def get_methods():
if mesonlib.is_osx():
return [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.EXTRAFRAMEWORK]
else:
return [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL]
def get_pcap_lib_version(self):
return self.compiler.get_return_value('pcap_lib_version', 'string',
'#include <pcap.h>', self.env, [], [self])
@staticmethod
def get_pcap_lib_version(ctdep):
return ctdep.compiler.get_return_value('pcap_lib_version', 'string',
'#include <pcap.h>', ctdep.env, [], [ctdep])
class CupsDependency(ExternalDependency):
def __init__(self, environment, kwargs):
super().__init__('cups', environment, None, kwargs)
kwargs['required'] = False
if DependencyMethods.PKGCONFIG in self.methods:
@classmethod
def _factory(cls, environment, kwargs):
methods = cls._process_method_kw(kwargs)
if DependencyMethods.PKGCONFIG in methods:
try:
pcdep = PkgConfigDependency('cups', environment, kwargs)
if pcdep.found():
self.type_name = 'pkgconfig'
self.is_found = True
self.compile_args = pcdep.get_compile_args()
self.link_args = pcdep.get_link_args()
self.version = pcdep.get_version()
self.pcdep = pcdep
return
return pcdep
except Exception as e:
mlog.debug('cups not found via pkgconfig. Trying next, error was:', str(e))
if DependencyMethods.CONFIG_TOOL in self.methods:
if DependencyMethods.CONFIG_TOOL in methods:
try:
ctdep = ConfigToolDependency.factory(
'cups', environment, None, kwargs, ['cups-config'], 'cups-config')
if ctdep.found():
self.config = ctdep.config
self.type_name = 'config-tool'
self.version = ctdep.version
self.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
self.link_args = ctdep.get_config_value(['--ldflags', '--libs'], 'link_args')
self.is_found = True
return
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))
if DependencyMethods.EXTRAFRAMEWORK in self.methods:
if DependencyMethods.EXTRAFRAMEWORK in methods:
if mesonlib.is_osx():
fwdep = ExtraFrameworkDependency('cups', False, None, self.env,
self.language, kwargs)
fwdep = ExtraFrameworkDependency('cups', False, None, environment,
kwargs.get('language', None), kwargs)
if fwdep.found():
self.is_found = True
self.compile_args = fwdep.get_compile_args()
self.link_args = fwdep.get_link_args()
self.version = fwdep.get_version()
return
return fwdep
mlog.log('Dependency', mlog.bold('cups'), 'found:', mlog.red('NO'))
def get_methods(self):
return CupsDependency(environment, kwargs)
@staticmethod
def get_methods():
if mesonlib.is_osx():
return [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.EXTRAFRAMEWORK]
else:
@ -906,36 +897,33 @@ class CupsDependency(ExternalDependency):
class LibWmfDependency(ExternalDependency):
def __init__(self, environment, kwargs):
super().__init__('libwmf', environment, None, kwargs)
if DependencyMethods.PKGCONFIG in self.methods:
@classmethod
def _factory(cls, environment, kwargs):
methods = cls._process_method_kw(kwargs)
if DependencyMethods.PKGCONFIG in methods:
try:
kwargs['required'] = False
pcdep = PkgConfigDependency('libwmf', environment, kwargs)
if pcdep.found():
self.type_name = 'pkgconfig'
self.is_found = True
self.compile_args = pcdep.get_compile_args()
self.link_args = pcdep.get_link_args()
self.version = pcdep.get_version()
self.pcdep = pcdep
return
return pcdep
except Exception as e:
mlog.debug('LibWmf not found via pkgconfig. Trying next, error was:', str(e))
if DependencyMethods.CONFIG_TOOL in self.methods:
if DependencyMethods.CONFIG_TOOL in methods:
try:
ctdep = ConfigToolDependency.factory(
'libwmf', environment, None, kwargs, ['libwmf-config'], 'libwmf-config')
if ctdep.found():
self.config = ctdep.config
self.type_name = 'config-too'
self.version = ctdep.version
self.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
self.link_args = ctdep.get_config_value(['--libs'], 'link_args')
self.is_found = True
return
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))
def get_methods(self):
return LibWmfDependency(environment, kwargs)
@staticmethod
def get_methods():
if mesonlib.is_osx():
return [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.EXTRAFRAMEWORK]
else:

@ -38,19 +38,6 @@ from .base import ConfigToolDependency
class GLDependency(ExternalDependency):
def __init__(self, environment, kwargs):
super().__init__('gl', environment, None, kwargs)
if DependencyMethods.PKGCONFIG in self.methods:
try:
pcdep = PkgConfigDependency('gl', environment, kwargs)
if pcdep.found():
self.type_name = 'pkgconfig'
self.is_found = True
self.compile_args = pcdep.get_compile_args()
self.link_args = pcdep.get_link_args()
self.version = pcdep.get_version()
self.pcdep = pcdep
return
except Exception:
pass
if DependencyMethods.SYSTEM in self.methods:
if mesonlib.is_osx():
self.is_found = True
@ -67,7 +54,19 @@ class GLDependency(ExternalDependency):
self.version = '1'
return
def get_methods(self):
@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)
@staticmethod
def get_methods():
if mesonlib.is_osx() or mesonlib.is_windows():
return [DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM]
else:
@ -337,7 +336,8 @@ class QtBaseDependency(ExternalDependency):
else:
return qvars['QT_INSTALL_BINS']
def get_methods(self):
@staticmethod
def get_methods():
return [DependencyMethods.PKGCONFIG, DependencyMethods.QMAKE]
def get_exe_args(self, compiler):
@ -380,47 +380,40 @@ class Qt5Dependency(QtBaseDependency):
class SDL2Dependency(ExternalDependency):
def __init__(self, environment, kwargs):
super().__init__('sdl2', environment, None, kwargs)
kwargs['required'] = False
if DependencyMethods.PKGCONFIG in self.methods:
@classmethod
def _factory(cls, environment, kwargs):
methods = cls._process_method_kw(kwargs)
if DependencyMethods.PKGCONFIG in methods:
try:
pcdep = PkgConfigDependency('sdl2', environment, kwargs)
if pcdep.found():
self.type_name = 'pkgconfig'
self.is_found = True
self.compile_args = pcdep.get_compile_args()
self.link_args = pcdep.get_link_args()
self.version = pcdep.get_version()
self.pcdep = pcdep
return
return pcdep
except Exception as e:
mlog.debug('SDL 2 not found via pkgconfig. Trying next, error was:', str(e))
if DependencyMethods.CONFIG_TOOL in self.methods:
if DependencyMethods.CONFIG_TOOL in methods:
try:
ctdep = ConfigToolDependency.factory(
'sdl2', environment, None, kwargs, ['sdl2-config'], 'sdl2-config')
if ctdep.found():
self.type_name = 'config-tool'
self.config = ctdep.config
self.version = ctdep.version
self.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
self.links_args = ctdep.get_config_value(['--libs'], 'link_args')
self.is_found = True
return
ctdep.compile_args = ctdep.get_config_value(['--cflags'], 'compile_args')
ctdep.links_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))
if DependencyMethods.EXTRAFRAMEWORK in self.methods:
if DependencyMethods.EXTRAFRAMEWORK in methods:
if mesonlib.is_osx():
fwdep = ExtraFrameworkDependency('sdl2', False, None, self.env,
self.language, kwargs)
fwdep = ExtraFrameworkDependency('sdl2', False, None, environment,
kwargs.get('language', None), kwargs)
if fwdep.found():
self.is_found = True
self.compile_args = fwdep.get_compile_args()
self.link_args = fwdep.get_link_args()
self.version = '2' # FIXME
return
fwdep.version = '2' # FIXME
return fwdep
mlog.log('Dependency', mlog.bold('sdl2'), 'found:', mlog.red('NO'))
def get_methods(self):
return SDL2Dependency(environment, kwargs)
@staticmethod
def get_methods():
if mesonlib.is_osx():
return [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.EXTRAFRAMEWORK]
else:
@ -456,20 +449,6 @@ class VulkanDependency(ExternalDependency):
def __init__(self, environment, kwargs):
super().__init__('vulkan', environment, None, kwargs)
if DependencyMethods.PKGCONFIG in self.methods:
try:
pcdep = PkgConfigDependency('vulkan', environment, kwargs)
if pcdep.found():
self.type_name = 'pkgconfig'
self.is_found = True
self.compile_args = pcdep.get_compile_args()
self.link_args = pcdep.get_link_args()
self.version = pcdep.get_version()
self.pcdep = pcdep
return
except Exception:
pass
if DependencyMethods.SYSTEM in self.methods:
try:
self.vulkan_sdk = os.environ['VULKAN_SDK']
@ -526,5 +505,18 @@ class VulkanDependency(ExternalDependency):
self.link_args.append(lib)
return
def get_methods(self):
@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
return VulkanDependency(environment, kwargs)
@staticmethod
def get_methods():
return [DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM]

@ -0,0 +1,51 @@
project('dependency factory')
dep = dependency('gl', method: 'pkg-config', required: false)
if dep.found() and dep.type_name() == 'pkgconfig'
dep.get_pkgconfig_variable('prefix')
endif
dep = dependency('SDL2', method: 'pkg-config', required: false)
if dep.found() and dep.type_name() == 'pkgconfig'
dep.get_pkgconfig_variable('prefix')
endif
dep = dependency('SDL2', method: 'config-tool', required: false)
if dep.found() and dep.type_name() == 'configtool'
dep.get_configtool_variable('prefix')
endif
dep = dependency('Vulkan', method: 'pkg-config', required: false)
if dep.found() and dep.type_name() == 'pkgconfig'
dep.get_pkgconfig_variable('prefix')
endif
dep = dependency('pcap', method: 'pkg-config', required: false)
if dep.found() and dep.type_name() == 'pkgconfig'
dep.get_pkgconfig_variable('prefix')
endif
dep = dependency('pcap', method: 'config-tool', required: false)
if dep.found() and dep.type_name() == 'configtool'
dep.get_configtool_variable('prefix')
endif
dep = dependency('cups', method: 'pkg-config', required: false)
if dep.found() and dep.type_name() == 'pkgconfig'
dep.get_pkgconfig_variable('prefix')
endif
dep = dependency('cups', method: 'config-tool', required: false)
if dep.found() and dep.type_name() == 'configtool'
dep.get_configtool_variable('prefix')
endif
dep = dependency('libwmf', method: 'pkg-config', required: false)
if dep.found() and dep.type_name() == 'pkgconfig'
dep.get_pkgconfig_variable('prefix')
endif
dep = dependency('libwmf', method: 'config-tool', required: false)
if dep.found() and dep.type_name() == 'configtool'
dep.get_configtool_variable('prefix')
endif
Loading…
Cancel
Save