aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2018-02-11 20:01:32 +0200
committerGitHub <noreply@github.com>2018-02-11 20:01:32 +0200
commit1b7b7fedb91f52b6ff35db461f6412a4ad5f7c7f (patch)
tree6f177682445c21582197f29af3bd35fe2f37b29e
parent2fa44cf326799b1f56db3e83b35fbecce45153fd (diff)
parent227ad7605b1c019f4022e12a50e91b1ce88e2914 (diff)
downloadmeson-1b7b7fedb91f52b6ff35db461f6412a4ad5f7c7f.zip
meson-1b7b7fedb91f52b6ff35db461f6412a4ad5f7c7f.tar.gz
meson-1b7b7fedb91f52b6ff35db461f6412a4ad5f7c7f.tar.bz2
Merge pull request #2926 from jon-turney/dependency-factory
Fix dependency object types returned by custom dependency detection
-rw-r--r--mesonbuild/dependencies/base.py59
-rw-r--r--mesonbuild/dependencies/misc.py120
-rw-r--r--mesonbuild/dependencies/ui.py104
-rw-r--r--test cases/common/174 dependency factory/meson.build51
4 files changed, 191 insertions, 143 deletions
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 1e3c49c..66bc3b4 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -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,7 +930,12 @@ 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, ))
- dep = packages[lname](env, kwargs)
+ # 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)
return dep
diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py
index 542de39..af80160 100644
--- a/mesonbuild/dependencies/misc.py
+++ b/mesonbuild/dependencies/misc.py
@@ -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
- mlog.log('Dependency', mlog.bold('cups'), 'found:', mlog.red('NO'))
+ return fwdep
+ mlog.log('Dependency', mlog.bold('cups'), 'found:', mlog.red('NO'))
+
+ return CupsDependency(environment, kwargs)
- def get_methods(self):
+ @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:
diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py
index c066c31..a6307c4 100644
--- a/mesonbuild/dependencies/ui.py
+++ b/mesonbuild/dependencies/ui.py
@@ -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]
diff --git a/test cases/common/174 dependency factory/meson.build b/test cases/common/174 dependency factory/meson.build
new file mode 100644
index 0000000..54f7d26
--- /dev/null
+++ b/test cases/common/174 dependency factory/meson.build
@@ -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