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
|
recurse in the subdir if they all return `true` when queried with
|
||||||
`.found()`
|
`.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()
|
### subproject()
|
||||||
|
|
||||||
``` meson
|
``` meson
|
||||||
|
|
|
@ -14,3 +14,10 @@ whose contents should look like this:
|
||||||
## Feature name
|
## Feature name
|
||||||
|
|
||||||
A short description explaining the new feature and how it should be used.
|
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 .dependencies import InternalDependency, Dependency, DependencyException
|
||||||
from .interpreterbase import InterpreterBase
|
from .interpreterbase import InterpreterBase
|
||||||
from .interpreterbase import check_stringlist, noPosargs, noKwargs, stringArgs, permittedKwargs, permittedMethodKwargs
|
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 .interpreterbase import InterpreterObject, MutableInterpreterObject, Disabler
|
||||||
from .modules import ModuleReturnValue
|
from .modules import ModuleReturnValue
|
||||||
|
|
||||||
|
@ -1612,6 +1612,7 @@ class Interpreter(InterpreterBase):
|
||||||
'static_library': self.func_static_lib,
|
'static_library': self.func_static_lib,
|
||||||
'test': self.func_test,
|
'test': self.func_test,
|
||||||
'vcs_tag': self.func_vcs_tag,
|
'vcs_tag': self.func_vcs_tag,
|
||||||
|
'subdir_done': self.func_subdir_done,
|
||||||
})
|
})
|
||||||
if 'MESON_UNIT_TEST' in os.environ:
|
if 'MESON_UNIT_TEST' in os.environ:
|
||||||
self.funcs.update({'exception': self.func_exception})
|
self.funcs.update({'exception': self.func_exception})
|
||||||
|
@ -2606,6 +2607,14 @@ root and issuing %s.
|
||||||
kwargs.setdefault('build_always', True)
|
kwargs.setdefault('build_always', True)
|
||||||
return self.func_custom_target(node, [kwargs['output']], kwargs)
|
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
|
@stringArgs
|
||||||
@permittedKwargs(permitted_kwargs['custom_target'])
|
@permittedKwargs(permitted_kwargs['custom_target'])
|
||||||
def func_custom_target(self, node, args, kwargs):
|
def func_custom_target(self, node, args, kwargs):
|
||||||
|
|
|
@ -105,6 +105,9 @@ class InvalidCode(InterpreterException):
|
||||||
class InvalidArguments(InterpreterException):
|
class InvalidArguments(InterpreterException):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class SubdirDoneRequest(BaseException):
|
||||||
|
pass
|
||||||
|
|
||||||
class InterpreterObject:
|
class InterpreterObject:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.methods = {}
|
self.methods = {}
|
||||||
|
@ -203,6 +206,8 @@ class InterpreterBase:
|
||||||
try:
|
try:
|
||||||
self.current_lineno = cur.lineno
|
self.current_lineno = cur.lineno
|
||||||
self.evaluate_statement(cur)
|
self.evaluate_statement(cur)
|
||||||
|
except SubdirDoneRequest:
|
||||||
|
break
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if not(hasattr(e, 'lineno')):
|
if not(hasattr(e, 'lineno')):
|
||||||
e.lineno = cur.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