diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 61f75358664e..8611ca2688ee 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -781,6 +781,10 @@ def eval_custom_target_command(self, target, absolute_outputs=False): i = i.replace('@SOURCE_ROOT@', source_root) elif '@BUILD_ROOT@' in i: i = i.replace('@BUILD_ROOT@', build_root) + elif '@OUTDIR@' in i: + if outdir == '': + outdir = '.' + i = i.replace('@OUTDIR@', outdir) elif '@DEPFILE@' in i: if target.depfile is None: msg = 'Custom target {!r} has @DEPFILE@ but no depfile ' \ diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 12f4bdb6eef9..a8b2f5adbbda 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -15,6 +15,7 @@ import copy, os, re from collections import OrderedDict import itertools +import pathlib from . import environment from . import dependencies @@ -1051,10 +1052,10 @@ def process_kwargs(self, kwargs): for rule in outputs: if not isinstance(rule, str): raise InvalidArguments('"output" may only contain strings.') - if '@BASENAME@' not in rule and '@PLAINNAME@' not in rule: - raise InvalidArguments('Every element of "output" must contain @BASENAME@ or @PLAINNAME@.') - if '/' in rule or '\\' in rule: - raise InvalidArguments('"outputs" must not contain a directory separator.') + if '@BASENAME@' not in rule and '@PLAINNAME@' not in rule and '@ROOTNAME@' not in rule: + raise InvalidArguments('Every element of "output" must contain @BASENAME@, @PLAINNAME@ or @ROOTNAME@.') + if '..' in pathlib.PurePath(rule).parts: + raise InvalidArguments('Output file path name must not contain a .. component.') if len(outputs) > 1: for o in outputs: if '@OUTPUT@' in o: @@ -1076,19 +1077,22 @@ def process_kwargs(self, kwargs): def get_base_outnames(self, inname): plainname = os.path.split(inname)[1] basename = os.path.splitext(plainname)[0] - return [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.outputs] + rootname = os.path.splitext(inname)[0] + return [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname).replace('@ROOTNAME@', rootname) for x in self.outputs] def get_dep_outname(self, inname): if self.depfile is None: raise InvalidArguments('Tried to get dep name for rule that does not have dependency file defined.') plainname = os.path.split(inname)[1] basename = os.path.splitext(plainname)[0] - return self.depfile.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) + rootname = os.path.splitext(inname)[0] + return self.depfile.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname).replace('@ROOTNAME@', rootname) def get_arglist(self, inname): plainname = os.path.split(inname)[1] basename = os.path.splitext(plainname)[0] - return [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.arglist] + rootname = os.path.splitext(inname)[0] + return [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname).replace('@ROOTNAME@', rootname) for x in self.arglist] def process_files(self, name, files, state, extra_args=[]): output = GeneratedList(self, extra_args=extra_args) @@ -1585,8 +1589,10 @@ def process_kwargs(self, kwargs): for i in self.outputs: if not(isinstance(i, str)): raise InvalidArguments('Output argument not a string.') - if '/' in i: - raise InvalidArguments('Output must not contain a path segment.') + if os.path.isabs(i): + raise InvalidArguments('Output file path name must not be an absolute path.') + if '..' in pathlib.PurePath(i).parts: + raise InvalidArguments('Output file path name must not contain a .. component.') if '@INPUT@' in i or '@INPUT0@' in i: m = 'Output cannot contain @INPUT@ or @INPUT0@, did you ' \ 'mean @PLAINNAME@ or @BASENAME@?' diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index c7a0fb71c906..90f9dfd34707 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -33,6 +33,7 @@ import os, sys, shutil, uuid import re, shlex from collections import namedtuple +import pathlib import importlib @@ -2617,17 +2618,19 @@ def func_configure_file(self, node, args, kwargs): values = mesonlib.get_filenames_templates_dict([ifile_abs], None) outputs = mesonlib.substitute_values([output], values) output = outputs[0] - if os.path.split(output)[0] != '': - raise InterpreterException('Output file name must not contain a subdirectory.') + if os.path.isabs(output): + raise InterpreterException('Output file path name must not be an absolute path.') + if '..' in pathlib.PurePath(output).parts: + raise InterpreterException('Output file path name must not contain a .. component.') (ofile_path, ofile_fname) = os.path.split(os.path.join(self.subdir, output)) ofile_abs = os.path.join(self.environment.build_dir, ofile_path, ofile_fname) + os.makedirs(os.path.join(self.environment.build_dir, ofile_path), exist_ok=True) if 'configuration' in kwargs: conf = kwargs['configuration'] if not isinstance(conf, ConfigurationDataHolder): raise InterpreterException('Argument "configuration" is not of type configuration_data') mlog.log('Configuring', mlog.bold(output), 'using configuration') if inputfile is not None: - os.makedirs(os.path.join(self.environment.build_dir, self.subdir), exist_ok=True) missing_variables = mesonlib.do_conf_file(ifile_abs, ofile_abs, conf.held_object) if missing_variables: diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 5c4c3747b6f7..53cf8315a491 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -610,8 +610,8 @@ def iter_regexin_iter(regexiter, initer): def _substitute_values_check_errors(command, values): # Error checking - inregex = ('@INPUT([0-9]+)?@', '@PLAINNAME@', '@BASENAME@') - outregex = ('@OUTPUT([0-9]+)?@', '@OUTDIR@') + inregex = ('@INPUT([0-9]+)?@', '@PLAINNAME@', '@BASENAME@', '@ROOTNAME@') + outregex = ('@OUTPUT([0-9]+)?@',) if '@INPUT@' not in values: # Error out if any input-derived templates are present in the command match = iter_regexin_iter(inregex, command) @@ -620,7 +620,7 @@ def _substitute_values_check_errors(command, values): raise MesonException(m.format(match)) else: if len(values['@INPUT@']) > 1: - # Error out if @PLAINNAME@ or @BASENAME@ is present in the command + # Error out if @PLAINNAME@, @BASENAME@ or @ROOTNAME@ is present in the command match = iter_regexin_iter(inregex[1:], command) if match: raise MesonException('Command cannot have {!r} when there is ' @@ -705,12 +705,12 @@ def get_filenames_templates_dict(inputs, outputs): @INPUT@ - the full path to one or more input files, from @inputs @OUTPUT@ - the full path to one or more output files, from @outputs - @OUTDIR@ - the full path to the directory containing the output files If there is only one input file, the following keys are also created: @PLAINNAME@ - the filename of the input file @BASENAME@ - the filename of the input file with the extension removed + @ROOTNAME@ - the full path name of the input file with the extension removed If there is more than one input file, the following keys are also created: @@ -732,16 +732,12 @@ def get_filenames_templates_dict(inputs, outputs): # Just one value, substitute @PLAINNAME@ and @BASENAME@ values['@PLAINNAME@'] = plain = os.path.split(inputs[0])[1] values['@BASENAME@'] = os.path.splitext(plain)[0] + values['@ROOTNAME@'] = os.path.splitext(inputs[0])[0] if outputs: # Gather values derived from the outputs, similar to above. values['@OUTPUT@'] = outputs for (ii, vv) in enumerate(outputs): values['@OUTPUT{}@'.format(ii)] = vv - # Outdir should be the same for all outputs - values['@OUTDIR@'] = os.path.split(outputs[0])[0] - # Many external programs fail on empty arguments. - if values['@OUTDIR@'] == '': - values['@OUTDIR@'] = '.' return values diff --git a/run_unittests.py b/run_unittests.py index fa8f049fd13c..678f93e81129 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -221,7 +221,7 @@ def test_string_templates_substitution(self): outputs = [] ret = dictfunc(inputs, outputs) d = {'@INPUT@': inputs, '@INPUT0@': inputs[0], - '@PLAINNAME@': 'foo.c.in', '@BASENAME@': 'foo.c'} + '@PLAINNAME@': 'foo.c.in', '@BASENAME@': 'foo.c', '@ROOTNAME@': "bar/foo.c"} # Check dictionary self.assertEqual(ret, d) # Check substitutions @@ -235,6 +235,9 @@ def test_string_templates_substitution(self): cmd = ['@INPUT@', '@BASENAME@.hah', 'strings'] self.assertEqual(substfunc(cmd, d), inputs + [d['@BASENAME@'] + '.hah'] + cmd[2:]) + cmd = ['@INPUT@', '@ROOTNAME@.bar', 'strings'] + self.assertEqual(substfunc(cmd, d), + inputs + [d['@ROOTNAME@'] + '.bar'] + cmd[2:]) cmd = ['@OUTPUT@'] self.assertRaises(ME, substfunc, cmd, d) @@ -243,8 +246,8 @@ def test_string_templates_substitution(self): outputs = ['out.c'] ret = dictfunc(inputs, outputs) d = {'@INPUT@': inputs, '@INPUT0@': inputs[0], - '@PLAINNAME@': 'foo.c.in', '@BASENAME@': 'foo.c', - '@OUTPUT@': outputs, '@OUTPUT0@': outputs[0], '@OUTDIR@': '.'} + '@PLAINNAME@': 'foo.c.in', '@BASENAME@': 'foo.c', '@ROOTNAME@': 'bar/foo.c', + '@OUTPUT@': outputs, '@OUTPUT0@': outputs[0]} # Check dictionary self.assertEqual(ret, d) # Check substitutions @@ -259,13 +262,16 @@ def test_string_templates_substitution(self): cmd = ['@INPUT@', '@BASENAME@.hah', 'strings'] self.assertEqual(substfunc(cmd, d), inputs + [d['@BASENAME@'] + '.hah'] + cmd[2:]) + cmd = ['@INPUT@', '@ROOTNAME@.bar', 'strings'] + self.assertEqual(substfunc(cmd, d), + inputs + [d['@ROOTNAME@'] + '.bar'] + cmd[2:]) # One input, one output with a subdir outputs = ['dir/out.c'] ret = dictfunc(inputs, outputs) d = {'@INPUT@': inputs, '@INPUT0@': inputs[0], - '@PLAINNAME@': 'foo.c.in', '@BASENAME@': 'foo.c', - '@OUTPUT@': outputs, '@OUTPUT0@': outputs[0], '@OUTDIR@': 'dir'} + '@PLAINNAME@': 'foo.c.in', '@BASENAME@': 'foo.c', '@ROOTNAME@': 'bar/foo.c', + '@OUTPUT@': outputs, '@OUTPUT0@': outputs[0]} # Check dictionary self.assertEqual(ret, d) @@ -298,19 +304,19 @@ def test_string_templates_substitution(self): self.assertRaises(ME, substfunc, cmd, d) cmd = ['@BASENAME@'] self.assertRaises(ME, substfunc, cmd, d) + cmd = ['@ROOTNAME@'] + self.assertRaises(ME, substfunc, cmd, d) # No outputs cmd = ['@OUTPUT@'] self.assertRaises(ME, substfunc, cmd, d) cmd = ['@OUTPUT0@'] self.assertRaises(ME, substfunc, cmd, d) - cmd = ['@OUTDIR@'] - self.assertRaises(ME, substfunc, cmd, d) # Two inputs, one output outputs = ['dir/out.c'] ret = dictfunc(inputs, outputs) d = {'@INPUT@': inputs, '@INPUT0@': inputs[0], '@INPUT1@': inputs[1], - '@OUTPUT@': outputs, '@OUTPUT0@': outputs[0], '@OUTDIR@': 'dir'} + '@OUTPUT@': outputs, '@OUTPUT0@': outputs[0]} # Check dictionary self.assertEqual(ret, d) # Check substitutions @@ -336,8 +342,7 @@ def test_string_templates_substitution(self): outputs = ['dir/out.c', 'dir/out2.c'] ret = dictfunc(inputs, outputs) d = {'@INPUT@': inputs, '@INPUT0@': inputs[0], '@INPUT1@': inputs[1], - '@OUTPUT@': outputs, '@OUTPUT0@': outputs[0], '@OUTPUT1@': outputs[1], - '@OUTDIR@': 'dir'} + '@OUTPUT@': outputs, '@OUTPUT0@': outputs[0], '@OUTPUT1@': outputs[1]} # Check dictionary self.assertEqual(ret, d) # Check substitutions @@ -347,8 +352,8 @@ def test_string_templates_substitution(self): self.assertEqual(substfunc(cmd, d), outputs + cmd[1:]) cmd = ['@OUTPUT0@', '@OUTPUT1@', 'strings'] self.assertEqual(substfunc(cmd, d), outputs + cmd[2:]) - cmd = ['@OUTPUT0@.out', '@INPUT1@.ok', '@OUTDIR@'] - self.assertEqual(substfunc(cmd, d), [outputs[0] + '.out', inputs[1] + '.ok', 'dir']) + cmd = ['@OUTPUT0@.out', '@INPUT1@.ok'] + self.assertEqual(substfunc(cmd, d), [outputs[0] + '.out', inputs[1] + '.ok']) # Many inputs, can't use @INPUT@ like this cmd = ['@INPUT@.out', 'ordinary', 'strings'] self.assertRaises(ME, substfunc, cmd, d) diff --git a/test cases/common/16 configure file/include/prjdir/foo.h b/test cases/common/16 configure file/include/prjdir/foo.h new file mode 100644 index 000000000000..574f62d5e935 --- /dev/null +++ b/test cases/common/16 configure file/include/prjdir/foo.h @@ -0,0 +1 @@ +// An ordinary header. diff --git a/test cases/common/16 configure file/include/prjdir/version.h.in b/test cases/common/16 configure file/include/prjdir/version.h.in new file mode 100644 index 000000000000..eaab0180b5cf --- /dev/null +++ b/test cases/common/16 configure file/include/prjdir/version.h.in @@ -0,0 +1 @@ +#define VERSION "@version@" diff --git a/test cases/common/16 configure file/meson.build b/test cases/common/16 configure file/meson.build index 9dc5fb55e662..8e181feb637c 100644 --- a/test cases/common/16 configure file/meson.build +++ b/test cases/common/16 configure file/meson.build @@ -103,3 +103,13 @@ configs = [ foreach c : configs test('@0@'.format(c), file_contains_py, args: [ c, test_string ]) endforeach + +# Generally you don't want to install version.h directly under /usr/local/include, +# so we also test generating headers to a subdir of builddir +conf_version = configuration_data() +conf_version.set('version', '1.0.0') +configure_file(input : 'include/prjdir/version.h.in', + output : 'prjdir/version.h', + configuration: conf_version) +e5 = executable('prog5', 'prog5.c', include_directories: include_directories('include')) +test('inctest5', e5) diff --git a/test cases/common/16 configure file/prog5.c b/test cases/common/16 configure file/prog5.c new file mode 100644 index 000000000000..fa6b0726cbc7 --- /dev/null +++ b/test cases/common/16 configure file/prog5.c @@ -0,0 +1,6 @@ +#include +#include + +int main(int argc, char **argv) { + return strcmp(VERSION, "1.0.0"); +} diff --git a/test cases/failing/27 output subdir/foo.in b/test cases/failing/27 output escaping/foo.in similarity index 100% rename from test cases/failing/27 output subdir/foo.in rename to test cases/failing/27 output escaping/foo.in diff --git a/test cases/failing/27 output subdir/meson.build b/test cases/failing/27 output escaping/meson.build similarity index 78% rename from test cases/failing/27 output subdir/meson.build rename to test cases/failing/27 output escaping/meson.build index 282d0b70aa60..f82590bc1512 100644 --- a/test cases/failing/27 output subdir/meson.build +++ b/test cases/failing/27 output escaping/meson.build @@ -1,5 +1,5 @@ project('outdir path', 'c') configure_file(input : 'foo.in', - output : 'subdir/foo', + output : '../subdir/foo', configuration : configuration_data()) diff --git a/test cases/failing/27 output subdir/subdir/dummy.txt b/test cases/failing/27 output escaping/subdir/dummy.txt similarity index 100% rename from test cases/failing/27 output subdir/subdir/dummy.txt rename to test cases/failing/27 output escaping/subdir/dummy.txt diff --git a/test cases/frameworks/5 protocol buffers/asubdir/defs.proto b/test cases/frameworks/5 protocol buffers/asubdir/defs.proto deleted file mode 100644 index f7956517c018..000000000000 --- a/test cases/frameworks/5 protocol buffers/asubdir/defs.proto +++ /dev/null @@ -1,3 +0,0 @@ -message Dummy { - required string text = 1; -} diff --git a/test cases/frameworks/5 protocol buffers/asubdir/main.cpp b/test cases/frameworks/5 protocol buffers/asubdir/main.cpp deleted file mode 100644 index f6566d52e663..000000000000 --- a/test cases/frameworks/5 protocol buffers/asubdir/main.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "defs.pb.h" - -int main(int argc, char **argv) { - GOOGLE_PROTOBUF_VERIFY_VERSION; - Dummy *d = new Dummy; - delete d; - google::protobuf::ShutdownProtobufLibrary(); - return 0; -} diff --git a/test cases/frameworks/5 protocol buffers/asubdir/meson.build b/test cases/frameworks/5 protocol buffers/asubdir/meson.build deleted file mode 100644 index 972716590599..000000000000 --- a/test cases/frameworks/5 protocol buffers/asubdir/meson.build +++ /dev/null @@ -1,8 +0,0 @@ -subdirgen = generator(protoc, \ - output : ['@BASENAME@.pb.cc', '@BASENAME@.pb.h'], - arguments : ['--proto_path=@CURRENT_SOURCE_DIR@', '--cpp_out=@BUILD_DIR@', '@INPUT@']) - -generated = subdirgen.process('defs.proto') -e = executable('subdir-prog', 'main.cpp', generated, - dependencies : dep) -test('subdir-prototest', e) diff --git a/test cases/frameworks/5 protocol buffers/defs.proto b/test cases/frameworks/5 protocol buffers/defs.proto deleted file mode 100644 index f7956517c018..000000000000 --- a/test cases/frameworks/5 protocol buffers/defs.proto +++ /dev/null @@ -1,3 +0,0 @@ -message Dummy { - required string text = 1; -} diff --git a/test cases/frameworks/5 protocol buffers/main.cpp b/test cases/frameworks/5 protocol buffers/main.cpp deleted file mode 100644 index f6566d52e663..000000000000 --- a/test cases/frameworks/5 protocol buffers/main.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "defs.pb.h" - -int main(int argc, char **argv) { - GOOGLE_PROTOBUF_VERIFY_VERSION; - Dummy *d = new Dummy; - delete d; - google::protobuf::ShutdownProtobufLibrary(); - return 0; -} diff --git a/test cases/frameworks/5 protocol buffers/meson.build b/test cases/frameworks/5 protocol buffers/meson.build index 58666f9b924c..7c758ea01d7c 100644 --- a/test cases/frameworks/5 protocol buffers/meson.build +++ b/test cases/frameworks/5 protocol buffers/meson.build @@ -1,20 +1,52 @@ project('protocol buffer test', 'cpp') -protoc = find_program('protoc', required : false) -dep = dependency('protobuf', required : false) +protobuf_dep = dependency('protobuf') +protoc = find_program('protoc') -if not protoc.found() or not dep.found() +if not protoc.found() or not protobuf_dep.found() error('MESON_SKIP_TEST: protoc tool and/or protobuf pkg-config dependency not found') endif +# Builds a proto subtree from top_level meson.build. +# Currently build proto subtree from outside requires a little hack in order to get proto headers +# currectly on include paths. Building with subdir at the top level of proto subtree is a cleaner +# solution. +protos_basename = [ + 'messages/dummy_messages', + 'dummy_service', +] +protos_src = [] +protos_hdr = [] +foreach p : protos_basename + cc_target = custom_target( + p.underscorify(), + input: 'proto/' + p + '.proto', + output: [p + '.pb.cc', p + '.pb.h'], + command: [protoc, '-I', '@CURRENT_SOURCE_DIR@/proto', '--cpp_out', '@OUTDIR@', '@INPUT@'] + ) + protos_src += cc_target[0] + protos_hdr += cc_target[1] +endforeach -gen = generator(protoc, \ - output : ['@BASENAME@.pb.cc', '@BASENAME@.pb.h'], - arguments : ['--proto_path=@SOURCE_DIR@', '--cpp_out=@BUILD_DIR@', '@INPUT@']) +# Builds another proto subtree in a subdir +subdir('proto_subdir') -generated = gen.process('defs.proto') -e = executable('prog', 'main.cpp', generated, - dependencies : dep) -test('prototest', e) +# Builds proto trees with generators. This acturally looks cleaner than the custom_target +# approach, but with some limits: it requires that the current source dir to be treated as +# proto root, instead of the top level of the proto tree. This may require changes of existing +# code. +proto_gen = generator(protoc, + arguments: ['-I', '@CURRENT_SOURCE_DIR@', '--cpp_out', '@BUILD_DIR@', '@INPUT@'], + output: ['@ROOTNAME@.pb.cc', '@ROOTNAME@.pb.h'], +) +protos_name = [ + 'proto_generator/messages/dummy_messages3.proto', + 'proto_generator/dummy_service3.proto', +] +protos_gen_src = proto_gen.process(protos_name) -subdir('asubdir') +dummy_bin = executable( + 'prog', + ['src/prog.cpp', protos_src, protos_hdr, protos_subdir_src, protos_subdir_hdr, protos_gen_src], + dependencies: protobuf_dep, +) diff --git a/test cases/frameworks/5 protocol buffers/proto/dummy_service.proto b/test cases/frameworks/5 protocol buffers/proto/dummy_service.proto new file mode 100644 index 000000000000..e870851017d2 --- /dev/null +++ b/test cases/frameworks/5 protocol buffers/proto/dummy_service.proto @@ -0,0 +1,8 @@ +syntax = "proto2"; +package configure_file; +option cc_generic_services = true; +import "messages/dummy_messages.proto"; + +service DummyService { + rpc DummyMethod (DummyRequest) returns (DummyResponse) {}; +} \ No newline at end of file diff --git a/test cases/frameworks/5 protocol buffers/proto/messages/dummy_messages.proto b/test cases/frameworks/5 protocol buffers/proto/messages/dummy_messages.proto new file mode 100644 index 000000000000..7b539684cc96 --- /dev/null +++ b/test cases/frameworks/5 protocol buffers/proto/messages/dummy_messages.proto @@ -0,0 +1,8 @@ +syntax = "proto2"; +package configure_file; + +message DummyRequest { +} + +message DummyResponse { +} diff --git a/test cases/frameworks/5 protocol buffers/proto_generator/dummy_service3.proto b/test cases/frameworks/5 protocol buffers/proto_generator/dummy_service3.proto new file mode 100644 index 000000000000..4ae15dfa9f36 --- /dev/null +++ b/test cases/frameworks/5 protocol buffers/proto_generator/dummy_service3.proto @@ -0,0 +1,8 @@ +syntax = "proto2"; +package configure_file; +option cc_generic_services = true; +import "proto_generator/messages/dummy_messages3.proto"; + +service DummyService3 { + rpc DummyMethod (DummyRequest3) returns (DummyResponse3) {}; +} \ No newline at end of file diff --git a/test cases/frameworks/5 protocol buffers/proto_generator/messages/dummy_messages3.proto b/test cases/frameworks/5 protocol buffers/proto_generator/messages/dummy_messages3.proto new file mode 100644 index 000000000000..7b328b8f5ddc --- /dev/null +++ b/test cases/frameworks/5 protocol buffers/proto_generator/messages/dummy_messages3.proto @@ -0,0 +1,8 @@ +syntax = "proto2"; +package configure_file; + +message DummyRequest3 { +} + +message DummyResponse3 { +} diff --git a/test cases/frameworks/5 protocol buffers/proto_subdir/dummy_service2.proto b/test cases/frameworks/5 protocol buffers/proto_subdir/dummy_service2.proto new file mode 100644 index 000000000000..5a04517a45e2 --- /dev/null +++ b/test cases/frameworks/5 protocol buffers/proto_subdir/dummy_service2.proto @@ -0,0 +1,8 @@ +syntax = "proto2"; +package configure_file; +option cc_generic_services = true; +import "messages/dummy_messages2.proto"; + +service DummyService2 { + rpc DummyMethod (DummyRequest2) returns (DummyResponse2) {}; +} \ No newline at end of file diff --git a/test cases/frameworks/5 protocol buffers/proto_subdir/meson.build b/test cases/frameworks/5 protocol buffers/proto_subdir/meson.build new file mode 100644 index 000000000000..9aea85473b78 --- /dev/null +++ b/test cases/frameworks/5 protocol buffers/proto_subdir/meson.build @@ -0,0 +1,17 @@ +protos_subdir_files = [ + 'messages/bits/dummy_enum.proto', + 'messages/dummy_messages2.proto', + 'dummy_service2.proto', +] +protos_subdir_src = [] +protos_subdir_hdr = [] +foreach p : protos_subdir_files + cc_target = custom_target( + p.underscorify(), + input: p, + output: ['@ROOTNAME@.pb.cc', '@ROOTNAME@.pb.h'], + command: [protoc, '-I', '@CURRENT_SOURCE_DIR@', '--cpp_out', '@OUTDIR@', '@INPUT@'] + ) + protos_subdir_src += cc_target[0] + protos_subdir_hdr += cc_target[1] +endforeach diff --git a/test cases/frameworks/5 protocol buffers/proto_subdir/messages/bits/dummy_enum.proto b/test cases/frameworks/5 protocol buffers/proto_subdir/messages/bits/dummy_enum.proto new file mode 100644 index 000000000000..d9a4bfebb750 --- /dev/null +++ b/test cases/frameworks/5 protocol buffers/proto_subdir/messages/bits/dummy_enum.proto @@ -0,0 +1,7 @@ +syntax = "proto2"; +package configure_file; + +enum DummyEnum { + DUMMY_OK = 1; + DUMMY_ERROR = 2; +} \ No newline at end of file diff --git a/test cases/frameworks/5 protocol buffers/proto_subdir/messages/dummy_messages2.proto b/test cases/frameworks/5 protocol buffers/proto_subdir/messages/dummy_messages2.proto new file mode 100644 index 000000000000..371f8dfeb5c2 --- /dev/null +++ b/test cases/frameworks/5 protocol buffers/proto_subdir/messages/dummy_messages2.proto @@ -0,0 +1,11 @@ +syntax = "proto2"; +package configure_file; +import "messages/bits/dummy_enum.proto"; + +message DummyRequest2 { + optional DummyEnum e = 1; +} + +message DummyResponse2 { + optional DummyEnum e = 1; +} diff --git a/test cases/frameworks/5 protocol buffers/src/prog.cpp b/test cases/frameworks/5 protocol buffers/src/prog.cpp new file mode 100644 index 000000000000..9c99d5fadca6 --- /dev/null +++ b/test cases/frameworks/5 protocol buffers/src/prog.cpp @@ -0,0 +1,11 @@ +/** + * dummy.cpp + */ + +#include +#include +#include + +int main() { + return 0; +}