diff --git a/docs/yaml/functions/_build_target_base.yaml b/docs/yaml/functions/_build_target_base.yaml index 3f0e88158..1db49a531 100644 --- a/docs/yaml/functions/_build_target_base.yaml +++ b/docs/yaml/functions/_build_target_base.yaml @@ -48,6 +48,11 @@ kwargs: compiler flags to use for the given language; eg: `cpp_args` for C++ + vala_args: + type: list[str | file] + description: | + Compiler flags for Vala. Unlike other languages this may contain Files + sources: type: str | file | custom_tgt | custom_idx | generated_list | structured_src description: Additional source files. Same as the source varargs. diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index a8bf387f9..dd9e6ee6c 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -1475,7 +1475,7 @@ class Backend: srcs += fname return srcs - def get_custom_target_depend_files(self, target: build.CustomTarget, absolute_paths: bool = False) -> T.List[str]: + def get_target_depend_files(self, target: T.Union[build.CustomTarget, build.BuildTarget], absolute_paths: bool = False) -> T.List[str]: deps: T.List[str] = [] for i in target.depend_files: if isinstance(i, mesonlib.File): diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 29883bac7..d4d4e2ff6 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1151,7 +1151,7 @@ class NinjaBackend(backends.Backend): self.custom_target_generator_inputs(target) (srcs, ofilenames, cmd) = self.eval_custom_target_command(target) deps = self.unwrap_dep_list(target) - deps += self.get_custom_target_depend_files(target) + deps += self.get_target_depend_files(target) if target.build_always_stale: deps.append('PHONY') if target.depfile is None: @@ -1214,7 +1214,7 @@ class NinjaBackend(backends.Backend): elem.add_item('description', f'Running external command {target.name}{cmd_type}') elem.add_item('pool', 'console') deps = self.unwrap_dep_list(target) - deps += self.get_custom_target_depend_files(target) + deps += self.get_target_depend_files(target) elem.add_dep(deps) self.add_build(elem) self.processed_targets.add(target.get_id()) @@ -1712,18 +1712,10 @@ class NinjaBackend(backends.Backend): if isinstance(gensrc, modules.GResourceTarget): gres_xml, = self.get_custom_target_sources(gensrc) args += ['--gresources=' + gres_xml] - extra_args = [] - - for a in target.extra_args.get('vala', []): - if isinstance(a, File): - relname = a.rel_to_builddir(self.build_to_src) - extra_dep_files.append(relname) - extra_args.append(relname) - else: - extra_args.append(a) dependency_vapis = self.determine_dep_vapis(target) extra_dep_files += dependency_vapis - args += extra_args + extra_dep_files.extend(self.get_target_depend_files(target)) + args += target.get_extra_args('vala') element = NinjaBuildElement(self.all_outputs, valac_outputs, self.compiler_to_rule_name(valac), all_files + dependency_vapis) @@ -2622,7 +2614,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) exe = generator.get_exe() infilelist = genlist.get_inputs() outfilelist = genlist.get_outputs() - extra_dependencies = self.get_custom_target_depend_files(genlist) + extra_dependencies = self.get_target_depend_files(genlist) for i, curfile in enumerate(infilelist): if len(generator.outputs) == 1: sole_output = os.path.join(self.get_target_private_dir(target), outfilelist[i]) diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index c9c21a135..b9ada532b 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -187,7 +187,7 @@ class Vs2010Backend(backends.Backend): else: sole_output = '' infilename = os.path.join(down, curfile.rel_to_builddir(self.build_to_src, target_private_dir)) - deps = self.get_custom_target_depend_files(genlist, True) + deps = self.get_target_depend_files(genlist, True) base_args = generator.get_arglist(infilename) outfiles_rel = genlist.get_outputs_for(curfile) outfiles = [os.path.join(target_private_dir, of) for of in outfiles_rel] @@ -699,7 +699,7 @@ class Vs2010Backend(backends.Backend): (root, type_config) = self.create_basic_project(target.name, temp_dir=target.get_id(), guid=guid) - depend_files = self.get_custom_target_depend_files(target) + depend_files = self.get_target_depend_files(target) if not target.command: # This is an alias target and thus doesn't run any command. It's @@ -738,7 +738,7 @@ class Vs2010Backend(backends.Backend): # from the target dir, not the build root. target.absolute_paths = True (srcs, ofilenames, cmd) = self.eval_custom_target_command(target, True) - depend_files = self.get_custom_target_depend_files(target, True) + depend_files = self.get_target_depend_files(target, True) # Always use a wrapper because MSBuild eats random characters when # there are many arguments. tdir_abs = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target)) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 8208fa0d9..9f0abf539 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -735,6 +735,7 @@ class BuildTarget(Target): self.link_language = kwargs.get('link_language') self.link_targets: T.List[LibTypes] = [] self.link_whole_targets: T.List[T.Union[StaticLibrary, CustomTarget, CustomTargetIndex]] = [] + self.depend_files: T.List[File] = [] self.link_depends = [] self.added_deps = set() self.name_prefix_set = False @@ -746,7 +747,7 @@ class BuildTarget(Target): # as Vala which generates .vapi and .h besides the compiled output. self.outputs = [self.filename] self.pch: T.Dict[str, T.List[str]] = {} - self.extra_args: T.Dict[str, T.List['FileOrString']] = {} + self.extra_args: T.Dict[str, T.List[str]] = {} self.sources: T.List[File] = [] self.generated: T.List['GeneratedTypes'] = [] self.extra_files: T.List[File] = [] @@ -1278,7 +1279,7 @@ class BuildTarget(Target): def get_outputs(self) -> T.List[str]: return self.outputs - def get_extra_args(self, language): + def get_extra_args(self, language) -> T.List[str]: return self.extra_args.get(language, []) @lru_cache(maxsize=None) diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 0b6ccef22..29eaed202 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -3230,6 +3230,46 @@ class Interpreter(InterpreterBase, HoldableObject): else: raise InterpreterException(f'Unknown default_library value: {default_library}.') + def __convert_file_args(self, raw: T.List[mesonlib.FileOrString], allow_file: bool) -> T.Tuple[T.List[mesonlib.File], T.List[str]]: + """Convert raw target arguments from File | str to File. + + This removes files from the command line and replaces them with string + values, but adds the files to depends list + + :param raw: the raw arguments + :return: A tuple of file dependencies and raw arguments + """ + depend_files: T.List[mesonlib.File] = [] + args: T.List[str] = [] + build_to_source = mesonlib.relpath(self.environment.get_source_dir(), + self.environment.get_build_dir()) + + for a in raw: + if isinstance(a, mesonlib.File): + if not allow_file: + raise InvalidArguments('File type arguments are only allowed for vala') + depend_files.append(a) + args.append(a.rel_to_builddir(build_to_source)) + else: + args.append(a) + + return depend_files, args + + def __process_language_args(self, kwargs: T.Dict[str, T.List[mesonlib.FileOrString]]) -> None: + """Convert split language args into a combined dictionary. + + The Meson DSL takes arguments in the form `_args : args`, but in the + build layer we store these in a single dictionary as `{: args}`. + This function extracts the arguments from the DSL format and prepares + them for the IR. + """ + d = kwargs.setdefault('depend_files', []) + + for l in compilers.all_languages: + deps, args = self.__convert_file_args(kwargs[f'{l}_args'], l == 'vala') + kwargs[f'{l}_args'] = args + d.extend(deps) + @T.overload def build_target(self, node: mparser.BaseNode, args: T.Tuple[str, SourcesVarargsType], kwargs: kwtypes.Executable, targetclass: T.Type[build.Executable]) -> build.Executable: ... @@ -3295,6 +3335,7 @@ class Interpreter(InterpreterBase, HoldableObject): mlog.debug('Unknown target type:', str(targetclass)) raise RuntimeError('Unreachable code') self.kwarg_strings_to_includedirs(kwargs) + self.__process_language_args(kwargs) # Filter out kwargs from other target types. For example 'soversion' # passed to library() when default_library == 'static'. diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py index 241a08b76..26ecb4ef9 100644 --- a/mesonbuild/interpreter/kwargs.py +++ b/mesonbuild/interpreter/kwargs.py @@ -7,7 +7,7 @@ from __future__ import annotations import typing as T -from typing_extensions import TypedDict, Literal, Protocol +from typing_extensions import TypedDict, Literal, Protocol, NotRequired from .. import build from .. import coredata @@ -326,6 +326,7 @@ class _BaseBuildTarget(TypedDict): """ override_options: T.Dict[OptionKey, T.Union[str, int, bool, T.List[str]]] + depend_files: NotRequired[T.List[File]] class _BuildTarget(_BaseBuildTarget): diff --git a/manual tests/7 vala composite widgets/meson.build b/test cases/vala/27 file as command line argument/meson.build similarity index 100% rename from manual tests/7 vala composite widgets/meson.build rename to test cases/vala/27 file as command line argument/meson.build diff --git a/manual tests/7 vala composite widgets/my-resources.xml b/test cases/vala/27 file as command line argument/my-resources.xml similarity index 100% rename from manual tests/7 vala composite widgets/my-resources.xml rename to test cases/vala/27 file as command line argument/my-resources.xml diff --git a/manual tests/7 vala composite widgets/mywidget.ui b/test cases/vala/27 file as command line argument/mywidget.ui similarity index 100% rename from manual tests/7 vala composite widgets/mywidget.ui rename to test cases/vala/27 file as command line argument/mywidget.ui diff --git a/manual tests/7 vala composite widgets/mywidget.vala b/test cases/vala/27 file as command line argument/mywidget.vala similarity index 100% rename from manual tests/7 vala composite widgets/mywidget.vala rename to test cases/vala/27 file as command line argument/mywidget.vala