Use an enum instead of strings for method names.

If a non-string value is passed as a method, reject this explicitly
with a clear error message rather than trying to match with it and
failing.
pull/1588/head
Aaron Small 8 years ago
parent 98a0f3ea40
commit 1fbf6300c5
  1. 63
      mesonbuild/dependencies.py

@ -24,6 +24,7 @@ import sys
import os, stat, glob, shutil import os, stat, glob, shutil
import subprocess import subprocess
import sysconfig import sysconfig
from enum import Enum
from collections import OrderedDict from collections import OrderedDict
from . mesonlib import MesonException, version_compare, version_compare_many, Popen_safe from . mesonlib import MesonException, version_compare, version_compare_many, Popen_safe
from . import mlog from . import mlog
@ -33,21 +34,35 @@ from .environment import detect_cpu_family, for_windows
class DependencyException(MesonException): class DependencyException(MesonException):
'''Exceptions raised while trying to find dependencies''' '''Exceptions raised while trying to find dependencies'''
class DependencyMethods(Enum):
# Auto means to use whatever dependency checking mechanisms in whatever order meson thinks is best.
AUTO = 'auto'
PKGCONFIG = 'pkg-config'
QMAKE = 'qmake'
# Just specify the standard link arguments, assuming the operating system provides the library.
SYSTEM = 'system'
# Detect using sdl2-config
SDLCONFIG = 'sdlconfig'
# This is only supported on OSX - search the frameworks directory by name.
EXTRAFRAMEWORK = 'extraframework'
# Detect using the sysconfig module.
SYSCONFIG = 'sysconfig'
class Dependency: class Dependency:
def __init__(self, type_name, kwargs): def __init__(self, type_name, kwargs):
self.name = "null" self.name = "null"
self.is_found = False self.is_found = False
self.type_name = type_name self.type_name = type_name
method = kwargs.get('method', 'auto') method = DependencyMethods(kwargs.get('method', 'auto'))
# Set the detection method. If the method is set to auto, use any available method. # 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 is set to a specific string, allow only that detection method.
if method == "auto": if method == DependencyMethods.AUTO:
self.methods = self.get_methods() self.methods = self.get_methods()
elif method in self.get_methods(): elif method in self.get_methods():
self.methods = [method] self.methods = [method]
else: else:
raise MesonException('Unsupported detection method: {}, allowed methods are {}'.format(method, mlog.format_list(["auto"] + self.get_methods()))) raise MesonException('Unsupported detection method: {}, allowed methods are {}'.format(method.value, mlog.format_list(map(lambda x: x.value, [DependencyMethods.AUTO] + self.get_methods()))))
def __repr__(self): def __repr__(self):
s = '<{0} {1}: {2}>' s = '<{0} {1}: {2}>'
@ -68,7 +83,7 @@ class Dependency:
return [] return []
def get_methods(self): def get_methods(self):
return ['auto'] return [DependencyMethods.AUTO]
def get_name(self): def get_name(self):
return self.name return self.name
@ -268,7 +283,7 @@ class PkgConfigDependency(Dependency):
return self.libs return self.libs
def get_methods(self): def get_methods(self):
return ['pkg-config'] return [DependencyMethods.PKGCONFIG]
def check_pkgconfig(self): def check_pkgconfig(self):
evar = 'PKG_CONFIG' evar = 'PKG_CONFIG'
@ -985,10 +1000,10 @@ class QtBaseDependency(Dependency):
# Keep track of the detection methods used, for logging purposes. # Keep track of the detection methods used, for logging purposes.
methods = [] methods = []
# Prefer pkg-config, then fallback to `qmake -query` # Prefer pkg-config, then fallback to `qmake -query`
if 'pkg-config' in self.methods: if DependencyMethods.PKGCONFIG in self.methods:
self._pkgconfig_detect(mods, env, kwargs) self._pkgconfig_detect(mods, env, kwargs)
methods.append('pkgconfig') methods.append('pkgconfig')
if not self.is_found and 'qmake' in self.methods: if not self.is_found and DependencyMethods.QMAKE in self.methods:
from_text = self._qmake_detect(mods, env, kwargs) from_text = self._qmake_detect(mods, env, kwargs)
methods.append('qmake-' + self.name) methods.append('qmake-' + self.name)
methods.append('qmake') methods.append('qmake')
@ -1137,7 +1152,7 @@ class QtBaseDependency(Dependency):
return self.largs return self.largs
def get_methods(self): def get_methods(self):
return ['pkg-config', 'qmake'] return [DependencyMethods.PKGCONFIG, DependencyMethods.QMAKE]
def found(self): def found(self):
return self.is_found return self.is_found
@ -1301,7 +1316,7 @@ class GLDependency(Dependency):
self.is_found = False self.is_found = False
self.cargs = [] self.cargs = []
self.linkargs = [] self.linkargs = []
if 'pkg-config' in self.methods: if DependencyMethods.PKGCONFIG in self.methods:
try: try:
pcdep = PkgConfigDependency('gl', environment, kwargs) pcdep = PkgConfigDependency('gl', environment, kwargs)
if pcdep.found(): if pcdep.found():
@ -1313,7 +1328,7 @@ class GLDependency(Dependency):
return return
except Exception: except Exception:
pass pass
if 'system' in self.methods: if DependencyMethods.SYSTEM in self.methods:
if mesonlib.is_osx(): if mesonlib.is_osx():
self.is_found = True self.is_found = True
self.linkargs = ['-framework', 'OpenGL'] self.linkargs = ['-framework', 'OpenGL']
@ -1333,9 +1348,9 @@ class GLDependency(Dependency):
def get_methods(self): def get_methods(self):
if mesonlib.is_osx() or mesonlib.is_windows(): if mesonlib.is_osx() or mesonlib.is_windows():
return ['pkg-config', 'system'] return [DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM]
else: else:
return ['pkg-config'] return [DependencyMethods.PKGCONFIG]
# There are three different ways of depending on SDL2: # There are three different ways of depending on SDL2:
# sdl2-config, pkg-config and OSX framework # sdl2-config, pkg-config and OSX framework
@ -1345,7 +1360,7 @@ class SDL2Dependency(Dependency):
self.is_found = False self.is_found = False
self.cargs = [] self.cargs = []
self.linkargs = [] self.linkargs = []
if 'pkg-config' in self.methods: if DependencyMethods.PKGCONFIG in self.methods:
try: try:
pcdep = PkgConfigDependency('sdl2', environment, kwargs) pcdep = PkgConfigDependency('sdl2', environment, kwargs)
if pcdep.found(): if pcdep.found():
@ -1358,7 +1373,7 @@ class SDL2Dependency(Dependency):
except Exception as e: except Exception as e:
mlog.debug('SDL 2 not found via pkgconfig. Trying next, error was:', str(e)) mlog.debug('SDL 2 not found via pkgconfig. Trying next, error was:', str(e))
pass pass
if 'sdlconfig' in self.methods: if DependencyMethods.SDLCONFIG in self.methods:
sdlconf = shutil.which('sdl2-config') sdlconf = shutil.which('sdl2-config')
if sdlconf: if sdlconf:
stdo = Popen_safe(['sdl2-config', '--cflags'])[1] stdo = Popen_safe(['sdl2-config', '--cflags'])[1]
@ -1372,7 +1387,7 @@ class SDL2Dependency(Dependency):
self.version, '(%s)' % sdlconf) self.version, '(%s)' % sdlconf)
return return
mlog.debug('Could not find sdl2-config binary, trying next.') mlog.debug('Could not find sdl2-config binary, trying next.')
if 'extraframework' in self.methods: if DependencyMethods.EXTRAFRAMEWORK in self.methods:
if mesonlib.is_osx(): if mesonlib.is_osx():
fwdep = ExtraFrameworkDependency('sdl2', kwargs.get('required', True), None, kwargs) fwdep = ExtraFrameworkDependency('sdl2', kwargs.get('required', True), None, kwargs)
if fwdep.found(): if fwdep.found():
@ -1397,9 +1412,9 @@ class SDL2Dependency(Dependency):
def get_methods(self): def get_methods(self):
if mesonlib.is_osx(): if mesonlib.is_osx():
return ['pkg-config', 'sdlconfig', 'extraframework'] return [DependencyMethods.PKGCONFIG, DependencyMethods.SDLCONFIG, DependencyMethods.EXTRAFRAMEWORK]
else: else:
return ['pkg-config', 'sdlconfig'] return [DependencyMethods.PKGCONFIG, DependencyMethods.SDLCONFIG]
class ExtraFrameworkDependency(Dependency): class ExtraFrameworkDependency(Dependency):
def __init__(self, name, required, path, kwargs): def __init__(self, name, required, path, kwargs):
@ -1465,7 +1480,7 @@ class Python3Dependency(Dependency):
self.is_found = False self.is_found = False
# We can only be sure that it is Python 3 at this point # We can only be sure that it is Python 3 at this point
self.version = '3' self.version = '3'
if 'pkg-config' in self.methods: if DependencyMethods.PKGCONFIG in self.methods:
try: try:
pkgdep = PkgConfigDependency('python3', environment, kwargs) pkgdep = PkgConfigDependency('python3', environment, kwargs)
if pkgdep.found(): if pkgdep.found():
@ -1477,9 +1492,9 @@ class Python3Dependency(Dependency):
except Exception: except Exception:
pass pass
if not self.is_found: if not self.is_found:
if mesonlib.is_windows() and 'sysconfig' in self.methods: if mesonlib.is_windows() and DependencyMethods.SYSCONFIG in self.methods:
self._find_libpy3_windows(environment) self._find_libpy3_windows(environment)
elif mesonlib.is_osx() and 'extraframework' in self.methods: elif mesonlib.is_osx() and DependencyMethods.EXTRAFRAMEWORK in self.methods:
# In OSX the Python 3 framework does not have a version # In OSX the Python 3 framework does not have a version
# number in its name. # number in its name.
fw = ExtraFrameworkDependency('python', False, None, kwargs) fw = ExtraFrameworkDependency('python', False, None, kwargs)
@ -1536,11 +1551,11 @@ class Python3Dependency(Dependency):
def get_methods(self): def get_methods(self):
if mesonlib.is_windows(): if mesonlib.is_windows():
return ['pkg-config', 'sysconfig'] return [DependencyMethods.PKGCONFIG, DependencyMethods.SYSCONFIG]
elif mesonlib.is_osx(): elif mesonlib.is_osx():
return ['pkg-config', 'extraframework'] return [DependencyMethods.PKGCONFIG, DependencyMethods.EXTRAFRAMEWORK]
else: else:
return ['pkg-config'] return [DependencyMethods.PKGCONFIG]
def get_version(self): def get_version(self):
return self.version return self.version
@ -1574,6 +1589,8 @@ def find_external_dependency(name, environment, kwargs):
required = kwargs.get('required', True) required = kwargs.get('required', True)
if not isinstance(required, bool): if not isinstance(required, bool):
raise DependencyException('Keyword "required" must be a boolean.') raise DependencyException('Keyword "required" must be a boolean.')
if not isinstance(kwargs.get('method', ''), str):
raise DependencyException('Keyword "method" must be a string.')
lname = name.lower() lname = name.lower()
if lname in packages: if lname in packages:
dep = packages[lname](environment, kwargs) dep = packages[lname](environment, kwargs)

Loading…
Cancel
Save