Skip to content

Commit

Permalink
Implicit dependency fallback when a subproject wrap or dir exists
Browse files Browse the repository at this point in the history
  • Loading branch information
xclaesse committed Jul 1, 2020
1 parent 64f3661 commit 56c9e95
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 3 deletions.
4 changes: 3 additions & 1 deletion docs/markdown/Reference-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,9 @@ arguments:
*(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.
of a list of 2 strings. *Since 0.55.0* the `fallback` keyword argument can be
omitted when there is a wrap file or a directory with the same `dependency_name`,
and subproject used `meson.override_dependency('dependency_name', subproj_dep)`.
- `language` *(since 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
Expand Down
9 changes: 9 additions & 0 deletions docs/markdown/snippets/implicit_fallback.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## Implicit dependency fallback

`dependency('foo')` now automatically fallback if the dependency is not found on
the system but a subproject wrap file or directory exists with the same name.

That means that simply adding `subprojects/foo.wrap` is enough to add fallback
to any `dependency('foo')` call. It is however requires that the subproject call
`meson.override_dependency('foo', foo_dep)` to specify which dependency object
should be used for `foo`.
8 changes: 8 additions & 0 deletions mesonbuild/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -3549,6 +3549,14 @@ def dependency_impl(self, name, display_name, kwargs):
return self.notfound_dependency()

has_fallback = 'fallback' in kwargs
if not has_fallback and name:
# Add an implicit fallback if we have a wrap file or a directory with the same name.
subproject_dir_abs = os.path.join(self.environment.get_source_dir(), self.subproject_dir)
wrap_, directory = wrap.get_directory(subproject_dir_abs, name)
if wrap_ or os.path.exists(os.path.join(subproject_dir_abs, directory)):
kwargs['fallback'] = name
has_fallback = True

if 'default_options' in kwargs and not has_fallback:
mlog.warning('The "default_options" keyworg argument does nothing without a "fallback" keyword argument.',
location=self.current_node)
Expand Down
5 changes: 5 additions & 0 deletions run_unittests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4080,6 +4080,11 @@ def test_introspect_projectinfo_subprojects(self):
'name': 'sub',
'version': '1.0'
},
{
'descriptive_name': 'sub_implicit',
'name': 'sub_implicit',
'version': '1.0',
},
{
'descriptive_name': 'sub-novar',
'name': 'sub_novar',
Expand Down
4 changes: 4 additions & 0 deletions test cases/common/102 subproject subdir/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@ dependency('sub-novar', fallback : 'sub_novar')
# Verify a subproject can force a dependency to be not-found
d = dependency('sub-notfound', fallback : 'sub_novar', required : false)
assert(not d.found(), 'Dependency should be not-found')

# Verify that implicit fallback works because subprojects/sub_implicit directory exists
d = dependency('sub_implicit')
assert(d.found(), 'Should implicitly fallback')
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
project('sub_implicit', 'c', version : '1.0')

dep = declare_dependency()
meson.override_dependency('sub_implicit', dep)
4 changes: 2 additions & 2 deletions test cases/linuxlike/5 dependency versions/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ dependency('somebrokenlib', version : '>=1.0', required : false)

# Search for an external dependency that won't be found, but must later be
# found via fallbacks
somelibnotfound = dependency('somelib', required : false)
somelibnotfound = dependency('somelib1', required : false)
assert(somelibnotfound.found() == false, 'somelibnotfound was found?')
# Find internal dependency without version
somelibver = dependency('somelib',
somelibver = dependency('somelib1',
fallback : ['somelibnover', 'some_dep'])
assert(somelibver.type_name() == 'internal', 'somelibver should be of type "internal", not ' + somelibver.type_name())
# Find an internal dependency again with the same name and a specific version
Expand Down

0 comments on commit 56c9e95

Please sign in to comment.