diff options
-rw-r--r-- | mesonbuild/dependencies/base.py | 59 | ||||
-rw-r--r-- | mesonbuild/dependencies/misc.py | 120 | ||||
-rw-r--r-- | mesonbuild/dependencies/ui.py | 104 | ||||
-rw-r--r-- | test cases/common/174 dependency factory/meson.build | 51 |
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 |