Simplify dependency() fallback

Now that subprojects can override the dependency name, there is no need
to provide a variable name for the fallback any more.
pull/6203/head
Xavier Claessens 5 years ago
parent 2fdedc4d0f
commit 943e9368f7
  1. 4
      docs/markdown/Reference-manual.md
  2. 6
      docs/markdown/snippets/override_dependency.md
  3. 38
      mesonbuild/interpreter.py
  4. 10
      run_unittests.py
  5. 4
      test cases/common/102 subproject subdir/meson.build
  6. 3
      test cases/common/102 subproject subdir/subprojects/sub_novar/meson.build

@ -445,6 +445,10 @@ arguments:
[`dependency()`](#dependency), etc. Note that this means the
fallback dependency may be a not-found dependency, in which
case the value of the `required:` kwarg will be obeyed.
*Since 0.54.0* `'subproj_dep'` argument can be omitted in the case the
subproject used `meson.override_dependency('dependency_name', subproj_dep)`.
In that case, the `fallback` keyword argument can be a single string instead
of a list of 2 strings.
- `language` *(added 0.42.0)* defines what language-specific
dependency to find if it's available for multiple languages.
- `method` defines the way the dependency is detected, the default is

@ -57,3 +57,9 @@ If the subproject does `dependency('foo')` but the main project wants to provide
its own implementation of `foo`, it can for example call
`meson.override_dependency('foo', declare_dependency(...))` before configuring the
subproject.
## Simplified `dependency()` fallback
In the case a subproject `foo` calls `meson.override_dependency('foo-2.0', foo_dep)`,
the parent project can omit the dependency variable name in fallback keyword
argument: `dependency('foo-2.0', fallback : 'foo')`.

@ -3280,10 +3280,24 @@ external dependencies (including libraries) must go to "dependencies".''')
def notfound_dependency(self):
return DependencyHolder(NotFoundDependency(self.environment), self.subproject)
def get_subproject_dep(self, display_name, dirname, varname, kwargs):
def get_subproject_dep(self, name, display_name, dirname, varname, kwargs):
required = kwargs.get('required', True)
wanted = mesonlib.stringlistify(kwargs.get('version', []))
subproj_path = os.path.join(self.subproject_dir, dirname)
dep = self.notfound_dependency()
try:
subproject = self.subprojects[dirname]
if varname is None:
# Assuming the subproject overriden the dependency we want
_, cached_dep = self._find_cached_dep(name, kwargs)
if cached_dep:
if required and not cached_dep.found():
m = 'Dependency {!r} is not satisfied'
raise DependencyException(m.format(display_name))
return DependencyHolder(cached_dep, self.subproject)
else:
m = 'Subproject {} did not override dependency {}'
raise DependencyException(m.format(subproj_path, display_name))
if subproject.found():
dep = self.subprojects[dirname].get_variable_method([varname], {})
except InvalidArguments:
@ -3293,10 +3307,6 @@ external dependencies (including libraries) must go to "dependencies".''')
raise InvalidCode('Fetched variable {!r} in the subproject {!r} is '
'not a dependency object.'.format(varname, dirname))
required = kwargs.get('required', True)
wanted = mesonlib.stringlistify(kwargs.get('version', []))
subproj_path = os.path.join(self.subproject_dir, dirname)
if not dep.found():
if required:
raise DependencyException('Could not find dependency {} in subproject {}'
@ -3400,7 +3410,7 @@ external dependencies (including libraries) must go to "dependencies".''')
if has_fallback:
dirname, varname = self.get_subproject_infos(kwargs)
if dirname in self.subprojects:
return self.get_subproject_dep(name, dirname, varname, kwargs)
return self.get_subproject_dep(name, display_name, dirname, varname, kwargs)
wrap_mode = self.coredata.get_builtin_option('wrap_mode')
forcefallback = wrap_mode == WrapMode.forcefallback and has_fallback
@ -3420,7 +3430,7 @@ external dependencies (including libraries) must go to "dependencies".''')
return DependencyHolder(dep, self.subproject)
if has_fallback:
return self.dependency_fallback(display_name, kwargs)
return self.dependency_fallback(name, display_name, kwargs)
return self.notfound_dependency()
@ -3448,13 +3458,15 @@ external dependencies (including libraries) must go to "dependencies".''')
mlog.warning(*message, location=self.current_node)
def get_subproject_infos(self, kwargs):
fbinfo = kwargs['fallback']
check_stringlist(fbinfo)
if len(fbinfo) != 2:
raise InterpreterException('Fallback info must have exactly two items.')
fbinfo = mesonlib.stringlistify(kwargs['fallback'])
if len(fbinfo) == 1:
FeatureNew('Fallback without variable name', '0.53.0').use(self.subproject)
return fbinfo[0], None
elif len(fbinfo) != 2:
raise InterpreterException('Fallback info must have one or two items.')
return fbinfo
def dependency_fallback(self, display_name, kwargs):
def dependency_fallback(self, name, display_name, kwargs):
required = kwargs.get('required', True)
if self.coredata.get_builtin_option('wrap_mode') == WrapMode.nofallback:
mlog.log('Not looking for a fallback subproject for the dependency',
@ -3476,7 +3488,7 @@ external dependencies (including libraries) must go to "dependencies".''')
'required': required,
}
self.do_subproject(dirname, 'meson', sp_kwargs)
return self.get_subproject_dep(display_name, dirname, varname, kwargs)
return self.get_subproject_dep(name, display_name, dirname, varname, kwargs)
@FeatureNewKwargs('executable', '0.42.0', ['implib'])
@permittedKwargs(permitted_kwargs['executable'])

@ -3981,10 +3981,16 @@ recommended as it is not supported on some platforms''')
'descriptive_name': 'sub',
'name': 'sub',
'version': '1.0'
}
},
{
'descriptive_name': 'sub-novar',
'name': 'sub_novar',
'version': '1.0',
},
]
}
self.assertDictEqual(res, expected)
res['subprojects'] = sorted(res['subprojects'], key=lambda i: i['name'])
self.assertDictEqual(expected, res)
def test_introspection_target_subproject(self):
testdir = os.path.join(self.common_test_dir, '45 subproject')

@ -17,3 +17,7 @@ assert(not d.found(), 'version should not match')
dependency('sub2', required : false)
d = dependency('sub2', fallback: ['sub', 'libSub'])
assert(d.found(), 'Should fallback even if a previous call returned not-found')
# Verify we can get a fallback dependency without specifying the variable name,
# because the subproject overridden 'sub-novar'.
dependency('sub-novar', fallback : 'sub_novar')

@ -0,0 +1,3 @@
project('sub-novar', 'c', version : '1.0')
meson.override_dependency('sub-novar', declare_dependency())
Loading…
Cancel
Save