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)