我想用一些protobuf
定义构建一个 c++ 静态库 cmake/make
.
我做了一个自定义COMMAND
来编译protobuf
c++
,并将其设置为静态库的PRE_BUILD
依赖项。
project(mylib)
set(PROTO_PATH "${CMAKE_CURRENT_SOURCE_DIR}/proto_definitions")
file(GLOB PROTO_FILES "${PROTO_PATH}/*.proto")
foreach(PROTO_FILE in ${PROTO_FILES})
string(REGEX REPLACE "[.]proto$" ".pb.cc" OUTPUT_SOURCE ${PROTO_FILE})
list(APPEND OUTPUT_SOURCES ${OUTPUT_SOURCE})
endforeach()
add_custom_command(TARGET ${PROJECT_NAME}
PRE_BUILD
COMMAND protoc --cpp_out=${CMAKE_CURRENT_SOURCE_DIR}/compiled_proto ${PROTO_FILES}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "some comment")
add_library(${PROJECT_NAME} STATIC ${OUTPUT_SOURCES})
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
运行cmake时出现以下错误:
CMake 错误:无法确定目标"mylib"的链接语言
不管这个错误如何,都会生成生成文件,但是当我制作mylib时,它不会触发任何原型编译
CMake 更原生的方法是添加具有OUTPUT
签名的自定义命令以生成.cc
文件,然后通常将它们用作库的源。这样,他们就会知道它们是什么以及如何生产它们:
project(mylib)
set(PROTO_PATH "${CMAKE_CURRENT_SOURCE_DIR}/proto_definitions")
file(GLOB PROTO_FILES "${PROTO_PATH}/*.proto")
foreach(PROTO_FILE in ${PROTO_FILES})
string(REGEX REPLACE "[.]proto$" ".pb.cc" OUTPUT_SOURCE ${PROTO_FILE})
list(APPEND OUTPUT_SOURCES ${OUTPUT_SOURCE})
endforeach()
add_custom_command(OUTPUT ${OUTPUT_SOURCES}
COMMAND protoc --cpp_out=${CMAKE_CURRENT_SOURCE_DIR}/compiled_proto ${PROTO_FILES}
DEPENDS ${PROTO_FILES}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "some comment")
add_library(${PROJECT_NAME} STATIC ${OUTPUT_SOURCES})
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
这样,将有一个命令读取所有.proto
文件并生成所有.cc
文件 - 这意味着如果任何.proto
文件发生更改,将重新生成所有.cc
文件。我不熟悉原始缓冲器,所以我不知道这是否理智。如果它们是独立的,则最好为每个输出文件引入一个add_custom_command
。
此外,给定要传递给 protocc
的参数,您可能必须修改 OUTPUT_SOURCES
中的路径以正确指向生成的文件。
另请注意,CMake 附带了一个 FindProtobuf 模块,该模块定义了protobuf_generate_cpp()
命令,因此您可能希望使用它而不是手动编码 Protobuf 支持。
对上述答案的评论:cmake foreach中没有in
,这花了我一些时间来解决这个问题。
在研究了他的回答(非常感谢!(之后,我总结了一个适合我的方法,它具有以下特点:
- 原型目录和输出目录可以不同
- 生成grpc_output
- 为每个原型创建一个custom_command
我的项目目标是:
- HWPB/(超级项目的库(
- .cpp/
- hwpb/(store *.pb.cc, *.pb.h(
- CMakeList.txt
原型 - /(存储原型(
- go/(和其他语言,这里未提及(
- .cpp/
这是我的CMakeListx.txt:
set(PROTO_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../proto")
set(OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/hwpb")
file(GLOB PROTO_FILES "${PROTO_DIR}/*.proto")
foreach(PROTO_FILE ${PROTO_FILES})
get_filename_component (FILENAME ${PROTO_FILE} NAME_WLE)
set(PROTO_SRC "${OUTPUT_DIR}/${FILENAME}.pb.cc")
set(PROTO_HDR "${OUTPUT_DIR}/${FILENAME}.pb.h")
set(GRPC_SRC "${OUTPUT_DIR}/${FILENAME}.grpc.pb.cc")
set(GRPC_HDR "${OUTPUT_DIR}/${FILENAME}.grpc.pb.h")
add_custom_command(
OUTPUT "${PROTO_SRC}" "${PROTO_HDR}" "${GRPC_SRC}" "${GRPC_HDR}"
COMMAND ${_PROTOBUF_PROTOC}
ARGS --plugin=protoc-gen-grpc=${_GRPC_CPP_PLUGIN_EXECUTABLE}
--cpp_out="${OUTPUT_DIR}" --grpc_out="${OUTPUT_DIR}"
-I"${PROTO_DIR}" "${PROTO_FILE}"
DEPENDS ${PROTO_FILE}
)
list(APPEND OUTPUT_SOURCES ${PROTO_SRC} ${GRPC_HDR})
endforeach()
add_library(hwpb ${OUTPUT_SOURCES})
target_link_libraries(hwpb ${_GRPC_GRPCPP_UNSECURE} ${_PROTOBUF_LIBPROTOBUF})
target_include_directories(hwpb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})