aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/interpreter.py4
-rw-r--r--mesonbuild/interpreterbase.py21
-rwxr-xr-xrun_unittests.py5
-rw-r--r--test cases/unit/82 meson version compare/meson.build17
4 files changed, 44 insertions, 3 deletions
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 2924172..322cc26 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -30,7 +30,7 @@ from .interpreterbase import check_stringlist, flatten, noPosargs, noKwargs, str
from .interpreterbase import InterpreterException, InvalidArguments, InvalidCode, SubdirDoneRequest
from .interpreterbase import InterpreterObject, MutableInterpreterObject, Disabler, disablerIfNotFound
from .interpreterbase import FeatureNew, FeatureDeprecated, FeatureNewKwargs, FeatureDeprecatedKwargs
-from .interpreterbase import ObjectHolder
+from .interpreterbase import ObjectHolder, MesonVersionString
from .modules import ModuleReturnValue
from .cmake import CMakeInterpreter
from .backend.backends import TestProtocol
@@ -2172,7 +2172,7 @@ class MesonMain(InterpreterObject):
@noPosargs
@permittedKwargs({})
def version_method(self, args, kwargs):
- return coredata.version
+ return MesonVersionString(coredata.version)
@noPosargs
@permittedKwargs({})
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:
diff --git a/run_unittests.py b/run_unittests.py
index c095605..8c03693 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -5094,6 +5094,11 @@ recommended as it is not supported on some platforms''')
self.init(testdir)
self.build()
+ def test_meson_version_compare(self):
+ testdir = os.path.join(self.unit_test_dir, '82 meson version compare')
+ out = self.init(testdir)
+ self.assertNotRegex(out, r'WARNING')
+
class FailureTests(BasePlatformTests):
'''
Tests that test failure conditions. Build files here should be dynamically
diff --git a/test cases/unit/82 meson version compare/meson.build b/test cases/unit/82 meson version compare/meson.build
new file mode 100644
index 0000000..ed69a8b
--- /dev/null
+++ b/test cases/unit/82 meson version compare/meson.build
@@ -0,0 +1,17 @@
+project('version compare', meson_version: '>= 0.1')
+
+if meson.version().version_compare('>= 9999')
+ error('This should not be executed')
+elif meson.version().version_compare('>= 0.55') and false
+ error('This should not be executed')
+elif not meson.version().version_compare('>= 0.55')
+ error('This should not be executed')
+elif meson.version().version_compare('>= 0.55')
+ # This Should not produce warning even when using function not available in
+ # meson 0.1.
+ foo_dep = declare_dependency()
+ meson.override_dependency('foo', foo_dep)
+endif
+
+# This will error out if elif cause did not enter
+assert(foo_dep.found(), 'meson.version_compare did not work')