aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2018-01-02 22:25:24 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2018-02-08 00:33:44 +0200
commit54d78170876e7b762aa3452faa44ec1b7cd44372 (patch)
tree7c65bb478818a90fa3d3991da4c6ca8b2c641eb2 /mesonbuild
parent0204895143d4aacf143be952f962dc47e415c187 (diff)
downloadmeson-54d78170876e7b762aa3452faa44ec1b7cd44372.zip
meson-54d78170876e7b762aa3452faa44ec1b7cd44372.tar.gz
meson-54d78170876e7b762aa3452faa44ec1b7cd44372.tar.bz2
User options can "yield to" a user option of the same name in superproject. Closes ##2853.
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/coredata.py30
-rw-r--r--mesonbuild/interpreter.py8
-rw-r--r--mesonbuild/optinterpreter.py37
3 files changed, 50 insertions, 25 deletions
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index c96a09e..f87e62c 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -1,5 +1,4 @@
-
-# Copyright 2012-2017 The Meson development team
+# Copyright 2012-2018 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -25,12 +24,19 @@ import ast
version = '0.45.0.dev1'
backendlist = ['ninja', 'vs', 'vs2010', 'vs2015', 'vs2017', 'xcode']
+default_yielding = False
+
class UserOption:
- def __init__(self, name, description, choices):
+ def __init__(self, name, description, choices, yielding):
super().__init__()
self.name = name
self.choices = choices
self.description = description
+ if yielding is None:
+ yielding = default_yielding
+ if not isinstance(yielding, bool):
+ raise MesonException('Value of "yielding" must be a boolean.')
+ self.yielding = yielding
# Check that the input is a valid value and return the
# "cleaned" or "native" version. For example the Boolean
@@ -39,8 +45,8 @@ class UserOption:
raise RuntimeError('Derived option class did not override validate_value.')
class UserStringOption(UserOption):
- def __init__(self, name, description, value, choices=None):
- super().__init__(name, description, choices)
+ def __init__(self, name, description, value, choices=None, yielding=None):
+ super().__init__(name, description, choices, yielding)
self.set_value(value)
def validate(self, value):
@@ -56,8 +62,8 @@ class UserStringOption(UserOption):
return value
class UserBooleanOption(UserOption):
- def __init__(self, name, description, value):
- super().__init__(name, description, [True, False])
+ def __init__(self, name, description, value, yielding=None):
+ super().__init__(name, description, [True, False], yielding)
self.set_value(value)
def tobool(self, thing):
@@ -79,8 +85,8 @@ class UserBooleanOption(UserOption):
return self.tobool(value)
class UserIntegerOption(UserOption):
- def __init__(self, name, description, min_value, max_value, value):
- super().__init__(name, description, None)
+ def __init__(self, name, description, min_value, max_value, value, yielding=None):
+ super().__init__(name, description, [True, False], yielding)
self.min_value = min_value
self.max_value = max_value
self.set_value(value)
@@ -112,8 +118,8 @@ class UserIntegerOption(UserOption):
return self.toint(value)
class UserComboOption(UserOption):
- def __init__(self, name, description, choices, value):
- super().__init__(name, description, choices)
+ def __init__(self, name, description, choices, value, yielding=None):
+ super().__init__(name, description, choices, yielding)
if not isinstance(self.choices, list):
raise MesonException('Combo choices must be an array.')
for i in self.choices:
@@ -134,7 +140,7 @@ class UserComboOption(UserOption):
class UserArrayOption(UserOption):
def __init__(self, name, description, value, **kwargs):
- super().__init__(name, description, kwargs.get('choices', []))
+ super().__init__(name, description, kwargs.get('choices', []), yielding=kwargs.get('yielding', None))
self.set_value(value, user_input=False)
def validate(self, value, user_input):
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index f68e25f..31d7616 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1768,7 +1768,7 @@ external dependencies (including libraries) must go to "dependencies".''')
def func_get_option(self, nodes, args, kwargs):
if len(args) != 1:
raise InterpreterException('Argument required for get_option.')
- optname = args[0]
+ undecorated_optname = optname = args[0]
if ':' in optname:
raise InterpreterException('''Having a colon in option name is forbidden, projects are not allowed
to directly access options of other subprojects.''')
@@ -1787,7 +1787,11 @@ to directly access options of other subprojects.''')
if not coredata.is_builtin_option(optname) and self.is_subproject():
optname = self.subproject + ':' + optname
try:
- return self.environment.coredata.user_options[optname].value
+ opt = self.environment.coredata.user_options[optname]
+ if opt.yielding and ':' in optname:
+ # If option not present in superproject, keep the original.
+ opt = self.environment.coredata.user_options.get(undecorated_optname, opt)
+ return opt.value
except KeyError:
pass
if optname.endswith('_link_args'):
diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py
index 7eeaa48..d4ea06a 100644
--- a/mesonbuild/optinterpreter.py
+++ b/mesonbuild/optinterpreter.py
@@ -64,16 +64,21 @@ def permitted_kwargs(permitted):
optname_regex = re.compile('[^a-zA-Z0-9_-]')
-@permitted_kwargs({'value'})
+@permitted_kwargs({'value', 'yield'})
def StringParser(name, description, kwargs):
- return coredata.UserStringOption(name, description,
- kwargs.get('value', ''), kwargs.get('choices', []))
+ return coredata.UserStringOption(name,
+ description,
+ kwargs.get('value', ''),
+ kwargs.get('choices', []),
+ kwargs.get('yield', coredata.default_yielding))
-@permitted_kwargs({'value'})
+@permitted_kwargs({'value', 'yield'})
def BooleanParser(name, description, kwargs):
- return coredata.UserBooleanOption(name, description, kwargs.get('value', True))
+ return coredata.UserBooleanOption(name, description,
+ kwargs.get('value', True),
+ kwargs.get('yield', coredata.default_yielding))
-@permitted_kwargs({'value', 'choices'})
+@permitted_kwargs({'value', 'yiel', 'choices'})
def ComboParser(name, description, kwargs):
if 'choices' not in kwargs:
raise OptionException('Combo option missing "choices" keyword.')
@@ -83,9 +88,14 @@ def ComboParser(name, description, kwargs):
for i in choices:
if not isinstance(i, str):
raise OptionException('Combo choice elements must be strings.')
- return coredata.UserComboOption(name, description, choices, kwargs.get('value', choices[0]))
+ return coredata.UserComboOption(name,
+ description,
+ choices,
+ kwargs.get('value', choices[0]),
+ kwargs.get('yield', coredata.default_yielding),)
-@permitted_kwargs({'value', 'min', 'max'})
+
+@permitted_kwargs({'value', 'min', 'max', 'yield'})
def IntegerParser(name, description, kwargs):
if 'value' not in kwargs:
raise OptionException('Integer option must contain value argument.')
@@ -93,9 +103,10 @@ def IntegerParser(name, description, kwargs):
description,
kwargs.get('min', None),
kwargs.get('max', None),
- kwargs['value'])
+ kwargs['value'],
+ kwargs.get('yield', coredata.default_yielding))
-@permitted_kwargs({'value', 'choices'})
+@permitted_kwargs({'value', 'yield', 'choices'})
def string_array_parser(name, description, kwargs):
if 'choices' in kwargs:
choices = kwargs['choices']
@@ -110,7 +121,11 @@ def string_array_parser(name, description, kwargs):
value = kwargs.get('value', [])
if not isinstance(value, list):
raise OptionException('Array choices must be passed as an array.')
- return coredata.UserArrayOption(name, description, value, choices=choices)
+ return coredata.UserArrayOption(name,
+ description,
+ value,
+ choices=choices,
+ yielding=kwargs.get('yield', coredata.default_yielding))
option_types = {'string': StringParser,
'boolean': BooleanParser,