diff options
Diffstat (limited to 'dependencies.py')
-rw-r--r-- | dependencies.py | 173 |
1 files changed, 168 insertions, 5 deletions
diff --git a/dependencies.py b/dependencies.py index de7ac43..141473e 100644 --- a/dependencies.py +++ b/dependencies.py @@ -14,16 +14,153 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This file contains the detection logic for all those -# packages and frameworks that either don't provide -# a pkg-confg file or require extra functionality -# that can't be expressed with it. +# This file contains the detection logic for external +# dependencies. Mostly just uses pkg-config but also contains +# custom logic for packages that don't provide them. # Currently one file, should probably be split into a # package before this gets too big. -import os, stat, glob +import os, stat, glob, subprocess from interpreter import InvalidArguments +from coredata import MesonException + +class DependencyException(MesonException): + def __init__(self, args, **kwargs): + MesonException.__init__(args, kwargs) + +class Dependency(): + def __init__(self): + pass + + def get_compile_flags(self): + return [] + + def get_link_flags(self): + return [] + + def found(self): + return False + + def get_sources(self): + """Source files that need to be added to the target. + As an example, gtest-all.cc when using GTest.""" + return [] + +class PackageDependency(Dependency): # Custom detector, not pkg-config. + def __init__(self, dep): + Dependency.__init__(self) + self.dep = dep + + def get_link_flags(self): + return self.dep.get_link_flags() + + def get_compile_flags(self): + return self.dep.get_compile_flags() + + def found(self): + return self.dep.found() + + def get_sources(self): + return self.dep.get_sources() + +# This should be an InterpreterObject. Fix it. + +class PkgConfigDependency(Dependency): + pkgconfig_found = False + + def __init__(self, name, required): + Dependency.__init__(self) + if not PkgConfigDependency.pkgconfig_found: + self.check_pkgconfig() + + self.is_found = False + p = subprocess.Popen(['pkg-config', '--modversion', name], stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out = p.communicate()[0] + if p.returncode != 0: + if required: + raise DependencyException('Required dependency %s not found.' % name) + self.modversion = 'none' + self.cflags = [] + self.libs = [] + else: + self.is_found = True + self.modversion = out.decode().strip() + p = subprocess.Popen(['pkg-config', '--cflags', name], stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out = p.communicate()[0] + if p.returncode != 0: + raise RuntimeError('Could not generate cflags for %s.' % name) + self.cflags = out.decode().split() + + p = subprocess.Popen(['pkg-config', '--libs', name], stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out = p.communicate()[0] + if p.returncode != 0: + raise RuntimeError('Could not generate libs for %s.' % name) + self.libs = out.decode().split() + + def get_modversion(self): + return self.modversion + + def get_compile_flags(self): + return self.cflags + + def get_link_flags(self): + return self.libs + + def check_pkgconfig(self): + p = subprocess.Popen(['pkg-config', '--version'], stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out = p.communicate()[0] + if p.returncode != 0: + raise RuntimeError('Pkg-config executable not found.') + print('Found pkg-config version %s.' % out.decode().strip()) + PkgConfigDependency.pkgconfig_found = True + + def found(self): + return self.is_found + +class ExternalProgram(): + def __init__(self, name, fullpath=None): + self.name = name + self.fullpath = fullpath + + def found(self): + return self.fullpath is not None + + def get_command(self): + return self.fullpath + + def get_name(self): + return self.name + +class ExternalLibrary(Dependency): + def __init__(self, name, fullpath=None): + Dependency.__init__(self) + self.name = name + self.fullpath = fullpath + + def found(self): + return self.fullpath is not None + + def get_name(self): + return self.name + + def get_link_flags(self): + if self.found(): + return [self.fullpath] + return [] + +def find_external_dependency(name, kwargs): + required = kwargs.get('required', False) + if name in packages: + dep = packages[name](kwargs) + if required and not dep.found(): + raise DependencyException('Dependency "%s" not found' % name) + return PackageDependency(dep) + return PkgConfigDependency(name, required) class BoostDependency(): def __init__(self, kwargs): @@ -145,7 +282,33 @@ class GMockDependency(): fname = os.path.join(self.libdir, self.libname) return os.path.exists(fname) +class Qt5Dependency(): + def __init__(self, kwargs): + self.root = '/usr' + self.modules = [] + for module in kwargs.get('modules', []): + self.modules.append(PkgConfigDependency(module)) + + def get_version(self): + return '1.something_maybe' + + def get_compile_flags(self): + return [] + + def get_sources(self): + return [] + + def get_link_flags(self): + return ['-lgmock'] + + def found(self): + fname = os.path.join(self.libdir, self.libname) + return os.path.exists(fname) + +# This has to be at the end so all classes it references +# are defined. packages = {'boost': BoostDependency, 'gtest': GTestDependency, 'gmock': GMockDependency, + 'qt5': Qt5Dependency, } |