aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/interpreterbase.py
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2020-08-14 17:41:18 -0400
committerXavier Claessens <xclaesse@gmail.com>2020-09-02 12:55:31 -0400
commit9365486104dc66ee05d5bfaf97a0e83ce9d1289d (patch)
tree778b787e9973e3b0eab2bf80903a2e77aeca3634 /mesonbuild/interpreterbase.py
parentbfb8d25deb794e9506775caa023bbf278dcf17e1 (diff)
downloadmeson-9365486104dc66ee05d5bfaf97a0e83ce9d1289d.zip
meson-9365486104dc66ee05d5bfaf97a0e83ce9d1289d.tar.gz
meson-9365486104dc66ee05d5bfaf97a0e83ce9d1289d.tar.bz2
Special case meson.version().version_compare() statement
when that statement gets evaluated, the interpreter remembers the version target and if it was part of the evaluation of a `if` condition then the target meson version is temporally overriden within that if-block. Fixes: #7590
Diffstat (limited to 'mesonbuild/interpreterbase.py')
-rw-r--r--mesonbuild/interpreterbase.py21
1 files changed, 20 insertions, 1 deletions
diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py
index 6c4f273..e071243 100644
--- a/mesonbuild/interpreterbase.py
+++ b/mesonbuild/interpreterbase.py
@@ -54,6 +54,9 @@ TYPE_var = T.Union[TYPE_elementary, list, dict, InterpreterObject, ObjectHolder]
TYPE_nvar = T.Union[TYPE_var, mparser.BaseNode]
TYPE_nkwargs = T.Dict[T.Union[mparser.BaseNode, str], TYPE_nvar]
+class MesonVersionString(str):
+ pass
+
# Decorators for method calls.
def check_stringlist(a: T.Any, msg: str = 'Arguments must be strings.') -> None:
@@ -451,6 +454,11 @@ class InterpreterBase:
# Current node set during a function call. This can be used as location
# when printing a warning message during a method call.
self.current_node = None # type: mparser.BaseNode
+ # This is set to `version_string` when this statement is evaluated:
+ # meson.version().compare_version(version_string)
+ # If it was part of a if-clause, it is used to temporally override the
+ # current meson version target within that if-block.
+ self.tmp_meson_version = None # type: str
def load_root_meson_file(self) -> None:
mesonfile = os.path.join(self.source_root, self.subdir, environment.build_filename)
@@ -606,13 +614,22 @@ class InterpreterBase:
def evaluate_if(self, node: mparser.IfClauseNode) -> T.Optional[Disabler]:
assert(isinstance(node, mparser.IfClauseNode))
for i in node.ifs:
+ # Reset self.tmp_meson_version to know if it gets set during this
+ # statement evaluation.
+ self.tmp_meson_version = None
result = self.evaluate_statement(i.condition)
if isinstance(result, Disabler):
return result
if not(isinstance(result, bool)):
raise InvalidCode('If clause {!r} does not evaluate to true or false.'.format(result))
if result:
- self.evaluate_codeblock(i.block)
+ prev_meson_version = mesonlib.project_meson_versions[self.subproject]
+ if self.tmp_meson_version:
+ mesonlib.project_meson_versions[self.subproject] = self.tmp_meson_version
+ try:
+ self.evaluate_codeblock(i.block)
+ finally:
+ mesonlib.project_meson_versions[self.subproject] = prev_meson_version
return None
if not isinstance(node.elseblock, mparser.EmptyNode):
self.evaluate_codeblock(node.elseblock)
@@ -1023,6 +1040,8 @@ The result of this is undefined and will become a hard error in a future Meson r
cmpr = posargs[0]
if not isinstance(cmpr, str):
raise InterpreterException('Version_compare() argument must be a string.')
+ if isinstance(obj, MesonVersionString):
+ self.tmp_meson_version = cmpr
return mesonlib.version_compare(obj, cmpr)
elif method_name == 'substring':
if len(posargs) > 2: