proto_cmake_test

proto_cmake_test

Proto与CMAKE结合编译源代码

工程编译

cd build
cmake ..
make
ls message/*

在message目录下生成cc和h文件

三种CMakelists编写方式

  • 第一种

    cmake_minimum_required(VERSION 2.6)
     
    project(proto_cmake_test)
     
    add_definitions(-std=c++11)
     
    find_package(Protobuf REQUIRED)
    find_package(Threads)
    
    if(PROTOBUF_FOUND)
       message(STATUS "protobuf library found")
    else()
        message(FATAL_ERROR "protobuf library is needed but cant be found")
    endif()
    
    
    #endif()
    
     
    
    # 设置编译阶段头文件路径
    include_directories(    ${CMAKE_CURRENT_BINARY_DIR}
                            ${PROTOBUF_INCLUDE_DIRS}
                            "/usr/include/")
    # 设置链接截断库文件路径
    link_directories(   /usr/lib/x86_64-linux-gnu/ 
                        #${EIGEN3_LIBRARY_DIRS}
                        )
    
    # 找到所有需要编译的.proto文件
    file(GLOB PROTO_FILES ${PROJECT_SOURCE_DIR}/proto/*.proto)
    message(STATUS "1-- ${PROTO_FILES}")
    # 法一:要求protobuf_generate_cpp命令和生成add_executable() 或 add_library() 的命令必须在同一个CMakeList中.
    ## PROTO_SRC,PROTO_HARS变量分别指代生成的cpp和h文件并可用于连接到target和设置include
    set(PROTOBUF_GENERATE_CPP_APPEND_PATH ON) # required for tensorflow
    protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_FILES})
    ## 生成动态库
    add_library(proto_lib STATIC ${PROTO_SRCS} ${PROTO_HDRS})
    ## 与C++文件一起编译生成可执行文件
    #add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
    #target_link_libraries(bar ${Protobuf_LIBRARIES})
    
  • 第二种

    cmake_minimum_required(VERSION 2.6)
     
    project(proto_cmake_test)
     
    add_definitions(-std=c++11)
     
    find_package(Protobuf REQUIRED)
    find_package(Threads)
    
    if(PROTOBUF_FOUND)
       message(STATUS "protobuf library found")
    else()
        message(FATAL_ERROR "protobuf library is needed but cant be found")
    endif()
    
    
    #endif()
    
     
    
    # 设置编译阶段头文件路径
    include_directories(    ${CMAKE_CURRENT_BINARY_DIR}
                            ${PROTOBUF_INCLUDE_DIRS}
                            "/usr/include/")
    # 设置链接截断库文件路径
    link_directories(   /usr/lib/x86_64-linux-gnu/ 
                        #${EIGEN3_LIBRARY_DIRS}
                        )
    
    
    # 法二:这种方法仍然存在缺点:每次执行cmake后,都会重新生成proto源码,导致make时会因为源码变动(内容未变,只是重新生成)而重新编译程序
    #设置输出路径
    SET(MESSAGE_DIR ${CMAKE_BINARY_DIR}/message)
    if(EXISTS "${CMAKE_BINARY_DIR}/message" AND IS_DIRECTORY "${CMAKE_BINARY_DIR}/message")
        SET(DST_DIR ${MESSAGE_DIR})
    else()
        file(MAKE_DIRECTORY ${MESSAGE_DIR})
        SET(DST_DIR ${MESSAGE_DIR})
    endif()
    
    #设置protoc的搜索路径:在其中搜索导入(import)的目录。可指定多次
    LIST(APPEND PROTO_FLAGS -I${CMAKE_SOURCE_DIR}/proto)
    
    #获取需要编译的proto文件
    file(GLOB_RECURSE MSG_PROTOS ${CMAKE_SOURCE_DIR}/proto/*.proto)
    
    set(PROTO_SRCS "")
    set(PROTO_HDRS "")
    foreach(msg ${MSG_PROTOS})
        get_filename_component(FIL_WE ${msg} NAME_WE)
        # 获取源码头文件和cpp文件路径
        list(APPEND PROTO_SRCS "${DST_DIR}/${FIL_WE}.pb.cc")
        list(APPEND PROTO_HDRS "${DST_DIR}/${FIL_WE}.pb.h")
        # 生成源码:protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
        execute_process(COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} ${PROTO_FLAGS} --cpp_out=${DST_DIR} ${msg})
    endforeach()
    # 设置生成的源码文件属性GENERATED为TRUE,否则cmake时会因找不到源码而报错
    set_source_files_properties(${PROTO_SRCS} ${PROTO_HDRS} PROPERTIES GENERATED TRUE)
    ## 与C++文件一起编译生成可执行文件
    #add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
    #target_link_libraries(bar ${Protobuf_LIBRARIES})
    
  • 第三种

cmake_minimum_required(VERSION 2.6)
 
project(proto_cmake_test)
 
add_definitions(-std=c++11)
 
find_package(Protobuf REQUIRED)
find_package(Threads)

if(PROTOBUF_FOUND)
   message(STATUS "protobuf library found")
else()
    message(FATAL_ERROR "protobuf library is needed but cant be found")
endif()


#endif()

 

# 设置编译阶段头文件路径
include_directories(    ${CMAKE_CURRENT_BINARY_DIR}
                        ${PROTOBUF_INCLUDE_DIRS}
                        "/usr/include/")
# 设置链接截断库文件路径
link_directories(   /usr/lib/x86_64-linux-gnu/ 
                    #${EIGEN3_LIBRARY_DIRS}
                    )
# 法三:使用add_custom_target与add_custom_command生成源码
#设置输出路径
SET(MESSAGE_DIR ${CMAKE_BINARY_DIR}/message)
if(EXISTS "${CMAKE_BINARY_DIR}/message" AND IS_DIRECTORY "${CMAKE_BINARY_DIR}/message")
    SET(DST_DIR ${MESSAGE_DIR})
else()
    file(MAKE_DIRECTORY ${MESSAGE_DIR})
    SET(DST_DIR ${MESSAGE_DIR})
endif()
#设置protoc的搜索路径:在其中搜索导入(import)的目录。可指定多次
LIST(APPEND PROTO_FLAGS -I${CMAKE_SOURCE_DIR}/proto)
#获取需要编译的proto文件
file(GLOB_RECURSE MSG_PROTOS ${CMAKE_SOURCE_DIR}/proto/*.proto)
set(PROTO_SRCS "")
set(PROTO_HDRS "")
foreach(msg ${MSG_PROTOS})
    get_filename_component(FIL_WE ${msg} NAME_WE)
    # 获取源码头文件和cpp文件路径
    list(APPEND PROTO_SRCS "${PROJECT_BINARY_DIR}/message/${FIL_WE}.pb.cc")
    list(APPEND PROTO_HDRS "${PROJECT_BINARY_DIR}/message/${FIL_WE}.pb.h")
    # 使用自定义命令
    add_custom_command(
          OUTPUT "${DST_DIR}/${FIL_WE}.pb.cc"
                 "${DST_DIR}/${FIL_WE}.pb.h"
          COMMAND  ${PROTOBUF_PROTOC_EXECUTABLE}
          ARGS --cpp_out  ${DST_DIR}
            ${PROTO_FLAGS}
            ${msg}
          DEPENDS ${msg}
          COMMENT "Running C++ protocol buffer compiler on ${msg}"
          VERBATIM
        )
endforeach()

# 设置文件属性为 GENERATED:设置生成的源码文件属性GENERATED为TRUE,否则cmake时会因找不到源码而报错
set_source_files_properties(${PROTO_SRCS} ${PROTO_HDRS} PROPERTIES GENERATED TRUE)
# 添加自定义target:使用add_custom_target添加目标时要设置ALL关键字,否则target将不在默认编译列表中
add_custom_target(generate_message ALL
    DEPENDS ${PROTO_SRCS} ${PROTO_HDRS}
    COMMENT "generate message target"
    VERBATIM)
## 与C++文件一起编译生成可执行文件
#add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
#target_link_libraries(bar ${Protobuf_LIBRARIES})
  • 第四种
cmake_minimum_required(VERSION 2.6)

project(Radar)

add_definitions(-std=c++11)


#find_package(Eigen3 REQUIRED)
find_package(OpenCV REQUIRED )
find_package(yaml-cpp REQUIRED)
find_package(Protobuf REQUIRED)
find_package(Threads)
find_package(PCL REQUIRED)

if(PROTOBUF_FOUND)
  message(STATUS "protobuf library found")
else()
   message(FATAL_ERROR "protobuf library is needed but cant be found")
endif()

#if(Eigen3)
#   message(STATUS "Eigen3 library found")
#   message(STATUS "Find Eigen3 include at ${EIGEN3_INCLUDE_DIR}")
#else()
#    message(FATAL_ERROR "Eigen3 library is needed but cant be found")
#endif()

#if(OpenCV)
#   message(STATUS "OpenCV library found")
#else()
#    message(FATAL_ERROR "OpenCV library is needed but cant be found")
#    message(STATUS "Find OpenCV include at ${OpenCV_INCLUDE_DIRS}")
#endif()



# 设置编译阶段头文件路径
include_directories(    ${CMAKE_CURRENT_BINARY_DIR}
                       #${EIGEN3_INCLUDE_DIR} 
                       ${YAML_CPP_INCLUDE_DIR} 
                       ${OpenCV_INCLUDE_DIRS}
                       ${PROTOBUF_INCLUDE_DIRS}
                       ${PCL_INCLUDE_DIRS}
                       ${CMAKE_CURRENT_BINARY_DIR}
                       ${CMAKE_BINARY_DIR}
                       ${CMAKE_BINARY_DIR}/message
                       "/usr/include/eigen3"
                       "/home/hegaozhi/ly/apollo/modules/perception/onboard"
                       "/home/hegaozhi/ly/apollo/modules/perception/"
                       "${CMAKE_SOURCE_DIR}/radar/modest"
                       "/usr/include/")
# 设置链接截断库文件路径
link_directories(   /usr/lib/x86_64-linux-gnu/ 
                   #${EIGEN3_LIBRARY_DIRS} 
                   ${OpenCV_LIBRARY_DIRS}
                   ${PROTOBUF_LIBRARY_DIRS}
                   ${PCL_LIBRARY_DIRS}
                   )




# PROTO_META_BASE_DIR为编译之后生成文件的目录。
#SET(PROTO_META_BASE_DIR ${CMAKE_CURRENT_BINARY_DIR})
# PROTO_FLAGS很重要,指定编译.proto文件时的总的寻找路径,.proto中的import命令根据根据这个地址去连接其他的.proto文件
#LIST(APPEND PROTO_FLAGS -I${CMAKE_CURRENT_SOURCE_DIR})   




#[[ 
# 找到所有需要编译的.proto文件
file(GLOB PROTO_FILES ${PROJECT_SOURCE_DIR}/proto/*.proto)
message(STATUS "1-- ${PROTO_FILES}")
# 法一:要求protobuf_generate_cpp命令和生成add_executable() 或 add_library() 的命令必须在同一个CMakeList中.
## PROTO_SRC,PROTO_HARS变量分别指代生成的cpp和h文件并可用于连接到target和设置include
set(PROTOBUF_GENERATE_CPP_APPEND_PATH ON) # required for tensorflow
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_FILES})
## 生成动态库
add_library(proto_lib STATIC ${PROTO_SRCS} ${PROTO_HDRS})
## 与C++文件一起编译生成可执行文件
#add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
#target_link_libraries(bar ${Protobuf_LIBRARIES})
]]

#[[ 
# 法二:这种方法仍然存在缺点:每次执行cmake后,都会重新生成proto源码,导致make时会因为源码变动(内容未变,只是重新生成)而重新编译程序
#设置输出路径
SET(MESSAGE_DIR ${CMAKE_BINARY_DIR}/message)
if(EXISTS "${CMAKE_BINARY_DIR}/message" AND IS_DIRECTORY "${CMAKE_BINARY_DIR}/message")
   SET(DST_DIR ${MESSAGE_DIR})
else()
   file(MAKE_DIRECTORY ${MESSAGE_DIR})
   SET(DST_DIR ${MESSAGE_DIR})
endif()

#设置protoc的搜索路径:在其中搜索导入(import)的目录。可指定多次
LIST(APPEND PROTO_FLAGS -I${CMAKE_SOURCE_DIR}/proto)

#获取需要编译的proto文件
file(GLOB_RECURSE MSG_PROTOS ${CMAKE_SOURCE_DIR}/proto/*.proto)

set(PROTO_SRCS "")
set(PROTO_HDRS "")
foreach(msg ${MSG_PROTOS})
   get_filename_component(FIL_WE ${msg} NAME_WE)
   # 获取源码头文件和cpp文件路径
   list(APPEND PROTO_SRCS "${DST_DIR}/${FIL_WE}.pb.cc")
   list(APPEND PROTO_HDRS "${DST_DIR}/${FIL_WE}.pb.h")
   # 生成源码:protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/addressbook.proto
   execute_process(COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} ${PROTO_FLAGS} --cpp_out=${DST_DIR} ${msg})
endforeach()
# 设置生成的源码文件属性GENERATED为TRUE,否则cmake时会因找不到源码而报错
set_source_files_properties(${PROTO_SRCS} ${PROTO_HDRS} PROPERTIES GENERATED TRUE)
## 与C++文件一起编译生成可执行文件
#add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
#target_link_libraries(bar ${Protobuf_LIBRARIES})
]]



# 法三:使用add_custom_target与add_custom_command生成源码
#设置输出路径
SET(MESSAGE_DIR ${CMAKE_BINARY_DIR}/message)
if(EXISTS "${CMAKE_BINARY_DIR}/message" AND IS_DIRECTORY "${CMAKE_BINARY_DIR}/message")
  SET(DST_DIR ${MESSAGE_DIR})
else()
  file(MAKE_DIRECTORY ${MESSAGE_DIR})
  SET(DST_DIR ${MESSAGE_DIR})
endif()


#设置protoc的搜索路径:在其中搜索导入(import)的目录。可指定多次
LIST(APPEND PROTO_FLAGS -I${CMAKE_SOURCE_DIR}/proto)
#获取需要编译的proto文件
file(GLOB_RECURSE MSG_PROTOS proto/common/*.proto )
set(PROTO_SRCS "")
set(PROTO_HDRS "")
foreach(msg ${MSG_PROTOS})

  # 获取'文件名'的'特定'部分
  get_filename_component(FIL_WE ${msg} NAME_WE)
  # 获取路径
  get_filename_component(PATH_WE ${msg} DIRECTORY)
  # 设置编译proto生成文件所在路径
  string(REPLACE "/" ";" protoName ${PATH_WE})
  string(REPLACE "/" ";" projectName ${PROJECT_SOURCE_DIR})
  foreach(tmp ${projectName})
      list(REMOVE_AT protoName 1 )      
  endforeach()
  SET(PROTO_PATH "${PROJECT_BINARY_DIR}/message")
  foreach(tmp ${protoName})    
       SET(PROTO_PATH "${PROTO_PATH}/${tmp}")
  endforeach()
  SET(PROTO_SRCS_PATH "${PROTO_PATH}/${FIL_WE}.pb.cc")
  SET(PROTO_HDRS_PATH "${PROTO_PATH}/${FIL_WE}.pb.h")
  # 获取源码头文件和cpp文件路径
  list(APPEND PROTO_SRCS ${PROTO_SRCS_PATH})
  list(APPEND PROTO_HDRS ${PROTO_HDRS_PATH})
  # 使用自定义命令
  add_custom_command(
        OUTPUT ${PROTO_SRCS_PATH}
               ${PROTO_HDRS_PATH}
        COMMAND  ${PROTOBUF_PROTOC_EXECUTABLE}
        ARGS --cpp_out  ${DST_DIR}
          ${PROTO_FLAGS}
          ${msg}
        DEPENDS ${msg}
        COMMENT "Running C++ protocol buffer compiler on ${msg}"
        VERBATIM
      )
endforeach()

# 设置文件属性为 GENERATED:设置生成的源码文件属性GENERATED为TRUE,否则cmake时会因找不到源码而报错
set_source_files_properties(${PROTO_SRCS} ${PROTO_HDRS} PROPERTIES GENERATED TRUE)
# 添加自定义target:使用add_custom_target添加目标时要设置ALL关键字,否则target将不在默认编译列表中
add_custom_target(generate_message ALL
  DEPENDS ${PROTO_SRCS} ${PROTO_HDRS}
  COMMENT "generate message target"
  VERBATIM)
   

测试例子

源码下载

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听雨听风眠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值