cmake - 生成的 PROTOBUF_INTERNAL_EXPORT 不包括导入的子目录
问题描述
我一直在努力让我的原型文件正确编译以用于我的 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<0> scc_info_BotArrived_messages_2fbot_5farrived_2eproto;
messages_2f
如果我从生成的 extern 中删除它,它就可以工作。为什么它没有正确地使用我从中导入的子目录生成东西?
我的原型文件存储:
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}")
解决方案
使用有什么用--proto_path=
?
参考:https ://github.com/google/or-tools/blob/stable/cmake/cpp.cmake#L267
推荐阅读
- javascript - 我们如何从服务器创建警告消息?
- c - TCP Socket - 如何连接到服务器套接字,然后关闭它并再次连接?
- r - 如何在删除行时不更改列名
- neo4j - 查询以写入跃点并从中间节点返回所有属性,还是更好的方法来完成并跳过跃点?
- oracle - 使用 SDO_CONTAINS 的 Oracle Spatial Query 结果不一致
- mysql - 代码:1064。您的 SQL 语法有误;'错误代码:158调用本机函数'concat'中的参数不正确'在第13行
- amazon-web-services - 在 AWS 负载均衡器上设置静态 IP
- javascript - 如何在 React 应用中处理多个环境
- python - 单元格中具有多个值的表的计数/枢轴跟进
- java - 处理程序调度失败;嵌套异常是 java.lang.NoSuchMethodError