aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/build.py214
-rw-r--r--mesonbuild/interpreter/interpreter.py125
-rw-r--r--mesonbuild/interpreter/kwargs.py6
-rw-r--r--mesonbuild/interpreter/type_checking.py3
-rw-r--r--mesonbuild/modules/gnome.py383
-rw-r--r--mesonbuild/modules/hotdoc.py7
-rw-r--r--mesonbuild/modules/i18n.py77
-rw-r--r--mesonbuild/modules/java.py18
-rw-r--r--mesonbuild/modules/qt.py59
-rw-r--r--mesonbuild/modules/unstable_external_project.py19
-rw-r--r--mesonbuild/modules/unstable_rust.py22
-rw-r--r--mesonbuild/modules/windows.py27
-rw-r--r--test cases/failing/41 custom target plainname many inputs/test.json2
13 files changed, 497 insertions, 465 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index a392f98..3fa647a 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from __future__ import annotations
from collections import OrderedDict
from dataclasses import dataclass, field
from functools import lru_cache
@@ -24,6 +25,7 @@ import re
import textwrap
import typing as T
+
from . import environment
from . import dependencies
from . import mlog
@@ -2328,47 +2330,78 @@ class CommandBase:
return final_cmd
class CustomTarget(Target, CommandBase):
- known_kwargs = {
- 'input',
- 'output',
- 'command',
- 'capture',
- 'feed',
- 'install',
- 'install_dir',
- 'install_mode',
- 'install_tag',
- 'build_always',
- 'build_always_stale',
- 'depends',
- 'depend_files',
- 'depfile',
- 'build_by_default',
- 'override_options',
- 'console',
- 'env',
- }
- install_dir: T.List[T.Union[str, bool]]
+ typename = 'custom'
- def __init__(self, name: str, subdir: str, subproject: str, kwargs: T.Mapping[str, T.Any],
- absolute_paths: bool = False, backend: T.Optional['Backend'] = None):
- self.typename = 'custom'
+ def __init__(self,
+ name: T.Optional[str],
+ subdir: str,
+ subproject: str,
+ command: T.Sequence[T.Union[
+ str, BuildTarget, CustomTarget, CustomTargetIndex, GeneratedList, programs.ExternalProgram, File]],
+ sources: T.Sequence[T.Union[
+ str, File, BuildTarget, CustomTarget, CustomTargetIndex,
+ ExtractedObjects, GeneratedList, programs.ExternalProgram]],
+ outputs: T.List[str],
+ *,
+ build_always_stale: bool = False,
+ build_by_default: T.Optional[bool] = None,
+ capture: bool = False,
+ console: bool = False,
+ depend_files: T.Optional[T.Sequence[FileOrString]] = None,
+ extra_depends: T.Optional[T.Sequence[T.Union[str, SourceOutputs]]] = None,
+ depfile: T.Optional[str] = None,
+ env: T.Optional[EnvironmentVariables] = None,
+ feed: bool = False,
+ install: bool = False,
+ install_dir: T.Optional[T.Sequence[T.Union[str, bool]]] = None,
+ install_mode: T.Optional[FileMode] = None,
+ install_tag: T.Optional[T.Sequence[T.Optional[str]]] = None,
+ override_options: T.Optional[T.Dict[OptionKey, str]] = None,
+ absolute_paths: bool = False,
+ backend: T.Optional['Backend'] = None,
+ ):
# TODO expose keyword arg to make MachineChoice.HOST configurable
super().__init__(name, subdir, subproject, False, MachineChoice.HOST)
+ self.sources = list(sources)
+ self.outputs = substitute_values(
+ outputs, get_filenames_templates_dict(
+ get_sources_string_names(sources, backend),
+ []))
+ self.build_by_default = build_by_default if build_by_default is not None else install
+ self.build_always_stale = build_always_stale
+ self.capture = capture
+ self.console = console
+ self.depend_files = list(depend_files or [])
self.dependencies: T.List[T.Union[CustomTarget, BuildTarget]] = []
- self.extra_depends: T.List[T.Union[CustomTarget, BuildTarget]] = []
- self.depend_files = [] # Files that this target depends on but are not on the command line.
- self.depfile = None
- self.process_kwargs(kwargs, backend)
+ # must be after depend_files and dependencies
+ self.command = self.flatten_command(command)
+ self.depfile = depfile
+ self.env = env or EnvironmentVariables()
+ self.extra_depends = list(extra_depends or [])
+ self.feed = feed
+ self.install = install
+ self.install_dir = list(install_dir or [])
+ self.install_mode = install_mode
+ _install_tag: T.List[T.Optional[str]]
+ if not install_tag:
+ _install_tag = [None] * len(self.outputs)
+ elif len(install_tag) == 1:
+ _install_tag = list(install_tag) * len(self.outputs)
+ else:
+ _install_tag = list(install_tag)
+ self.install_tag = _install_tag
+ self.name = name if name else self.outputs[0]
+
+ if override_options:
+ for k, v in override_options.items():
+ if k.lang:
+ self.option_overrides_compiler[k.evolve(machine=self.for_machine)] = v
+ else:
+ self.option_overrides_base[k] = v
+
# Whether to use absolute paths for all files on the commandline
self.absolute_paths = absolute_paths
- unknowns = []
- for k in kwargs:
- if k not in CustomTarget.known_kwargs:
- unknowns.append(k)
- if unknowns:
- mlog.warning('Unknown keyword arguments in target {}: {}'.format(self.name, ', '.join(unknowns)))
def get_default_install_dir(self, environment) -> T.Tuple[str, str]:
return None, None
@@ -2405,119 +2438,6 @@ class CustomTarget(Target, CommandBase):
bdeps.update(d.get_transitive_build_target_deps())
return bdeps
- def process_kwargs(self, kwargs, backend):
- self.process_kwargs_base(kwargs)
- self.sources = extract_as_list(kwargs, 'input')
- if 'output' not in kwargs:
- raise InvalidArguments('Missing keyword argument "output".')
- self.outputs = listify(kwargs['output'])
- # This will substitute values from the input into output and return it.
- inputs = get_sources_string_names(self.sources, backend)
- values = get_filenames_templates_dict(inputs, [])
- for i in self.outputs:
- if not isinstance(i, str):
- raise InvalidArguments('Output argument not a string.')
- if i == '':
- raise InvalidArguments('Output must not be empty.')
- if i.strip() == '':
- raise InvalidArguments('Output must not consist only of whitespace.')
- if has_path_sep(i):
- raise InvalidArguments(f'Output {i!r} must not contain a path segment.')
- if '@INPUT@' in i or '@INPUT0@' in i:
- m = 'Output cannot contain @INPUT@ or @INPUT0@, did you ' \
- 'mean @PLAINNAME@ or @BASENAME@?'
- raise InvalidArguments(m)
- # We already check this during substitution, but the error message
- # will be unclear/confusing, so check it here.
- if len(inputs) != 1 and ('@PLAINNAME@' in i or '@BASENAME@' in i):
- m = "Output cannot contain @PLAINNAME@ or @BASENAME@ when " \
- "there is more than one input (we can't know which to use)"
- raise InvalidArguments(m)
- self.outputs = substitute_values(self.outputs, values)
- if not self.name:
- self.name = self.outputs[0]
- self.capture = kwargs.get('capture', False)
- if self.capture and len(self.outputs) != 1:
- raise InvalidArguments('Capturing can only output to a single file.')
- self.feed = kwargs.get('feed', False)
- if self.feed and len(self.sources) != 1:
- raise InvalidArguments('Feeding can only input from a single file.')
- self.console = kwargs.get('console', False)
- if not isinstance(self.console, bool):
- raise InvalidArguments('"console" kwarg only accepts booleans')
- if self.capture and self.console:
- raise InvalidArguments("Can't both capture output and output to console")
- if 'command' not in kwargs:
- raise InvalidArguments('Missing keyword argument "command".')
- if kwargs.get('depfile') is not None:
- depfile = kwargs['depfile']
- if not isinstance(depfile, str):
- raise InvalidArguments('Depfile must be a string.')
- if os.path.basename(depfile) != depfile:
- raise InvalidArguments('Depfile must be a plain filename without a subdirectory.')
- self.depfile = depfile
- self.command = self.flatten_command(kwargs['command'])
- for c in self.command:
- if self.capture and isinstance(c, str) and '@OUTPUT@' in c:
- raise InvalidArguments('@OUTPUT@ is not allowed when capturing output.')
- if self.feed and isinstance(c, str) and '@INPUT@' in c:
- raise InvalidArguments('@INPUT@ is not allowed when feeding input.')
- if 'install' in kwargs:
- self.install = kwargs['install']
- if not isinstance(self.install, bool):
- raise InvalidArguments('"install" must be boolean.')
- if self.install:
- if not kwargs.get('install_dir', False):
- raise InvalidArguments('"install_dir" must be specified '
- 'when installing a target')
-
- if isinstance(kwargs['install_dir'], list):
- FeatureNew.single_use('multiple install_dir for custom_target', '0.40.0', self.subproject)
- # If an item in this list is False, the output corresponding to
- # the list index of that item will not be installed
- self.install_dir = typeslistify(kwargs['install_dir'], (str, bool))
- self.install_mode = kwargs.get('install_mode', None)
- # If only one tag is provided, assume all outputs have the same tag.
- # Otherwise, we must have as much tags as outputs.
- install_tag: T.List[T.Union[str, bool, None]] = typeslistify(kwargs.get('install_tag', []), (str, bool, type(None)))
- if not install_tag:
- self.install_tag = [None] * len(self.outputs)
- elif len(install_tag) == 1:
- self.install_tag = install_tag * len(self.outputs)
- elif install_tag and len(install_tag) != len(self.outputs):
- m = f'Target {self.name!r} has {len(self.outputs)} outputs but {len(install_tag)} "install_tag"s were found.'
- raise InvalidArguments(m)
- else:
- self.install_tag = install_tag
- else:
- self.install = False
- self.install_dir = []
- self.install_mode = None
- self.install_tag = []
- if kwargs.get('build_always') is not None and kwargs.get('build_always_stale') is not None:
- raise InvalidArguments('build_always and build_always_stale are mutually exclusive. Combine build_by_default and build_always_stale.')
- elif kwargs.get('build_always') is not None:
- if kwargs.get('build_by_default') is not None:
- self.build_by_default = kwargs['build_always']
- self.build_always_stale = kwargs['build_always']
- elif kwargs.get('build_always_stale') is not None:
- self.build_always_stale = kwargs['build_always_stale']
- if not isinstance(self.build_always_stale, bool):
- raise InvalidArguments('Argument build_always_stale must be a boolean.')
- extra_deps, depend_files = (extract_as_list(kwargs, c, pop=False) for c in ['depends', 'depend_files'])
- for ed in extra_deps:
- if not isinstance(ed, (CustomTarget, BuildTarget)):
- raise InvalidArguments('Can only depend on toplevel targets: custom_target or build_target '
- f'(executable or a library) got: {type(ed)}({ed})')
- self.extra_depends.append(ed)
- for i in depend_files:
- if isinstance(i, (File, str)):
- self.depend_files.append(i)
- else:
- mlog.debug(i)
- raise InvalidArguments(f'Unknown type {type(i).__name__!r} in depend_files.')
- self.env = kwargs.get('env')
-
def get_dependencies(self):
return self.dependencies
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index bed9278..7681834 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -50,7 +50,9 @@ from .interpreterobjects import (
NullSubprojectInterpreter,
)
from .type_checking import (
- COMMAND_KW, CT_BUILD_ALWAYS, CT_BUILD_ALWAYS_STALE,
+ COMMAND_KW,
+ CT_BUILD_ALWAYS,
+ CT_BUILD_ALWAYS_STALE,
CT_BUILD_BY_DEFAULT,
CT_INPUT_KW,
CT_INSTALL_DIR_KW,
@@ -1696,8 +1698,14 @@ external dependencies (including libraries) must go to "dependencies".''')
else:
vcs_cmd = [' '] # executing this cmd will fail in vcstagger.py and force to use the fallback string
# vcstagger.py parameters: infile, outfile, fallback, source_dir, replace_string, regex_selector, command...
- cmd_kwargs = {
- 'command': self.environment.get_build_command() + \
+
+ self._validate_custom_target_outputs(len(kwargs['input']) > 1, kwargs['output'], "vcs_tag")
+
+ tg = build.CustomTarget(
+ kwargs['output'][0],
+ self.subdir,
+ self.subproject,
+ self.environment.get_build_command() + \
['--internal',
'vcstagger',
'@INPUT0@',
@@ -1706,12 +1714,13 @@ external dependencies (including libraries) must go to "dependencies".''')
source_dir,
replace_string,
regex_selector] + vcs_cmd,
- 'input': kwargs['input'],
- 'output': kwargs['output'],
- 'build_by_default': True,
- 'build_always_stale':True,
- }
- return self._func_custom_target_impl(node, [kwargs['output']], cmd_kwargs)
+ self.source_strings_to_files(kwargs['input']),
+ kwargs['output'],
+ build_by_default=True,
+ build_always_stale=True,
+ )
+ self.add_target(tg.name, tg)
+ return tg
@FeatureNew('subdir_done', '0.46.0')
@noPosargs
@@ -1719,6 +1728,18 @@ external dependencies (including libraries) must go to "dependencies".''')
def func_subdir_done(self, node, args, kwargs):
raise SubdirDoneRequest()
+ @staticmethod
+ def _validate_custom_target_outputs(has_multi_in: bool, outputs: T.Iterable[str], name: str) -> None:
+ """Checks for additional invalid values in a custom_target output.
+
+ This cannot be done with typed_kwargs because it requires the number of
+ inputs.
+ """
+ for out in outputs:
+ if has_multi_in and ('@PLAINNAME@' in out or '@BASENAME@' in out):
+ raise InvalidArguments(f'{name}: output cannot containe "@PLAINNAME@" or "@BASENAME@" '
+ 'when there is more than one input (we can\'t know which to use)')
+
@typed_pos_args('custom_target', optargs=[str])
@typed_kwargs(
'custom_target',
@@ -1747,49 +1768,87 @@ external dependencies (including libraries) must go to "dependencies".''')
FeatureNew.single_use('substitutions in custom_target depfile', '0.47.0', self.subproject, location=node)
# Don't mutate the kwargs
- kwargs = kwargs.copy()
+ build_by_default = kwargs['build_by_default']
+ build_always_stale = kwargs['build_always_stale']
# 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
+ if build_by_default is None and kwargs['install']:
+ 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
+ if build_by_default is None:
+ build_by_default = kwargs['build_always']
+ build_always_stale = kwargs['build_by_default']
# These are are nullaable so that we can know 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
+ if build_by_default is None:
+ build_by_default = False
+ if build_always_stale is None:
+ build_always_stale = False
- return self._func_custom_target_impl(node, args, kwargs)
-
- def _func_custom_target_impl(self, node, args, kwargs):
- 'Implementation-only, without FeatureNew checks, for internal use'
name = args[0]
if name is None:
# name will default to first output, but we cannot do that yet because
# they could need substitutions (e.g. @BASENAME@) first. CustomTarget()
# will take care of setting a proper default but name must be an empty
# string in the meantime.
- FeatureNew('custom_target() with no name argument', '0.60.0', location=node).use(self.subproject)
+ FeatureNew.single_use('custom_target() with no name argument', '0.60.0', self.subproject, location=node)
name = ''
- if 'input' in kwargs:
- kwargs['input'] = self.source_strings_to_files(extract_as_list(kwargs, 'input'), strict=False)
- if 'command' in kwargs and isinstance(kwargs['command'], list) and kwargs['command']:
- if isinstance(kwargs['command'][0], str):
- kwargs['command'][0] = self.find_program_impl([kwargs['command'][0]])
- tg = build.CustomTarget(name, self.subdir, self.subproject, kwargs, backend=self.backend)
+ inputs = self.source_strings_to_files(kwargs['input'], strict=False)
+ command = kwargs['command']
+ if command and isinstance(command[0], str):
+ command[0] = self.find_program_impl([command[0]])
+
+ if len(inputs) > 1 and kwargs['feed']:
+ raise InvalidArguments('custom_target: "feed" keyword argument can only be used used with a single input')
+ if len(kwargs['output']) > 1 and kwargs['capture']:
+ raise InvalidArguments('custom_target: "capture" keyword argument can only be used used with a single output')
+ if kwargs['capture'] and kwargs['console']:
+ raise InvalidArguments('custom_target: "capture" and "console" keyword arguments are mutually exclusive')
+ for c in command:
+ if kwargs['capture'] and isinstance(c, str) and '@OUTPUT@' in c:
+ raise InvalidArguments('custom_target: "capture" keyword argument cannot be used with "@OUTPUT@"')
+ if kwargs['feed'] and isinstance(c, str) and '@INPUT@' in c:
+ raise InvalidArguments('custom_target: "feed" keyword argument cannot be used with "@INPUT@"')
+ if kwargs['install'] and not kwargs['install_dir']:
+ raise InvalidArguments('custom_target: "install_dir" keyword argument must be set when "install" is true.')
+ if len(kwargs['install_dir']) > 1:
+ FeatureNew.single_use('multiple install_dir for custom_target', '0.40.0', self.subproject, location=node)
+ if len(kwargs['install_tag']) not in {0, 1, len(kwargs['output'])}:
+ raise InvalidArguments('custom_target: install_tag argument must have 0 or 1 outputs, '
+ 'or the same number of elements as the output keyword argument. '
+ f'(there are {len(kwargs["install_tag"])} install_tags, '
+ f'and {len(kwargs["output"])} outputs)')
+
+ self._validate_custom_target_outputs(len(inputs) > 1, kwargs['output'], "custom_target")
+
+ tg = build.CustomTarget(
+ name,
+ self.subdir,
+ self.subproject,
+ command,
+ inputs,
+ kwargs['output'],
+ build_always_stale=build_always_stale,
+ build_by_default=build_by_default,
+ capture=kwargs['capture'],
+ console=kwargs['console'],
+ depend_files=kwargs['depend_files'],
+ depfile=kwargs['depfile'],
+ extra_depends=kwargs['depends'],
+ env=kwargs['env'],
+ feed=kwargs['feed'],
+ install=kwargs['install'],
+ install_dir=kwargs['install_dir'],
+ install_mode=kwargs['install_mode'],
+ install_tag=kwargs['install_tag'],
+ override_options=kwargs['override_options'],
+ backend=self.backend)
self.add_target(tg.name, tg)
return tg
diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py
index 99c54c1..b97fe05 100644
--- a/mesonbuild/interpreter/kwargs.py
+++ b/mesonbuild/interpreter/kwargs.py
@@ -167,8 +167,8 @@ class RunTarget(TypedDict):
class CustomTarget(TypedDict):
build_always: bool
- build_always_stale: bool
- build_by_default: bool
+ build_always_stale: T.Optional[bool]
+ build_by_default: T.Optional[bool]
capture: bool
command: T.List[T.Union[str, build.BuildTarget, build.CustomTarget,
build.CustomTargetIndex, ExternalProgram, File]]
@@ -183,7 +183,7 @@ class CustomTarget(TypedDict):
install: bool
install_dir: T.List[T.Union[str, bool]]
install_mode: FileMode
- install_tag: T.List[T.Union[str, bool]]
+ install_tag: T.List[T.Optional[str]]
output: T.List[str]
override_options: T.Dict[OptionKey, str]
diff --git a/mesonbuild/interpreter/type_checking.py b/mesonbuild/interpreter/type_checking.py
index 52a9005..15fa61b 100644
--- a/mesonbuild/interpreter/type_checking.py
+++ b/mesonbuild/interpreter/type_checking.py
@@ -244,6 +244,8 @@ def _output_validator(outputs: T.List[str]) -> T.Optional[str]:
return 'Output must not consist only of whitespace.'
elif has_path_sep(i):
return f'Output {i!r} must not contain a path segment.'
+ elif '@INPUT' in i:
+ return f'output {i!r} contains "@INPUT", which is invalid. Did you mean "@PLAINNAME@" or "@BASENAME@?'
return None
@@ -269,6 +271,7 @@ CT_INSTALL_TAG_KW: KwargInfo[T.List[T.Union[str, bool]]] = KwargInfo(
listify=True,
default=[],
since='0.60.0',
+ convertor=lambda x: [y if isinstance(y, str) else None for y in x],
)
INSTALL_KW = KwargInfo('install', bool, default=False)
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index ffdfd42..37d4d92 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -148,7 +148,7 @@ if T.TYPE_CHECKING:
build_by_default: T.Optional[bool]
depend_files: T.List[mesonlib.File]
extra_args: T.List[str]
- install_dir: T.List[T.Union[str, bool]]
+ install_dir: T.Union[str, bool]
install_header: bool
internal: bool
nostdinc: bool
@@ -404,7 +404,7 @@ class GnomeModule(ExtensionModule):
glib_version = self._get_native_glib_version(state)
glib_compile_resources = state.find_program('glib-compile-resources')
- cmd = [glib_compile_resources, '@INPUT@']
+ cmd: T.List[T.Union[ExternalProgram, str]] = [glib_compile_resources, '@INPUT@']
source_dirs = kwargs['source_dir']
dependencies = kwargs['dependencies']
@@ -486,39 +486,47 @@ class GnomeModule(ExtensionModule):
if install_header and not kwargs['export']:
raise MesonException('GResource header is installed yet export is not enabled')
- c_kwargs: T.Dict[str, T.Any] = {
- 'build_by_default': kwargs['build_by_default'],
- 'depends': depends,
- 'input': input_file,
- 'install': kwargs['install'],
- 'install_dir': kwargs['install_dir'] or [],
- 'output': output,
- }
+ depfile: T.Optional[str] = None
+ target_cmd: T.List[T.Union[ExternalProgram, str]]
if not mesonlib.version_compare(glib_version, gresource_dep_needed_version):
# This will eventually go out of sync if dependencies are added
- c_kwargs['depend_files'] = depend_files
- c_kwargs['command'] = cmd
+ target_cmd = cmd
else:
depfile = f'{output}.d'
- c_kwargs['depfile'] = depfile
- c_kwargs['command'] = copy.copy(cmd) + ['--dependency-file', '@DEPFILE@']
- target_c = GResourceTarget(name, state.subdir, state.subproject, c_kwargs)
+ depend_files = []
+ target_cmd = copy.copy(cmd) + ['--dependency-file', '@DEPFILE@']
+ target_c = GResourceTarget(
+ name,
+ state.subdir,
+ state.subproject,
+ target_cmd,
+ [input_file],
+ [output],
+ build_by_default=kwargs['build_by_default'],
+ depfile=depfile,
+ depend_files=depend_files,
+ extra_depends=depends,
+ install=kwargs['install'],
+ install_dir=[kwargs['install_dir']] if kwargs['install_dir'] else [],
+ )
if gresource: # Only one target for .gresource files
return ModuleReturnValue(target_c, [target_c])
- h_kwargs: T.Dict[str, T.Any] = {
- 'command': cmd,
- 'input': input_file,
- 'output': f'{target_name}.h',
- # The header doesn't actually care about the files yet it errors if missing
- 'depends': depends,
- 'build_by_default': kwargs['build_by_default'],
- 'install_dir': kwargs['install_dir'] or [state.environment.coredata.get_option(mesonlib.OptionKey('includedir'))],
- }
- if install_header:
- h_kwargs['install'] = install_header
- target_h = GResourceHeaderTarget(f'{target_name}_h', state.subdir, state.subproject, h_kwargs)
+ install_dir = kwargs['install_dir'] or state.environment.coredata.get_option(mesonlib.OptionKey('includedir'))
+ assert isinstance(install_dir, str), 'for mypy'
+ target_h = GResourceHeaderTarget(
+ f'{target_name}_h',
+ state.subdir,
+ state.subproject,
+ cmd,
+ [input_file],
+ [f'{target_name}.h'],
+ build_by_default=kwargs['build_by_default'],
+ extra_depends=depends,
+ install=install_header,
+ install_dir=[install_dir],
+ )
rv = [target_c, target_h]
return ModuleReturnValue(rv, rv)
@@ -932,18 +940,19 @@ class GnomeModule(ExtensionModule):
elif install_dir is False:
install = False
- scankwargs = {
- 'input': generated_files,
- 'output': girfile,
- 'command': scan_command,
- 'depends': depends,
- 'install': install,
- 'install_dir': install_dir,
- 'install_tag': 'devel',
- 'build_by_default': kwargs['build_by_default'],
- }
-
- return GirTarget(girfile, state.subdir, state.subproject, scankwargs)
+ return GirTarget(
+ girfile,
+ state.subdir,
+ state.subproject,
+ scan_command,
+ generated_files,
+ [girfile],
+ build_by_default=kwargs['build_by_default'],
+ extra_depends=depends,
+ install=install,
+ install_dir=[install_dir],
+ install_tag=['devel'],
+ )
@staticmethod
def _make_typelib_target(state: 'ModuleState', typelib_output: str,
@@ -960,17 +969,18 @@ class GnomeModule(ExtensionModule):
elif install_dir is False:
install = False
- typelib_kwargs = {
- 'input': generated_files,
- 'output': [typelib_output],
- 'command': list(typelib_cmd),
- 'install': install,
- 'install_dir': install_dir,
- 'install_tag': 'typelib',
- 'build_by_default': kwargs['build_by_default'],
- }
-
- return TypelibTarget(typelib_output, state.subdir, state.subproject, typelib_kwargs)
+ return TypelibTarget(
+ typelib_output,
+ state.subdir,
+ state.subproject,
+ typelib_cmd,
+ generated_files,
+ [typelib_output],
+ install=install,
+ install_dir=[install_dir],
+ install_tag=['typelib'],
+ build_by_default=kwargs['build_by_default'],
+ )
@staticmethod
def _gather_typelib_includes_and_update_depends(
@@ -1178,16 +1188,21 @@ class GnomeModule(ExtensionModule):
srcdir = os.path.join(state.build_to_src, state.subdir)
outdir = state.subdir
- cmd = [state.find_program('glib-compile-schemas'), '--targetdir', outdir, srcdir]
- ct_kwargs = T.cast(T.Dict[str, T.Any], kwargs.copy())
- ct_kwargs['command'] = cmd
- ct_kwargs['input'] = []
- ct_kwargs['output'] = 'gschemas.compiled'
+ cmd: T.List[T.Union[ExternalProgram, str]] = [state.find_program('glib-compile-schemas'), '--targetdir', outdir, srcdir]
if state.subdir == '':
targetname = 'gsettings-compile'
else:
targetname = 'gsettings-compile-' + state.subdir.replace('/', '_')
- target_g = build.CustomTarget(targetname, state.subdir, state.subproject, ct_kwargs)
+ target_g = build.CustomTarget(
+ targetname,
+ state.subdir,
+ state.subproject,
+ cmd,
+ [],
+ ['gschemas.compiled'],
+ build_by_default=kwargs['build_by_default'],
+ depend_files=kwargs['depend_files'],
+ )
self._devenv_prepend('GSETTINGS_SCHEMA_DIR', os.path.join(state.environment.get_build_dir(), state.subdir))
return ModuleReturnValue(target_g, [target_g])
@@ -1289,22 +1304,27 @@ class GnomeModule(ExtensionModule):
potargets.append(potarget)
gmo_file = project_id + '-' + l + '.gmo'
- gmo_kwargs = {'command': [msgfmt, '@INPUT@', '-o', '@OUTPUT@'],
- 'input': po_file,
- 'output': gmo_file,
- }
- gmotarget = build.CustomTarget(f'help-{project_id}-{l}-gmo', l_subdir, state.subproject, gmo_kwargs)
+ gmotarget = build.CustomTarget(
+ f'help-{project_id}-{l}-gmo',
+ l_subdir,
+ state.subproject,
+ [msgfmt, '@INPUT@', '-o', '@OUTPUT@'],
+ [po_file],
+ [gmo_file],
+ )
targets.append(gmotarget)
- merge_kwargs = {'command': [itstool, '-m', os.path.join(l_subdir, gmo_file),
- '-o', '@OUTDIR@', '@INPUT@'],
- 'input': sources_files,
- 'output': sources,
- 'depends': gmotarget,
- 'install': True,
- 'install_dir': l_install_dir,
- }
- mergetarget = build.CustomTarget(f'help-{project_id}-{l}', l_subdir, state.subproject, merge_kwargs)
+ mergetarget = build.CustomTarget(
+ f'help-{project_id}-{l}',
+ l_subdir,
+ state.subproject,
+ [itstool, '-m', os.path.join(l_subdir, gmo_file), '-o', '@OUTDIR@', '@INPUT@'],
+ sources_files,
+ sources,
+ extra_depends=[gmotarget],
+ install=True,
+ install_dir=[l_install_dir],
+ )
targets.append(mergetarget)
allpotarget = build.AliasTarget(f'help-{project_id}-update-po', potargets,
@@ -1377,15 +1397,16 @@ class GnomeModule(ExtensionModule):
else:
header_dirs.append(src_dir)
- t_args = ['--internal', 'gtkdoc',
- '--sourcedir=' + state.environment.get_source_dir(),
- '--builddir=' + state.environment.get_build_dir(),
- '--subdir=' + state.subdir,
- '--headerdirs=' + '@@'.join(header_dirs),
- '--mainfile=' + main_file,
- '--modulename=' + modulename,
- '--moduleversion=' + moduleversion,
- '--mode=' + kwargs['mode']]
+ t_args: T.List[str] = [
+ '--internal', 'gtkdoc',
+ '--sourcedir=' + state.environment.get_source_dir(),
+ '--builddir=' + state.environment.get_build_dir(),
+ '--subdir=' + state.subdir,
+ '--headerdirs=' + '@@'.join(header_dirs),
+ '--mainfile=' + main_file,
+ '--modulename=' + modulename,
+ '--moduleversion=' + moduleversion,
+ '--mode=' + kwargs['mode']]
for tool in ['scan', 'scangobj', 'mkdb', 'mkhtml', 'fixxref']:
program_name = 'gtkdoc-' + tool
program = state.find_program(program_name)
@@ -1432,12 +1453,16 @@ class GnomeModule(ExtensionModule):
t_args.append(f'--installdir={"@@".join(kwargs["install_dir"])}')
t_args += self._get_build_args(kwargs['c_args'], kwargs['include_directories'],
kwargs['dependencies'], state, depends)
- custom_kwargs = {'output': modulename + '-decl.txt',
- 'command': command + t_args,
- 'depends': depends,
- 'build_always_stale': True,
- }
- custom_target = build.CustomTarget(targetname, state.subdir, state.subproject, custom_kwargs)
+ custom_target = build.CustomTarget(
+ targetname,
+ state.subdir,
+ state.subproject,
+ command + t_args,
+ [],
+ [f'{modulename}-decl.txt'],
+ build_always_stale=True,
+ extra_depends=depends,
+ )
alias_target = build.AliasTarget(targetname, [custom_target], state.subdir, state.subproject)
if kwargs['check']:
check_cmd = state.find_program('gtkdoc-check')
@@ -1555,11 +1580,7 @@ class GnomeModule(ExtensionModule):
# Added in https://gitlab.gnome.org/GNOME/glib/commit/e4d68c7b3e8b01ab1a4231bf6da21d045cb5a816 (2.55.2)
# Fixed in https://gitlab.gnome.org/GNOME/glib/commit/cd1f82d8fc741a2203582c12cc21b4dacf7e1872 (2.56.2)
if mesonlib.version_compare(glib_version, '>= 2.56.2'):
- custom_kwargs = {'input': xml_files,
- 'output': output,
- 'command': cmd + ['--body', '--output', '@OUTPUT@', '@INPUT@'],
- 'build_by_default': build_by_default
- }
+ c_cmd = cmd + ['--body', '--output', '@OUTPUT@', '@INPUT@']
else:
if kwargs['docbook'] is not None:
docbook = kwargs['docbook']
@@ -1572,36 +1593,39 @@ class GnomeModule(ExtensionModule):
else:
self._print_gdbus_warning()
cmd += ['--generate-c-code', '@OUTDIR@/' + namebase, '@INPUT@']
-
- custom_kwargs = {'input': xml_files,
- 'output': output,
- 'command': cmd,
- 'build_by_default': build_by_default
- }
-
- cfile_custom_target = build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs)
+ c_cmd = cmd
+
+ cfile_custom_target = build.CustomTarget(
+ output,
+ state.subdir,
+ state.subproject,
+ c_cmd,
+ xml_files,
+ [output],
+ build_by_default=build_by_default,
+ )
targets.append(cfile_custom_target)
output = namebase + '.h'
if mesonlib.version_compare(glib_version, '>= 2.56.2'):
- custom_kwargs = {'input': xml_files,
- 'output': output,
- 'command': cmd + ['--header', '--output', '@OUTPUT@', '@INPUT@'],
- 'build_by_default': build_by_default,
- 'install': install_header,
- 'install_dir': install_dir
- }
+ hfile_cmd = cmd + ['--header', '--output', '@OUTPUT@', '@INPUT@']
+ depends = []
else:
- custom_kwargs = {'input': xml_files,
- 'output': output,
- 'command': cmd,
- 'build_by_default': build_by_default,
- 'install': install_header,
- 'install_dir': install_dir,
- 'depends': cfile_custom_target
- }
-
- hfile_custom_target = build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs)
+ hfile_cmd = cmd
+ depends = [cfile_custom_target]
+
+ hfile_custom_target = build.CustomTarget(
+ output,
+ state.subdir,
+ state.subproject,
+ hfile_cmd,
+ xml_files,
+ [output],
+ build_by_default=build_by_default,
+ extra_depends=depends,
+ install=install_header,
+ install_dir=[install_dir],
+ )
targets.append(hfile_custom_target)
if kwargs['docbook'] is not None:
@@ -1609,8 +1633,6 @@ class GnomeModule(ExtensionModule):
if not isinstance(docbook, str):
raise MesonException('docbook value must be a string.')
- docbook_cmd = cmd + ['--output-directory', '@OUTDIR@', '--generate-docbook', docbook, '@INPUT@']
-
# The docbook output is always ${docbook}-${name_of_xml_file}
output = namebase + '-docbook'
outputs = []
@@ -1618,20 +1640,22 @@ class GnomeModule(ExtensionModule):
outputs.append('{}-{}'.format(docbook, os.path.basename(str(f))))
if mesonlib.version_compare(glib_version, '>= 2.56.2'):
- custom_kwargs = {'input': xml_files,
- 'output': outputs,
- 'command': docbook_cmd,
- 'build_by_default': build_by_default
- }
+ docbook_cmd = cmd + ['--output-directory', '@OUTDIR@', '--generate-docbook', docbook, '@INPUT@']
+ depends = []
else:
- custom_kwargs = {'input': xml_files,
- 'output': outputs,
- 'command': cmd,
- 'build_by_default': build_by_default,
- 'depends': cfile_custom_target
- }
-
- docbook_custom_target = build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs)
+ docbook_cmd = cmd
+ depends = [cfile_custom_target]
+
+ docbook_custom_target = build.CustomTarget(
+ output,
+ state.subdir,
+ state.subproject,
+ docbook_cmd,
+ xml_files,
+ outputs,
+ build_by_default=build_by_default,
+ extra_depends=depends,
+ )
targets.append(docbook_custom_target)
return ModuleReturnValue(targets, targets)
@@ -1835,18 +1859,23 @@ class GnomeModule(ExtensionModule):
) -> build.CustomTarget:
real_cmd: T.List[T.Union[str, ExternalProgram]] = [state.find_program(['glib-mkenums', 'mkenums'])]
real_cmd.extend(cmd)
- custom_kwargs = {
- 'input': sources,
- 'output': [output],
- 'capture': True,
- 'command': real_cmd,
- 'install': install,
- 'install_dir': install_dir or state.environment.coredata.get_option(mesonlib.OptionKey('includedir')),
- 'depends': list(depends or []),
- }
- return build.CustomTarget(output, state.subdir, state.subproject, custom_kwargs,
- # https://github.com/mesonbuild/meson/issues/973
- absolute_paths=True)
+ _install_dir = install_dir or state.environment.coredata.get_option(mesonlib.OptionKey('includedir'))
+ assert isinstance(_install_dir, str), 'for mypy'
+
+ return build.CustomTarget(
+ output,
+ state.subdir,
+ state.subproject,
+ real_cmd,
+ sources,
+ [output],
+ capture=True,
+ install=install,
+ install_dir=[_install_dir],
+ extra_depends=depends,
+ # https://github.com/mesonbuild/meson/issues/973
+ absolute_paths=True,
+ )
@typed_pos_args('gnome.genmarshal', str)
@typed_kwargs(
@@ -1886,36 +1915,45 @@ class GnomeModule(ExtensionModule):
cmd.append(f'--{k.replace("_", "-")}')
install_header = kwargs['install_header']
- install_dir: T.List[T.Union[str, bool]] = kwargs['install_dir'] or []
-
-
- custom_kwargs: T.Dict[str, T.Any] = {
- 'input': sources,
- 'depend_files': kwargs['depend_files'],
- 'install_dir': kwargs['install_dir'],
- }
+ capture = False
# https://github.com/GNOME/glib/commit/0fbc98097fac4d3e647684f344e508abae109fdf
if mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.51.0'):
cmd += ['--output', '@OUTPUT@']
else:
- custom_kwargs['capture'] = True
+ capture = True
header_file = output + '.h'
- custom_kwargs['command'] = cmd + ['--body', '@INPUT@']
+ c_cmd = cmd + ['--body', '@INPUT@']
if mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.53.4'):
# Silence any warnings about missing prototypes
- custom_kwargs['command'] += ['--include-header', header_file]
- custom_kwargs['output'] = output + '.c'
- body = build.CustomTarget(output + '_c', state.subdir, state.subproject, custom_kwargs)
-
- custom_kwargs['install'] = install_header
- custom_kwargs['install_dir'] = install_dir
+ c_cmd += ['--include-header', header_file]
+ body = build.CustomTarget(
+ output + '_c',
+ state.subdir,
+ state.subproject,
+ c_cmd,
+ sources,
+ [f'{output}.c'],
+ capture=capture,
+ depend_files=kwargs['depend_files'],
+ )
+
+ h_cmd = cmd + ['--header', '@INPUT@']
if new_genmarshal:
- cmd += ['--pragma-once']
- custom_kwargs['command'] = cmd + ['--header', '@INPUT@']
- custom_kwargs['output'] = header_file
- header = build.CustomTarget(output + '_h', state.subdir, state.subproject, custom_kwargs)
+ h_cmd += ['--pragma-once']
+ header = build.CustomTarget(
+ output + '_h',
+ state.subdir,
+ state.subproject,
+ h_cmd,
+ sources,
+ [header_file],
+ install=install_header,
+ install_dir=[kwargs['install_dir']] if kwargs['install_dir'] else [],
+ capture=capture,
+ depend_files=kwargs['depend_files'],
+ )
rv = [body, header]
return ModuleReturnValue(rv, rv)
@@ -2021,24 +2059,25 @@ class GnomeModule(ExtensionModule):
cmd.append(gir_file)
vapi_output = library + '.vapi'
- custom_kwargs = {
- 'command': cmd,
- 'input': inputs,
- 'output': vapi_output,
- 'depends': vapi_depends,
- }
datadir = state.environment.coredata.get_option(mesonlib.OptionKey('datadir'))
assert isinstance(datadir, str), 'for mypy'
install_dir = kwargs['install_dir'] or os.path.join(datadir, 'vala', 'vapi')
- custom_kwargs['install'] = kwargs['install']
- custom_kwargs['install_dir'] = install_dir
- custom_kwargs['packages'] = packages
if kwargs['install']:
# We shouldn't need this locally but we install it
deps_target = self._generate_deps(state, library, vapi_packages, install_dir)
created_values.append(deps_target)
- vapi_target = VapiTarget(vapi_output, state.subdir, state.subproject, custom_kwargs)
+ vapi_target = VapiTarget(
+ vapi_output,
+ state.subdir,
+ state.subproject,
+ command=cmd,
+ sources=inputs,
+ outputs=[vapi_output],
+ extra_depends=vapi_depends,
+ install=kwargs['install'],
+ install_dir=[install_dir],
+ )
# So to try our best to get this to just work we need:
# - link with with the correct library
diff --git a/mesonbuild/modules/hotdoc.py b/mesonbuild/modules/hotdoc.py
index 1b89d50..69f39a6 100644
--- a/mesonbuild/modules/hotdoc.py
+++ b/mesonbuild/modules/hotdoc.py
@@ -344,8 +344,9 @@ class HotdocTargetBuilder:
extra_assets=self._extra_assets,
subprojects=self._subprojects,
command=target_cmd,
- depends=self._dependencies,
- output=fullname,
+ extra_depends=self._dependencies,
+ outputs=[fullname],
+ sources=[],
depfile=os.path.basename(depfile),
build_by_default=self.build_by_default)
@@ -379,7 +380,7 @@ class HotdocTargetHolder(CustomTargetHolder):
class HotdocTarget(build.CustomTarget):
def __init__(self, name, subdir, subproject, hotdoc_conf, extra_extension_paths, extra_assets,
subprojects, **kwargs):
- super().__init__(name, subdir, subproject, kwargs, absolute_paths=True)
+ super().__init__(name, subdir, subproject, **kwargs, absolute_paths=True)
self.hotdoc_conf = hotdoc_conf
self.extra_extension_paths = extra_extension_paths
self.extra_assets = extra_assets
diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py
index d84f66e..98070d7 100644
--- a/mesonbuild/modules/i18n.py
+++ b/mesonbuild/modules/i18n.py
@@ -188,18 +188,18 @@ class I18nModule(ExtensionModule):
if build_by_default is None:
build_by_default = kwargs['install']
- real_kwargs = {
- 'build_by_default': build_by_default,
- 'command': command,
- 'install': kwargs['install'],
- 'install_dir': kwargs['install_dir'],
- 'output': kwargs['output'],
- 'input': kwargs['input'],
- 'install_tag': kwargs['install_tag'],
- }
-
- ct = build.CustomTarget('', state.subdir, state.subproject,
- T.cast(T.Dict[str, T.Any], real_kwargs))
+ ct = build.CustomTarget(
+ '',
+ state.subdir,
+ state.subproject,
+ command,
+ kwargs['input'],
+ kwargs['output'],
+ build_by_default=build_by_default,
+ install=kwargs['install'],
+ install_dir=kwargs['install_dir'],
+ install_tag=kwargs['install_tag'],
+ )
return ModuleReturnValue(ct, [ct])
@@ -258,18 +258,21 @@ class I18nModule(ExtensionModule):
for l in languages:
po_file = mesonlib.File.from_source_file(state.environment.source_dir,
state.subdir, l+'.po')
- gmo_kwargs = {'command': ['msgfmt', '@INPUT@', '-o', '@OUTPUT@'],
- 'input': po_file,
- 'output': packagename+'.mo',
- 'install': install,
- # We have multiple files all installed as packagename+'.mo' in different install subdirs.
- # What we really wanted to do, probably, is have a rename: kwarg, but that's not available
- # to custom_targets. Crude hack: set the build target's subdir manually.
- # Bonus: the build tree has something usable as an uninstalled bindtextdomain() target dir.
- 'install_dir': path.join(install_dir, l, 'LC_MESSAGES'),
- 'install_tag': 'i18n',
- }
- gmotarget = build.CustomTarget(f'{packagename}-{l}.mo', path.join(state.subdir, l, 'LC_MESSAGES'), state.subproject, gmo_kwargs)
+ gmotarget = build.CustomTarget(
+ f'{packagename}-{l}.mo',
+ path.join(state.subdir, l, 'LC_MESSAGES'),
+ state.subproject,
+ ['msgfmt', '@INPUT@', '-o', '@OUTPUT@'],
+ [po_file],
+ [f'{packagename}.mo'],
+ install=install,
+ # We have multiple files all installed as packagename+'.mo' in different install subdirs.
+ # What we really wanted to do, probably, is have a rename: kwarg, but that's not available
+ # to custom_targets. Crude hack: set the build target's subdir manually.
+ # Bonus: the build tree has something usable as an uninstalled bindtextdomain() target dir.
+ install_dir=[path.join(install_dir, l, 'LC_MESSAGES')],
+ install_tag=['i18n'],
+ )
targets.append(gmotarget)
gmotargets.append(gmotarget)
@@ -331,19 +334,19 @@ class I18nModule(ExtensionModule):
if build_by_default is None:
build_by_default = kwargs['install']
- real_kwargs = {
- 'build_by_default': build_by_default,
- 'command': command,
- 'depends': mo_targets,
- 'install': kwargs['install'],
- 'install_dir': kwargs['install_dir'],
- 'output': kwargs['output'],
- 'input': kwargs['input'],
- 'install_tag': kwargs['install_tag'],
- }
-
- ct = build.CustomTarget('', state.subdir, state.subproject,
- T.cast(T.Dict[str, T.Any], real_kwargs))
+ ct = build.CustomTarget(
+ '',
+ state.subdir,
+ state.subproject,
+ command,
+ kwargs['input'],
+ kwargs['output'],
+ build_by_default=build_by_default,
+ extra_depends=mo_targets,
+ install=kwargs['install'],
+ install_dir=kwargs['install_dir'],
+ install_tag=kwargs['install_tag'],
+ )
return ModuleReturnValue(ct, [ct])
diff --git a/mesonbuild/modules/java.py b/mesonbuild/modules/java.py
index 0af5aec..20cf3fd 100644
--- a/mesonbuild/modules/java.py
+++ b/mesonbuild/modules/java.py
@@ -51,20 +51,22 @@ class JavaModule(ExtensionModule):
else:
header = f'{pathlib.Path(file.fname).stem}.h'
- ct_kwargs = {
- 'input': file,
- 'output': header,
- 'command': [
+ target = CustomTarget(
+ os.path.basename(header),
+ state.subdir,
+ state.subproject,
+ [
self.javac.exelist[0],
'-d',
'@PRIVATE_DIR@',
'-h',
state.subdir,
'@INPUT@',
- ]
- }
-
- target = CustomTarget(os.path.basename(header), state.subdir, state.subproject, backend=state.backend, kwargs=ct_kwargs)
+ ],
+ [file],
+ [header],
+ backend=state.backend,
+ )
# It is only known that 1.8.0 won't pre-create the directory. 11 and 16
# do not exhibit this behavior.
if version_compare(self.javac.version, '1.8.0'):
diff --git a/mesonbuild/modules/qt.py b/mesonbuild/modules/qt.py
index cf97368..37072b4 100644
--- a/mesonbuild/modules/qt.py
+++ b/mesonbuild/modules/qt.py
@@ -328,14 +328,16 @@ class QtBaseModule(ExtensionModule):
for s in sources:
qrc_deps.extend(self._parse_qrc_deps(state, s))
- rcc_kwargs: T.Dict[str, T.Any] = { # TODO: if CustomTarget had typing information we could use that here...
- 'input': sources,
- 'output': name + '.cpp',
- 'command': self.tools['rcc'].get_command() + ['-name', name, '-o', '@OUTPUT@'] + extra_args + ['@INPUT@'] + DEPFILE_ARGS,
- 'depend_files': qrc_deps,
- 'depfile': f'{name}.d',
- }
- res_target = build.CustomTarget(name, state.subdir, state.subproject, rcc_kwargs)
+ res_target = build.CustomTarget(
+ name,
+ state.subdir,
+ state.subproject,
+ self.tools['rcc'].get_command() + ['-name', name, '-o', '@OUTPUT@'] + extra_args + ['@INPUT@'] + DEPFILE_ARGS,
+ sources,
+ [f'{name}.cpp'],
+ depend_files=qrc_deps,
+ depfile=f'{name}.d',
+ )
targets.append(res_target)
else:
for rcc_file in sources:
@@ -345,14 +347,16 @@ class QtBaseModule(ExtensionModule):
else:
basename = os.path.basename(rcc_file.fname)
name = f'qt{self.qt_version}-{basename.replace(".", "_")}'
- rcc_kwargs = {
- 'input': rcc_file,
- 'output': f'{name}.cpp',
- 'command': self.tools['rcc'].get_command() + ['-name', '@BASENAME@', '-o', '@OUTPUT@'] + extra_args + ['@INPUT@'] + DEPFILE_ARGS,
- 'depend_files': qrc_deps,
- 'depfile': f'{name}.d',
- }
- res_target = build.CustomTarget(name, state.subdir, state.subproject, rcc_kwargs)
+ res_target = build.CustomTarget(
+ name,
+ state.subdir,
+ state.subproject,
+ self.tools['rcc'].get_command() + ['-name', '@BASENAME@', '-o', '@OUTPUT@'] + extra_args + ['@INPUT@'] + DEPFILE_ARGS,
+ [rcc_file],
+ [f'{name}.cpp'],
+ depend_files=qrc_deps,
+ depfile=f'{name}.d',
+ )
targets.append(res_target)
return targets
@@ -570,16 +574,19 @@ class QtBaseModule(ExtensionModule):
ts = os.path.basename(ts)
else:
outdir = state.subdir
- cmd = [self.tools['lrelease'], '@INPUT@', '-qm', '@OUTPUT@']
- lrelease_kwargs: T.Dict[str, T.Any] = {
- 'output': '@BASENAME@.qm',
- 'input': ts,
- 'install': kwargs['install'],
- 'install_dir': install_dir or [],
- 'install_tag': 'i18n',
- 'build_by_default': kwargs['build_by_default'],
- 'command': cmd}
- lrelease_target = build.CustomTarget(f'qt{self.qt_version}-compile-{ts}', outdir, state.subproject, lrelease_kwargs)
+ cmd: T.List[T.Union[ExternalProgram, str]] = [self.tools['lrelease'], '@INPUT@', '-qm', '@OUTPUT@']
+ lrelease_target = build.CustomTarget(
+ f'qt{self.qt_version}-compile-{ts}',
+ outdir,
+ state.subproject,
+ cmd,
+ [ts],
+ ['@BASENAME@.qm'],
+ install=kwargs['install'],
+ install_dir=install_dir,
+ install_tag=['i18n'],
+ build_by_default=kwargs['build_by_default'],
+ )
translations.append(lrelease_target)
if qresource:
return ModuleReturnValue(results.return_value[0], [results.new_objects, translations])
diff --git a/mesonbuild/modules/unstable_external_project.py b/mesonbuild/modules/unstable_external_project.py
index 4e3d6db..164af9b 100644
--- a/mesonbuild/modules/unstable_external_project.py
+++ b/mesonbuild/modules/unstable_external_project.py
@@ -227,15 +227,16 @@ class ExternalProject(NewExtensionModule):
if self.verbose:
cmd.append('--verbose')
- target_kwargs = {'output': f'{self.name}.stamp',
- 'depfile': f'{self.name}.d',
- 'command': cmd + ['@OUTPUT@', '@DEPFILE@'],
- 'console': True,
- }
- self.target = build.CustomTarget(self.name,
- self.subdir.as_posix(),
- self.subproject,
- target_kwargs)
+ self.target = build.CustomTarget(
+ self.name,
+ self.subdir.as_posix(),
+ self.subproject,
+ cmd + ['@OUTPUT@', '@DEPFILE@'],
+ [],
+ [f'{self.name}.stamp'],
+ depfile=f'{self.name}.d',
+ console=True,
+ )
idir = build.InstallDir(self.subdir.as_posix(),
Path('dist', self.rel_prefix).as_posix(),
diff --git a/mesonbuild/modules/unstable_rust.py b/mesonbuild/modules/unstable_rust.py
index d0d9ca5..501273f 100644
--- a/mesonbuild/modules/unstable_rust.py
+++ b/mesonbuild/modules/unstable_rust.py
@@ -212,18 +212,16 @@ class RustModule(ExtensionModule):
f'rustmod-bindgen-{name}'.replace('/', '_'),
state.subdir,
state.subproject,
- {
- 'input': header,
- 'output': kwargs['output'],
- 'command': self._bindgen_bin.get_command() + [
- '@INPUT@', '--output',
- os.path.join(state.environment.build_dir, '@OUTPUT@')] +
- kwargs['args'] + ['--'] + kwargs['c_args'] + inc_strs +
- ['-MD', '-MQ', '@INPUT@', '-MF', '@DEPFILE@'],
- 'depfile': '@PLAINNAME@.d',
- 'depends': depends,
- 'depend_files': depend_files,
- },
+ self._bindgen_bin.get_command() + [
+ '@INPUT@', '--output',
+ os.path.join(state.environment.build_dir, '@OUTPUT@')] +
+ kwargs['args'] + ['--'] + kwargs['c_args'] + inc_strs +
+ ['-MD', '-MQ', '@INPUT@', '-MF', '@DEPFILE@'],
+ [header],
+ [kwargs['output']],
+ depfile='@PLAINNAME@.d',
+ extra_depends=depends,
+ depend_files=depend_files,
backend=state.backend,
)
diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py
index 5f7301d..eb07ced 100644
--- a/mesonbuild/modules/windows.py
+++ b/mesonbuild/modules/windows.py
@@ -181,26 +181,25 @@ class WindowsModule(ExtensionModule):
command: T.List[T.Union[str, ExternalProgram]] = []
command.append(rescomp)
command.extend(res_args)
-
- res_kwargs: 'RcKwargs' = {
- 'output': output,
- 'input': [src],
- 'depfile': None,
- 'depend_files': wrc_depend_files,
- 'depends': wrc_depends,
- 'command': [],
- }
-
+ depfile: T.Optional[str] = None
# instruct binutils windres to generate a preprocessor depfile
if rescomp_type == ResourceCompilerType.windres:
- res_kwargs['depfile'] = f'{output}.d'
+ depfile = f'{output}.d'
command.extend(['--preprocessor-arg=-MD',
'--preprocessor-arg=-MQ@OUTPUT@',
'--preprocessor-arg=-MF@DEPFILE@'])
- res_kwargs['command'] = command
-
- res_targets.append(build.CustomTarget(name_formatted, state.subdir, state.subproject, res_kwargs))
+ res_targets.append(build.CustomTarget(
+ name_formatted,
+ state.subdir,
+ state.subproject,
+ command,
+ [src],
+ [output],
+ depfile=depfile,
+ depend_files=wrc_depend_files,
+ extra_depends=wrc_depends,
+ ))
return ModuleReturnValue(res_targets, [res_targets])
diff --git a/test cases/failing/41 custom target plainname many inputs/test.json b/test cases/failing/41 custom target plainname many inputs/test.json
index 8c15cda..66a56f6 100644
--- a/test cases/failing/41 custom target plainname many inputs/test.json
+++ b/test cases/failing/41 custom target plainname many inputs/test.json
@@ -1,7 +1,7 @@
{
"stdout": [
{
- "line": "test cases/failing/41 custom target plainname many inputs/meson.build:5:0: ERROR: Output cannot contain @PLAINNAME@ or @BASENAME@ when there is more than one input (we can't know which to use)"
+ "line": "test cases/failing/41 custom target plainname many inputs/meson.build:5:0: ERROR: custom_target: output cannot containe \"@PLAINNAME@\" or \"@BASENAME@\" when there is more than one input (we can't know which to use)"
}
]
}