aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon Turney <jon.turney@dronecode.org.uk>2018-05-18 20:50:03 +0100
committerJon Turney <jon.turney@dronecode.org.uk>2018-08-01 14:26:01 +0100
commitf2673d9b57d0134c293e7acf5af5a0b3364523fb (patch)
tree02266f8449cf50f7cda389c1f6193a2d40957c02
parent3576623b0f46dab27fbb243f6d5595916187642f (diff)
downloadmeson-f2673d9b57d0134c293e7acf5af5a0b3364523fb.zip
meson-f2673d9b57d0134c293e7acf5af5a0b3364523fb.tar.gz
meson-f2673d9b57d0134c293e7acf5af5a0b3364523fb.tar.bz2
Consolidate reporting result of a dependency check
If successful, we should identify the method which was successful If successful, we should report the version found (if known) If failing, we should identify the methods we tried Some dependency detectors which had no reporting now gain it There's all kinds of complexities, inconsistencies and special cases hidden in the existing behaviour, e.g.: - boost reports modules requested, and BOOST_ROOT (if set) - gtest/gmock report if they are a prebuilt library or header only - mpi reports the language - qt reports modules requested, and the config tool used or tried - configtool reports the config tool used - llvm reports if missing modules are optional (one per line) We add some simple hooks to allow the dependency object to expose the currently reported information into the consolidated reporting Note that PkgConfigDependency() takes a silent: keyword which is used internallly to suppress reporting. This behaviour isn't needed in find_external_dependency().
-rw-r--r--mesonbuild/dependencies/base.py97
-rw-r--r--mesonbuild/dependencies/boost.py20
-rw-r--r--mesonbuild/dependencies/dev.py39
-rw-r--r--mesonbuild/dependencies/misc.py13
-rw-r--r--mesonbuild/dependencies/ui.py26
5 files changed, 98 insertions, 97 deletions
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index e3faacd..8fdc10e 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -266,6 +266,15 @@ class ExternalDependency(Dependency):
return new
+ def log_details(self):
+ return ''
+
+ def log_info(self):
+ return ''
+
+ def log_tried(self):
+ return ''
+
class NotFoundDependency(Dependency):
def __init__(self, environment):
@@ -391,11 +400,9 @@ class ConfigToolDependency(ExternalDependency):
else:
mlog.log('Found', mlog.bold(self.tool_name), repr(req_version),
mlog.red('NO'))
- mlog.log('Dependency', mlog.bold(self.name), 'found:', mlog.red('NO'))
return False
mlog.log('Found {}:'.format(self.tool_name), mlog.bold(shutil.which(self.config)),
'({})'.format(version))
- mlog.log('Dependency', mlog.bold(self.name), 'found:', mlog.green('YES'))
return True
def get_config_value(self, args, stage):
@@ -423,6 +430,9 @@ class ConfigToolDependency(ExternalDependency):
mlog.debug('Got config-tool variable {} : {}'.format(variable_name, variable))
return variable
+ def log_tried(self):
+ return self.type_name
+
class PkgConfigDependency(ExternalDependency):
# The class's copy of the pkg-config path. Avoids having to search for it
@@ -464,17 +474,12 @@ class PkgConfigDependency(ExternalDependency):
if self.required:
raise DependencyException('Pkg-config not found.')
return
- if self.want_cross:
- self.type_string = 'Cross'
- else:
- self.type_string = 'Native'
mlog.debug('Determining dependency {!r} with pkg-config executable '
'{!r}'.format(name, self.pkgbin.get_path()))
ret, self.version = self._call_pkgbin(['--modversion', name])
if ret != 0:
return
- found_msg = [self.type_string + ' dependency', mlog.bold(name), 'found:']
if self.version_reqs is None:
self.is_found = True
else:
@@ -485,14 +490,6 @@ class PkgConfigDependency(ExternalDependency):
(self.is_found, not_found, found) = \
version_compare_many(self.version, self.version_reqs)
if not self.is_found:
- found_msg += [mlog.red('NO'),
- 'found {!r} but need:'.format(self.version),
- ', '.join(["'{}'".format(e) for e in not_found])]
- if found:
- found_msg += ['; matched:',
- ', '.join(["'{}'".format(e) for e in found])]
- if not self.silent:
- mlog.log(*found_msg)
if self.required:
m = 'Invalid version of dependency, need {!r} {!r} found {!r}.'
raise DependencyException(m.format(name, not_found, self.version))
@@ -503,7 +500,6 @@ class PkgConfigDependency(ExternalDependency):
self._set_cargs()
# Fetch the libraries and library paths needed for using this
self._set_libs()
- found_msg += [mlog.green('YES'), self.version]
except DependencyException as e:
if self.required:
raise
@@ -511,12 +507,7 @@ class PkgConfigDependency(ExternalDependency):
self.compile_args = []
self.link_args = []
self.is_found = False
- found_msg += [mlog.red('NO'), '; reason: {}'.format(str(e))]
-
- # Print the found message only at the very end because fetching cflags
- # and libs can also fail if other needed pkg-config files aren't found.
- if not self.silent:
- mlog.log(*found_msg)
+ self.reason = e
def __repr__(self):
s = '<{0} {1}: {2} {3}>'
@@ -705,8 +696,8 @@ class PkgConfigDependency(ExternalDependency):
variable = ''
if ret != 0:
if self.required:
- raise DependencyException('%s dependency %s not found.' %
- (self.type_string, self.name))
+ raise DependencyException('dependency %s not found.' %
+ (self.name))
else:
variable = out.strip()
@@ -790,6 +781,9 @@ class PkgConfigDependency(ExternalDependency):
# a path rather than the raw dlname
return os.path.basename(dlname)
+ def log_tried(self):
+ return self.type_name
+
class DubDependency(ExternalDependency):
class_dubbin = None
@@ -811,7 +805,6 @@ class DubDependency(ExternalDependency):
if self.required:
raise DependencyException('DUB not found.')
self.is_found = False
- mlog.log('Dependency', mlog.bold(name), 'found:', mlog.red('NO'))
return
mlog.debug('Determining dependency {!r} with DUB executable '
@@ -822,7 +815,6 @@ class DubDependency(ExternalDependency):
if ret != 0:
self.is_found = False
- mlog.log('Dependency', mlog.bold(name), 'found:', mlog.red('NO'))
return
j = json.loads(res)
@@ -834,7 +826,6 @@ class DubDependency(ExternalDependency):
msg += [mlog.bold(j['compiler']), 'and we are using', mlog.bold(comp)]
mlog.error(*msg)
self.is_found = False
- mlog.log('Dependency', mlog.bold(name), 'found:', mlog.red('NO'))
return
self.version = package['version']
@@ -842,7 +833,6 @@ class DubDependency(ExternalDependency):
break
# Check if package version meets the requirements
- found_msg = ['Dependency', mlog.bold(name), 'found:']
if self.version_reqs is None:
self.is_found = True
else:
@@ -853,21 +843,11 @@ class DubDependency(ExternalDependency):
(self.is_found, not_found, found) = \
version_compare_many(self.version, self.version_reqs)
if not self.is_found:
- found_msg += [mlog.red('NO'),
- 'found {!r} but need:'.format(self.version),
- ', '.join(["'{}'".format(e) for e in not_found])]
- if found:
- found_msg += ['; matched:',
- ', '.join(["'{}'".format(e) for e in found])]
- if not self.silent:
- mlog.log(*found_msg)
if self.required:
m = 'Invalid version of dependency, need {!r} {!r} found {!r}.'
raise DependencyException(m.format(name, not_found, self.version))
return
- found_msg += [mlog.green('YES'), self.version]
-
if self.pkg['targetFileName'].endswith('.a'):
self.static = True
@@ -889,12 +869,8 @@ class DubDependency(ExternalDependency):
if not found:
self.is_found = False
- mlog.log('Dependency', mlog.bold(name), 'found:', mlog.red('NO'))
return
- if not self.silent:
- mlog.log(*found_msg)
-
def get_compiler(self):
return self.compiler
@@ -1216,10 +1192,6 @@ class ExtraFrameworkDependency(ExternalDependency):
if self.found():
self.compile_args = ['-I' + os.path.join(self.path, self.name, 'Headers')]
self.link_args = ['-F' + self.path, '-framework', self.name.split('.')[0]]
- mlog.log('Dependency', mlog.bold(name), 'found:', mlog.green('YES'),
- os.path.join(self.path, self.name))
- else:
- mlog.log('Dependency', name, 'found:', mlog.red('NO'))
def detect(self, name, path):
lname = name.lower()
@@ -1242,6 +1214,12 @@ class ExtraFrameworkDependency(ExternalDependency):
def get_version(self):
return 'unknown'
+ def log_info(self):
+ return os.path.join(self.path, self.name)
+
+ def log_tried(self):
+ return 'framework'
+
def get_dep_identifier(name, kwargs, want_cross):
# Need immutable objects since the identifier will be used as a dict key
@@ -1277,6 +1255,8 @@ def find_external_dependency(name, env, kwargs):
pkg_exc = None
pkgdep = []
+ details = ''
+
for c in candidates:
# try this dependency method
try:
@@ -1288,11 +1268,33 @@ def find_external_dependency(name, env, kwargs):
if not pkg_exc:
pkg_exc = e
else:
+ details = d.log_details()
+ if details:
+ details = '(' + details + ') '
+ if 'language' in kwargs:
+ details += 'for ' + d.language + ' '
+
# if the dependency was found
if d.found():
+
+ info = d.log_info()
+ if info:
+ info = ', ' + info
+
+ mlog.log('Dependency', mlog.bold(name), details + 'found:', mlog.green('YES'), d.version + info)
+
return d
# otherwise, the dependency could not be found
+ tried_methods = [d.log_tried() for d in pkgdep if d.log_tried()]
+ if tried_methods:
+ tried = '{}'.format(mlog.format_list(tried_methods))
+ else:
+ tried = ''
+
+ mlog.log('Dependency', mlog.bold(name), details + 'found:', mlog.red('NO'),
+ '(tried {})'.format(tried) if tried else '')
+
if required:
# if exception(s) occurred, re-raise the first one (on the grounds that
# it came from a preferred dependency detection method)
@@ -1301,8 +1303,7 @@ def find_external_dependency(name, env, kwargs):
# we have a list of failed ExternalDependency objects, so we can report
# the methods we tried to find the dependency
- tried_methods = ','.join([d.type_name for d in pkgdep])
- raise DependencyException('Dependency "%s" not found, tried %s' % (name, tried_methods))
+ raise DependencyException('Dependency "%s" not found, tried %s' % (name, tried))
# return the last failed dependency object
if pkgdep:
diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py
index 7acde2d..17f9240 100644
--- a/mesonbuild/dependencies/boost.py
+++ b/mesonbuild/dependencies/boost.py
@@ -132,7 +132,6 @@ class BoostDependency(ExternalDependency):
self.incdir = self.detect_nix_incdir()
if self.check_invalid_modules():
- self.log_fail()
return
mlog.debug('Boost library root dir is', mlog.bold(self.boost_root))
@@ -146,12 +145,6 @@ class BoostDependency(ExternalDependency):
self.detect_lib_modules()
mlog.debug('Boost library directory is', mlog.bold(self.libdir))
- # 3. Report success or failure
- if self.is_found:
- self.log_success()
- else:
- self.log_fail()
-
def check_invalid_modules(self):
invalid_modules = [c for c in self.requested_modules if 'boost_' + c not in BOOST_LIBS]
@@ -172,17 +165,14 @@ class BoostDependency(ExternalDependency):
else:
return False
- def log_fail(self):
+ def log_details(self):
module_str = ', '.join(self.requested_modules)
- mlog.log("Dependency Boost (%s) found:" % module_str, mlog.red('NO'))
+ return module_str
- def log_success(self):
- module_str = ', '.join(self.requested_modules)
+ def log_info(self):
if self.boost_root:
- info = self.version + ', ' + self.boost_root
- else:
- info = self.version
- mlog.log('Dependency Boost (%s) found:' % module_str, mlog.green('YES'), info)
+ return self.boost_root
+ return ''
def detect_nix_roots(self):
return [os.path.abspath(os.path.join(x, '..'))
diff --git a/mesonbuild/dependencies/dev.py b/mesonbuild/dependencies/dev.py
index 4ea3385..0cd3c2b 100644
--- a/mesonbuild/dependencies/dev.py
+++ b/mesonbuild/dependencies/dev.py
@@ -45,7 +45,7 @@ class GTestDependency(ExternalDependency):
if self.main:
self.link_args += gtest_main_detect
self.sources = []
- mlog.log('Dependency GTest found:', mlog.green('YES'), '(prebuilt)')
+ self.prebuilt = True
elif self.detect_srcdir():
self.is_found = True
self.compile_args = ['-I' + d for d in self.src_include_dirs]
@@ -54,9 +54,8 @@ class GTestDependency(ExternalDependency):
self.sources = [self.all_src, self.main_src]
else:
self.sources = [self.all_src]
- mlog.log('Dependency GTest found:', mlog.green('YES'), '(building self)')
+ self.prebuilt = False
else:
- mlog.log('Dependency GTest found:', mlog.red('NO'))
self.is_found = False
def detect_srcdir(self):
@@ -76,6 +75,12 @@ class GTestDependency(ExternalDependency):
def need_threads(self):
return True
+ def log_info(self):
+ if self.prebuilt:
+ return 'prebuilt'
+ else:
+ return 'building self'
+
class GMockDependency(ExternalDependency):
def __init__(self, environment, kwargs):
@@ -89,7 +94,7 @@ class GMockDependency(ExternalDependency):
self.compile_args = []
self.link_args = gmock_detect
self.sources = []
- mlog.log('Dependency GMock found:', mlog.green('YES'), '(prebuilt)')
+ self.prebuilt = True
return
for d in ['/usr/src/googletest/googlemock/src', '/usr/src/gmock/src', '/usr/src/gmock']:
@@ -106,11 +111,17 @@ class GMockDependency(ExternalDependency):
self.sources = [all_src, main_src]
else:
self.sources = [all_src]
- mlog.log('Dependency GMock found:', mlog.green('YES'), '(building self)')
+ self.prebuilt = False
return
- mlog.log('Dependency GMock found:', mlog.red('NO'))
+
self.is_found = False
+ def log_info(self):
+ if self.prebuilt:
+ return 'prebuilt'
+ else:
+ return 'building self'
+
class LLVMDependency(ConfigToolDependency):
"""
@@ -145,6 +156,7 @@ class LLVMDependency(ConfigToolDependency):
super().__init__('LLVM', environment, 'cpp', kwargs)
self.provided_modules = []
self.required_modules = set()
+ self.module_details = []
if not self.is_found:
return
self.static = kwargs.get('static', False)
@@ -237,21 +249,30 @@ class LLVMDependency(ConfigToolDependency):
is required.
"""
for mod in sorted(set(modules)):
+ status = ''
+
if mod not in self.provided_modules:
- mlog.log('LLVM module', mlog.bold(mod), 'found:', mlog.red('NO'),
- '(optional)' if not required else '')
if required:
self.is_found = False
if self.required:
raise DependencyException(
'Could not find required LLVM Component: {}'.format(mod))
+ status = '(missing)'
+ else:
+ status = '(missing but optional)'
else:
self.required_modules.add(mod)
- mlog.log('LLVM module', mlog.bold(mod), 'found:', mlog.green('YES'))
+
+ self.module_details.append(mod + status)
def need_threads(self):
return True
+ def log_details(self):
+ if self.module_details:
+ return 'modules: ' + ', '.join(self.module_details)
+ return ''
+
class ValgrindDependency(PkgConfigDependency):
'''
diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py
index 389157a..78ce51b 100644
--- a/mesonbuild/dependencies/misc.py
+++ b/mesonbuild/dependencies/misc.py
@@ -103,11 +103,6 @@ class MPIDependency(ExternalDependency):
self.is_found = True
self.version, self.compile_args, self.link_args = result
- if self.is_found:
- mlog.log('Dependency', mlog.bold(self.name), 'for', self.language, 'found:', mlog.green('YES'), self.version)
- else:
- mlog.log('Dependency', mlog.bold(self.name), 'for', self.language, 'found:', mlog.red('NO'))
-
def _filter_compile_args(self, args):
"""
MPI wrappers return a bunch of garbage args.
@@ -265,10 +260,6 @@ class OpenMPDependency(ExternalDependency):
self.is_found = True
else:
mlog.log(mlog.yellow('WARNING:'), 'OpenMP found but omp.h missing.')
- if self.is_found:
- mlog.log('Dependency', mlog.bold(self.name), 'found:', mlog.green('YES'), self.version)
- else:
- mlog.log('Dependency', mlog.bold(self.name), 'found:', mlog.red('NO'))
def need_openmp(self):
return True
@@ -324,10 +315,6 @@ class Python3Dependency(ExternalDependency):
self.compile_args = fw.get_compile_args()
self.link_args = fw.get_link_args()
self.is_found = True
- if self.is_found:
- mlog.log('Dependency', mlog.bold(self.name), 'found:', mlog.green('YES'))
- else:
- mlog.log('Dependency', mlog.bold(self.name), 'found:', mlog.red('NO'))
@staticmethod
def get_windows_python_arch():
diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py
index 904c37f..c877f51 100644
--- a/mesonbuild/dependencies/ui.py
+++ b/mesonbuild/dependencies/ui.py
@@ -204,12 +204,10 @@ class QtBaseDependency(ExternalDependency):
self.bindir = None
self.private_headers = kwargs.get('private_headers', False)
mods = extract_as_list(kwargs, 'modules')
+ self.requested_modules = mods
if not mods:
raise DependencyException('No ' + self.qtname + ' modules specified.')
- type_text = 'cross' if env.is_cross_build() else 'native'
- found_msg = '{} {} {{}} dependency (modules: {}) found:' \
- ''.format(self.qtname, type_text, ', '.join(mods))
- from_text = 'pkg-config'
+ self.from_text = 'pkg-config'
# Keep track of the detection methods used, for logging purposes.
methods = []
@@ -218,21 +216,15 @@ class QtBaseDependency(ExternalDependency):
self._pkgconfig_detect(mods, kwargs)
methods.append('pkgconfig')
if not self.is_found and DependencyMethods.QMAKE in self.methods:
- from_text = self._qmake_detect(mods, kwargs)
+ self.from_text = self._qmake_detect(mods, kwargs)
methods.append('qmake-' + self.name)
methods.append('qmake')
if not self.is_found:
# Reset compile args and link args
self.compile_args = []
self.link_args = []
- from_text = '(checked {})'.format(mlog.format_list(methods))
+ self.from_text = mlog.format_list(methods)
self.version = 'none'
- if not self.silent:
- mlog.log(found_msg.format(from_text), mlog.red('NO'))
- return
- from_text = '`{}`'.format(from_text)
- if not self.silent:
- mlog.log(found_msg.format(from_text), mlog.green('YES'))
def compilers_detect(self):
"Detect Qt (4 or 5) moc, uic, rcc in the specified bindir or in PATH"
@@ -413,6 +405,16 @@ class QtBaseDependency(ExternalDependency):
def get_private_includes(self, mod_inc_dir, module):
return tuple()
+ def log_details(self):
+ module_str = ', '.join(self.requested_modules)
+ return 'modules: ' + module_str
+
+ def log_info(self):
+ return '`{}`'.format(self.from_text)
+
+ def log_tried(self):
+ return self.from_text
+
class Qt4Dependency(QtBaseDependency):
def __init__(self, env, kwargs):