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文件执行protoc
    get_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 ALL
        DEPENDS ${PROTO_SRCS} ${PROTO_HDRS}
        COMMENT "build generate_proto_rule target"
        VERBATIM
)




        其中,PROTOBUF_PROTOC_EXECUTABLE需要在cmake命令中通过-D手动指定protoc二进制的路径。

参考链接:CMake使用protobuf生成c++代码_cmake protobuf-CSDN博客

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A:在CMake中,add_custom_command函数用于添加自定义命令。该函数的语法如下: ``` add_custom_command(TARGET target POST_BUILD COMMAND command1 [args1...] [COMMAND command2 [args2...]...] [WORKING_DIRECTORY dir] [COMMENT comment] [VERBATIM] [USES_TERMINAL] [OUTPUT output] [DEPENDS dep1 [dep2] ... ] [BYPRODUCTS files... ] [IMPLICIT_DEPENDS <lang1> <lang2> ... ] [COMMAND_EXPAND_LISTS] [SOURCES src1 ...] [MAIN_DEPENDENCY depfile]) ``` 其中,TARGET参数表示该自定义命令的目标,可以是一个已经存在的目标,也可以是自定义的名称。POST_BUILD参数表示该命令将在构建目标之后执行。COMMAND参数表示实际要执行的命令及其参数,可以有多个。WORKING_DIRECTORY参数表示要在哪个目录执行该命令。COMMENT参数表示该命令的注释信息。VERBATIM参数表示是否以字面量方式处理命令参数。USES_TERMINAL参数表示是否在终端(terminal)中执行该命令。OUTPUT参数表示该命令创建的输出文件。DEPENDS参数表示该命令依赖的其他文件。BYPRODUCTS参数表示该命令生成的副产品文件。IMPLICIT_DEPENDS参数表示该命令的隐式依赖文件。COMMAND_EXPAND_LISTS参数表示是否要展开命令中的变量或列表。SOURCES参数表示该命令源文件列表。MAIN_DEPENDENCY参数表示该命令主要依赖文件。 通过add_custom_command函数,可以实现各种自定义命令,例如生成代码、打包文件、运行脚本等等。在CMake中,add_custom_command函数对于构建复杂项目非常有用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值