aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2022-01-19 12:42:25 -0800
committerEli Schwartz <eschwartz93@gmail.com>2022-01-28 15:53:20 -0500
commit11f96380351a88059ec55f1070fdebc1b1033117 (patch)
tree3577f52920c3e2159f193605a894cb090b95ec10
parentb402817fb6f0392812bfa272bdbc05c9c30139fa (diff)
downloadmeson-11f96380351a88059ec55f1070fdebc1b1033117.zip
meson-11f96380351a88059ec55f1070fdebc1b1033117.tar.gz
meson-11f96380351a88059ec55f1070fdebc1b1033117.tar.bz2
build: replace kwargs in CustomTarget initializer
Because we don't want to pass the Interpreter kwargs into the build layer. This turned out to be a mega commit, as there's really on elegant way to make this change in an incremental way. On the nice side, mypy made this change super easy, as nearly all of the calls to `CustomTarget` are fully type checked! It also turns out that we're not handling install_tags in custom_target correctly, since we're not converting the boolean values into Optional values!
-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)"
}
]
}