文章目录
bazel迁移cmake要点及具体迁移工程示例
迁移要点指南
迁移主要的内容包括以下部分,
依赖库管理
apollo存在的三方依赖,一部分包括网络导入(例gtest、absl等),一部分使用本地环境导入(例boost等)
bazel的依赖管理通过**@repo//:target**
cmake依赖管理则通过fetchcontent/find_package/connan导入。
//bazel
apollo_component(
name = "libcomponent.so",
srcs = ["component.cc"],
hdrs = ["component.h"],
deps = [
"@com_google_absl//:absl",
"@eigen",
"@osqp",
],
)
//cmake
include(FetchContent)
FetchContent_Declare(
absl
GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)
FetchContent_Declare(
osqp
GIT_REPOSITORY https://github.com/osqp/osqp.git
GIT_TAG v0.5.0
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)
FetchContent_MakeAvailable(absl osqp)
target_link_libraries(
example
PRIVATE osqp
absl::base
absl::synchronization
PUBLIC $<BUILD_INTERFACE:absl::strings>)
proto编译
在bazel中,每一个proto都需要对应一个proto_library,较为繁琐
cmake中3.13版本后提供了proto编译的高层接口。
find_package(Protobuf 3.14.0 REQUIRED)
file(GLOB_RECURSE src "*.cc" "*.proto")
add_library(AAA SHARED ${src})
protobuf_generate(
TARGET AAA
)
target_link_libraries(AAA PRIVATE protobuf::libprotobuf)
target_include_directories(AAA PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
根据以上语法,PROTO生成的cc文件会自动纳入AAA的待编译文件进行编译,但是默认未将头文件include,因此需要另外target_include_directories(AAA PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
目标库及二进制文件生成
bazel原生有cc_library(库),cc_binary(二进制执行文件),cc_test(测试)
分别对应cmake add_library,add_executable,gtest_discover_tests。
apollo 对原生的cc_library等进行了进一步封装apollo_cc_library,apollo_cc_binary,apollo_componet。
实际使用中,指定编译源码文件,编译选项、依赖库指定等,cmake基本都存在对应可替代命令。
apollo_component(
name = "libconti_radar.so",
srcs = ["conti_radar_canbus_component.cc"],
hdrs = ["conti_radar_canbus_component.h"],
copts = ['-DMODULE_NAME=\\"conti_radar\\"'],
deps = [
":conti_radar_message_manager",
"//cyber",
"//modules/common/adapters:adapter_gflags",
"//modules/common/monitor_log",
"//modules/drivers/canbus:apollo_drivers_canbus",
"//modules/drivers/canbus/proto:sensor_canbus_conf_cc_proto",
"//modules/drivers/radar/conti_radar/protocol:drivers_conti_radar_protocol",
"//modules/common_msgs/localization_msgs:localization_cc_proto",
"//modules/common_msgs/localization_msgs:pose_cc_proto",
"@eigen",
],
)
file(GLOB_RECURSE SRCS "*.cc")
add_library(conti_radar SHARED ${SRCS})
target_link_libraries(conti_radar PRIVATE protobuf::libprotobuf cyber common
canbus Eigen3::Eigen)
target_include_directories(
conti_radar PRIVATE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR})
target_compile_definitions(conti_radar PRIVATE MODULE_NAME="conti_radar")
项目导出
部分库需要导出供他人使用的库,需要使用cmake导出cmake包,供使用者调用
生成xxxConfig.cmake供调用者find_package,以及配套的版本控制、依赖、头文件管理。
include(CMakePackageConfigHelpers)
configure_package_config_file(
${CMAKE_SOURCE_DIR}/cmake/common-config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/common-TargetsConfig.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/common")
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/common-TargetConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion)
install(FILES
"${PROJECT_BINARY_DIR}/cmake/${TARGET_NAME}-config.cmake"
"${PROJECT_BINARY_DIR}/cmake/${TARGET_NAME}-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${TARGET_NAME}"
)
install(TARGETS ${TARGET_NAME}
EXPORT ${TARGET_NAME}-targets
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
)
install(EXPORT ${TARGET_NAME}-targets
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/${TARGET_NAME}"
)
runtime_data
主要之一些配置/参数/资源等文档的打包。
bazel不支持相关文件install等操作,apollo另外封装自实现了模块资源的安装。
// apollo
filegroup(
name = "runtime_data",
srcs = glob([
"conf/*.txt",
"conf/*.conf",
"dag/*.dag",
"launch/*.launch",
]),
)
//cmake
install(
DIRECTORY .
DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}
FILES_MATCHING
PATTERN "conf/*.txt"
PATTERN "conf/*.conf"
PATTERN "dag/*.dag"
PATTERN "launch/*.launch")
软件打包
cpack或者直接ci/cd做
include(InstallRequiredSystemLibraries)
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY FALSE)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
set(CPACK_GENERATOR ZIP)
include(CPack)
cpack是集成在cmake中内建工具,可以获取cmake编译系统中的信息,可以方便的在包名输出平台、版本号、编译时间等等编译时信息
conti_rardar完整迁移过程
目录位于modules/drivers/radar/conti_radar。
根据目录内的BUILD文件
apollo_cc_library(
name = "conti_radar_message_manager",
srcs = ["conti_radar_message_manager.cc"],
hdrs = ["conti_radar_message_manager.h"],
deps = [
"//modules/common/util:util_tool",
"//modules/drivers/canbus:apollo_drivers_canbus",
"//modules/drivers/radar/conti_radar/protocol:drivers_conti_radar_protocol",
],
)
apollo_component(
name = "libconti_radar.so",
srcs = ["conti_radar_canbus_component.cc"],
hdrs = ["conti_radar_canbus_component.h"],
copts = ['-DMODULE_NAME=\\"conti_radar\\"'],
deps = [
":conti_radar_message_manager",
"//cyber",
"//modules/common/adapters:adapter_gflags",
"//modules/common/monitor_log",
"//modules/drivers/canbus:apollo_drivers_canbus",
"//modules/drivers/canbus/proto:sensor_canbus_conf_cc_proto",
"//modules/drivers/radar/conti_radar/protocol:drivers_conti_radar_protocol",
"//modules/common_msgs/localization_msgs:localization_cc_proto",
"//modules/common_msgs/localization_msgs:pose_cc_proto",
"@eigen",
],
)
除了CYBER,另外依赖的canbus、common_msg、common子模块,以及eigen等三方库。
conti_radar_message_manager只对内暴露,不需要定义为一个库。
common_msg
目录:modules/common_msgs
里面存放的都是proto文件,查看网络上的cmake版本cyberrt,将这些proto生成的cc文件编译进libcyber了。
不需要另外编译,不过cmake版本cyberrt编译未导出这些proto文件以及头文件,cyberrt cmake脚本需要做一些调整。
我这里简单处理,直接将modules/common_msgs直接复制进自己的工程内;
common
目录:modules/commom
代码主要是一些工具类模块。每个子目录都对应了一个编译对象。
- adapters
- configs/data
- filters
- kv_db
- latency_recorder
- math
- monitor_log
- proto
- status
- util
- vehicle_state
迁移至cmake将以上所有编译对象统一成单一库,并且对外输出头文件、ptoto等。
common目录下的cmakelist如下:
FetchContent_Declare(
absl
GIT_REPOSITORY https://github.com/abseil/abseil-cpp.git
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)
FetchContent_Declare(
osqp
GIT_REPOSITORY https://github.com/osqp/osqp.git
GIT_TAG v0.5.0
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE)
# FetchContent_Declare( boost GIT_REPOSITORY
# https://github.com/boostorg/boost.git GIT_SHALLOW TRUE GIT_PROGRESS TRUE )
FetchContent_MakeAvailable(absl osqp)
find_package(Boost REQUIRED)
file(GLOB_RECURSE src "*.cc" "*.proto")
list(FILTER src EXCLUDE REGEX ".+test\.cc")
add_library(common SHARED ${src})
protobuf_generate(
TARGET common IMPORT_DIRS ${CMAKE_SOURCE_DIR}
# APPEND_PATH
)
target_include_directories(
common
PRIVATE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
INTERFACE $<INSTALL_INTERFACE:include>)
target_link_libraries(
common
PRIVATE cyber
protobuf::libprotobuf
can_card
Eigen3::Eigen
osqp
Boost::boost
SQLite::SQLite3
absl::base
absl::synchronization
PUBLIC $<BUILD_INTERFACE:absl::strings>)
include(CMakePackageConfigHelpers)
configure_package_config_file(
${CMAKE_SOURCE_DIR}/cmake/common-config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/common-TargetsConfig.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/common")
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/common-TargetConfigVersion.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/common-TargetsConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/common-TargetConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/common")
install(
TARGETS common
EXPORT common-Targets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin)
install(EXPORT common-Targets
DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/common")
file(RELATIVE_PATH rel_path "${CMAKE_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}")
install(
DIRECTORY .
DESTINATION include/${rel_path}
FILES_MATCHING
PATTERN "*.h"
PATTERN "*.proto")
list(FILTER src INCLUDE REGEX ".+\.proto")
foreach(proto_file IN LISTS src)
get_filename_component(filename_we "${proto_file}" NAME_WE)
get_filename_component(dir "${proto_file}" DIRECTORY)
file(RELATIVE_PATH subdir "${CMAKE_CURRENT_SOURCE_DIR}" "${dir}")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${subdir}/${filename_we}.pb.h"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${rel_path}/${subdir})
endforeach()
canbus
目录: modules/drivers/canbus
bazel脚本
apollo_cc_library(
name = "apollo_drivers_canbus",
srcs = [
"sensor_gflags.cc",
"can_client/can_client_factory.cc",
"can_client/fake/fake_can_client.cc",
"can_client/hermes_can/hermes_can_client.cc",
"can_client/socket/socket_can_client_raw.cc",
"common/byte.cc",
],
hdrs = [
"sensor_gflags.h",
"can_client/can_client.h",
"can_client/can_client_factory.h",
"can_client/fake/fake_can_client.h",
"can_client/hermes_can/bcan.h",
"can_client/hermes_can/bcan_defs.h",
"can_client/hermes_can/hermes_can_client.h",
"can_client/socket/socket_can_client_raw.h",
"can_comm/can_receiver.h",
"can_comm/can_sender.h",
"can_comm/message_manager.h",
"can_comm/protocol_data.h",
"common/byte.cc",
"common/byte.h",
"common/canbus_consts.h",
],
deps = [
"//cyber",
"//modules/common/util:common_util",
"//modules/common/monitor_log",
"//modules/common_msgs/basic_msgs:error_code_cc_proto",
"//modules/common_msgs/drivers_msgs:can_card_parameter_cc_proto",
"//third_party/can_card_library/hermes_can",
"@com_github_gflags_gflags//:gflags",
"@com_google_googletest//:gtest",
],
)
对应cmakelist:
project(canbus VERSION 1.0.0)
# find_package(PkgConfig REQUIRED) pkg_check_modules(Gflags REQUIRED
# IMPORTED_TARGET gflags)
find_package(gflags REQUIRED)
file(GLOB_RECURSE SRCS "*.proto")
add_library(
canbus SHARED
sensor_gflags.cc
can_client/can_client_factory.cc
can_client/fake/fake_can_client.cc
can_client/hermes_can/hermes_can_client.cc
can_client/socket/socket_can_client_raw.cc
common/byte.cc
${SRCS})
protobuf_generate(
TARGET canbus IMPORT_DIRS ${CMAKE_SOURCE_DIR}
# APPEND_PATH
)
target_link_libraries(
canbus
PRIVATE cyber
common
can_card
gflags_shared
absl::base
absl::synchronization
absl::strings)
target_include_directories(
canbus PRIVATE ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_BINARY_DIR})
install(
TARGETS canbus
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin)
conti_radar
目录:modules/drivers/radar/conti_radar
bazel
filegroup(
name = "runtime_data",
srcs = glob([
"conf/*.txt",
"conf/*.conf",
"dag/*.dag",
"launch/*.launch",
]),
)
apollo_cc_library(
name = "conti_radar_message_manager",
srcs = ["conti_radar_message_manager.cc"],
hdrs = ["conti_radar_message_manager.h"],
deps = [
"//modules/common/util:util_tool",
"//modules/drivers/canbus:apollo_drivers_canbus",
"//modules/drivers/radar/conti_radar/protocol:drivers_conti_radar_protocol",
],
)
apollo_component(
name = "libconti_radar.so",
srcs = ["conti_radar_canbus_component.cc"],
hdrs = ["conti_radar_canbus_component.h"],
copts = ['-DMODULE_NAME=\\"conti_radar\\"'],
deps = [
":conti_radar_message_manager",
"//cyber",
"//modules/common/adapters:adapter_gflags",
"//modules/common/monitor_log",
"//modules/drivers/canbus:apollo_drivers_canbus",
"//modules/drivers/canbus/proto:sensor_canbus_conf_cc_proto",
"//modules/drivers/radar/conti_radar/protocol:drivers_conti_radar_protocol",
"//modules/common_msgs/localization_msgs:localization_cc_proto",
"//modules/common_msgs/localization_msgs:pose_cc_proto",
"@eigen",
],
)
cmake
project(conti_radar VERSION 1.0.0)
file(GLOB_RECURSE SRCS "*.cc" "*.proto")
add_library(conti_radar SHARED ${SRCS})
protobuf_generate(
TARGET conti_radar
# PROTOC_OUT_DIR ${CMAKE_CURRENT_SOURCE_DIR}
IMPORT_DIRS ${CMAKE_SOURCE_DIR})
target_link_libraries(conti_radar PRIVATE protobuf::libprotobuf cyber common
canbus Eigen3::Eigen)
target_include_directories(
conti_radar PRIVATE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}
${CMAKE_CURRENT_BINARY_DIR})
target_compile_definitions(conti_radar PRIVATE MODULE_NAME="conti_radar")
install(
TARGETS conti_radar
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin)
install(
DIRECTORY .
DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}
FILES_MATCHING
PATTERN "conf/*.txt"
PATTERN "conf/*.conf"
PATTERN "dag/*.dag"
PATTERN "launch/*.launch")
编译
cd project
cmake -B build
cmake --build build --target install
打包
cd build
cpack