From 4e5efd3897c5bd03fbcd32fcf43c82879ca8caf4 Mon Sep 17 00:00:00 2001 From: Matthias Klumpp Date: Thu, 25 Feb 2021 19:53:41 +0100 Subject: [PATCH] Allow custom target output to be processed by generators --- .../snippets/permit_generator_customtarget.md | 4 +++ mesonbuild/backend/vs2010backend.py | 26 +++++++++----- mesonbuild/build.py | 34 +++++++++++++------ .../common/106 generatorcustom/gen-resx.py | 9 +++++ test cases/common/106 generatorcustom/main.c | 5 +-- .../common/106 generatorcustom/meson.build | 12 +++++-- 6 files changed, 67 insertions(+), 23 deletions(-) create mode 100644 docs/markdown/snippets/permit_generator_customtarget.md create mode 100755 test cases/common/106 generatorcustom/gen-resx.py diff --git a/docs/markdown/snippets/permit_generator_customtarget.md b/docs/markdown/snippets/permit_generator_customtarget.md new file mode 100644 index 000000000..0a5a6b5ee --- /dev/null +++ b/docs/markdown/snippets/permit_generator_customtarget.md @@ -0,0 +1,4 @@ +## Allow using generator with CustomTaget or Index of CustomTarget. + +Calling `generator.process()` with either a CustomTaget or Index of CustomTarget +as files is now permitted. diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 7bbd2b616..82891cdd3 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -272,17 +272,25 @@ class Vs2010Backend(backends.Backend): all_deps[ldep.get_id()] = ldep for obj_id, objdep in self.get_obj_target_deps(target.objects): all_deps[obj_id] = objdep - for gendep in target.get_generated_sources(): - if isinstance(gendep, build.CustomTarget): - all_deps[gendep.get_id()] = gendep - elif isinstance(gendep, build.CustomTargetIndex): - all_deps[gendep.target.get_id()] = gendep.target - else: - gen_exe = gendep.generator.get_exe() - if isinstance(gen_exe, build.Executable): - all_deps[gen_exe.get_id()] = gen_exe else: raise MesonException('Unknown target type for target %s' % target) + + for gendep in target.get_generated_sources(): + if isinstance(gendep, build.CustomTarget): + all_deps[gendep.get_id()] = gendep + elif isinstance(gendep, build.CustomTargetIndex): + all_deps[gendep.target.get_id()] = gendep.target + else: + generator = gendep.get_generator() + gen_exe = generator.get_exe() + if isinstance(gen_exe, build.Executable): + all_deps[gen_exe.get_id()] = gen_exe + for d in generator.depends: + if isinstance(d, build.CustomTargetIndex): + all_deps[d.get_id()] = d.target + else: + all_deps[d.get_id()] = d + if not t or not recursive: return all_deps ret = self.get_target_deps(all_deps, recursive) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index de8d94b6c..b6ded5e0c 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1571,17 +1571,31 @@ class Generator: return relpath.parts[0] != '..' # For subdirs we can only go "down". def process_files(self, name, files, state, preserve_path_from=None, extra_args=None): + new = False output = GeneratedList(self, state.subdir, preserve_path_from, extra_args=extra_args if extra_args is not None else []) - for f in files: - if isinstance(f, str): - f = File.from_source_file(state.environment.source_dir, state.subdir, f) - elif not isinstance(f, File): - raise InvalidArguments('{} arguments must be strings or files not {!r}.'.format(name, f)) - if preserve_path_from: - abs_f = f.absolute_path(state.environment.source_dir, state.environment.build_dir) - if not self.is_parent_path(preserve_path_from, abs_f): - raise InvalidArguments('When using preserve_path_from, all input files must be in a subdirectory of the given dir.') - output.add_file(f, state) + for e in unholder(files): + fs = [e] + if isinstance(e, (CustomTarget, CustomTargetIndex, GeneratedList)): + self.depends.append(e) + fs = [] + for f in e.get_outputs(): + fs.append(File.from_built_file(state.subdir, f)) + new = True + elif isinstance(e, str): + fs = [File.from_source_file(state.environment.source_dir, state.subdir, e)] + elif not isinstance(e, File): + raise InvalidArguments('{} arguments must be strings, files or CustomTargets, not {!r}.'.format(name, e)) + + for f in fs: + if preserve_path_from: + abs_f = f.absolute_path(state.environment.source_dir, state.environment.build_dir) + if not self.is_parent_path(preserve_path_from, abs_f): + raise InvalidArguments('generator.process: When using preserve_path_from, all input files must be in a subdirectory of the given dir.') + output.add_file(f, state) + if new: + FeatureNew.single_use( + 'Calling "{}" with CustomTaget or Index of CustomTarget.'.format(name), + '0.57.0', state.subproject) return output diff --git a/test cases/common/106 generatorcustom/gen-resx.py b/test cases/common/106 generatorcustom/gen-resx.py new file mode 100755 index 000000000..7d31ade93 --- /dev/null +++ b/test cases/common/106 generatorcustom/gen-resx.py @@ -0,0 +1,9 @@ +#!/usr/bin/env python3 + +import sys + +ofile = sys.argv[1] +num = sys.argv[2] + +with open(ofile, 'w') as f: + f.write('res{}\n'.format(num)) diff --git a/test cases/common/106 generatorcustom/main.c b/test cases/common/106 generatorcustom/main.c index 4b6857d52..153dc12cb 100644 --- a/test cases/common/106 generatorcustom/main.c +++ b/test cases/common/106 generatorcustom/main.c @@ -1,7 +1,8 @@ -#include +#include -#include"alltogether.h" +#include "alltogether.h" int main(void) { + printf("%s - %s - %s - %s\n", res1, res2, res3, res4); return 0; } diff --git a/test cases/common/106 generatorcustom/meson.build b/test cases/common/106 generatorcustom/meson.build index b3f50bb52..2128d2164 100644 --- a/test cases/common/106 generatorcustom/meson.build +++ b/test cases/common/106 generatorcustom/meson.build @@ -2,12 +2,21 @@ project('generatorcustom', 'c') creator = find_program('gen.py') catter = find_program('catter.py') +gen_resx = find_program('gen-resx.py') gen = generator(creator, output: '@BASENAME@.h', arguments : ['@INPUT@', '@OUTPUT@']) -hs = gen.process('res1.txt', 'res2.txt') +res3 = custom_target('gen-res3', + output : 'res3.txt', + command : [gen_resx, '@OUTPUT@', '3']) + +res4 = custom_target('gen-res4', + output : 'res4.txt', + command : [gen_resx, '@OUTPUT@', '4']) + +hs = gen.process('res1.txt', 'res2.txt', res3, res4[0]) allinone = custom_target('alltogether', input : hs, @@ -17,4 +26,3 @@ allinone = custom_target('alltogether', proggie = executable('proggie', 'main.c', allinone) test('proggie', proggie) -