本文主要是介绍CMake编译proto的方法(custom_target和custom_command),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近在项目中涉及到在QNX平台上编译CyberRT,其中CyberRT使用到了protobuf,因此,仓库内部有许多proto文件,需要先行将这些proto文件生成对应的.cc和.h文件才能被其他文件使用。
之前一直使用protobuf_generate_cpp来编译proto文件,但这个有一个弊端,就是无法控制生成的.cc和.h文件的路径,这个会影响到依赖改proto文件的其他源代码文件的编译,例如a.cpp依赖message.proto,其头文件包含是这样写的
#include "myapplication/proto/message.pb.h"
就是这种和原始proto文件同路径的包含方式,而protobuf_generate_cpp无法将proto生成到这么一个多级路径中。
因此,这次改用add_custom_command和add_custom_target来完成这个编译。
思路大致如下:
1. 通过add_custom_target设置一个虚拟的目标文件,其实不会编译处二进制目标文件
2. custome_target依赖custom_command中的输出
3.通过custom_command手动调用protoc来编译proto,通过--cpp_out, -I以及proto文件控制生成的.pb.h, .pb.cc文件的路径
CMake写法如下:
file(GLOB PROTO_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.proto)set(PROTO_DIR ${CMAKE_BINARY_DIR}/proto/message) # 生成文件的路径if(EXISTS ${PROTO_DIR} AND IS_DIRECTORY ${PROTO_DIR}) # 创建上面路径对应的目录message(info " ${PROTO_DIR} ALREADY EXISTS")
else()file(MAKE_DIRECTORY ${PROTO_DIR})
endif()foreach(proto ${PROTO_FILES} # 对每个proto文件执行protocget_filename_component(FILE_WE ${proto} NAME_WE)list(APPEND PROTO_SRCS ${PROTO_DIR}/${FILE_WE}.ph.cc) # 更新pb.cc文件列表list(APPEND PROTO_HDRS ${PROTO_DIR}/${FILE_WE}.ph.h) # 更新ph.h文件列表add_custom_command(OUTPUT "${PROTO_DIR}/${FILE_WE}.ph.cc""${PROTO_DIR}/${FILE_WE}.ph.h"COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}ARGS --cpp_out ${PROTO_DIR}-I ${CMAKE_BINARY_DIR}/proto/message${proto}DEPENDS ${proto}COMMENT "Running protoc on proto file ${proto}"VERBATIM
endforeach()add_custom_target(generate_proto_rule ALLDEPENDS ${PROTO_SRCS} ${PROTO_HDRS}COMMENT "build generate_proto_rule target"VERBATIM
)
其中,PROTOBUF_PROTOC_EXECUTABLE需要在cmake命令中通过-D手动指定protoc二进制的路径。
这篇关于CMake编译proto的方法(custom_target和custom_command)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!