Browse Source

Merge topic 'FindProtobuf-gen-desc'

1299f4cc FindProtobuf: add flag to allow descriptor files to be generated
4e91be95 FindProtobuf: Refactor custom command output listing

Acked-by: Kitware Robot <[email protected]>
Merge-request: !1301
Brad King 8 years ago
parent
commit
046625d26f

+ 5 - 0
Help/release/dev/protobuf-desc.rst

@@ -0,0 +1,5 @@
+protobuf-desc
+-------------
+
+* The :module:`FindProtobuf` module :command:`protobuf_generate_cpp` command
+  gained a ``DESCRIPTORS`` option to generate descriptor files.

+ 34 - 10
Modules/FindProtobuf.cmake

@@ -79,6 +79,7 @@
 #   include_directories(${CMAKE_CURRENT_BINARY_DIR})
 #   protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS foo.proto)
 #   protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS EXPORT_MACRO DLL_EXPORT foo.proto)
+#   protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS DESCRIPTORS PROTO_DESCS foo.proto)
 #   protobuf_generate_python(PROTO_PY foo.proto)
 #   add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
 #   target_link_libraries(bar ${Protobuf_LIBRARIES})
@@ -92,12 +93,15 @@
 #
 #   Add custom commands to process ``.proto`` files to C++::
 #
-#     protobuf_generate_cpp (<SRCS> <HDRS> [EXPORT_MACRO <MACRO>] [<ARGN>...])
+#     protobuf_generate_cpp (<SRCS> <HDRS>
+#         [DESCRIPTORS <DESC>] [EXPORT_MACRO <MACRO>] [<ARGN>...])
 #
 #   ``SRCS``
 #     Variable to define with autogenerated source files
 #   ``HDRS``
 #     Variable to define with autogenerated header files
+#   ``DESCRIPTORS``
+#     Variable to define with auotgenerated descriptor files, if requested.
 #   ``EXPORT_MACRO``
 #     is a macro which should expand to ``__declspec(dllexport)`` or
 #     ``__declspec(dllimport)`` depending on what is being compiled.
@@ -116,7 +120,7 @@
 #     ``.proto`` filess
 
 function(PROTOBUF_GENERATE_CPP SRCS HDRS)
-  cmake_parse_arguments(protobuf "" "EXPORT_MACRO" "" ${ARGN})
+  cmake_parse_arguments(protobuf "" "EXPORT_MACRO;DESCRIPTORS" "" ${ARGN})
 
   set(PROTO_FILES "${protobuf_UNPARSED_ARGUMENTS}")
   if(NOT PROTO_FILES)
@@ -158,6 +162,10 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS)
 
   set(${SRCS})
   set(${HDRS})
+  if (protobuf_DESCRIPTORS)
+    set(${protobuf_DESCRIPTORS})
+  endif()
+
   foreach(FIL ${PROTO_FILES})
     get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
     get_filename_component(FIL_WE ${FIL} NAME_WE)
@@ -168,22 +176,38 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS)
       endif()
     endif()
 
-    list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
-    list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
+    set(_protobuf_protoc_src "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
+    set(_protobuf_protoc_hdr "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
+    list(APPEND ${SRCS} "${_protobuf_protoc_src}")
+    list(APPEND ${HDRS} "${_protobuf_protoc_hdr}")
+
+    if(protobuf_DESCRIPTORS)
+      set(_protobuf_protoc_desc "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.desc")
+      set(_protobuf_protoc_flags "--descriptor_set_out=${_protobuf_protoc_desc}")
+      list(APPEND ${protobuf_DESCRIPTORS} "${_protobuf_protoc_desc}")
+    else()
+      set(_protobuf_protoc_desc "")
+      set(_protobuf_protoc_flags "")
+    endif()
 
     add_custom_command(
-      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
-             "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
+      OUTPUT "${_protobuf_protoc_src}"
+             "${_protobuf_protoc_hdr}"
+             ${_protobuf_protoc_desc}
       COMMAND  protobuf::protoc
-      ARGS "--cpp_out=${DLL_EXPORT_DECL}${CMAKE_CURRENT_BINARY_DIR}" ${_protobuf_include_path} ${ABS_FIL}
+               "--cpp_out=${DLL_EXPORT_DECL}${CMAKE_CURRENT_BINARY_DIR}"
+               ${_protobuf_protoc_flags}
+               ${_protobuf_include_path} ${ABS_FIL}
       DEPENDS ${ABS_FIL} protobuf::protoc
       COMMENT "Running C++ protocol buffer compiler on ${FIL}"
       VERBATIM )
   endforeach()
 
-  set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
-  set(${SRCS} ${${SRCS}} PARENT_SCOPE)
-  set(${HDRS} ${${HDRS}} PARENT_SCOPE)
+  set(${SRCS} "${${SRCS}}" PARENT_SCOPE)
+  set(${HDRS} "${${HDRS}}" PARENT_SCOPE)
+  if(protobuf_DESCRIPTORS)
+    set(${protobuf_DESCRIPTORS} "${${protobuf_DESCRIPTORS}}" PARENT_SCOPE)
+  endif()
 endfunction()
 
 function(PROTOBUF_GENERATE_PYTHON SRCS)

+ 17 - 1
Tests/FindProtobuf/Test/CMakeLists.txt

@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.4)
+cmake_minimum_required(VERSION 3.8)
 project(TestFindProtobuf CXX)
 include(CTest)
 
@@ -32,3 +32,19 @@ target_link_libraries(test_var_protoc PRIVATE ${Protobuf_PROTOC_LIBRARIES})
 add_test(NAME test_var_protoc COMMAND test_var_protoc)
 
 add_test(NAME test_tgt_protoc_version COMMAND protobuf::protoc --version)
+
+set(Protobuf_IMPORT_DIRS ${Protobuf_INCLUDE_DIRS})
+PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HEADER msgs/example.proto)
+PROTOBUF_GENERATE_CPP(DESC_PROTO_SRC DESC_PROTO_HEADER DESCRIPTORS DESC_PROTO_DESC msgs/example_desc.proto)
+add_library(msgs ${PROTO_SRC} ${PROTO_HEADER})
+
+add_executable(test_generate main-generate.cxx ${PROTO_SRC})
+target_include_directories(test_generate PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+target_link_libraries(test_generate msgs ${Protobuf_LIBRARIES})
+add_test(NAME test_generate COMMAND test_generate)
+
+add_executable(test_desc main-desc.cxx ${DESC_PROTO_SRC})
+target_compile_features(test_desc PRIVATE cxx_std_11)
+target_include_directories(test_desc PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+target_link_libraries(test_desc msgs ${Protobuf_LIBRARIES})
+add_test(NAME test_desc COMMAND test_desc ${DESC_PROTO_DESC})

+ 57 - 0
Tests/FindProtobuf/Test/main-desc.cxx

@@ -0,0 +1,57 @@
+#include <fstream>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/text_format.h>
+#include <iostream>
+#include <string>
+
+int main(int argc, char* argv[])
+{
+  std::ifstream fs;
+  fs.open(argv[1], std::ifstream::in);
+  google::protobuf::FileDescriptorSet file_descriptor_set;
+  file_descriptor_set.ParseFromIstream(&fs);
+
+  const google::protobuf::DescriptorPool* compiled_pool =
+    google::protobuf::DescriptorPool::generated_pool();
+
+  if (compiled_pool == NULL) {
+    std::cerr << "compiled pool is NULL." << std::endl;
+    return 1;
+  }
+
+  google::protobuf::DescriptorPool pool(compiled_pool);
+  google::protobuf::DynamicMessageFactory dynamic_message_factory(&pool);
+
+  for (const google::protobuf::FileDescriptorProto& file_descriptor_proto :
+       file_descriptor_set.file()) {
+    const google::protobuf::FileDescriptor* file_descriptor =
+      pool.BuildFile(file_descriptor_proto);
+    if (file_descriptor == NULL) {
+      continue;
+    }
+
+    const google::protobuf::Descriptor* descriptor =
+      pool.FindMessageTypeByName("example.msgs.ExampleDesc");
+
+    if (descriptor == NULL) {
+      continue;
+    }
+
+    google::protobuf::Message* msg =
+      dynamic_message_factory.GetPrototype(descriptor)->New();
+    std::string data = "data: 1";
+    bool success = google::protobuf::TextFormat::ParseFromString(data, msg);
+
+    if (success) {
+      return 0;
+    } else {
+      std::cerr << "Failed to parse message." << std::endl;
+      return 2;
+    }
+  }
+
+  std::cerr << "No matching message found." << std::endl;
+  return 3;
+}

+ 8 - 0
Tests/FindProtobuf/Test/main-generate.cxx

@@ -0,0 +1,8 @@
+#include <example.pb.h>
+
+int main()
+{
+  example::msgs::Example msg;
+
+  return 0;
+}

+ 6 - 0
Tests/FindProtobuf/Test/msgs/example.proto

@@ -0,0 +1,6 @@
+syntax = "proto2";
+package example.msgs;
+
+message Example {
+  required int32 data = 1;
+}

+ 10 - 0
Tests/FindProtobuf/Test/msgs/example_desc.proto

@@ -0,0 +1,10 @@
+syntax = "proto2";
+package example.msgs;
+
+import "google/protobuf/descriptor.proto";
+
+message ExampleDesc {
+  required int32 data = 1;
+
+  optional google.protobuf.FileDescriptorSet desc = 2;
+}