aboutsummaryrefslogtreecommitdiff
path: root/dependencies.py
diff options
context:
space:
mode:
Diffstat (limited to 'dependencies.py')
-rw-r--r--dependencies.py173
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,
}