bazel迁移cmake要点及具体迁移工程示例(apollo radar)

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值