ROS中通过CmakeLists.txt文件自动生成protobuf的源文件

1 目录结构

目录结构如下图所示,其中:
mocius是工作空间workspace名称;
proto是rospackage的名称;
pb是rospackage包中用于存放*.proto文件的文件夹,可以看到pb中包含两个文件夹commonsample,两个文件夹下面分别存放着*.proto文件.
ROS中通过CmakeLists.txt文件自动生成protobuf的源文件
三个*.proto文件的内容如下:

//header.proto

syntax = "proto3";
package mocius.common;
message Header {
   double timestamp_sec = 1;
   string module_name = 2;
   uint32 sequence_num = 3;
   uint64 lidar_timestamp = 4;
   uint64 camera_timestamp = 5;
   uint64 radar_timestamp = 6;
   uint32 version = 7;
   string frame_id = 8;
}

//sample_status.proto
syntax = "proto3";
package mocius.common;
enum SampleStatus {
   OK = 0;
   NOK = 1;
}
sample.proto
syntax = "proto3";

package mocius.common;
import "common/header.proto";
import "sample/sample_status.proto";

message Sample {
   mocius.common.Header header = 1;
   mocius.common.SampleStatus status = 2;
}

可以看到sample.proto中既有对本文件夹下sample_status.proto的引用,又有对common文件夹中header.proto的引用。

2 CmakeLists

cmake_minimum_required(VERSION 3.5.1)
project(proto)

find_package(catkin REQUIRED)


find_package(Protobuf REQUIRED)

include_directories(
   ./
   ${catkin_INCLUDE_DIRS}
)

catkin_package(
  INCLUDE_DIRS ../
)

find_program(PROTOC protoc) #寻找protoc
set(pb_file_root ${CMAKE_CURRENT_SOURCE_DIR}/pb)#设置pb文件的根目录

function(generate_cpp_pb_file pb_path)
    set(pb_file_path ${pb_file_root}/${pb_path})#设置pb file实际所在的目录
    file(GLOB proto_files ${pb_file_path}/*.proto)#找出所有的pb file
    set(pb_out_path ${CMAKE_CURRENT_SOURCE_DIR})#设置pb file生成文件的输出目录

    foreach(pb_file ${proto_files})
        get_filename_component(pb_file_name ${pb_file} NAME_WE)#获取pb file文件名
        set(cur_out_file # 设置输出文件名
            ${pb_out_path}/${pb_path}/${pb_file_name}.pb.h
            ${pb_out_path}/${pb_path}/${pb_file_name}.pb.cc
           )
        set(pb_out_files ${pb_out_files} ${cur_out_file})
        add_custom_command(
            OUTPUT ${cur_out_file}
            COMMAND ${PROTOC} ${pb_file} --cpp_out ${pb_out_path} -I${pb_file_root}
            DEPENDS ${PROTOC} ${pb_file}
            WORKING_DIRECTORY ../
            # ${CMAKE_CURRENT_SOURCE_DIR}
           )
    endforeach(pb_file ${proto_files})

    set_source_files_properties(${pb_out_files} PROPERTIES GENERATED TRUE)

    add_library(${pb_path}_pb
       ${pb_out_files}
    )
    target_link_libraries(${pb_path}_pb
       ${catkin_LIBRARIES}
       ${PROTOBUF_LIBRARIES}
    )
endfunction()

set(proto_dirs# 添加pbfile所在的相对路径,即pb文件夹下的各个文件夹
    common
    sample
    )
foreach(pb_dir ${proto_dirs})
    generate_cpp_pb_file(${pb_dir})
endforeach(pb_dir ${proto_dirs})

最终结果
ROS中通过CmakeLists.txt文件自动生成protobuf的源文件