diff options
author | Xavier Claessens <xavier.claessens@collabora.com> | 2018-12-19 20:56:07 -0500 |
---|---|---|
committer | Xavier Claessens <xavier.claessens@collabora.com> | 2020-03-06 15:25:46 -0500 |
commit | 2fdedc4d0fc73c509669bf9f89863017e0f0989b (patch) | |
tree | fcb933a45797f7a1a1ef4516ba709dfd0888f781 /mesonbuild | |
parent | 74769617907f571d2099001d3a7443e23b4f6cda (diff) | |
download | meson-2fdedc4d0fc73c509669bf9f89863017e0f0989b.zip meson-2fdedc4d0fc73c509669bf9f89863017e0f0989b.tar.gz meson-2fdedc4d0fc73c509669bf9f89863017e0f0989b.tar.bz2 |
Add meson.override_dependency()
Similar to meson.override_find_program() but overrides the result of the
dependency() function.
Also ensure that dependency() always returns the same result when
looking for the same dependency, this fixes cases where parts of the
project could be using a system library and other parts use the library
provided by a subproject.
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/build.py | 1 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 71 |
2 files changed, 55 insertions, 17 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 48d21b1..33820b4 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -141,6 +141,7 @@ class Build: self.test_setup_default_name = None self.find_overrides = {} self.searched_programs = set() # The list of all programs that have been searched for. + self.dependency_overrides = PerMachine({}, {}) def copy(self): other = Build(self.environment) diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 9e88975..4b978c4 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -1857,6 +1857,7 @@ class MesonMain(InterpreterObject): 'add_postconf_script': self.add_postconf_script_method, 'add_dist_script': self.add_dist_script_method, 'install_dependency_manifest': self.install_dependency_manifest_method, + 'override_dependency': self.override_dependency_method, 'override_find_program': self.override_find_program_method, 'project_version': self.project_version_method, 'project_license': self.project_license_method, @@ -2013,6 +2014,26 @@ class MesonMain(InterpreterObject): raise InterpreterException('Second argument must be an external program or executable.') self.interpreter.add_find_program_override(name, exe) + @FeatureNew('meson.override_dependency', '0.53.0') + @permittedKwargs({'native'}) + def override_dependency_method(self, args, kwargs): + if len(args) != 2: + raise InterpreterException('Override needs two arguments') + name = args[0] + dep = args[1] + if not isinstance(name, str) or not name: + raise InterpreterException('First argument must be not empty string') + if hasattr(dep, 'held_object'): + dep = dep.held_object + if not isinstance(dep, dependencies.Dependency): + raise InterpreterException('Second argument must be a dependency object') + identifier = dependencies.get_dep_identifier(name, kwargs) + for_machine = self.interpreter.machine_from_native_kwarg(kwargs) + if identifier in self.build.dependency_overrides[for_machine]: + raise InterpreterException('Tried to override dependency "%s" which has already been overridden.' + % name) + self.build.dependency_overrides[for_machine][identifier] = dep + @noPosargs @permittedKwargs({}) def project_version_method(self, args, kwargs): @@ -3218,30 +3239,38 @@ external dependencies (including libraries) must go to "dependencies".''') # Check if we want this as a build-time / build machine or runt-time / # host machine dep. for_machine = self.machine_from_native_kwarg(kwargs) - identifier = dependencies.get_dep_identifier(name, kwargs) - cached_dep = self.coredata.deps[for_machine].get(identifier) - if cached_dep: - if not cached_dep.found(): - mlog.log('Dependency', mlog.bold(name), - 'found:', mlog.red('NO'), mlog.blue('(cached)')) - return identifier, cached_dep + wanted_vers = mesonlib.stringlistify(kwargs.get('version', [])) - # Verify the cached dep version match - wanted_vers = mesonlib.stringlistify(kwargs.get('version', [])) + cached_dep = self.build.dependency_overrides[for_machine].get(identifier) + if cached_dep: found_vers = cached_dep.get_version() - if not wanted_vers or mesonlib.version_compare_many(found_vers, wanted_vers)[0]: - info = [mlog.blue('(cached)')] - if found_vers: - info = [mlog.normal_cyan(found_vers), *info] + if not self.check_version(wanted_vers, found_vers): mlog.log('Dependency', mlog.bold(name), - 'found:', mlog.green('YES'), *info) - return identifier, cached_dep + 'found:', mlog.red('NO'), + 'found', mlog.normal_cyan(found_vers), 'but need:', + mlog.bold(', '.join(["'{}'".format(e) for e in wanted_vers])), + mlog.blue('(cached)')) + return identifier, NotFoundDependency(self.environment) + else: + cached_dep = self.coredata.deps[for_machine].get(identifier) + if cached_dep: + found_vers = cached_dep.get_version() + if not self.check_version(wanted_vers, found_vers): + return identifier, None + + if cached_dep: + info = [mlog.blue('(cached)')] + if found_vers: + info = [mlog.normal_cyan(found_vers), *info] + mlog.log('Dependency', mlog.bold(name), + 'found:', mlog.green('YES'), *info) + return identifier, cached_dep return identifier, None @staticmethod - def check_subproject_version(wanted, found): + def check_version(wanted, found): if not wanted: return True if found == 'undefined' or not mesonlib.version_compare_many(found, wanted)[0]: @@ -3278,7 +3307,7 @@ external dependencies (including libraries) must go to "dependencies".''') return dep found = dep.held_object.get_version() - if not self.check_subproject_version(wanted, found): + if not self.check_version(wanted, found): if required: raise DependencyException('Version {} of subproject dependency {} already ' 'cached, requested incompatible version {} for ' @@ -3330,6 +3359,14 @@ external dependencies (including libraries) must go to "dependencies".''') raise if not d.found() and not_found_message: self.message_impl([not_found_message]) + self.message_impl([not_found_message]) + # Override this dependency to have consistent results in subsequent + # dependency lookups. + if name and d.found(): + for_machine = self.machine_from_native_kwarg(kwargs) + identifier = dependencies.get_dep_identifier(name, kwargs) + if identifier not in self.build.dependency_overrides[for_machine]: + self.build.dependency_overrides[for_machine][identifier] = d.held_object return d def dependency_impl(self, name, display_name, kwargs): |