Allow meson build file to exit early. (#2808)
This commit is contained in:
parent
6146353f45
commit
37d379ebe5
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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})
|
||||
|
@ -2606,6 +2607,14 @@ root and issuing %s.
|
|||
kwargs.setdefault('build_always', True)
|
||||
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):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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')
|
||||
|
|
@ -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')
|
|
@ -0,0 +1,3 @@
|
|||
subdir_done()
|
||||
|
||||
error('Unreachable')
|
Loading…
Reference in New Issue