【发布时间】:2020-11-10 22:26:39
【问题描述】:
为了让我的 proto 文件正确编译以便在我的 C++ 项目中使用,我付出了很多努力。从几个 stackoverflow 帖子中,我不得不尝试至少 8 种不同的方法,但都失败了。
目前,我收到一个错误:
‘PROTOBUF_INTERNAL_EXPORT_messages_2fbot_5farrived_2eproto’ does not name a type; did you mean ‘PROTOBUF_INTERNAL_EXPORT_bot_5farrived_2eproto’?
extern PROTOBUF_INTERNAL_EXPORT_messages_2fbot_5farrived_2eproto ::PROTOBUF_NAMESPACE_ID::internal::SCCInfo scc_info_BotArrived_messages_2fbot_5farrived_2eproto;
如果我从生成的 extern 中删除 messages_2f,它会起作用。为什么它没有正确地使用我从中导入的子目录生成内容?
我的 proto 文件已存储:
project
protos
message # This imports all the concrete types using import "messages/<concretetype>
messages
bot_arrived.proto
.... other concrete types
CmakeLists.txt
...
我当前的 Frakenstein-ed cmake 文件部分(生成文件的位置)如下所示:
# Generated Proto files
file(GLOB_RECURSE proto_files "${CMAKE_CURRENT_SOURCE_DIR}/*.proto")
# Create an include path for each file specified
if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
foreach(FIL ${proto_files})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
list(FIND protobuf_include_path ${ABS_PATH} contains_already)
if(${contains_already} EQUAL -1)
list(APPEND protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
else()
set(protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
endif()
message(STATUS "Proto Include Path: ${protobuf_include_path}")
set(proto_srcs)
set(proto_hdrs)
set(grpc_proto_srcs)
set(grpc_proto_hdrs)
set(grpc_generated_include_paths "${CMAKE_CURRENT_BINARY_DIR}" CACHE STRING "Will be needed in the include path of targets that consume this lib")
foreach(FIL ${proto_files})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)
get_filename_component(DIR ${FIL} DIRECTORY)
file(RELATIVE_PATH REL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/protos/" ${DIR})
if("${REL_DIR}" STREQUAL "")
set(proto_src "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
set(proto_hdr "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
set(grpc_proto_src "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.grpc.pb.cc")
set(grpc_proto_hdr "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.grpc.pb.h")
set(grpc_out_dir "${CMAKE_CURRENT_BINARY_DIR}")
else()
set(proto_src "${CMAKE_CURRENT_BINARY_DIR}/${REL_DIR}/${FIL_WE}.pb.cc")
set(proto_hdr "${CMAKE_CURRENT_BINARY_DIR}/${REL_DIR}/${FIL_WE}.pb.h")
set(grpc_proto_src "${CMAKE_CURRENT_BINARY_DIR}/${REL_DIR}/${FIL_WE}.grpc.pb.cc")
set(grpc_proto_hdr "${CMAKE_CURRENT_BINARY_DIR}/${REL_DIR}/${FIL_WE}.grpc.pb.h")
set(grpc_out_dir "${CMAKE_CURRENT_BINARY_DIR}/${REL_DIR}")
endif()
if( NOT EXISTS "${grpc_out_dir}" AND NOT IS_DIRECTORY "${grpc_out_dir}")
file(MAKE_DIRECTORY "${grpc_out_dir}")
endif()
list(FIND grpc_generated_include_paths ${grpc_out_dir} contains_already)
if(${contains_already} EQUAL -1)
list(APPEND grpc_generated_include_paths ${grpc_out_dir})
endif()
list(APPEND proto_srcs "${proto_src}")
list(APPEND proto_hdrs "${proto_hdr}")
list(APPEND grpc_proto_srcs "${grpc_proto_src}")
list(APPEND grpc_proto_hdrs "${grpc_proto_hdr}")
add_custom_command(
OUTPUT "${proto_src}" "${proto_hdr}" "${grpc_proto_src}" "${grpc_proto_hdr}"
COMMAND ${Protobuf_PROTOC_EXECUTABLE}
ARGS --grpc_out "${grpc_out_dir}"
--cpp_out "${grpc_out_dir}"
--plugin=protoc-gen-grpc=${GRPC_PLUGIN}
${protobuf_include_path} ${ABS_FIL}
DEPENDS ${ABS_FIL} ${Protobuf_PROTOC_EXECUTABLE}
COMMENT "Running gRPC C++ protocol buffer compiler on ${FIL}. Output going to ${grpc_out_dir}"
VERBATIM)
endforeach()
set_source_files_properties(${proto_srcs} ${proto_hdrs} PROPERTIES SKIP_AUTOMOC TRUE)
set_source_files_properties(${proto_srcs} ${proto_hdrs} PROPERTIES GENERATED TRUE)
message(STATUS "Proto generated sources: ${proto_srcs}")
message(STATUS "Proto generated headers: ${proto_hdrs}")
message(STATUS "gRPC generated sources: ${grpc_proto_srcs}")
message(STATUS "gRPC generated headers: ${grpc_proto_hdrs}")
message(STATUS "gRPC generated include paths ${grpc_generated_include_paths}")
【问题讨论】:
标签: cmake protocol-buffers grpc