diff options
-rw-r--r-- | docs/markdown/Reference-manual.md | 27 | ||||
-rw-r--r-- | docs/markdown/Release-notes-for-0.46.0.md | 7 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 11 | ||||
-rw-r--r-- | mesonbuild/interpreterbase.py | 5 | ||||
-rw-r--r-- | test cases/common/188 subdir_done/meson.build | 10 | ||||
-rw-r--r-- | test cases/failing/71 skip only subdir/meson.build | 8 | ||||
-rw-r--r-- | test cases/failing/71 skip only subdir/subdir/meson.build | 3 |
7 files changed, 70 insertions, 1 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index 54b7131..5109b25 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -1129,6 +1129,33 @@ This function has one keyword argument. recurse in the subdir if they all return `true` when queried with `.found()` +### subdir_done() + +``` meson + subdir_done() +``` + +Stops further interpretation of the meson script file from the point of +the invocation. All steps executed up to this point are valid and will +be executed by meson. This means that all targets defined before the call +of `subdir_done` will be build. + +If the current script was called by `subdir` the execution returns to the +calling directory and continues as if the script had reached the end. +If the current script is the top level script meson configures the project +as defined up to this point. + +Example: +```meson +project('example exit', 'cpp') +executable('exe1', 'exe1.cpp') +subdir_done() +executable('exe2', 'exe2.cpp') +``` + +The executable `exe1` will be build, while the executable `exe2` is not +build. + ### subproject() ``` meson diff --git a/docs/markdown/Release-notes-for-0.46.0.md b/docs/markdown/Release-notes-for-0.46.0.md index 395a94d..e062459 100644 --- a/docs/markdown/Release-notes-for-0.46.0.md +++ b/docs/markdown/Release-notes-for-0.46.0.md @@ -14,3 +14,10 @@ whose contents should look like this: ## Feature name A short description explaining the new feature and how it should be used. + +## Allow early return from a script + +Added the function `subdir_done()`. Its invocation exits the current script at +the point of invocation. All previously invoked build targets and commands are +build/executed. All following ones are ignored. If the current script was +invoked via `subdir()` the parent script continues normally. diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index c87a49b..7dbf1cc 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -26,7 +26,7 @@ from .dependencies import ExternalProgram from .dependencies import InternalDependency, Dependency, DependencyException from .interpreterbase import InterpreterBase from .interpreterbase import check_stringlist, noPosargs, noKwargs, stringArgs, permittedKwargs, permittedMethodKwargs -from .interpreterbase import InterpreterException, InvalidArguments, InvalidCode +from .interpreterbase import InterpreterException, InvalidArguments, InvalidCode, SubdirDoneRequest from .interpreterbase import InterpreterObject, MutableInterpreterObject, Disabler from .modules import ModuleReturnValue @@ -1612,6 +1612,7 @@ class Interpreter(InterpreterBase): 'static_library': self.func_static_lib, 'test': self.func_test, 'vcs_tag': self.func_vcs_tag, + 'subdir_done': self.func_subdir_done, }) if 'MESON_UNIT_TEST' in os.environ: self.funcs.update({'exception': self.func_exception}) @@ -2607,6 +2608,14 @@ root and issuing %s. return self.func_custom_target(node, [kwargs['output']], kwargs) @stringArgs + def func_subdir_done(self, node, args, kwargs): + if len(kwargs) > 0: + raise InterpreterException('exit does not take named arguments') + if len(args) > 0: + raise InterpreterException('exit does not take any arguments') + raise SubdirDoneRequest() + + @stringArgs @permittedKwargs(permitted_kwargs['custom_target']) def func_custom_target(self, node, args, kwargs): if len(args) != 1: diff --git a/mesonbuild/interpreterbase.py b/mesonbuild/interpreterbase.py index 9279506..f957d90 100644 --- a/mesonbuild/interpreterbase.py +++ b/mesonbuild/interpreterbase.py @@ -105,6 +105,9 @@ class InvalidCode(InterpreterException): class InvalidArguments(InterpreterException): pass +class SubdirDoneRequest(BaseException): + pass + class InterpreterObject: def __init__(self): self.methods = {} @@ -203,6 +206,8 @@ class InterpreterBase: try: self.current_lineno = cur.lineno self.evaluate_statement(cur) + except SubdirDoneRequest: + break except Exception as e: if not(hasattr(e, 'lineno')): e.lineno = cur.lineno diff --git a/test cases/common/188 subdir_done/meson.build b/test cases/common/188 subdir_done/meson.build new file mode 100644 index 0000000..5692f3a --- /dev/null +++ b/test cases/common/188 subdir_done/meson.build @@ -0,0 +1,10 @@ +# Should run, even though main.cpp does not exist and we call error in the last line. +# subdir_done jumps to end, so both lines are not executed. + +project('example exit', 'cpp') + +subdir_done() + +executable('main', 'main.cpp') +error('Unreachable') + diff --git a/test cases/failing/71 skip only subdir/meson.build b/test cases/failing/71 skip only subdir/meson.build new file mode 100644 index 0000000..4832bd4 --- /dev/null +++ b/test cases/failing/71 skip only subdir/meson.build @@ -0,0 +1,8 @@ +# Check that skip_rest only exits subdir, not the whole script. +# Should create an error because main.cpp does not exists. +project('example exit', 'cpp') + +subdir('subdir') + +message('Good') +executable('main', 'main.cpp') diff --git a/test cases/failing/71 skip only subdir/subdir/meson.build b/test cases/failing/71 skip only subdir/subdir/meson.build new file mode 100644 index 0000000..1ba447b --- /dev/null +++ b/test cases/failing/71 skip only subdir/subdir/meson.build @@ -0,0 +1,3 @@ +subdir_done() + +error('Unreachable') |