Linux编程:简单实例演示CMake和Bazel的使用

0. 引言

Apollo的Cyber Time 模块通过提供 TimeDurationClockRate 四个核心类,简化了时间管理和控制的复杂性。无论是在实际应用中进行精准的时间控制,还是在仿真环境中模拟真实时间,Cyber Time 模块都能提供稳定的实现。

本文尝试从Apollo中摘录出可以独立使用的Cyber Time 模块,并编写出CMake和Bazel编译脚本。完整代码见:apollo-cyber-time .

提前阅读:从 Apollo CyberRT 中提取可独立使用的Time 模块,本文主要介绍其CMake和Bazel编译脚本。

1. 代码结构

$ tree . -L 1                                                                                                                                                               .
├── BUILD
├── CMakeLists.txt
├── cyber_duration.cc
├── cyber_duration.h
├── cyber_duration_test.cc
├── cyber_rate.cc
├── cyber_rate_example.cc
├── cyber_rate.h
├── cyber_time.cc
├── cyber_time.h
├── cyber_time_test.cc
└── WORKSPACE

2. CMakeLists.txt

# 指定最低的 CMake 版本要求
cmake_minimum_required(VERSION 3.10)

# 定义项目名称和使用的语言
project(CyberTimeTests LANGUAGES CXX)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 启用测试功能
enable_testing()

# 使用 FetchContent 模块来下载和配置 GoogleTest
include(FetchContent)

FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/refs/tags/release-1.12.1.zip
)

# 防止 GoogleTest 覆盖父项目的编译器设置(尤其是在 Windows 上)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

# 下载并配置 GoogleTest
FetchContent_MakeAvailable(googletest)

# 创建一个静态库包含所有源文件(除了测试文件)
add_library(cyber_time_lib
    cyber_duration.cc
    cyber_time.cc
    cyber_rate.cc
)

# 指定库的包含目录
target_include_directories(cyber_time_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

# 为每个测试文件创建一个可执行文件并链接相应的库和 GoogleTest

# 1. Duration Test
add_executable(cyber_duration_test cyber_duration_test.cc)
target_link_libraries(cyber_duration_test PRIVATE cyber_time_lib gtest_main)

# 2. Time Test
add_executable(cyber_time_test cyber_time_test.cc)
target_link_libraries(cyber_time_test PRIVATE cyber_time_lib gtest_main)

# 注册测试,以便使用 ctest 运行
include(GoogleTest)
gtest_discover_tests(cyber_duration_test)
gtest_discover_tests(cyber_time_test)

#####################
# 3. Rate Example
add_executable(cyber_rate_example cyber_rate_example.cc)
target_link_libraries(cyber_rate_example PRIVATE cyber_time_lib)

2.1 CMake说明

  • 启用测试功能
enable_testing()

启用 CMake 的测试功能,使得可以使用 ctest 命令运行测试。

  • 使用 FetchContent 下载和配置 GoogleTest
include(FetchContent)

FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/refs/tags/release-1.12.1.zip
)

set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)

FetchContent_MakeAvailable(googletest)

FetchContent:模块用于在构建时下载和集成外部项目。

FetchContent_Declare:声明要下载的内容,这里是 GoogleTest 的发布版本 1.12.1。

gtest_force_shared_crt:在 Windows 上强制使用共享的 C 运行时库,避免潜在的链接问题。

FetchContent_MakeAvailable:下载并配置 GoogleTest,使其在后续可以被使用。

注册测试

include(GoogleTest)
gtest_discover_tests(clock_test)
gtest_discover_tests(duration_test)
gtest_discover_tests(time_test)

include(GoogleTest):包含 GoogleTest 的 CMake 模块。

gtest_discover_tests:自动发现并注册测试,使得可以通过 ctest 命令运行它们。

3. Bazel

# 定义静态库 cyber_time_lib
cc_library(
    name = "cyber_time_lib",
    srcs = [
        "cyber_duration.cc",
        "cyber_time.cc",
        "cyber_rate.cc",
    ],
    hdrs = [
        "cyber_duration.h",
        "cyber_time.h",
        "cyber_rate.h",
    ],
    visibility = ["//visibility:publi