Interpreter: Fallback when required is false but forcefallback is true

pull/8701/head
Xavier Claessens 4 years ago committed by Jussi Pakkanen
parent b6d277c140
commit 3af39a463b
  1. 3
      docs/markdown/Wrap-dependency-system-manual.md
  2. 21
      docs/markdown/snippets/forcefallback.md
  3. 16
      mesonbuild/interpreter/interpreter.py
  4. 8
      run_unittests.py
  5. 8
      test cases/unit/95 implicit force fallback/meson.build
  6. 3
      test cases/unit/95 implicit force fallback/subprojects/something/meson.build

@ -189,6 +189,9 @@ endif
`dependency('foo-1.0', required: get_option('foo_opt'))` will only
fallback when the user sets `foo_opt` to `enabled` instead of
`auto`.
*Since 0.58.0* optional dependency like above will fallback to the subproject
defined in the wrap file in the case `wrap_mode` is set to `forcefallback`
or `force_fallback_for` contains the subproject.
If it is desired to fallback for an optional dependency, the
`fallback` or `allow_fallback` keyword arguments must be passed

@ -0,0 +1,21 @@
## Use fallback from wrap file when force fallback
Optional dependency like below will now fallback to the subproject
defined in the wrap file in the case `wrap_mode` is set to `forcefallback`
or `force_fallback_for` contains the subproject.
```meson
# required is false because we could fallback to cc.find_library(), but in the
# forcefallback case this now configure the subproject.
dep = dependency('foo-1.0', required: false)
if not dep.found()
dep = cc.find_library('foo', has_headers: 'foo.h')
endif
```
```ini
[wrap-file]
...
[provide]
dependency_names = foo-1.0
```

@ -1598,6 +1598,11 @@ external dependencies (including libraries) must go to "dependencies".''')
if not isinstance(allow_fallback, bool):
raise InvalidArguments('"allow_fallback" argument must be boolean')
wrap_mode = self.coredata.get_option(OptionKey('wrap_mode'))
force_fallback_for = self.coredata.get_option(OptionKey('force_fallback_for'))
force_fallback |= (wrap_mode == WrapMode.forcefallback or
name in force_fallback_for)
# If "fallback" is absent, look for an implicit fallback.
if name and fallback is None and allow_fallback is not False:
# Add an implicit fallback if we have a wrap file or a directory with the same name,
@ -1609,7 +1614,8 @@ external dependencies (including libraries) must go to "dependencies".''')
if not provider and allow_fallback is True:
raise InvalidArguments('Fallback wrap or subproject not found for dependency \'%s\'' % name)
subp_name = mesonlib.listify(provider)[0]
if provider and (allow_fallback is True or required or self.get_subproject(subp_name)):
force_fallback |= subp_name in force_fallback_for
if provider and (allow_fallback is True or required or self.get_subproject(subp_name) or force_fallback):
fallback = provider
if 'default_options' in kwargs and not fallback:
@ -1640,13 +1646,7 @@ external dependencies (including libraries) must go to "dependencies".''')
subp_name, varname = self.get_subproject_infos(fallback)
if self.get_subproject(subp_name):
return self.get_subproject_dep(name, display_name, subp_name, varname, kwargs)
wrap_mode = self.coredata.get_option(OptionKey('wrap_mode'))
force_fallback_for = self.coredata.get_option(OptionKey('force_fallback_for'))
force_fallback = (force_fallback or
wrap_mode == WrapMode.forcefallback or
name in force_fallback_for or
subp_name in force_fallback_for)
force_fallback |= subp_name in force_fallback_for
if name != '' and (not fallback or not force_fallback):
self._handle_featurenew_dependencies(name)

@ -2513,6 +2513,14 @@ class AllPlatformTests(BasePlatformTests):
self.build()
self.run_tests()
def test_implicit_forcefallback(self):
testdir = os.path.join(self.unit_test_dir, '95 implicit force fallback')
with self.assertRaises(subprocess.CalledProcessError) as cm:
self.init(testdir)
self.init(testdir, extra_args=['--wrap-mode=forcefallback'])
self.new_builddir()
self.init(testdir, extra_args=['--force-fallback-for=something'])
def test_nopromote(self):
testdir = os.path.join(self.common_test_dir, '99 subproject subdir')
with self.assertRaises(subprocess.CalledProcessError) as cm:

@ -0,0 +1,8 @@
project('implicit force fallback')
# The dependency 'something' is provided by a subproject. Normally this won't
# use the fallback subproject because required is false. However this unit test
# is configured with wrap_mode=forcefallback and force_fallback_for=something
# in which case we are expecting the fallback to be done.
d = dependency('something', required: false)
assert(d.found())

@ -0,0 +1,3 @@
project('something')
meson.override_dependency('something', declare_dependency())
Loading…
Cancel
Save