aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/interpreter/interpreter.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/interpreter/interpreter.py')
-rw-r--r--mesonbuild/interpreter/interpreter.py90
1 files changed, 77 insertions, 13 deletions
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 78c8f95..c5997f2 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -52,11 +52,12 @@ from .interpreterobjects import (
from .type_checking import (
COMMAND_KW,
DEPENDS_KW,
+ DEPEND_FILES_KW,
DEPFILE_KW,
ENV_KW,
INSTALL_MODE_KW,
LANGUAGE_KW,
- NATIVE_KW,
+ NATIVE_KW, OVERRIDE_OPTIONS_KW,
REQUIRED_KW,
NoneType,
in_set_validator,
@@ -89,6 +90,18 @@ if T.TYPE_CHECKING:
build.GeneratedList]
+def _output_validator(outputs: T.List[str]) -> T.Optional[str]:
+ for i in outputs:
+ if i == '':
+ return 'Output must not be empty.'
+ elif i.strip() == '':
+ return 'Output must not consist only of whitespace.'
+ elif has_path_sep(i):
+ return f'Output {i!r} must not contain a path segment.'
+
+ return None
+
+
def stringifyUserArguments(args, quote=False):
if isinstance(args, list):
return '[%s]' % ', '.join([stringifyUserArguments(x, True) for x in args])
@@ -1626,20 +1639,71 @@ external dependencies (including libraries) must go to "dependencies".''')
def func_subdir_done(self, node, args, kwargs):
raise SubdirDoneRequest()
- @FeatureNewKwargs('custom_target', '0.60.0', ['install_tag'])
- @FeatureNewKwargs('custom_target', '0.57.0', ['env'])
- @FeatureNewKwargs('custom_target', '0.48.0', ['console'])
- @FeatureNewKwargs('custom_target', '0.47.0', ['install_mode', 'build_always_stale'])
- @FeatureNewKwargs('custom_target', '0.40.0', ['build_by_default'])
- @FeatureNewKwargs('custom_target', '0.59.0', ['feed'])
- @permittedKwargs({'input', 'output', 'command', 'install', 'install_dir', 'install_mode',
- 'build_always', 'capture', 'depends', 'depend_files', 'depfile',
- 'build_by_default', 'build_always_stale', 'console', 'env',
- 'feed', 'install_tag'})
@typed_pos_args('custom_target', optargs=[str])
- def func_custom_target(self, node: mparser.FunctionNode, args: T.Tuple[T.Optional[str]], kwargs: 'TYPE_kwargs') -> build.CustomTarget:
- if 'depfile' in kwargs and ('@BASENAME@' in kwargs['depfile'] or '@PLAINNAME@' in kwargs['depfile']):
+ @typed_kwargs(
+ 'custom_target',
+ COMMAND_KW,
+ DEPEND_FILES_KW,
+ DEPENDS_KW,
+ DEPFILE_KW,
+ ENV_KW.evolve(since='0.57.0'),
+ INSTALL_MODE_KW.evolve(since='0.47.0'),
+ OVERRIDE_OPTIONS_KW,
+ KwargInfo('build_by_default', (bool, type(None)), since='0.40.0'),
+ KwargInfo('build_always', (bool, type(None)), deprecated='0.47.0'),
+ KwargInfo('build_always_stale', (bool, type(None)), since='0.47.0'),
+ KwargInfo('feed', bool, default=False, since='0.59.0'),
+ KwargInfo('capture', bool, default=False),
+ KwargInfo('console', bool, default=False, since='0.48.0'),
+ KwargInfo('install', bool, default=False),
+ KwargInfo('install_dir', ContainerTypeInfo(list, (str, bool)), listify=True, default=[]),
+ KwargInfo(
+ 'output',
+ ContainerTypeInfo(list, str, allow_empty=False),
+ listify=True,
+ required=True,
+ default=[],
+ validator=_output_validator,
+ ),
+ KwargInfo(
+ 'input',
+ ContainerTypeInfo(list, (str, mesonlib.File, ExternalProgram, build.BuildTarget, build.CustomTarget, build.CustomTargetIndex, build.ExtractedObjects, build.GeneratedList)),
+ listify=True,
+ default=[],
+ ),
+ KwargInfo('install_tag', ContainerTypeInfo(list, (str, bool)), listify=True, default=[], since='0.60.0'),
+ )
+ def func_custom_target(self, node: mparser.FunctionNode, args: T.Tuple[str],
+ kwargs: 'kwargs.CustomTarget') -> build.CustomTarget:
+ if kwargs['depfile'] and ('@BASENAME@' in kwargs['depfile'] or '@PLAINNAME@' in kwargs['depfile']):
FeatureNew.single_use('substitutions in custom_target depfile', '0.47.0', self.subproject)
+
+ # Don't mutate the kwargs
+ kwargs = kwargs.copy()
+
+ # Remap build_always to build_by_default and build_always_stale
+ if kwargs['build_always'] is not None and kwargs['build_always_stale'] is not None:
+ raise InterpreterException('CustomTarget: "build_always" and "build_always_stale" are mutually exclusive')
+
+ if kwargs['build_by_default'] is None and kwargs['install']:
+ kwargs['build_by_default'] = True
+
+ elif kwargs['build_always'] is not None:
+ if kwargs['build_by_default'] is None:
+ kwargs['build_by_default'] = kwargs['build_always']
+ kwargs['build_always_stale'] = kwargs['build_by_default']
+
+ # Set this to None to satisfy process_kwargs
+ kwargs['build_always'] = None
+
+ # These are are nullaable so that we can konw whether they're explicitly
+ # set or not. If they haven't been overwritten, set them to their true
+ # default
+ if kwargs['build_by_default'] is None:
+ kwargs['build_by_default'] = False
+ if kwargs['build_always_stale'] is None:
+ kwargs['build_always_stale'] = False
+
return self._func_custom_target_impl(node, args, kwargs)
def _func_custom_target_impl(self, node, args, kwargs):