Skip to content

Commit

Permalink
interpreter: add feature.disable_auto_if()
Browse files Browse the repository at this point in the history
Add a method to downgrade an option to disabled if it is not used.
This is useful to avoid unnecessary search for dependencies;
for example

    dep = dependency('dep', required: get_option('feature').disable_auto_if(not foo))

can be used instead of the more verbose and complex

    if get_option('feature').auto() and not foo then
      dep = dependency('', required: false)
    else
      dep = dependency('dep', required: get_option('feature'))
    endif

or to avoid unnecessary dependency searches:

  dep1 = dependency('dep1', required: get_option('foo'))
  # dep2 is only used together with dep1
  dep2 = dependency('dep2', required: get_option('foo').disable_auto_if(not dep1.found()))
 ```

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
bonzini committed May 31, 2021
1 parent 1c208e6 commit ede6692
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 0 deletions.
9 changes: 9 additions & 0 deletions docs/markdown/Reference-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -2819,6 +2819,15 @@ The following methods are defined for all [`feature` options](Build-options.md#f
- `disabled()`: returns whether the feature was set to `'disabled'`
- `auto()`: returns whether the feature was set to `'auto'`
- `allowed()` *(since 0.59.0)*: returns whether the feature was set to `'enabled'` or `'auto'`
- `disable_auto_if(value)` *(since 0.59.0)*: returns the feature, with
`'auto'` converted to `'disabled'` if value is true.

| Feature / Condition | True | False |
| ------------------- | ---- | ----- |
| Enabled | Enabled | Enabled |
| Disabled | Disabled | Disabled |
| Auto | Disabled | Auto |

- `require(value, error_message: '')` *(since 0.59.0)*: returns
the object itself if the value is true; an error if the object is
`'enabled'` and the value is false; a disabled feature if the object
Expand Down
9 changes: 9 additions & 0 deletions mesonbuild/interpreter/interpreterobjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def __init__(self, env: 'Environment', name: str, option: coredata.UserFeatureOp
'allowed': self.allowed_method,
'auto': self.auto_method,
'require': self.require_method,
'disable_auto_if': self.disable_auto_if_method,
})

@property
Expand Down Expand Up @@ -122,6 +123,14 @@ def require_method(self, args, kwargs):
raise InterpreterException(prefix + error_message)
return self.as_disabled()

@permittedKwargs({})
def disable_auto_if_method(self, args, kwargs):
if len(args) != 1:
raise InvalidArguments('Expected 1 argument, got %d.' % (len(args), ))
if not isinstance(args[0], bool):
raise InvalidArguments('boolean argument expected.')
return self if self.value != 'auto' or not args[0] else self.as_disabled()


class RunProcess(InterpreterObject):

Expand Down
6 changes: 6 additions & 0 deletions test cases/common/192 feature option/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,26 @@ assert(not required_opt.disabled(), 'Should be enabled option')
assert(not required_opt.auto(), 'Should be enabled option')
assert(required_opt.allowed(), 'Should be enabled option')
assert(required_opt.require(true, error_message: 'xyz').enabled(), 'Should be enabled option')
assert(required_opt.disable_auto_if(true).enabled(), 'Should be enabled option')
assert(required_opt.disable_auto_if(false).enabled(), 'Should be enabled option')

assert(not optional_opt.enabled(), 'Should be auto option')
assert(not optional_opt.disabled(), 'Should be auto option')
assert(optional_opt.auto(), 'Should be auto option')
assert(optional_opt.allowed(), 'Should be auto option')
assert(optional_opt.require(true).auto(), 'Should be auto option')
assert(optional_opt.require(false, error_message: 'xyz').disabled(), 'Should be disabled auto option')
assert(optional_opt.disable_auto_if(true).disabled(), 'Should be disabled auto option')
assert(optional_opt.disable_auto_if(false).auto(), 'Should be auto option')

assert(not disabled_opt.enabled(), 'Should be disabled option')
assert(disabled_opt.disabled(), 'Should be disabled option')
assert(not disabled_opt.auto(), 'Should be disabled option')
assert(not disabled_opt.allowed(), 'Should be disabled option')
assert(disabled_opt.require(true).disabled(), 'Should be disabled option')
assert(disabled_opt.require(false, error_message: 'xyz').disabled(), 'Should be disabled option')
assert(disabled_opt.disable_auto_if(true).disabled(), 'Should be disabled option')
assert(disabled_opt.disable_auto_if(false).disabled(), 'Should be disabled option')

dep = dependency('threads', required : required_opt)
assert(dep.found(), 'Should find required "threads" dep')
Expand Down

0 comments on commit ede6692

Please sign in to comment.