From 4795e345504a02e53b5183d8e0f4d8a74872bd4f Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Wed, 11 Oct 2023 18:50:01 +0000 Subject: [PATCH 01/23] Harmonic bazel Signed-off-by: Michael Carroll --- BUILD.bazel | 116 ++++++++++----- core/generator_lite/Generator.cc | 116 +++++++++++++++ core/generator_lite/Generator.hh | 57 ++++++++ core/generator_lite/generator_main.cc | 42 ++++++ core/src/impl/InstallationDirectories.cc | 27 ++++ tools/BUILD.bazel | 14 +- tools/gz_msgs_generate.bzl | 178 ++++++++++++++++++----- tools/gz_msgs_generate.py | 174 ++++++++++++---------- tools/gz_msgs_generate_factory.py | 91 +++++++----- 9 files changed, 632 insertions(+), 183 deletions(-) create mode 100644 core/generator_lite/Generator.cc create mode 100644 core/generator_lite/Generator.hh create mode 100644 core/generator_lite/generator_main.cc create mode 100644 core/src/impl/InstallationDirectories.cc diff --git a/BUILD.bazel b/BUILD.bazel index 9a23f639..3bc7c86f 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -9,8 +9,8 @@ load( ) load( "@gz//msgs/tools:gz_msgs_generate.bzl", - "get_proto_headers", - "gz_msgs_generate", + "gz_proto_library", + "gz_proto_factory", ) package( @@ -24,46 +24,38 @@ exports_files(["LICENSE"]) gz_configure_header( name = "msgs_config_hh", - src = "include/gz/msgs/config.hh.in", + src = "core/include/gz/msgs/config.hh.in", cmakelists = ["CMakeLists.txt"], package = "msgs", ) gz_export_header( - name = "include/gz/msgs/Export.hh", + name = "core/include/gz/msgs/Export.hh", export_base = "GZ_MSGS", lib_name = "gz-msgs", visibility = ["//visibility:private"], ) public_headers_no_gen = glob([ - "include/gz/msgs/*.hh", - "include/gz/msgs/detail/*.hh", + "core/include/gz/msgs/*.hh", + "core/include/gz/msgs/convert/*.hh", + "core/include/gz/msgs/detail/*.hh", ]) protos = glob(["proto/gz/msgs/*.proto"]) -gz_include_header( - name = "messagetypes_hh_genrule", - out = "include/gz/msgs/MessageTypes.hh", - hdrs = get_proto_headers(protos), - strip_prefix = ["gz_msgs"], -) - gz_include_header( name = "msgs_hh_genrule", out = "include/gz/msgs.hh", hdrs = public_headers_no_gen + [ - "include/gz/msgs/config.hh", - "include/gz/msgs/Export.hh", - "include/gz/msgs/MessageTypes.hh", + "core/include/gz/msgs/config.hh", + "core/include/gz/msgs/Export.hh", ], ) public_headers = public_headers_no_gen + [ - "include/gz/msgs/config.hh", - "include/gz/msgs/Export.hh", - "include/gz/msgs/MessageTypes.hh", + "core/include/gz/msgs/config.hh", + "core/include/gz/msgs/Export.hh", "include/gz/msgs.hh", ] @@ -71,9 +63,9 @@ public_headers = public_headers_no_gen + [ cc_binary( name = "gz_msgs_gen", srcs = [ - "src/Generator.cc", - "src/Generator.hh", - "src/generator_main.cc", + "core/generator_lite/Generator.cc", + "core/generator_lite/Generator.hh", + "core/generator_lite/generator_main.cc", ], deps = [ "@com_google_protobuf//:protobuf", @@ -91,26 +83,37 @@ proto_library( ], ) -gz_msgs_generate( - name = "gzmsgs_cc_proto", - deps = [ - ":gzmsgs_proto", - "@com_google_protobuf//:any_proto", - ], +gz_proto_library( + name = "gzmsgs_cc_proto", + proto_deps = [":gzmsgs_proto"], + deps = [ + "@com_google_protobuf//:protobuf", + ] +) + +gz_proto_factory( + name = "gzmsgs_proto_factory", + deps = [":gzmsgs_proto"], + namespace = "gz::msgs", + cc_output = "core/src/RegisterMsgs.cc", + hh_output = "core/src/MessageTypes.hh" ) cc_library( name = "msgs", srcs = [ - "src/Factory.cc", - "src/Filesystem.cc", - "src/Utility.cc", - ":gzmsgs_cc_proto", + "core/src/Factory.cc", + "core/src/DynamicFactory.cc", + "core/src/DynamicFactory.hh", + "core/src/MessageFactory.cc", + "core/src/impl/InstallationDirectories.cc", + "core/src/RegisterMsgs.cc" ], hdrs = public_headers, - includes = ["include"], + includes = ["core/include", "core/src"], deps = [ ":gzmsgs_cc_proto", + ":gzmsgs_proto_factory", GZ_ROOT + "math", "@com_google_protobuf//:protobuf", "@tinyxml2", @@ -138,3 +141,50 @@ test_sources = glob( "@gtest//:gtest_main", ], ) for src in test_sources] + + +cc_test( + name = "INTEGRATION_headers", + srcs = ["test/integration/headers.cc"], + deps = [ + ":gzmsgs_cc_proto", + "@gtest", + "@gtest//:gtest_main", + ], +) + +cc_test( + name = "INTEGRATION_image_msg", + srcs = ["test/integration/image_msg.cc"], + deps = [ + ":gzmsgs_cc_proto", + "@gtest", + "@gtest//:gtest_main", + ], +) + +cc_test( + name = "INTEGRATION_Utility", + srcs = ["test/integration/Utility_TEST.cc"], + deps = [ + ":msgs", + GZ_ROOT + "common/testing", + "@gtest", + "@gtest//:gtest_main", + ], +) + +cc_test( + name = "INTEGRATION_Factory", + srcs = ["test/integration/Factory_TEST.cc"], + data = ["test/desc/stringmsg.desc"], + deps = [ + ":msgs", + GZ_ROOT + "common/testing", + "@gtest", + "@gtest//:gtest_main", + ], + defines = [ + 'GZ_MSGS_TEST_PATH=\\"msgs/test\\"', + ], +) diff --git a/core/generator_lite/Generator.cc b/core/generator_lite/Generator.cc new file mode 100644 index 00000000..1279fac6 --- /dev/null +++ b/core/generator_lite/Generator.cc @@ -0,0 +1,116 @@ +/* + * Copyright 2016 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4100 4512 4127 4068 4244 4267 4251 4146) +#endif + +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include "Generator.hh" + +namespace google::protobuf::compiler::cpp { + +///////////////////////////////////////////////// +Generator::Generator(const std::string &/*_name*/) +{ +} + +///////////////////////////////////////////////// +Generator::~Generator() = default; + +///////////////////////////////////////////////// +bool Generator::Generate(const FileDescriptor *_file, + const std::string &/*_parameter*/, + OutputDirectory *_generatorContext, + std::string * /*_error*/) const +{ + std::string delim = ".proto"; + auto headerFilename = _file->name(); + auto sourceFilename = _file->name(); + + { + auto pos = headerFilename.rfind(delim); + headerFilename.replace(pos, delim.size(), ".pb.h"); + } + { + auto pos = sourceFilename.rfind(delim); + sourceFilename.replace(pos, delim.size(), ".pb.h"); + } + + { + auto *output = _generatorContext->OpenForInsert(headerFilename, "includes"); + auto printer = io::Printer(output, '$'); + printer.Print("#include \n", "name", "includes"); + } + + { + auto *output = _generatorContext->OpenForInsert( + headerFilename, "namespace_scope"); + auto printer = io::Printer(output, '$'); + + for (auto i = 0; i < _file->message_type_count(); ++i) + { + const auto *desc = _file->message_type(i); + std::string ptrTypes; + + // Define std::unique_ptr types for our messages + ptrTypes += "typedef std::unique_ptr<" + + desc->name() + "> " + + desc->name() + "UniquePtr;\n"; + + // Define const std::unique_ptr types for our messages + ptrTypes += "typedef std::unique_ptrname() + "> Const" + + desc->name() + "UniquePtr;\n"; + + // Define std::shared_ptr types for our messages + ptrTypes += "typedef std::shared_ptr<" + + desc->name() + "> " + + desc->name() + "SharedPtr;\n"; + + // Define const std::shared_ptr types for our messages + ptrTypes += "typedef std::shared_ptrname() + "> Const" + + desc->name() + "SharedPtr;\n"; + + printer.PrintRaw(ptrTypes.c_str()); + } + } + return true; +} +} // namespace google::protobuf::compiler::cpp diff --git a/core/generator_lite/Generator.hh b/core/generator_lite/Generator.hh new file mode 100644 index 00000000..4630b20f --- /dev/null +++ b/core/generator_lite/Generator.hh @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2016 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#ifndef GZ_MSGS_GENERATOR_HH_ +#define GZ_MSGS_GENERATOR_HH_ + +#include +#include + +namespace google { +namespace protobuf { +namespace compiler { +namespace cpp { +/// \cond +/// \brief Google protobuf message generator for igntion::msgs +class Generator : public CodeGenerator +{ + /// \brief Constructor + /// \param[in] _name Name value (currently unused) + public: explicit Generator(const std::string &_name); + + /// \brief Destructor + public: virtual ~Generator(); + + /// \brief Generate a message. + /// \param[in] _file File descriptor of the message. + /// \param[in] _parameter Unused string value + /// \param[in] _generatorContext Output directory. + /// \param[in] _error Unused string value + /// \return true if successful, otherwise sets _error and returns false + public: virtual bool Generate(const FileDescriptor *_file, + const std::string &_parameter, + OutputDirectory *_generatorContext, + std::string *_error) const; + + // private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator); +}; +/// \endcond +} +} +} +} +#endif diff --git a/core/generator_lite/generator_main.cc b/core/generator_lite/generator_main.cc new file mode 100644 index 00000000..79008fb6 --- /dev/null +++ b/core/generator_lite/generator_main.cc @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2016 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4251) +#endif + +#include + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#include "Generator.hh" + +int main(int _argc, char *_argv[]) +{ +#ifdef _MSC_VER + // Don't print a silly message or stick a modal dialog box in my face, + // please. + _set_abort_behavior(0, ~0); +#endif // !_MSC_VER + + google::protobuf::compiler::cpp::Generator + generator("gz-msgs-plugin"); + return google::protobuf::compiler::PluginMain(_argc, _argv, &generator); +} diff --git a/core/src/impl/InstallationDirectories.cc b/core/src/impl/InstallationDirectories.cc new file mode 100644 index 00000000..7f25a895 --- /dev/null +++ b/core/src/impl/InstallationDirectories.cc @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include + +namespace gz::msgs +{ +inline namespace GZ_MSGS_VERSION_NAMESPACE { +std::string getInstallPrefix() { return {};} +} // namespcae +} // namespace gz::msgs diff --git a/tools/BUILD.bazel b/tools/BUILD.bazel index bba0c8c1..3568652b 100644 --- a/tools/BUILD.bazel +++ b/tools/BUILD.bazel @@ -1,8 +1,12 @@ -load("@gz//bazel/skylark:build_defs.bzl", "gz_py_binary") +load( + "@gz//bazel/skylark:build_defs.bzl", + "GZ_VISIBILITY", + "gz_py_binary", +) gz_py_binary( - name = "gz_msgs_generate_py", - srcs = ["gz_msgs_generate.py"], - main = "gz_msgs_generate.py", - visibility = ["//visibility:public"], + name = "gz_msgs_generate_factory_py", + srcs = ["gz_msgs_generate_factory.py"], + main = "gz_msgs_generate_factory.py", + visibility = GZ_VISIBILITY, ) diff --git a/tools/gz_msgs_generate.bzl b/tools/gz_msgs_generate.bzl index b28024e8..80862211 100644 --- a/tools/gz_msgs_generate.bzl +++ b/tools/gz_msgs_generate.bzl @@ -9,11 +9,29 @@ load( _VIRTUAL_IMPORTS = "/_virtual_imports/" -def _get_detail_directory(hh_file, ctx): - base = hh_file.path[hh_file.path.index(_VIRTUAL_IMPORTS) + 1:] - base = base.split("/") - base.insert(-1, "details") - return ctx.actions.declare_file("/".join(base)) +def _filter_files_impl(ctx): + """Filter the files in DefaultInfo.""" + return [DefaultInfo( + files = depset([ + file + for file in ctx.attr.target.files.to_list() + if file.extension in ctx.attr.extensions + ]), + )] + +filter_files = rule( + implementation = _filter_files_impl, + attrs = { + "target": attr.label( + doc = "The source target to filter", + mandatory = True, + ), + "extensions": attr.string_list( + doc = "The extensions of the files to keep eg. ['h']", + mandatory = True, + ), + }, +) def get_proto_headers(protos): out = [] @@ -23,42 +41,127 @@ def get_proto_headers(protos): out.append("/".join(split)) return out -def _gz_msgs_generate_impl(ctx): +def _gz_proto_factory_impl(ctx): protos = protos_from_context(ctx) out_dir = get_out_dir(protos, ctx) - + in_protos = [] include_dirs = depset([get_include_directory(proto) for proto in protos]) + for src in ctx.attr.deps: + for proto in src[ProtoInfo].direct_sources: + in_protos.append(proto) + + for proto in src[ProtoInfo].transitive_sources.to_list(): + in_protos.append(proto) + + in_protos = depset(in_protos).to_list() arguments = [ - "--protoc-exec=" + ctx.executable._protoc.path, - "--gz-generator-bin=" + ctx.executable._gz_gen_bin.path, - "--generate-cpp", - "--output-cpp-path=" + out_dir.path, + "--cc-output=" + ctx.outputs.cc_output.path, + "--hh-output=" + ctx.outputs.hh_output.path ] - for proto in protos: - arguments.append("--input-path=" + proto.path) - for include_dir in include_dirs.to_list(): arguments.append("--proto-path=" + include_dir) - out_protos = [proto for proto in protos if proto.path.find("gz/msgs") > 0] + arguments.append("--proto-include-path=" + out_dir.path) + arguments.append("--namespace=" + ctx.attr.namespace) + arguments.append("--protos") + for proto in in_protos: + arguments.append(proto.path) + + ctx.actions.run( + inputs = protos, + outputs = [ctx.outputs.cc_output, ctx.outputs.hh_output], + arguments = arguments, + executable = ctx.executable.gz_msgs_generate_factory_py, + ) + + compilation_context = cc_common.create_compilation_context( + headers = depset([ctx.outputs.hh_output]), + system_includes = depset([ctx.outputs.hh_output.dirname]), + ) + + return [ + CcInfo(compilation_context = compilation_context), + ] + +_gz_proto_factory = rule( + attrs = { + "deps": attr.label_list( + mandatory = True, + allow_empty = False, + providers = [ProtoInfo], + ), + "namespace": attr.string( + mandatory = True, + ), + "cc_output": attr.output(mandatory = True), + "hh_output": attr.output(mandatory = True), + "gz_msgs_generate_factory_py": attr.label( + default = Label("@gz//msgs/tools:gz_msgs_generate_factory_py"), + executable = True, + cfg = "host", + ), + }, + implementation = _gz_proto_factory_impl, +) + +def gz_proto_factory( + deps, + **kwargs): + _gz_proto_factory( + deps = deps, + **kwargs + ) + +def _gz_proto_library_impl(ctx): + protos = protos_from_context(ctx) + out_dir = get_out_dir(protos, ctx) + + arguments = [] + + in_protos = [] + out_protos = [] + include_dirs = [] + + for src in ctx.attr.deps: + for proto in src[ProtoInfo].direct_sources: + in_protos.append(proto) + include_dirs.append(get_include_directory(proto)) + out_protos.append(proto) + + for proto in src[ProtoInfo].transitive_sources.to_list(): + in_protos.append(proto) + include_dirs.append(get_include_directory(proto)) + + in_protos = depset(in_protos).to_list() + out_protos = depset(out_protos).to_list() + include_dirs = depset(include_dirs).to_list() + + for include_dir in include_dirs: + arguments.append("--proto_path=" + include_dir) + + arguments.append("--plugin=protoc-gen-gzmsgs=" + ctx.executable._gz_gen_bin.path) + arguments.append("--cpp_out=" + out_dir.path) + arguments.append("--gzmsgs_out=" + out_dir.path) + + for proto in in_protos: + arguments.append(proto.path) cc_files = declare_out_files(out_protos, ctx, "{}.pb.cc") hh_files = declare_out_files(out_protos, ctx, "{}.pb.h") - detail_hh_files = [_get_detail_directory(file, ctx) for file in hh_files] - out_files = cc_files + hh_files + detail_hh_files + out_files = cc_files + hh_files ctx.actions.run( - inputs = protos, + inputs = in_protos, outputs = out_files, arguments = arguments, - executable = ctx.executable.gz_msgs_generate_py, - tools = [ctx.executable._protoc, ctx.executable._gz_gen_bin, ctx.executable.gz_msgs_generate_py], + executable = ctx.executable._protoc, + tools = [ctx.executable._protoc, ctx.executable._gz_gen_bin], ) compilation_context = cc_common.create_compilation_context( - headers = depset(out_files), + headers = depset(hh_files), system_includes = depset([out_dir.path]), ) @@ -67,7 +170,7 @@ def _gz_msgs_generate_impl(ctx): CcInfo(compilation_context = compilation_context), ] -_gz_msgs_generate_gen = rule( +_gz_proto_library = rule( attrs = { "deps": attr.label_list( mandatory = True, @@ -84,19 +187,24 @@ _gz_msgs_generate_gen = rule( executable = True, cfg = "host", ), - "gz_msgs_generate_py": attr.label( - default = Label("@gz//msgs/tools:gz_msgs_generate_py"), - executable = True, - cfg = "host", - ), }, - implementation = _gz_msgs_generate_impl, + implementation = _gz_proto_library_impl, ) -def gz_msgs_generate( - deps, - **kwargs): - _gz_msgs_generate_gen( - deps = deps, - **kwargs - ) +def gz_proto_library( + name, + proto_deps, + **kwargs): + + _gz_proto_library(name = name + "_pb", deps = proto_deps) + + filter_files(name=name + "_srcs", target=":" + name + "_pb", extensions=["cc"]) + filter_files(name=name + "_hdrs", target=":" + name + "_pb", extensions=["h"]) + kwargs['deps'].append(":" + name + "_pb") + + native.cc_library( + name = name, + srcs = [name + "_srcs"], + hdrs = [name + "_hdrs"], + **kwargs + ) diff --git a/tools/gz_msgs_generate.py b/tools/gz_msgs_generate.py index 1805e2f3..6b755a7d 100755 --- a/tools/gz_msgs_generate.py +++ b/tools/gz_msgs_generate.py @@ -35,14 +35,18 @@ def main(argv=sys.argv[1:]): help='Flag to indicate if C++ bindings should be generated', action='store_true') parser.add_argument( - '--generate-python', - help='Flag to indicate if Python bindings should be generated', + '--generate-ruby', + help='Flag to indicate if Ruby bindings should be generated', + action='store_true') + parser.add_argument( + '--generate-ignition', + help='Flag to indicate if ignition/ headers should be generated', action='store_true') parser.add_argument( '--output-cpp-path', help='The basepath of the generated C++ files') parser.add_argument( - '--output-python-path', + '--output-ruby-path', help='The basepath of the generated C++ files') parser.add_argument( '--proto-path', @@ -52,79 +56,101 @@ def main(argv=sys.argv[1:]): parser.add_argument( '--input-path', required=True, - help='The location of the template files') - parser.add_argument( - '--dependency-proto-descs', - nargs='*', - help='The location of proto descriptor files these messages depend on') - parser.add_argument( - '--dllexport-decl', - help='The DLL visibility macro to use, if not set, no macro will be used') + help='The location of the template files', + action='append') args = parser.parse_args(argv) - # First generate the base cpp files - cmd = [args.protoc_exec] - - for path in args.proto_path: - cmd += [f'--proto_path={path}'] - - if args.dependency_proto_descs: - for path in args.dependency_proto_descs: - cmd += [f'--descriptor_set_in={path}'] - - if args.generate_cpp: - cmd += [f'--plugin=protoc-gen-gzmsgs={args.gz_generator_bin}'] - if args.dllexport_decl: - cmd += [f'--cpp_out=dllexport_decl={args.dllexport_decl}:{args.output_cpp_path}'] - else: - cmd += [f'--cpp_out={args.output_cpp_path}'] - - cmd += [f'--gzmsgs_out={args.output_cpp_path}'] - if args.generate_python: - cmd += [f'--python_out={args.output_python_path}'] - - cmd += [args.input_path] - - try: - subprocess.check_call(cmd) - except subprocess.CalledProcessError as e: - print(f'Failed to execute protoc compiler: {e}') - sys.exit(-1) - - os.makedirs(args.output_cpp_path, exist_ok=True) - - try: - subprocess.check_call(cmd) - except subprocess.CalledProcessError as e: - print(f'Failed to execute protoc compiler: {e}') - sys.exit(-1) - - # Move original generated cpp to details/ - proto_file = os.path.splitext(os.path.relpath(args.input_path, args.proto_path[0]))[0] - detail_proto_file = proto_file.split(os.sep) - - detail_proto_dir = detail_proto_file[:-1] - detail_proto_dir.append('details') - detail_proto_dir = os.path.join(*detail_proto_dir) - detail_proto_file.insert(-1, 'details') - detail_proto_file = os.path.join(*detail_proto_file) - - header = os.path.join(args.output_cpp_path, proto_file + ".pb.h") - gz_header = os.path.join(args.output_cpp_path, proto_file + ".gz.h") - detail_header = os.path.join(args.output_cpp_path, detail_proto_file + ".pb.h") - - try: - os.makedirs(os.path.join(args.output_cpp_path, detail_proto_dir), - exist_ok=True) - # Windows cannot rename a file to an existing file - if os.path.exists(detail_header): - os.remove(detail_header) - - os.rename(header, detail_header) - os.rename(gz_header, header) - except Exception as e: - print(f'Failed to manipulate gz-msgs headers: {e}') - sys.exit(-1) + for input_file in args.input_path: + # First generate the base cpp and ruby files + cmd = [args.protoc_exec] + + for pp in args.proto_path: + cmd += [f'--proto_path={pp}'] + + if args.generate_cpp: + cmd += [f'--plugin=protoc-gen-ignmsgs={args.gz_generator_bin}'] + cmd += [f'--cpp_out=dllexport_decl=GZ_MSGS_VISIBLE:{args.output_cpp_path}'] + cmd += [f'--ignmsgs_out={args.output_cpp_path}'] + if args.generate_ruby: + cmd += [f'--ruby_out=dllexport_decl=GZ_MSGS_VISIBLE:{args.output_ruby_path}'] + cmd += [input_file] + + try: + subprocess.check_call(cmd) + except subprocess.CalledProcessError as e: + print(f'Failed to execute protoc compiler: {e}') + sys.exit(-1) + + # Move original generated cpp to details/ + proto_file = None + for proto_path in args.proto_path: + if input_file.find(proto_path) == 0: + proto_file = os.path.splitext(os.path.relpath(input_file, proto_path))[0] + if not proto_file: + continue + + detail_proto_file = proto_file.split(os.sep) + + detail_proto_dir = detail_proto_file[:-1] + detail_proto_dir.append('details') + detail_proto_dir = os.path.join(*detail_proto_dir) + detail_proto_file.insert(-1, 'details') + detail_proto_file = os.path.join(*detail_proto_file) + + header = os.path.join(args.output_cpp_path, proto_file + ".pb.h") + gz_header = os.path.join(args.output_cpp_path, proto_file + ".gz.h") + detail_header = os.path.join(args.output_cpp_path, detail_proto_file + ".pb.h") + + if proto_file.find('google/protobuf') >= 0: + continue + + try: + os.makedirs(os.path.join(args.output_cpp_path, detail_proto_dir), + exist_ok=True) + # Windows cannot rename a file to an existing file + if os.path.exists(detail_header): + os.remove(detail_header) + + os.rename(header, detail_header) + os.rename(gz_header, header) + except Exception as e: + print(f'Failed to manipulate gz-msgs headers: {e}') + sys.exit(-1) + + + if args.generate_ignition: + ignition_header_dir = os.path.join(args.output_cpp_path, 'ignition', 'msgs') + ignition_header = proto_file.split(os.sep) + ignition_header[0] = 'ignition' + + proto_name = ignition_header[2] + + ignition_header = os.path.join(*ignition_header) + ignition_header = os.path.join(args.output_cpp_path, ignition_header + ".pb.h") + + os.makedirs(os.path.join(args.output_cpp_path, ignition_header_dir), + exist_ok=True) + + with open(ignition_header, 'w') as f: + f.write('''/* + * Copyright (C) 2022 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + ''') + f.write(f'#include \n') + f.write('#include \n') if __name__ == '__main__': sys.exit(main()) diff --git a/tools/gz_msgs_generate_factory.py b/tools/gz_msgs_generate_factory.py index 89553422..4fa8002e 100755 --- a/tools/gz_msgs_generate_factory.py +++ b/tools/gz_msgs_generate_factory.py @@ -16,7 +16,7 @@ import argparse import os -import pathlib +import re import sys # Create @@ -72,9 +72,10 @@ * Do not edit this directly */ +#include "MessageTypes.hh" + #include "gz/msgs/Factory.hh" #include "gz/msgs/MessageFactory.hh" -#include "{package_path}/MessageTypes.hh" #include @@ -110,17 +111,25 @@ def main(argv=sys.argv[1:]): description='Generate protobuf factory file', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument( - '--output-cpp-path', + '--cc-output', + required=True, + help='The path to the generated cpp file') + parser.add_argument( + '--hh-output', required=True, - help='The basepath of the generated C++ files') + help='The path to the generated hh file') parser.add_argument( - '--proto-package', + '--namespace', required=True, - help='The basepath of the generated C++ files') + help='The namespace to use') parser.add_argument( '--proto-path', required=True, help='The location of the protos') + parser.add_argument( + '--proto-include-path', + required=True, + help='The location of the protos') parser.add_argument( '--protos', type=str, @@ -131,45 +140,55 @@ def main(argv=sys.argv[1:]): args = parser.parse_args(argv) - headers = [] - registrations = [] + package_re = re.compile('^package (.*);$') + message_re = re.compile('message (.*)') - package = [p for p in args.proto_package.split('.') if len(p)] - namespace = '::'.join(package) - package_str = '.'.join(package) - package_path = '/'.join(package) + registrations = [] + gz_msgs_headers = [] for proto in args.protos: - proto_file = os.path.splitext(os.path.relpath(proto, args.proto_path))[0] - header = proto_file + ".pb.h" - headers.append(f"#include <{header}>") - - proto_file = '_'.join(pathlib.Path(proto_file).parts) - - # The gazebo extensions to the gazebo compiler write out a series of index files - # which capture the message types - index = os.path.join(args.output_cpp_path, proto_file + ".pb_index") - with open(index, "r") as index_f: - for line in index_f.readlines(): - line = line.strip() + package = None + messages = [] + + try: + with open(proto, 'r') as f: + content = f.readlines() + for line in content: + package_found = package_re.match(line) + if package_found: + package = package_found.group(1).split('.') + + message_found = message_re.match(line) + if message_found: + messages.append(message_found.group(1)) + except: + pass + + if package and messages: + for message in messages: + registrations.append(register_fn.format( + package_str='.'.join(package), + message_str=message, + message_cpp_type='::'.join([*package, message]) + )) - message_str = line - message_cpp_type = '::'.join(package) + '::' + message_str - registrations.append(register_fn.format( - package_str=package_str, - message_str=message_str, - message_cpp_type=message_cpp_type)) + split = proto.replace(args.proto_include_path, '') + split = [s for s in split.split("/") if s] + split[-1] = split[-1].replace(".proto", ".pb.h") + print(split) - with open(os.path.join(args.output_cpp_path, *package, 'MessageTypes.hh'), 'w') as f: - f.write(cc_header.format(gz_msgs_headers='\n'.join(headers), namespace=namespace)) + gz_msgs_headers.append("#include <" + "/".join(split) + ">") - with open(os.path.join(args.output_cpp_path, *package, 'register.cc'), 'w') as f: + with open(os.path.join(args.cc_output), 'w') as f: f.write((cc_source.format(registrations='\n'.join(registrations), nRegistrations=len(registrations), - namespace=namespace, - package_path=package_path) + - cc_factory.format(namespace=namespace))) + namespace=args.namespace) + + cc_factory.format(namespace=args.namespace))) + + with open(os.path.join(args.hh_output), 'w') as f: + f.write(cc_header.format(namespace=args.namespace, + gz_msgs_headers='\n'.join(gz_msgs_headers))) if __name__ == '__main__': sys.exit(main()) From cf54236c47d7549d0f62706d724b5ecf21f17f42 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Tue, 6 Feb 2024 23:09:10 +0000 Subject: [PATCH 02/23] Fix RE and install path Signed-off-by: Michael Carroll --- BUILD.bazel | 16 +++++++++------- tools/gz_msgs_generate_factory.py | 2 +- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index 3bc7c86f..8fc7b8ef 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -53,12 +53,6 @@ gz_include_header( ], ) -public_headers = public_headers_no_gen + [ - "core/include/gz/msgs/config.hh", - "core/include/gz/msgs/Export.hh", - "include/gz/msgs.hh", -] - # Custom Gazebo Protoc plugin cc_binary( name = "gz_msgs_gen", @@ -96,9 +90,17 @@ gz_proto_factory( deps = [":gzmsgs_proto"], namespace = "gz::msgs", cc_output = "core/src/RegisterMsgs.cc", - hh_output = "core/src/MessageTypes.hh" + hh_output = "include/gz/msgs/MessageTypes.hh" ) +public_headers = public_headers_no_gen + [ + "core/include/gz/msgs/config.hh", + "core/include/gz/msgs/Export.hh", + "include/gz/msgs.hh", + "include/gz/msgs/MessageTypes.hh" +] + + cc_library( name = "msgs", srcs = [ diff --git a/tools/gz_msgs_generate_factory.py b/tools/gz_msgs_generate_factory.py index 4fa8002e..32caf416 100755 --- a/tools/gz_msgs_generate_factory.py +++ b/tools/gz_msgs_generate_factory.py @@ -141,7 +141,7 @@ def main(argv=sys.argv[1:]): args = parser.parse_args(argv) package_re = re.compile('^package (.*);$') - message_re = re.compile('message (.*)') + message_re = re.compile(r'message (\w*)\s?{?$') registrations = [] gz_msgs_headers = [] From 4fc843fe0604c5d55851e405bf0ffd563d1df204 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Tue, 6 Feb 2024 23:22:28 +0000 Subject: [PATCH 03/23] Fix up generate script Signed-off-by: Michael Carroll --- tools/gz_msgs_generate.py | 77 +++++++++++++-------------------------- 1 file changed, 25 insertions(+), 52 deletions(-) diff --git a/tools/gz_msgs_generate.py b/tools/gz_msgs_generate.py index 6b755a7d..da2e48f0 100755 --- a/tools/gz_msgs_generate.py +++ b/tools/gz_msgs_generate.py @@ -35,19 +35,15 @@ def main(argv=sys.argv[1:]): help='Flag to indicate if C++ bindings should be generated', action='store_true') parser.add_argument( - '--generate-ruby', - help='Flag to indicate if Ruby bindings should be generated', - action='store_true') - parser.add_argument( - '--generate-ignition', - help='Flag to indicate if ignition/ headers should be generated', + '--generate-python', + help='Flag to indicate if Python bindings should be generated', action='store_true') parser.add_argument( '--output-cpp-path', help='The basepath of the generated C++ files') parser.add_argument( - '--output-ruby-path', - help='The basepath of the generated C++ files') + '--output-python-path', + help='The basepath of the generated Python files') parser.add_argument( '--proto-path', required=True, @@ -58,23 +54,36 @@ def main(argv=sys.argv[1:]): required=True, help='The location of the template files', action='append') + parser.add_argument( + '--dependency-proto-descs', + nargs='*', + help='The location of proto descriptor files these messages depend on') + parser.add_argument( + '--dllexport-decl', + help='The DLL visibility macro to use, if not set, no macro will be used') args = parser.parse_args(argv) for input_file in args.input_path: - # First generate the base cpp and ruby files + # First generate the base cpp files cmd = [args.protoc_exec] - for pp in args.proto_path: - cmd += [f'--proto_path={pp}'] + for path in args.proto_path: + cmd += [f'--proto_path={path}'] if args.generate_cpp: - cmd += [f'--plugin=protoc-gen-ignmsgs={args.gz_generator_bin}'] - cmd += [f'--cpp_out=dllexport_decl=GZ_MSGS_VISIBLE:{args.output_cpp_path}'] - cmd += [f'--ignmsgs_out={args.output_cpp_path}'] - if args.generate_ruby: - cmd += [f'--ruby_out=dllexport_decl=GZ_MSGS_VISIBLE:{args.output_ruby_path}'] + cmd += [f'--plugin=protoc-gen-gzmsgs={args.gz_generator_bin}'] + if args.dllexport_decl: + cmd += [f'--cpp_out=dllexport_decl={args.dllexport_decl}:{args.output_cpp_path}'] + else: + cmd += [f'--cpp_out={args.output_cpp_path}'] + + cmd += [f'--gzmsgs_out={args.output_cpp_path}'] + if args.generate_python: + cmd += [f'--python_out={args.output_python_path}'] cmd += [input_file] + os.makedirs(args.output_cpp_path, exist_ok=True) + try: subprocess.check_call(cmd) except subprocess.CalledProcessError as e: @@ -90,7 +99,6 @@ def main(argv=sys.argv[1:]): continue detail_proto_file = proto_file.split(os.sep) - detail_proto_dir = detail_proto_file[:-1] detail_proto_dir.append('details') detail_proto_dir = os.path.join(*detail_proto_dir) @@ -117,40 +125,5 @@ def main(argv=sys.argv[1:]): print(f'Failed to manipulate gz-msgs headers: {e}') sys.exit(-1) - - if args.generate_ignition: - ignition_header_dir = os.path.join(args.output_cpp_path, 'ignition', 'msgs') - ignition_header = proto_file.split(os.sep) - ignition_header[0] = 'ignition' - - proto_name = ignition_header[2] - - ignition_header = os.path.join(*ignition_header) - ignition_header = os.path.join(args.output_cpp_path, ignition_header + ".pb.h") - - os.makedirs(os.path.join(args.output_cpp_path, ignition_header_dir), - exist_ok=True) - - with open(ignition_header, 'w') as f: - f.write('''/* - * Copyright (C) 2022 Open Source Robotics Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - ''') - f.write(f'#include \n') - f.write('#include \n') - if __name__ == '__main__': sys.exit(main()) From f7db1e1e6a91c62cd44306b31ced22bd401cfe69 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Tue, 6 Feb 2024 23:25:38 +0000 Subject: [PATCH 04/23] Minimize diff Signed-off-by: Michael Carroll --- tools/gz_msgs_generate.py | 107 ++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/tools/gz_msgs_generate.py b/tools/gz_msgs_generate.py index da2e48f0..b1cf2476 100755 --- a/tools/gz_msgs_generate.py +++ b/tools/gz_msgs_generate.py @@ -19,7 +19,7 @@ import subprocess import sys -def main(argv=sys.argv[1:]): +def parse_args(argv=sys.argv[1:]): parser = argparse.ArgumentParser( description='Generate protobuf support files', formatter_class=argparse.ArgumentDefaultsHelpFormatter) @@ -62,68 +62,71 @@ def main(argv=sys.argv[1:]): '--dllexport-decl', help='The DLL visibility macro to use, if not set, no macro will be used') args = parser.parse_args(argv) + return args - for input_file in args.input_path: - # First generate the base cpp files - cmd = [args.protoc_exec] +def generate_proto(input_file, args): + # First generate the base cpp files + cmd = [args.protoc_exec] - for path in args.proto_path: - cmd += [f'--proto_path={path}'] + for path in args.proto_path: + cmd += [f'--proto_path={path}'] - if args.generate_cpp: - cmd += [f'--plugin=protoc-gen-gzmsgs={args.gz_generator_bin}'] - if args.dllexport_decl: - cmd += [f'--cpp_out=dllexport_decl={args.dllexport_decl}:{args.output_cpp_path}'] - else: - cmd += [f'--cpp_out={args.output_cpp_path}'] + if args.generate_cpp: + cmd += [f'--plugin=protoc-gen-gzmsgs={args.gz_generator_bin}'] + if args.dllexport_decl: + cmd += [f'--cpp_out=dllexport_decl={args.dllexport_decl}:{args.output_cpp_path}'] + else: + cmd += [f'--cpp_out={args.output_cpp_path}'] - cmd += [f'--gzmsgs_out={args.output_cpp_path}'] - if args.generate_python: - cmd += [f'--python_out={args.output_python_path}'] - cmd += [input_file] + cmd += [f'--gzmsgs_out={args.output_cpp_path}'] + if args.generate_python: + cmd += [f'--python_out={args.output_python_path}'] + cmd += [input_file] - os.makedirs(args.output_cpp_path, exist_ok=True) + os.makedirs(args.output_cpp_path, exist_ok=True) - try: - subprocess.check_call(cmd) - except subprocess.CalledProcessError as e: - print(f'Failed to execute protoc compiler: {e}') - sys.exit(-1) + try: + subprocess.check_call(cmd) + except subprocess.CalledProcessError as e: + print(f'Failed to execute protoc compiler: {e}') + sys.exit(-1) - # Move original generated cpp to details/ - proto_file = None - for proto_path in args.proto_path: - if input_file.find(proto_path) == 0: - proto_file = os.path.splitext(os.path.relpath(input_file, proto_path))[0] - if not proto_file: - continue + # Move original generated cpp to details/ + proto_file = None + for proto_path in args.proto_path: + if input_file.find(proto_path) == 0: + proto_file = os.path.splitext(os.path.relpath(input_file, proto_path))[0] + if not proto_file: + return - detail_proto_file = proto_file.split(os.sep) - detail_proto_dir = detail_proto_file[:-1] - detail_proto_dir.append('details') - detail_proto_dir = os.path.join(*detail_proto_dir) - detail_proto_file.insert(-1, 'details') - detail_proto_file = os.path.join(*detail_proto_file) + detail_proto_file = proto_file.split(os.sep) + detail_proto_dir = detail_proto_file[:-1] + detail_proto_dir.append('details') + detail_proto_dir = os.path.join(*detail_proto_dir) + detail_proto_file.insert(-1, 'details') + detail_proto_file = os.path.join(*detail_proto_file) - header = os.path.join(args.output_cpp_path, proto_file + ".pb.h") - gz_header = os.path.join(args.output_cpp_path, proto_file + ".gz.h") - detail_header = os.path.join(args.output_cpp_path, detail_proto_file + ".pb.h") + header = os.path.join(args.output_cpp_path, proto_file + ".pb.h") + gz_header = os.path.join(args.output_cpp_path, proto_file + ".gz.h") + detail_header = os.path.join(args.output_cpp_path, detail_proto_file + ".pb.h") - if proto_file.find('google/protobuf') >= 0: - continue + if proto_file.find('google/protobuf') >= 0: + return - try: - os.makedirs(os.path.join(args.output_cpp_path, detail_proto_dir), - exist_ok=True) - # Windows cannot rename a file to an existing file - if os.path.exists(detail_header): - os.remove(detail_header) + try: + os.makedirs(os.path.join(args.output_cpp_path, detail_proto_dir), + exist_ok=True) + # Windows cannot rename a file to an existing file + if os.path.exists(detail_header): + os.remove(detail_header) - os.rename(header, detail_header) - os.rename(gz_header, header) - except Exception as e: - print(f'Failed to manipulate gz-msgs headers: {e}') - sys.exit(-1) + os.rename(header, detail_header) + os.rename(gz_header, header) + except Exception as e: + print(f'Failed to manipulate gz-msgs headers: {e}') + sys.exit(-1) if __name__ == '__main__': - sys.exit(main()) + args = parse_args() + for input_file in args.input_file: + generate_proto(input_file, args) From 8881d33056a6e6cc920b645ee55882b7f7cc2082 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Tue, 6 Feb 2024 23:31:08 +0000 Subject: [PATCH 05/23] Fix arg Signed-off-by: Michael Carroll --- tools/gz_msgs_generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gz_msgs_generate.py b/tools/gz_msgs_generate.py index b1cf2476..3697c5b7 100755 --- a/tools/gz_msgs_generate.py +++ b/tools/gz_msgs_generate.py @@ -128,5 +128,5 @@ def generate_proto(input_file, args): if __name__ == '__main__': args = parse_args() - for input_file in args.input_file: + for input_file in args.input_path: generate_proto(input_file, args) From 554b57c974f86527f30310c7a001d8f0d29d9f24 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Tue, 6 Feb 2024 23:36:23 +0000 Subject: [PATCH 06/23] Revert all changes to gz_msgs_generate Signed-off-by: Michael Carroll --- tools/gz_msgs_generate.py | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/tools/gz_msgs_generate.py b/tools/gz_msgs_generate.py index 3697c5b7..1805e2f3 100755 --- a/tools/gz_msgs_generate.py +++ b/tools/gz_msgs_generate.py @@ -19,7 +19,7 @@ import subprocess import sys -def parse_args(argv=sys.argv[1:]): +def main(argv=sys.argv[1:]): parser = argparse.ArgumentParser( description='Generate protobuf support files', formatter_class=argparse.ArgumentDefaultsHelpFormatter) @@ -43,7 +43,7 @@ def parse_args(argv=sys.argv[1:]): help='The basepath of the generated C++ files') parser.add_argument( '--output-python-path', - help='The basepath of the generated Python files') + help='The basepath of the generated C++ files') parser.add_argument( '--proto-path', required=True, @@ -52,8 +52,7 @@ def parse_args(argv=sys.argv[1:]): parser.add_argument( '--input-path', required=True, - help='The location of the template files', - action='append') + help='The location of the template files') parser.add_argument( '--dependency-proto-descs', nargs='*', @@ -62,15 +61,17 @@ def parse_args(argv=sys.argv[1:]): '--dllexport-decl', help='The DLL visibility macro to use, if not set, no macro will be used') args = parser.parse_args(argv) - return args -def generate_proto(input_file, args): # First generate the base cpp files cmd = [args.protoc_exec] for path in args.proto_path: cmd += [f'--proto_path={path}'] + if args.dependency_proto_descs: + for path in args.dependency_proto_descs: + cmd += [f'--descriptor_set_in={path}'] + if args.generate_cpp: cmd += [f'--plugin=protoc-gen-gzmsgs={args.gz_generator_bin}'] if args.dllexport_decl: @@ -81,7 +82,14 @@ def generate_proto(input_file, args): cmd += [f'--gzmsgs_out={args.output_cpp_path}'] if args.generate_python: cmd += [f'--python_out={args.output_python_path}'] - cmd += [input_file] + + cmd += [args.input_path] + + try: + subprocess.check_call(cmd) + except subprocess.CalledProcessError as e: + print(f'Failed to execute protoc compiler: {e}') + sys.exit(-1) os.makedirs(args.output_cpp_path, exist_ok=True) @@ -92,14 +100,9 @@ def generate_proto(input_file, args): sys.exit(-1) # Move original generated cpp to details/ - proto_file = None - for proto_path in args.proto_path: - if input_file.find(proto_path) == 0: - proto_file = os.path.splitext(os.path.relpath(input_file, proto_path))[0] - if not proto_file: - return - + proto_file = os.path.splitext(os.path.relpath(args.input_path, args.proto_path[0]))[0] detail_proto_file = proto_file.split(os.sep) + detail_proto_dir = detail_proto_file[:-1] detail_proto_dir.append('details') detail_proto_dir = os.path.join(*detail_proto_dir) @@ -110,9 +113,6 @@ def generate_proto(input_file, args): gz_header = os.path.join(args.output_cpp_path, proto_file + ".gz.h") detail_header = os.path.join(args.output_cpp_path, detail_proto_file + ".pb.h") - if proto_file.find('google/protobuf') >= 0: - return - try: os.makedirs(os.path.join(args.output_cpp_path, detail_proto_dir), exist_ok=True) @@ -127,6 +127,4 @@ def generate_proto(input_file, args): sys.exit(-1) if __name__ == '__main__': - args = parse_args() - for input_file in args.input_path: - generate_proto(input_file, args) + sys.exit(main()) From 35d48cd1d656e44ff13ebf14d7998655d527ad01 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Mon, 4 Mar 2024 19:14:26 +0000 Subject: [PATCH 07/23] Clean up harmonic implementation Signed-off-by: Michael Carroll --- BUILD.bazel | 9 +- protobuf.bzl | 235 ------------------------------ tools/gz_msgs_generate.bzl | 9 +- tools/gz_msgs_generate_factory.py | 35 ++--- 4 files changed, 22 insertions(+), 266 deletions(-) delete mode 100644 protobuf.bzl diff --git a/BUILD.bazel b/BUILD.bazel index 8fc7b8ef..3c316071 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -46,7 +46,7 @@ protos = glob(["proto/gz/msgs/*.proto"]) gz_include_header( name = "msgs_hh_genrule", - out = "include/gz/msgs.hh", + out = "core/include/gz/msgs.hh", hdrs = public_headers_no_gen + [ "core/include/gz/msgs/config.hh", "core/include/gz/msgs/Export.hh", @@ -88,16 +88,15 @@ gz_proto_library( gz_proto_factory( name = "gzmsgs_proto_factory", deps = [":gzmsgs_proto"], - namespace = "gz::msgs", cc_output = "core/src/RegisterMsgs.cc", - hh_output = "include/gz/msgs/MessageTypes.hh" + hh_output = "core/include/gz/msgs/MessageTypes.hh" ) public_headers = public_headers_no_gen + [ "core/include/gz/msgs/config.hh", "core/include/gz/msgs/Export.hh", - "include/gz/msgs.hh", - "include/gz/msgs/MessageTypes.hh" + "core/include/gz/msgs.hh", + "core/include/gz/msgs/MessageTypes.hh" ] diff --git a/protobuf.bzl b/protobuf.bzl deleted file mode 100644 index ac7bb013..00000000 --- a/protobuf.bzl +++ /dev/null @@ -1,235 +0,0 @@ -"""Utility functions for generating protobuf code.""" - -load("@rules_proto//proto:defs.bzl", "ProtoInfo") - -_PROTO_EXTENSION = ".proto" -_VIRTUAL_IMPORTS = "/_virtual_imports/" - -def well_known_proto_libs(): - return [ - "@com_google_protobuf//:any_proto", - "@com_google_protobuf//:api_proto", - "@com_google_protobuf//:compiler_plugin_proto", - "@com_google_protobuf//:descriptor_proto", - "@com_google_protobuf//:duration_proto", - "@com_google_protobuf//:empty_proto", - "@com_google_protobuf//:field_mask_proto", - "@com_google_protobuf//:source_context_proto", - "@com_google_protobuf//:struct_proto", - "@com_google_protobuf//:timestamp_proto", - "@com_google_protobuf//:type_proto", - "@com_google_protobuf//:wrappers_proto", - ] - -def get_proto_root(workspace_root): - """Gets the root protobuf directory. - Args: - workspace_root: context.label.workspace_root - Returns: - The directory relative to which generated include paths should be. - """ - if workspace_root: - return "/{}".format(workspace_root) - else: - return "" - -def _strip_proto_extension(proto_filename): - if not proto_filename.endswith(_PROTO_EXTENSION): - fail('"{}" does not end with "{}"'.format( - proto_filename, - _PROTO_EXTENSION, - )) - return proto_filename[:-len(_PROTO_EXTENSION)] - -def proto_path_to_generated_filename(proto_path, fmt_str): - """Calculates the name of a generated file for a protobuf path. - For example, "examples/protos/helloworld.proto" might map to - "helloworld.pb.h". - Args: - proto_path: The path to the .proto file. - fmt_str: A format string used to calculate the generated filename. For - example, "{}.pb.h" might be used to calculate a C++ header filename. - Returns: - The generated filename. - """ - return fmt_str.format(_strip_proto_extension(proto_path)) - -def get_include_directory(source_file): - """Returns the include directory path for the source_file. I.e. all of the - include statements within the given source_file are calculated relative to - the directory returned by this method. - The returned directory path can be used as the "--proto_path=" argument - value. - Args: - source_file: A proto file. - Returns: - The include directory path for the source_file. - """ - directory = source_file.path - prefix_len = 0 - - if is_in_virtual_imports(source_file): - root, relative = source_file.path.split(_VIRTUAL_IMPORTS, 2) - result = root + _VIRTUAL_IMPORTS + relative.split("/", 1)[0] - return result - - if not source_file.is_source and directory.startswith(source_file.root.path): - prefix_len = len(source_file.root.path) + 1 - - if directory.startswith("external", prefix_len): - external_separator = directory.find("/", prefix_len) - repository_separator = directory.find("/", external_separator + 1) - return directory[:repository_separator] - else: - return source_file.root.path if source_file.root.path else "." - -def get_plugin_args( - plugin, - flags, - dir_out, - generate_mocks, - plugin_name = "PLUGIN"): - """Returns arguments configuring protoc to use a plugin for a language. - Args: - plugin: An executable file to run as the protoc plugin. - flags: The plugin flags to be passed to protoc. - dir_out: The output directory for the plugin. - generate_mocks: A bool indicating whether to generate mocks. - plugin_name: A name of the plugin, it is required to be unique when there - are more than one plugin used in a single protoc command. - Returns: - A list of protoc arguments configuring the plugin. - """ - augmented_flags = list(flags) - if generate_mocks: - augmented_flags.append("generate_mock_code=true") - - augmented_dir_out = dir_out - if augmented_flags: - augmented_dir_out = ",".join(augmented_flags) + ":" + dir_out - - return [ - "--plugin=protoc-gen-{plugin_name}={plugin_path}".format( - plugin_name = plugin_name, - plugin_path = plugin.path, - ), - "--{plugin_name}_out={dir_out}".format( - plugin_name = plugin_name, - dir_out = augmented_dir_out, - ), - ] - -def _get_staged_proto_file(context, source_file): - if source_file.dirname == context.label.package or \ - is_in_virtual_imports(source_file): - # Current target and source_file are in same package - return source_file - else: - # Current target and source_file are in different packages (most - # probably even in different repositories) - copied_proto = context.actions.declare_file(source_file.basename) - context.actions.run_shell( - inputs = [source_file], - outputs = [copied_proto], - command = "cp {} {}".format(source_file.path, copied_proto.path), - mnemonic = "CopySourceProto", - ) - return copied_proto - -def protos_from_context(context): - """Copies proto files to the appropriate location. - Args: - context: The ctx object for the rule. - Returns: - A list of the protos. - """ - protos = [] - for src in context.attr.deps: - for file in src[ProtoInfo].direct_sources: - protos.append(_get_staged_proto_file(context, file)) - return protos - -def includes_from_deps(deps): - """Get includes from rule dependencies.""" - return [ - file - for src in deps - for file in src[ProtoInfo].transitive_imports.to_list() - ] - -def get_proto_arguments(protos, genfiles_dir_path): - """Get the protoc arguments specifying which protos to compile.""" - arguments = [] - for proto in protos: - strip_prefix_len = 0 - if is_in_virtual_imports(proto): - incl_directory = get_include_directory(proto) - if proto.path.startswith(incl_directory): - strip_prefix_len = len(incl_directory) + 1 - elif proto.path.startswith(genfiles_dir_path): - strip_prefix_len = len(genfiles_dir_path) + 1 - - arguments.append(proto.path[strip_prefix_len:]) - - return arguments - -def declare_out_files(protos, context, generated_file_format): - """Declares and returns the files to be generated.""" - - out_file_paths = [] - for proto in protos: - if not is_in_virtual_imports(proto): - out_file_paths.append(proto.basename) - else: - path = proto.path[proto.path.index(_VIRTUAL_IMPORTS) + 1:] - out_file_paths.append(path) - - return [ - context.actions.declare_file( - proto_path_to_generated_filename( - out_file_path, - generated_file_format, - ), - ) - for out_file_path in out_file_paths - ] - -def get_out_dir(protos, context): - """ Returns the calculated value for --_out= protoc argument based on - the input source proto files and current context. - Args: - protos: A list of protos to be used as source files in protoc command - context: A ctx object for the rule. - Returns: - The value of --_out= argument. - """ - at_least_one_virtual = 0 - for proto in protos: - if is_in_virtual_imports(proto): - at_least_one_virtual = True - elif at_least_one_virtual: - fail("Proto sources must be either all virtual imports or all real") - if at_least_one_virtual: - out_dir = get_include_directory(protos[0]) - ws_root = protos[0].owner.workspace_root - if ws_root and out_dir.find(ws_root) >= 0: - out_dir = "".join(out_dir.rsplit(ws_root, 1)) - return struct( - path = out_dir, - import_path = out_dir[out_dir.find(_VIRTUAL_IMPORTS) + 1:], - ) - return struct(path = context.genfiles_dir.path, import_path = None) - -def is_in_virtual_imports(source_file, virtual_folder = _VIRTUAL_IMPORTS): - """Determines if source_file is virtual (is placed in _virtual_imports - subdirectory). The output of all proto_library targets which use - import_prefix and/or strip_import_prefix arguments is placed under - _virtual_imports directory. - Args: - source_file: A proto file. - virtual_folder: The virtual folder name (is set to "_virtual_imports" - by default) - Returns: - True if source_file is located under _virtual_imports, False otherwise. - """ - return not source_file.is_source and virtual_folder in source_file.path diff --git a/tools/gz_msgs_generate.bzl b/tools/gz_msgs_generate.bzl index 80862211..6559fb20 100644 --- a/tools/gz_msgs_generate.bzl +++ b/tools/gz_msgs_generate.bzl @@ -51,8 +51,9 @@ def _gz_proto_factory_impl(ctx): for proto in src[ProtoInfo].direct_sources: in_protos.append(proto) - for proto in src[ProtoInfo].transitive_sources.to_list(): - in_protos.append(proto) + #for proto in src[ProtoInfo].transitive_sources.to_list(): + # print('transitive: ', proto) + # in_protos.append(proto) in_protos = depset(in_protos).to_list() arguments = [ @@ -64,7 +65,6 @@ def _gz_proto_factory_impl(ctx): arguments.append("--proto-path=" + include_dir) arguments.append("--proto-include-path=" + out_dir.path) - arguments.append("--namespace=" + ctx.attr.namespace) arguments.append("--protos") for proto in in_protos: arguments.append(proto.path) @@ -92,9 +92,6 @@ _gz_proto_factory = rule( allow_empty = False, providers = [ProtoInfo], ), - "namespace": attr.string( - mandatory = True, - ), "cc_output": attr.output(mandatory = True), "hh_output": attr.output(mandatory = True), "gz_msgs_generate_factory_py": attr.label( diff --git a/tools/gz_msgs_generate_factory.py b/tools/gz_msgs_generate_factory.py index 32caf416..a327da0e 100755 --- a/tools/gz_msgs_generate_factory.py +++ b/tools/gz_msgs_generate_factory.py @@ -72,10 +72,9 @@ * Do not edit this directly */ -#include "MessageTypes.hh" - #include "gz/msgs/Factory.hh" #include "gz/msgs/MessageFactory.hh" +#include "{include_path}/MessageTypes.hh" #include @@ -118,10 +117,6 @@ def main(argv=sys.argv[1:]): '--hh-output', required=True, help='The path to the generated hh file') - parser.add_argument( - '--namespace', - required=True, - help='The namespace to use') parser.add_argument( '--proto-path', required=True, @@ -143,13 +138,12 @@ def main(argv=sys.argv[1:]): package_re = re.compile('^package (.*);$') message_re = re.compile(r'message (\w*)\s?{?$') - registrations = [] + registrations = dict() gz_msgs_headers = [] + package = None + messages = [] for proto in args.protos: - package = None - messages = [] - try: with open(proto, 'r') as f: content = f.readlines() @@ -166,28 +160,29 @@ def main(argv=sys.argv[1:]): if package and messages: for message in messages: - registrations.append(register_fn.format( + registrations['_'.join([*package, message])] = register_fn.format( package_str='.'.join(package), message_str=message, message_cpp_type='::'.join([*package, message]) - )) - + ) split = proto.replace(args.proto_include_path, '') split = [s for s in split.split("/") if s] split[-1] = split[-1].replace(".proto", ".pb.h") - print(split) - gz_msgs_headers.append("#include <" + "/".join(split) + ">") + namespace = '::'.join(package) + include_path = '/'.join(package) + with open(os.path.join(args.cc_output), 'w') as f: - f.write((cc_source.format(registrations='\n'.join(registrations), - nRegistrations=len(registrations), - namespace=args.namespace) + - cc_factory.format(namespace=args.namespace))) + f.write((cc_source.format(registrations='\n'.join(registrations.values()), + nRegistrations=len(registrations.values()), + namespace=namespace, + include_path=include_path) + + cc_factory.format(namespace=namespace))) with open(os.path.join(args.hh_output), 'w') as f: - f.write(cc_header.format(namespace=args.namespace, + f.write(cc_header.format(namespace=namespace, gz_msgs_headers='\n'.join(gz_msgs_headers))) if __name__ == '__main__': From 6338d74ae234d33fb4aad8ffa3b69807da0f5dd5 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Mon, 4 Mar 2024 19:29:35 +0000 Subject: [PATCH 08/23] Add a "lite" factory variant Signed-off-by: Michael Carroll --- tools/BUILD.bazel | 4 +- tools/gz_msgs_generate_factory.py | 90 +++++------- tools/gz_msgs_generate_factory_lite.py | 189 +++++++++++++++++++++++++ 3 files changed, 229 insertions(+), 54 deletions(-) create mode 100755 tools/gz_msgs_generate_factory_lite.py diff --git a/tools/BUILD.bazel b/tools/BUILD.bazel index 3568652b..359f83e5 100644 --- a/tools/BUILD.bazel +++ b/tools/BUILD.bazel @@ -6,7 +6,7 @@ load( gz_py_binary( name = "gz_msgs_generate_factory_py", - srcs = ["gz_msgs_generate_factory.py"], - main = "gz_msgs_generate_factory.py", + srcs = ["gz_msgs_generate_factory_lite.py"], + main = "gz_msgs_generate_factory_lite.py", visibility = GZ_VISIBILITY, ) diff --git a/tools/gz_msgs_generate_factory.py b/tools/gz_msgs_generate_factory.py index a327da0e..89553422 100755 --- a/tools/gz_msgs_generate_factory.py +++ b/tools/gz_msgs_generate_factory.py @@ -16,7 +16,7 @@ import argparse import os -import re +import pathlib import sys # Create @@ -74,7 +74,7 @@ #include "gz/msgs/Factory.hh" #include "gz/msgs/MessageFactory.hh" -#include "{include_path}/MessageTypes.hh" +#include "{package_path}/MessageTypes.hh" #include @@ -110,21 +110,17 @@ def main(argv=sys.argv[1:]): description='Generate protobuf factory file', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument( - '--cc-output', + '--output-cpp-path', required=True, - help='The path to the generated cpp file') + help='The basepath of the generated C++ files') parser.add_argument( - '--hh-output', + '--proto-package', required=True, - help='The path to the generated hh file') + help='The basepath of the generated C++ files') parser.add_argument( '--proto-path', required=True, help='The location of the protos') - parser.add_argument( - '--proto-include-path', - required=True, - help='The location of the protos') parser.add_argument( '--protos', type=str, @@ -135,55 +131,45 @@ def main(argv=sys.argv[1:]): args = parser.parse_args(argv) - package_re = re.compile('^package (.*);$') - message_re = re.compile(r'message (\w*)\s?{?$') + headers = [] + registrations = [] - registrations = dict() - gz_msgs_headers = [] - package = None - messages = [] + package = [p for p in args.proto_package.split('.') if len(p)] + namespace = '::'.join(package) + package_str = '.'.join(package) + package_path = '/'.join(package) for proto in args.protos: - try: - with open(proto, 'r') as f: - content = f.readlines() - for line in content: - package_found = package_re.match(line) - if package_found: - package = package_found.group(1).split('.') - - message_found = message_re.match(line) - if message_found: - messages.append(message_found.group(1)) - except: - pass - - if package and messages: - for message in messages: - registrations['_'.join([*package, message])] = register_fn.format( - package_str='.'.join(package), - message_str=message, - message_cpp_type='::'.join([*package, message]) - ) - - split = proto.replace(args.proto_include_path, '') - split = [s for s in split.split("/") if s] - split[-1] = split[-1].replace(".proto", ".pb.h") - gz_msgs_headers.append("#include <" + "/".join(split) + ">") + proto_file = os.path.splitext(os.path.relpath(proto, args.proto_path))[0] + header = proto_file + ".pb.h" + headers.append(f"#include <{header}>") - namespace = '::'.join(package) - include_path = '/'.join(package) + proto_file = '_'.join(pathlib.Path(proto_file).parts) - with open(os.path.join(args.cc_output), 'w') as f: - f.write((cc_source.format(registrations='\n'.join(registrations.values()), - nRegistrations=len(registrations.values()), + # The gazebo extensions to the gazebo compiler write out a series of index files + # which capture the message types + index = os.path.join(args.output_cpp_path, proto_file + ".pb_index") + with open(index, "r") as index_f: + for line in index_f.readlines(): + line = line.strip() + + message_str = line + message_cpp_type = '::'.join(package) + '::' + message_str + + registrations.append(register_fn.format( + package_str=package_str, + message_str=message_str, + message_cpp_type=message_cpp_type)) + + with open(os.path.join(args.output_cpp_path, *package, 'MessageTypes.hh'), 'w') as f: + f.write(cc_header.format(gz_msgs_headers='\n'.join(headers), namespace=namespace)) + + with open(os.path.join(args.output_cpp_path, *package, 'register.cc'), 'w') as f: + f.write((cc_source.format(registrations='\n'.join(registrations), + nRegistrations=len(registrations), namespace=namespace, - include_path=include_path) + + package_path=package_path) + cc_factory.format(namespace=namespace))) - with open(os.path.join(args.hh_output), 'w') as f: - f.write(cc_header.format(namespace=namespace, - gz_msgs_headers='\n'.join(gz_msgs_headers))) - if __name__ == '__main__': sys.exit(main()) diff --git a/tools/gz_msgs_generate_factory_lite.py b/tools/gz_msgs_generate_factory_lite.py new file mode 100755 index 00000000..624b664f --- /dev/null +++ b/tools/gz_msgs_generate_factory_lite.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2023 Open Source Robotics Foundation +# +# Licensed under the Apache License, Version 2.0 (the "License") +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import os +import re +import sys + +# Create +cc_header = """/* + * Copyright (C) 2023 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +/* This file was automatically generated. + * Do not edit this directly + */ + +#ifndef GZ_MSGS_MESSAGE_TYPES_HH_ +#define GZ_MSGS_MESSAGE_TYPES_HH_ +{gz_msgs_headers} + +namespace {namespace} {{ +int RegisterAll(); +}} +#endif""" + +# Create factory registration bits +cc_source = """/* + * Copyright (C) 2023 Open Source Robotics Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * +*/ + +/* This file was automatically generated. + * Do not edit this directly + */ + +#include "gz/msgs/Factory.hh" +#include "gz/msgs/MessageFactory.hh" +#include "{include_path}/MessageTypes.hh" + +#include + +namespace {{ + using NamedFactoryFn = std::pair; + + std::array kFactoryFunctions = {{{{ +{registrations} +}}}}; +}} // namespace +""" + +cc_factory = """ +namespace {namespace} {{ +int RegisterAll() {{ + size_t registered = 0; + for (const auto &entry: kFactoryFunctions) {{ + gz::msgs::Factory::Register(entry.first, entry.second); + registered++; + }} + return registered; +}} + +static int kMessagesRegistered = RegisterAll(); +}} // namespace {namespace} +""" + +register_fn = """ {{"{package_str}.{message_str}", + []()->std::unique_ptr{{return std::make_unique<{message_cpp_type}>();}}}},""" + +def main(argv=sys.argv[1:]): + parser = argparse.ArgumentParser( + description='Generate protobuf factory file', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument( + '--cc-output', + required=True, + help='The path to the generated cpp file') + parser.add_argument( + '--hh-output', + required=True, + help='The path to the generated hh file') + parser.add_argument( + '--proto-path', + required=True, + help='The location of the protos') + parser.add_argument( + '--proto-include-path', + required=True, + help='The location of the protos') + parser.add_argument( + '--protos', + type=str, + nargs='*', + required=True, + help='The list of protos to include' + ) + + args = parser.parse_args(argv) + + package_re = re.compile('^package (.*);$') + message_re = re.compile(r'message (\w*)\s?{?$') + + registrations = dict() + gz_msgs_headers = [] + package = [] + messages = [] + + for proto in args.protos: + try: + with open(proto, 'r') as f: + content = f.readlines() + for line in content: + package_found = package_re.match(line) + if package_found: + package = package_found.group(1).split('.') + + message_found = message_re.match(line) + if message_found: + messages.append(message_found.group(1)) + except: + pass + + if package and messages: + for message in messages: + registrations['_'.join([*package, message])] = register_fn.format( + package_str='.'.join(package), + message_str=message, + message_cpp_type='::'.join([*package, message]) + ) + + split = proto.replace(args.proto_include_path, '') + split = [s for s in split.split("/") if s] + split[-1] = split[-1].replace(".proto", ".pb.h") + gz_msgs_headers.append("#include <" + "/".join(split) + ">") + + namespace = '::'.join(package) + include_path = '/'.join(package) + + with open(os.path.join(args.cc_output), 'w') as f: + f.write((cc_source.format(registrations='\n'.join(registrations.values()), + nRegistrations=len(registrations.values()), + namespace=namespace, + include_path=include_path) + + cc_factory.format(namespace=namespace))) + + with open(os.path.join(args.hh_output), 'w') as f: + f.write(cc_header.format(namespace=namespace, + gz_msgs_headers='\n'.join(gz_msgs_headers))) + +if __name__ == '__main__': + sys.exit(main()) From 5138cc52ca28ee52f3cd31a16c33133e9f487040 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Mon, 4 Mar 2024 19:43:13 +0000 Subject: [PATCH 09/23] Add lint support Signed-off-by: Michael Carroll --- BUILD.bazel | 114 +++++++++++++++++++++---------------- tools/gz_msgs_generate.bzl | 37 ++++++------ 2 files changed, 82 insertions(+), 69 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index 3c316071..871369e1 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -7,18 +7,29 @@ load( "gz_export_header", "gz_include_header", ) +load( + "@gz//bazel/lint:lint.bzl", + "add_lint_tests", +) load( "@gz//msgs/tools:gz_msgs_generate.bzl", - "gz_proto_library", "gz_proto_factory", + "gz_proto_library", ) +load("@rules_license//rules:license.bzl", "license") package( + default_applicable_licenses = [GZ_ROOT + "msgs:license"], default_visibility = GZ_VISIBILITY, features = GZ_FEATURES, ) -licenses(["notice"]) # Apache-2.0 +license( + name = "license", + package_name = "gz-msgs", +) + +licenses(["notice"]) exports_files(["LICENSE"]) @@ -78,40 +89,42 @@ proto_library( ) gz_proto_library( - name = "gzmsgs_cc_proto", - proto_deps = [":gzmsgs_proto"], - deps = [ - "@com_google_protobuf//:protobuf", - ] + name = "gzmsgs_cc_proto", + proto_deps = [":gzmsgs_proto"], + deps = [ + "@com_google_protobuf//:protobuf", + ], ) gz_proto_factory( - name = "gzmsgs_proto_factory", - deps = [":gzmsgs_proto"], - cc_output = "core/src/RegisterMsgs.cc", - hh_output = "core/include/gz/msgs/MessageTypes.hh" + name = "gzmsgs_proto_factory", + cc_output = "core/src/RegisterMsgs.cc", + hh_output = "core/include/gz/msgs/MessageTypes.hh", + deps = [":gzmsgs_proto"], ) public_headers = public_headers_no_gen + [ "core/include/gz/msgs/config.hh", "core/include/gz/msgs/Export.hh", "core/include/gz/msgs.hh", - "core/include/gz/msgs/MessageTypes.hh" + "core/include/gz/msgs/MessageTypes.hh", ] - cc_library( name = "msgs", srcs = [ - "core/src/Factory.cc", "core/src/DynamicFactory.cc", "core/src/DynamicFactory.hh", + "core/src/Factory.cc", "core/src/MessageFactory.cc", + "core/src/RegisterMsgs.cc", "core/src/impl/InstallationDirectories.cc", - "core/src/RegisterMsgs.cc" ], hdrs = public_headers, - includes = ["core/include", "core/src"], + includes = [ + "core/include", + "core/src", + ], deps = [ ":gzmsgs_cc_proto", ":gzmsgs_proto_factory", @@ -143,49 +156,50 @@ test_sources = glob( ], ) for src in test_sources] - cc_test( - name = "INTEGRATION_headers", - srcs = ["test/integration/headers.cc"], - deps = [ - ":gzmsgs_cc_proto", - "@gtest", - "@gtest//:gtest_main", - ], + name = "INTEGRATION_headers", + srcs = ["test/integration/headers.cc"], + deps = [ + ":gzmsgs_cc_proto", + "@gtest", + "@gtest//:gtest_main", + ], ) cc_test( - name = "INTEGRATION_image_msg", - srcs = ["test/integration/image_msg.cc"], - deps = [ - ":gzmsgs_cc_proto", - "@gtest", - "@gtest//:gtest_main", - ], + name = "INTEGRATION_image_msg", + srcs = ["test/integration/image_msg.cc"], + deps = [ + ":gzmsgs_cc_proto", + "@gtest", + "@gtest//:gtest_main", + ], ) cc_test( - name = "INTEGRATION_Utility", - srcs = ["test/integration/Utility_TEST.cc"], - deps = [ - ":msgs", - GZ_ROOT + "common/testing", - "@gtest", - "@gtest//:gtest_main", - ], + name = "INTEGRATION_Utility", + srcs = ["test/integration/Utility_TEST.cc"], + deps = [ + ":msgs", + GZ_ROOT + "common/testing", + "@gtest", + "@gtest//:gtest_main", + ], ) cc_test( - name = "INTEGRATION_Factory", - srcs = ["test/integration/Factory_TEST.cc"], - data = ["test/desc/stringmsg.desc"], - deps = [ - ":msgs", - GZ_ROOT + "common/testing", - "@gtest", - "@gtest//:gtest_main", - ], - defines = [ - 'GZ_MSGS_TEST_PATH=\\"msgs/test\\"', + name = "INTEGRATION_Factory", + srcs = ["test/integration/Factory_TEST.cc"], + data = ["test/desc/stringmsg.desc"], + defines = [ + 'GZ_MSGS_TEST_PATH=\\"msgs/test\\"', + ], + deps = [ + ":msgs", + GZ_ROOT + "common/testing", + "@gtest", + "@gtest//:gtest_main", ], ) + +add_lint_tests() diff --git a/tools/gz_msgs_generate.bzl b/tools/gz_msgs_generate.bzl index 6559fb20..335f1b81 100644 --- a/tools/gz_msgs_generate.bzl +++ b/tools/gz_msgs_generate.bzl @@ -58,7 +58,7 @@ def _gz_proto_factory_impl(ctx): in_protos = depset(in_protos).to_list() arguments = [ "--cc-output=" + ctx.outputs.cc_output.path, - "--hh-output=" + ctx.outputs.hh_output.path + "--hh-output=" + ctx.outputs.hh_output.path, ] for include_dir in include_dirs.to_list(): @@ -67,7 +67,7 @@ def _gz_proto_factory_impl(ctx): arguments.append("--proto-include-path=" + out_dir.path) arguments.append("--protos") for proto in in_protos: - arguments.append(proto.path) + arguments.append(proto.path) ctx.actions.run( inputs = protos, @@ -143,7 +143,7 @@ def _gz_proto_library_impl(ctx): arguments.append("--gzmsgs_out=" + out_dir.path) for proto in in_protos: - arguments.append(proto.path) + arguments.append(proto.path) cc_files = declare_out_files(out_protos, ctx, "{}.pb.cc") hh_files = declare_out_files(out_protos, ctx, "{}.pb.h") @@ -189,19 +189,18 @@ _gz_proto_library = rule( ) def gz_proto_library( - name, - proto_deps, - **kwargs): - - _gz_proto_library(name = name + "_pb", deps = proto_deps) - - filter_files(name=name + "_srcs", target=":" + name + "_pb", extensions=["cc"]) - filter_files(name=name + "_hdrs", target=":" + name + "_pb", extensions=["h"]) - kwargs['deps'].append(":" + name + "_pb") - - native.cc_library( - name = name, - srcs = [name + "_srcs"], - hdrs = [name + "_hdrs"], - **kwargs - ) + name, + proto_deps, + **kwargs): + _gz_proto_library(name = name + "_pb", deps = proto_deps) + + filter_files(name = name + "_srcs", target = ":" + name + "_pb", extensions = ["cc"]) + filter_files(name = name + "_hdrs", target = ":" + name + "_pb", extensions = ["h"]) + kwargs["deps"].append(":" + name + "_pb") + + native.cc_library( + name = name, + srcs = [name + "_srcs"], + hdrs = [name + "_hdrs"], + **kwargs + ) From 4e737953caefd4ba0a7993ce5a29e3120a87d38e Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Fri, 8 Mar 2024 17:01:32 +0000 Subject: [PATCH 10/23] Generate command line files Signed-off-by: Michael Carroll --- BUILD.bazel | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/BUILD.bazel b/BUILD.bazel index 871369e1..51991131 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -3,6 +3,7 @@ load( "GZ_FEATURES", "GZ_ROOT", "GZ_VISIBILITY", + "gz_configure_file", "gz_configure_header", "gz_export_header", "gz_include_header", @@ -202,4 +203,34 @@ cc_test( ], ) +gz_configure_file( + name = "msgs_yaml", + src = "conf/msgs.yaml.in", + out = "msgs.yaml", + package = "msgs", + defines = [ + "PROJECT_NAME_NO_VERSION_LOWER=msgs", + "gz_library_path=msgs/cmdmsgs", + ] + +) + +gz_configure_file( + name = "msgs_rb", + src = "core/src/cmd/cmdmsgs.rb.in", + out = "cmdmsgs.rb", + package = "msgs", + defines = [ + "library_location=libgz-msgs.so", + ] +) + +cc_binary( + name = "gz-msgs", + linkshared = True, + srcs = ["core/src/gz.cc"], + data = [":msgs_yaml", ":msgs_rb", ":gzmsgs_proto"], + deps = [":msgs"] +) + add_lint_tests() From b4ac4da0ac1babf6c0a41f679e721479764974c6 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Fri, 8 Mar 2024 17:01:51 +0000 Subject: [PATCH 11/23] Allow dynamic factory to load from descriptor files Signed-off-by: Michael Carroll --- core/src/DynamicFactory.cc | 88 +++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 40 deletions(-) diff --git a/core/src/DynamicFactory.cc b/core/src/DynamicFactory.cc index b46ad039..397f22be 100644 --- a/core/src/DynamicFactory.cc +++ b/core/src/DynamicFactory.cc @@ -87,58 +87,66 @@ void DynamicFactory::LoadDescriptors(const std::string &_paths) std::vector descDirs = split(_paths, kEnvironmentVariableSeparator); - - for (const std::string &descDir : descDirs) + auto loadDescFile = [this](const std::string &descFile) { - for (auto const &dirIter : std::filesystem::directory_iterator{descDir}) + std::cout << "Loading: " << descFile << std::endl; + + // Ignore files without the correct extensions. + if (descFile.rfind(".desc") == std::string::npos && + descFile.rfind(".proto") == std::string::npos && + descFile.rfind(".proto.bin") == std::string::npos) + return; + + // Parse the .desc file. + std::ifstream ifs(descFile); + if (!ifs.is_open()) + { + std::cerr << "DynamicFactory(): Unable to open [" << descFile << "]" + << std::endl; + return; + } + + google::protobuf::FileDescriptorSet fileDescriptorSet; + if (!fileDescriptorSet.ParseFromIstream(&ifs)) { - // Ignore files without the .desc extension. - if (dirIter.path().extension() != ".desc" && - dirIter.path().extension() != ".gz_desc") - continue; + std::cerr << "DynamicFactory(): Unable to parse descriptor set from [" + << descFile << "]" << std::endl; + return; + } - std::ifstream ifs(dirIter.path().string(), std::ifstream::in); - if (!ifs.is_open()) + // Place the real descriptors in the descriptor pool. + for (const google::protobuf::FileDescriptorProto &fileDescriptorProto : + fileDescriptorSet.file()) + { + if (!static_cast(this->pool.BuildFile(fileDescriptorProto))) { - std::cerr << "DynamicFactory(): Unable to open [" - << dirIter.path() << "]" - << std::endl; - continue; + std::cerr << "DynamicFactory(). Unable to place descriptors from [" + << descFile << "] in the descriptor pool" << std::endl; } - - google::protobuf::FileDescriptorSet fileDescriptorSet; - if (!fileDescriptorSet.ParseFromIstream(&ifs)) + else { - std::cerr << "DynamicFactory(): Unable to parse descriptor set from [" - << dirIter.path() << "]" << std::endl; - continue; + this->db.Add(fileDescriptorProto); } - for (const google::protobuf::FileDescriptorProto &fileDescriptorProto : - fileDescriptorSet.file()) - { - // If the descriptor already exists in the database, then skip it. - // This may happen as gz_desc files can potentially contain the - // transitive message definitions - google::protobuf::FileDescriptorProto checkDescriptorProto; - if (this->db.FindFileByName( - fileDescriptorProto.name(), &checkDescriptorProto)) - { - continue; - } - - if (!static_cast(pool.BuildFile(fileDescriptorProto))) - { - std::cerr << "DynamicFactory(). Unable to place descriptors from [" - << dirIter.path() - << "] in the descriptor pool" << std::endl; - } + } - this->db.Add(fileDescriptorProto); + }; + + + for (const std::string &descDir : descDirs) + { + if (!std::filesystem::is_directory(descDir)) + { + loadDescFile(descDir); + } + else + { + for (auto const &dirIter : std::filesystem::directory_iterator{descDir}) + { + loadDescFile(dirIter.path()); } } } - } ////////////////////////////////////////////////// From 4a840f8a0b1543107fa92d8896b3b0585bd7c533 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Fri, 8 Mar 2024 17:10:25 +0000 Subject: [PATCH 12/23] Lint Signed-off-by: Michael Carroll --- BUILD.bazel | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index 51991131..82a63128 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -204,33 +204,36 @@ cc_test( ) gz_configure_file( - name = "msgs_yaml", - src = "conf/msgs.yaml.in", - out = "msgs.yaml", - package = "msgs", - defines = [ - "PROJECT_NAME_NO_VERSION_LOWER=msgs", - "gz_library_path=msgs/cmdmsgs", - ] - + name = "msgs_yaml", + src = "conf/msgs.yaml.in", + out = "msgs.yaml", + defines = [ + "PROJECT_NAME_NO_VERSION_LOWER=msgs", + "gz_library_path=msgs/cmdmsgs", + ], + package = "msgs", ) gz_configure_file( - name = "msgs_rb", - src = "core/src/cmd/cmdmsgs.rb.in", - out = "cmdmsgs.rb", - package = "msgs", - defines = [ - "library_location=libgz-msgs.so", - ] + name = "msgs_rb", + src = "core/src/cmd/cmdmsgs.rb.in", + out = "cmdmsgs.rb", + defines = [ + "library_location=libgz-msgs.so", + ], + package = "msgs", ) cc_binary( - name = "gz-msgs", - linkshared = True, - srcs = ["core/src/gz.cc"], - data = [":msgs_yaml", ":msgs_rb", ":gzmsgs_proto"], - deps = [":msgs"] + name = "gz-msgs", + srcs = ["core/src/gz.cc"], + data = [ + ":gzmsgs_proto", + ":msgs_rb", + ":msgs_yaml", + ], + linkshared = True, + deps = [":msgs"], ) add_lint_tests() From 155304a991728e583ff19bb2d3b50c26e05dea75 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Fri, 8 Mar 2024 17:46:49 +0000 Subject: [PATCH 13/23] Remove dead code Signed-off-by: Michael Carroll --- tools/gz_msgs_generate.bzl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tools/gz_msgs_generate.bzl b/tools/gz_msgs_generate.bzl index 335f1b81..f70c82f2 100644 --- a/tools/gz_msgs_generate.bzl +++ b/tools/gz_msgs_generate.bzl @@ -51,10 +51,6 @@ def _gz_proto_factory_impl(ctx): for proto in src[ProtoInfo].direct_sources: in_protos.append(proto) - #for proto in src[ProtoInfo].transitive_sources.to_list(): - # print('transitive: ', proto) - # in_protos.append(proto) - in_protos = depset(in_protos).to_list() arguments = [ "--cc-output=" + ctx.outputs.cc_output.path, From 8e1d0dbc4bb9e7246c88b7d92fcdf1bbdb061605 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Fri, 8 Mar 2024 18:20:29 +0000 Subject: [PATCH 14/23] Add iostream header Signed-off-by: Michael Carroll --- core/src/DynamicFactory.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/DynamicFactory.cc b/core/src/DynamicFactory.cc index 397f22be..f83daffc 100644 --- a/core/src/DynamicFactory.cc +++ b/core/src/DynamicFactory.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "DynamicFactory.hh" From f02ed9046924a0ef84078db7c5dcf6793108fb46 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Fri, 8 Mar 2024 18:21:15 +0000 Subject: [PATCH 15/23] Change data deps Signed-off-by: Michael Carroll --- BUILD.bazel | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index 82a63128..003baccc 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -229,10 +229,11 @@ cc_binary( srcs = ["core/src/gz.cc"], data = [ ":gzmsgs_proto", - ":msgs_rb", - ":msgs_yaml", + "cmdmsgs.rb", + "msgs.yaml", ], linkshared = True, + linkstatic = True, deps = [":msgs"], ) From 0ebc36692d13e40c7ba98c8465d069a10c329483 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Fri, 8 Mar 2024 18:37:05 +0000 Subject: [PATCH 16/23] Lint Signed-off-by: Michael Carroll --- core/src/DynamicFactory.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/DynamicFactory.cc b/core/src/DynamicFactory.cc index f83daffc..8f93b2ad 100644 --- a/core/src/DynamicFactory.cc +++ b/core/src/DynamicFactory.cc @@ -90,8 +90,6 @@ void DynamicFactory::LoadDescriptors(const std::string &_paths) auto loadDescFile = [this](const std::string &descFile) { - std::cout << "Loading: " << descFile << std::endl; - // Ignore files without the correct extensions. if (descFile.rfind(".desc") == std::string::npos && descFile.rfind(".proto") == std::string::npos && @@ -128,9 +126,7 @@ void DynamicFactory::LoadDescriptors(const std::string &_paths) { this->db.Add(fileDescriptorProto); } - } - }; From 8d03c234ea7a84e66e41ab439ab7244ca9c18f2c Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Fri, 8 Mar 2024 19:08:57 +0000 Subject: [PATCH 17/23] Needs .string() on Windows Signed-off-by: Michael Carroll --- core/src/DynamicFactory.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/DynamicFactory.cc b/core/src/DynamicFactory.cc index 8f93b2ad..aababaf8 100644 --- a/core/src/DynamicFactory.cc +++ b/core/src/DynamicFactory.cc @@ -140,7 +140,7 @@ void DynamicFactory::LoadDescriptors(const std::string &_paths) { for (auto const &dirIter : std::filesystem::directory_iterator{descDir}) { - loadDescFile(dirIter.path()); + loadDescFile(dirIter.path().string()); } } } From 4ed422645ea117992ca4d9ae9b68e1c547ac95dd Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Fri, 8 Mar 2024 19:39:26 +0000 Subject: [PATCH 18/23] add docs Signed-off-by: Michael Carroll --- tools/gz_msgs_generate.bzl | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/tools/gz_msgs_generate.bzl b/tools/gz_msgs_generate.bzl index f70c82f2..4f60f9ac 100644 --- a/tools/gz_msgs_generate.bzl +++ b/tools/gz_msgs_generate.bzl @@ -1,3 +1,5 @@ +"""Helper functions for generating gz-msgs compatible messages""" + load("@rules_proto//proto:defs.bzl", "ProtoInfo") load( "@gz//bazel/skylark:protobuf.bzl", @@ -7,8 +9,6 @@ load( "protos_from_context", ) -_VIRTUAL_IMPORTS = "/_virtual_imports/" - def _filter_files_impl(ctx): """Filter the files in DefaultInfo.""" return [DefaultInfo( @@ -34,6 +34,9 @@ filter_files = rule( ) def get_proto_headers(protos): + """ + Get headers for a set of proto files + """ out = [] for proto in protos: split = proto.split("/")[1:] @@ -42,6 +45,9 @@ def get_proto_headers(protos): return out def _gz_proto_factory_impl(ctx): + """ + Implementation of gz_proto_factory rule + """ protos = protos_from_context(ctx) out_dir = get_out_dir(protos, ctx) in_protos = [] @@ -102,12 +108,18 @@ _gz_proto_factory = rule( def gz_proto_factory( deps, **kwargs): + """ + gz_proto_factory rule implementation wrapper + """ _gz_proto_factory( deps = deps, **kwargs ) def _gz_proto_library_impl(ctx): + """ + Implementation of the gz_proto_library rule + """ protos = protos_from_context(ctx) out_dir = get_out_dir(protos, ctx) @@ -188,6 +200,9 @@ def gz_proto_library( name, proto_deps, **kwargs): + """ + gz_proto_library rule implementation wrapper + """ _gz_proto_library(name = name + "_pb", deps = proto_deps) filter_files(name = name + "_srcs", target = ":" + name + "_pb", extensions = ["cc"]) From e55e4e3b51f8fb57b33408d291dbb92bc0c129bc Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Fri, 8 Mar 2024 19:41:52 +0000 Subject: [PATCH 19/23] IWYU Signed-off-by: Michael Carroll --- core/src/DynamicFactory.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/DynamicFactory.cc b/core/src/DynamicFactory.cc index aababaf8..8dae855e 100644 --- a/core/src/DynamicFactory.cc +++ b/core/src/DynamicFactory.cc @@ -16,9 +16,12 @@ */ #include +#include #include #include #include +#include +#include #include #include "DynamicFactory.hh" From a6fab0ca345762cf55567d67fe75043353fc0026 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Fri, 8 Mar 2024 19:50:35 +0000 Subject: [PATCH 20/23] Move generated file location Signed-off-by: Michael Carroll --- BUILD.bazel | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index 003baccc..1fc77fae 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -37,12 +37,13 @@ exports_files(["LICENSE"]) gz_configure_header( name = "msgs_config_hh", src = "core/include/gz/msgs/config.hh.in", + out = "include/gz/msgs/config.hh", cmakelists = ["CMakeLists.txt"], package = "msgs", ) gz_export_header( - name = "core/include/gz/msgs/Export.hh", + name = "include/gz/msgs/Export.hh", export_base = "GZ_MSGS", lib_name = "gz-msgs", visibility = ["//visibility:private"], @@ -58,10 +59,10 @@ protos = glob(["proto/gz/msgs/*.proto"]) gz_include_header( name = "msgs_hh_genrule", - out = "core/include/gz/msgs.hh", + out = "include/gz/msgs.hh", hdrs = public_headers_no_gen + [ - "core/include/gz/msgs/config.hh", - "core/include/gz/msgs/Export.hh", + "include/gz/msgs/config.hh", + "include/gz/msgs/Export.hh", ], ) @@ -100,15 +101,15 @@ gz_proto_library( gz_proto_factory( name = "gzmsgs_proto_factory", cc_output = "core/src/RegisterMsgs.cc", - hh_output = "core/include/gz/msgs/MessageTypes.hh", + hh_output = "include/gz/msgs/MessageTypes.hh", deps = [":gzmsgs_proto"], ) public_headers = public_headers_no_gen + [ - "core/include/gz/msgs/config.hh", - "core/include/gz/msgs/Export.hh", - "core/include/gz/msgs.hh", - "core/include/gz/msgs/MessageTypes.hh", + "include/gz/msgs/config.hh", + "include/gz/msgs/Export.hh", + "include/gz/msgs.hh", + "include/gz/msgs/MessageTypes.hh", ] cc_library( @@ -125,6 +126,7 @@ cc_library( includes = [ "core/include", "core/src", + "include", ], deps = [ ":gzmsgs_cc_proto", @@ -228,9 +230,9 @@ cc_binary( name = "gz-msgs", srcs = ["core/src/gz.cc"], data = [ - ":gzmsgs_proto", "cmdmsgs.rb", "msgs.yaml", + ":gzmsgs_proto", ], linkshared = True, linkstatic = True, From dbb768896e64e66c21ff59b8b03f058b7da004b9 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Mon, 11 Mar 2024 18:23:50 +0000 Subject: [PATCH 21/23] Add descriptors test Signed-off-by: Michael Carroll --- BUILD.bazel | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/BUILD.bazel b/BUILD.bazel index 1fc77fae..99b487a7 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -205,6 +205,21 @@ cc_test( ], ) +cc_test( + name = "INTEGRATION_descriptors", + srcs = ["test/integration/descriptors.cc"], + data = ["test/desc"], + defines = [ + 'GZ_MSGS_TEST_PATH=\\"msgs/test\\"', + ], + deps = [ + ":msgs", + GZ_ROOT + "common/testing", + "@gtest", + "@gtest//:gtest_main", + ], +) + gz_configure_file( name = "msgs_yaml", src = "conf/msgs.yaml.in", From 317d704435dd0d8647977ac296dd13515f2c2395 Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Mon, 1 Apr 2024 22:55:57 +0000 Subject: [PATCH 22/23] Differentiate message names Signed-off-by: Michael Carroll --- test/desc/testing.proto | 2 +- test/desc/testing.proto.bin | 24 ++++++++++++------------ test/desc/testing/bytes.proto | 2 +- test/integration/descriptors.cc | 4 ++-- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test/desc/testing.proto b/test/desc/testing.proto index b2524164..d6927372 100644 --- a/test/desc/testing.proto +++ b/test/desc/testing.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package testing; -message Bytes +message BarBytes { bytes data = 1; } diff --git a/test/desc/testing.proto.bin b/test/desc/testing.proto.bin index ea7cbe8c..20422275 100644 --- a/test/desc/testing.proto.bin +++ b/test/desc/testing.proto.bin @@ -1,16 +1,16 @@ -C -testing/bytes.prototesting" -Bytes -data ( Rdatabproto3 -ˆ -testing/message.prototesting" +´ +testing/message.prototesting" -FooMessage -foo ( Rfoo" +FooMessage +data ( Rdata"3 -BarMessage -foo ( Rfoo" +BarMessage% +foo ( 2.testing.FooMessageRfoo"3 -BazMessage -foo ( Rfoobproto3 \ No newline at end of file +BazMessage% +bar ( 2.testing.BarMessageRbarbproto3 +F +testing/bytes.prototesting" +FooBytes +data ( Rdatabproto3 \ No newline at end of file diff --git a/test/desc/testing/bytes.proto b/test/desc/testing/bytes.proto index b2524164..83eb9da8 100644 --- a/test/desc/testing/bytes.proto +++ b/test/desc/testing/bytes.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package testing; -message Bytes +message FooBytes { bytes data = 1; } diff --git a/test/integration/descriptors.cc b/test/integration/descriptors.cc index 2d7ee0d5..4cc62291 100644 --- a/test/integration/descriptors.cc +++ b/test/integration/descriptors.cc @@ -62,7 +62,7 @@ TEST(FactoryTest, DynamicFactory) gz::msgs::Factory::LoadDescriptors(paths); } EXPECT_EQ(nullptr, gz::msgs::Factory::New("example.msgs.StringMsg")); - EXPECT_EQ(nullptr, gz::msgs::Factory::New("testing.Bytes")); + EXPECT_EQ(nullptr, gz::msgs::Factory::New("testing.BarBytes")); EXPECT_EQ(nullptr, gz::msgs::Factory::New("testing.FooMessage")); EXPECT_EQ(nullptr, gz::msgs::Factory::New("testing.BarMessage")); EXPECT_EQ(nullptr, gz::msgs::Factory::New("testing.BazMessage")); @@ -88,7 +88,7 @@ TEST(FactoryTest, DynamicFactory) } EXPECT_NE(nullptr, gz::msgs::Factory::New("example.msgs.StringMsg")); - EXPECT_NE(nullptr, gz::msgs::Factory::New("testing.Bytes")); + EXPECT_NE(nullptr, gz::msgs::Factory::New("testing.FooBytes")); EXPECT_NE(nullptr, gz::msgs::Factory::New("testing.FooMessage")); EXPECT_NE(nullptr, gz::msgs::Factory::New("testing.BarMessage")); EXPECT_NE(nullptr, gz::msgs::Factory::New("testing.BazMessage")); From 1c36fed06a92913b475c5f8afc2e6bb93474568d Mon Sep 17 00:00:00 2001 From: Michael Carroll Date: Wed, 3 Apr 2024 16:21:13 +0000 Subject: [PATCH 23/23] Address reviewer comments Signed-off-by: Michael Carroll --- BUILD.bazel | 4 ++++ core/generator_lite/Generator.hh | 3 +-- core/src/impl/InstallationDirectories.cc | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index 99b487a7..9d116bd9 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -122,6 +122,10 @@ cc_library( "core/src/RegisterMsgs.cc", "core/src/impl/InstallationDirectories.cc", ], + copts = [ + "-Wno-duplicate-decl-specifier", + "-fexceptions", + ], hdrs = public_headers, includes = [ "core/include", diff --git a/core/generator_lite/Generator.hh b/core/generator_lite/Generator.hh index 4630b20f..3e4cabbe 100644 --- a/core/generator_lite/Generator.hh +++ b/core/generator_lite/Generator.hh @@ -26,7 +26,7 @@ namespace protobuf { namespace compiler { namespace cpp { /// \cond -/// \brief Google protobuf message generator for igntion::msgs +/// \brief Google protobuf message generator for gz::msgs class Generator : public CodeGenerator { /// \brief Constructor @@ -47,7 +47,6 @@ class Generator : public CodeGenerator OutputDirectory *_generatorContext, std::string *_error) const; - // private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Generator); }; /// \endcond } diff --git a/core/src/impl/InstallationDirectories.cc b/core/src/impl/InstallationDirectories.cc index 7f25a895..e24cee12 100644 --- a/core/src/impl/InstallationDirectories.cc +++ b/core/src/impl/InstallationDirectories.cc @@ -23,5 +23,5 @@ namespace gz::msgs { inline namespace GZ_MSGS_VERSION_NAMESPACE { std::string getInstallPrefix() { return {};} -} // namespcae +} // namespace } // namespace gz::msgs