mirror of
https://github.com/reactos/CMake.git
synced 2025-01-07 11:40:23 +00:00
FindProtobuf: add flag to allow descriptor files to be generated
- The .desc files will be in the same folder as the generated .cc and .h files. - Paths to generate .desc files are stored in a variable passed in - This is only implemented for C++ - Remove legacy ARGS - Add test that generates and uses C++ protobuf message - Add test that checks that the generated .desc file can be instantiated with DynamicMessageFactory - Add Help rst for new feature
This commit is contained in:
parent
4e91be9532
commit
1299f4cc5e
5
Help/release/dev/protobuf-desc.rst
Normal file
5
Help/release/dev/protobuf-desc.rst
Normal file
@ -0,0 +1,5 @@
|
||||
protobuf-desc
|
||||
-------------
|
||||
|
||||
* The :module:`FindProtobuf` module :command:`protobuf_generate_cpp` command
|
||||
gained a ``DESCRIPTORS`` option to generate descriptor files.
|
@ -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)
|
||||
@ -173,11 +181,23 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS)
|
||||
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 "${_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 )
|
||||
@ -185,6 +205,9 @@ function(PROTOBUF_GENERATE_CPP SRCS HDRS)
|
||||
|
||||
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)
|
||||
|
@ -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
Tests/FindProtobuf/Test/main-desc.cxx
Normal file
57
Tests/FindProtobuf/Test/main-desc.cxx
Normal file
@ -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
Tests/FindProtobuf/Test/main-generate.cxx
Normal file
8
Tests/FindProtobuf/Test/main-generate.cxx
Normal file
@ -0,0 +1,8 @@
|
||||
#include <example.pb.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
example::msgs::Example msg;
|
||||
|
||||
return 0;
|
||||
}
|
6
Tests/FindProtobuf/Test/msgs/example.proto
Normal file
6
Tests/FindProtobuf/Test/msgs/example.proto
Normal file
@ -0,0 +1,6 @@
|
||||
syntax = "proto2";
|
||||
package example.msgs;
|
||||
|
||||
message Example {
|
||||
required int32 data = 1;
|
||||
}
|
10
Tests/FindProtobuf/Test/msgs/example_desc.proto
Normal file
10
Tests/FindProtobuf/Test/msgs/example_desc.proto
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user