From f0626e6cc15bfcba66e3218314f9aee5ba3d6052 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Mon, 13 Jun 2016 00:06:05 +0300 Subject: [PATCH 1/2] Created failing test for using generated outputs in a custom target. --- test cases/common/113 generatorcustom/catter.py | 13 +++++++++++++ test cases/common/113 generatorcustom/gen.py | 11 +++++++++++ test cases/common/113 generatorcustom/main.c | 7 +++++++ .../common/113 generatorcustom/meson.build | 17 +++++++++++++++++ test cases/common/113 generatorcustom/res1.txt | 1 + test cases/common/113 generatorcustom/res2.txt | 1 + 6 files changed, 50 insertions(+) create mode 100755 test cases/common/113 generatorcustom/catter.py create mode 100755 test cases/common/113 generatorcustom/gen.py create mode 100644 test cases/common/113 generatorcustom/main.c create mode 100644 test cases/common/113 generatorcustom/meson.build create mode 100644 test cases/common/113 generatorcustom/res1.txt create mode 100644 test cases/common/113 generatorcustom/res2.txt diff --git a/test cases/common/113 generatorcustom/catter.py b/test cases/common/113 generatorcustom/catter.py new file mode 100755 index 000000000..1ee0f538c --- /dev/null +++ b/test cases/common/113 generatorcustom/catter.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +import sys, os + +output = sys.argv[1] +inputs = sys.argv[2:] + +with open(output, 'w') as ofile: + ofile.write('#pragma once\n') + for i in inputs: + content = open(i, 'r').read() + i.write(content) + i.write('\n') diff --git a/test cases/common/113 generatorcustom/gen.py b/test cases/common/113 generatorcustom/gen.py new file mode 100755 index 000000000..2fc0fdddf --- /dev/null +++ b/test cases/common/113 generatorcustom/gen.py @@ -0,0 +1,11 @@ +#!/usr/bin/env python3 + +import sys, os + +ifile = sys.argv[1] +ofile = sys.argv[2] + +resname = open(ifile, 'r').readline().strip() + +templ = 'char %s[] = "%s";\n' +open(ofile, 'w').write(templ % (resname, resname)) diff --git a/test cases/common/113 generatorcustom/main.c b/test cases/common/113 generatorcustom/main.c new file mode 100644 index 000000000..04abcf69a --- /dev/null +++ b/test cases/common/113 generatorcustom/main.c @@ -0,0 +1,7 @@ +#include + +#include"alltogether.h" + +int main(int argc, char **argv) { + return 0; +} diff --git a/test cases/common/113 generatorcustom/meson.build b/test cases/common/113 generatorcustom/meson.build new file mode 100644 index 000000000..529f28a82 --- /dev/null +++ b/test cases/common/113 generatorcustom/meson.build @@ -0,0 +1,17 @@ +project('generatorcustom', 'c') + +creator = find_program('gen.py') +catter = find_program('catter.py') + +gen = generator(creator, + output: '@BASENAME@.h', + arguments : ['@INPUT@', '@OUTPUT@']) + +hs = gen.process('res1.txt', 'res2.txt') + +all_headers_in_one = custom_target('alltogether', + input : hs, + output : 'alltogether.h', + command : [catter, '@INPUT@', '@OUTPUT@']) + +executable('proggie', 'main.c', hs) diff --git a/test cases/common/113 generatorcustom/res1.txt b/test cases/common/113 generatorcustom/res1.txt new file mode 100644 index 000000000..6487c56ba --- /dev/null +++ b/test cases/common/113 generatorcustom/res1.txt @@ -0,0 +1 @@ +res1 diff --git a/test cases/common/113 generatorcustom/res2.txt b/test cases/common/113 generatorcustom/res2.txt new file mode 100644 index 000000000..0a8879d51 --- /dev/null +++ b/test cases/common/113 generatorcustom/res2.txt @@ -0,0 +1 @@ +res2 From 475175f4b5e5aecdd48455efb6a10f4bd7ce7b81 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Mon, 13 Jun 2016 21:11:27 +0300 Subject: [PATCH 2/2] Can use generator outputs in custom targets. Closes #587. --- mesonbuild/backend/backends.py | 12 +-- mesonbuild/backend/ninjabackend.py | 79 +++++++++++-------- mesonbuild/build.py | 2 +- .../common/113 generatorcustom/catter.py | 8 +- test cases/common/113 generatorcustom/gen.py | 2 +- .../common/113 generatorcustom/meson.build | 4 +- 6 files changed, 60 insertions(+), 47 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 4ff15537c..109861c7f 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -473,14 +473,16 @@ class Backend(): if hasattr(i, 'held_object'): i = i.held_object if isinstance(i, str): - fname = os.path.join(self.build_to_src, target.subdir, i) + fname = [os.path.join(self.build_to_src, target.subdir, i)] elif isinstance(i, build.BuildTarget): - fname = self.get_target_filename(i) + fname = [self.get_target_filename(i)] + elif isinstance(i, build.GeneratedList): + fname = [os.path.join(self.get_target_private_dir(target), p) for p in i.get_outfilelist()] else: - fname = i.rel_to_builddir(self.build_to_src) + fname = [i.rel_to_builddir(self.build_to_src)] if absolute_paths: - fname = os.path.join(self.environment.get_build_dir(), fname) - srcs.append(fname) + fname =[os.path.join(self.environment.get_build_dir(), f) for f in fname] + srcs += fname cmd = [] for i in target.command: if isinstance(i, build.Executable): diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index b97d99e37..92623a927 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -340,7 +340,15 @@ int dummy; if not tname in self.processed_targets: self.generate_target(t, outfile) + def custom_target_generator_inputs(self, target, outfile): + for s in target.sources: + if hasattr(s, 'held_object'): + s = s.held_object + if isinstance(s, build.GeneratedList): + self.generate_genlist_for_target(s, target, outfile) + def generate_custom_target(self, target, outfile): + self.custom_target_generator_inputs(target, outfile) (srcs, ofilenames, cmd) = self.eval_custom_target_command(target) deps = [] desc = 'Generating {0} with a {1} command.' @@ -1303,40 +1311,43 @@ rule FORTRAN_DEP_HACK for genlist in target.get_generated_sources(): if isinstance(genlist, build.CustomTarget): continue # Customtarget has already written its output rules - generator = genlist.get_generator() - exe = generator.get_exe() - exe_arr = self.exe_object_to_cmd_array(exe) - infilelist = genlist.get_infilelist() - outfilelist = genlist.get_outfilelist() - base_args = generator.get_arglist() - extra_dependencies = [os.path.join(self.build_to_src, i) for i in genlist.extra_depends] - for i in range(len(infilelist)): - if len(generator.outputs) == 1: - sole_output = os.path.join(self.get_target_private_dir(target), outfilelist[i]) - else: - sole_output = '' - curfile = infilelist[i] - infilename = os.path.join(self.build_to_src, curfile) - outfiles = genlist.get_outputs_for(curfile) - outfiles = [os.path.join(self.get_target_private_dir(target), of) for of in outfiles] - args = [x.replace("@INPUT@", infilename).replace('@OUTPUT@', sole_output)\ - for x in base_args] - args = self.replace_outputs(args, self.get_target_private_dir(target), outfilelist) - # We have consumed output files, so drop them from the list of remaining outputs. - if sole_output == '': - outfilelist = outfilelist[len(generator.outputs):] - relout = self.get_target_private_dir(target) - args = [x.replace("@SOURCE_DIR@", self.build_to_src).replace("@BUILD_DIR@", relout) - for x in args] - cmdlist = exe_arr + self.replace_extra_args(args, genlist) - elem = NinjaBuildElement(self.all_outputs, outfiles, 'CUSTOM_COMMAND', infilename) - if len(extra_dependencies) > 0: - elem.add_dep(extra_dependencies) - elem.add_item('DESC', 'Generating $out') - if isinstance(exe, build.BuildTarget): - elem.add_dep(self.get_target_filename(exe)) - elem.add_item('COMMAND', cmdlist) - elem.write(outfile) + self.generate_genlist_for_target(genlist, target, outfile) + + def generate_genlist_for_target(self, genlist, target, outfile): + generator = genlist.get_generator() + exe = generator.get_exe() + exe_arr = self.exe_object_to_cmd_array(exe) + infilelist = genlist.get_infilelist() + outfilelist = genlist.get_outfilelist() + base_args = generator.get_arglist() + extra_dependencies = [os.path.join(self.build_to_src, i) for i in genlist.extra_depends] + for i in range(len(infilelist)): + if len(generator.outputs) == 1: + sole_output = os.path.join(self.get_target_private_dir(target), outfilelist[i]) + else: + sole_output = '' + curfile = infilelist[i] + infilename = os.path.join(self.build_to_src, curfile) + outfiles = genlist.get_outputs_for(curfile) + outfiles = [os.path.join(self.get_target_private_dir(target), of) for of in outfiles] + args = [x.replace("@INPUT@", infilename).replace('@OUTPUT@', sole_output)\ + for x in base_args] + args = self.replace_outputs(args, self.get_target_private_dir(target), outfilelist) + # We have consumed output files, so drop them from the list of remaining outputs. + if sole_output == '': + outfilelist = outfilelist[len(generator.outputs):] + relout = self.get_target_private_dir(target) + args = [x.replace("@SOURCE_DIR@", self.build_to_src).replace("@BUILD_DIR@", relout) + for x in args] + cmdlist = exe_arr + self.replace_extra_args(args, genlist) + elem = NinjaBuildElement(self.all_outputs, outfiles, 'CUSTOM_COMMAND', infilename) + if len(extra_dependencies) > 0: + elem.add_dep(extra_dependencies) + elem.add_item('DESC', 'Generating $out') + if isinstance(exe, build.BuildTarget): + elem.add_dep(self.get_target_filename(exe)) + elem.add_item('COMMAND', cmdlist) + elem.write(outfile) def scan_fortran_module_outputs(self, target): compiler = None diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 105230331..bfdbca8aa 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -824,7 +824,7 @@ class CustomTarget: for c in self.sources: if hasattr(c, 'held_object'): c = c.held_object - if isinstance(c, BuildTarget) or isinstance(c, CustomTarget): + if isinstance(c, BuildTarget) or isinstance(c, CustomTarget) or isinstance(c, GeneratedList): deps.append(c) return deps diff --git a/test cases/common/113 generatorcustom/catter.py b/test cases/common/113 generatorcustom/catter.py index 1ee0f538c..354d6e080 100755 --- a/test cases/common/113 generatorcustom/catter.py +++ b/test cases/common/113 generatorcustom/catter.py @@ -2,12 +2,12 @@ import sys, os -output = sys.argv[1] -inputs = sys.argv[2:] +output = sys.argv[-1] +inputs = sys.argv[1:-1] with open(output, 'w') as ofile: ofile.write('#pragma once\n') for i in inputs: content = open(i, 'r').read() - i.write(content) - i.write('\n') + ofile.write(content) + ofile.write('\n') diff --git a/test cases/common/113 generatorcustom/gen.py b/test cases/common/113 generatorcustom/gen.py index 2fc0fdddf..ba02e3fbc 100755 --- a/test cases/common/113 generatorcustom/gen.py +++ b/test cases/common/113 generatorcustom/gen.py @@ -7,5 +7,5 @@ ofile = sys.argv[2] resname = open(ifile, 'r').readline().strip() -templ = 'char %s[] = "%s";\n' +templ = 'const char %s[] = "%s";\n' open(ofile, 'w').write(templ % (resname, resname)) diff --git a/test cases/common/113 generatorcustom/meson.build b/test cases/common/113 generatorcustom/meson.build index 529f28a82..1f4cc88d2 100644 --- a/test cases/common/113 generatorcustom/meson.build +++ b/test cases/common/113 generatorcustom/meson.build @@ -9,9 +9,9 @@ gen = generator(creator, hs = gen.process('res1.txt', 'res2.txt') -all_headers_in_one = custom_target('alltogether', +allinone = custom_target('alltogether', input : hs, output : 'alltogether.h', command : [catter, '@INPUT@', '@OUTPUT@']) -executable('proggie', 'main.c', hs) +executable('proggie', 'main.c', allinone)