大家好,我是杂烩君。

今天,我们就通过一个简单的Linux C 语言实战案例,带你深度剖析嵌入式 CMake 的核心套路。

使用 CMake 的好处

平台无关性:一套配置文件,适配 ARM、x86 等多种架构。

模块化管理:轻松分离驱动层、库和应用程序,代码结构一目了然。

自动化构建:从编译、链接到生成固件,一条make命令搞定。

CMake例子

我们的例子包含三个核心模块:

  • 静态库(strutils):字符串处理工具。
  • 动态库(mathutils):数学计算工具。
  • 应用程序(myapp):主程序,调用上述两个库。
1.项目结构
linux-cmake-example/
├── CMakeLists.txt          # 顶层配置文件
├── lib/
│   ├── CMakeLists.txt      # 库模块配置
│   ├── include/
│   │   ├── string_utils.h  # 字符串库头文件
│   │   └── math_utils.h    # 数学库头文件
│   ├── string_utils.c      # 字符串库实现
│   └── math_utils.c        # 数学库实现
├── app/
│   ├── CMakeLists.txt      # 应用程序配置
│   ├── include/
│   └── main.c              # 主程序代码
└── test/
    ├── CMakeLists.txt      # 测试模块配置
    └── test_string_utils.c # 字符串库测试代码
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

嵌入式必备工具 CMake 的使用套路!_嵌入式

嵌入式必备工具 CMake 的使用套路!_应用程序_02

每个文件夹都有独立的CMakeLists.txt,各司其职,这种 “分而治之” 的思想是嵌入式项目管理的精髓。

2. 顶层 CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(LinuxSystem C)

# 核心编译选项:开启严格检查 + 优化
set(CMAKE_C_STANDARD 11)
add_compile_options(
  -Wall -Wextra -Werror
  -O2
)

# 引入子模块:库、应用、测试
add_subdirectory(lib)
add_subdirectory(app)
add_subdirectory(test)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

关键点

  • add_compile_options统一设置编译规则。
  • add_subdirectory让 CMake 自动扫描子目录的配置文件,简化顶层逻辑。
3. 库模块:静态库、动态库
静态库(strutils)配置
add_library(strutils STATIC
  string_utils.c
)
target_include_directories(strutils PUBLIC include)
  • 1.
  • 2.
  • 3.
  • 4.

关键点

  • add_library(strutils STATIC):创建静态库,代码将直接嵌入可执行文件。
  • PUBLIC include:将头文件路径暴露给依赖它的模块,确保其他代码能调用库函数。
动态库(mathutils)配置
add_library(mathutils SHARED
  math_utils.c
)
target_include_directories(mathutils PUBLIC include)
  • 1.
  • 2.
  • 3.
  • 4.

关键点:

  • SHARED选项:生成独立的动态链接库,可被多个程序复用。
  • 实际部署时,需确保库文件在系统库路径中,否则运行会报错。
4. 应用程序:整合所有模块
add_executable(myapp
  main.c
)
target_include_directories(myapp PRIVATE include)
target_link_libraries(myapp 
  strutils 
  mathutils
  m # 链接标准数学库
)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

关键点:

  • target_link_libraries将静态库、动态库与主程序绑定。
  • PRIVATE include:仅在应用程序内部使用头文件,不对外暴露。
5. 测试模块
add_executable(test_strutils
  test_string_utils.c
)
target_link_libraries(test_strutils
  strutils
  cmocka # 引入单元测试框架
)
add_test(NAME test_strutils COMMAND test_strutils)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.

关键点

  • 使用 cmocka框架编写单元测试。
  • add_test定义测试任务, make test一键运行。
6、编译执行

嵌入式必备工具 CMake 的使用套路!_应用程序_03

嵌入式必备工具 CMake 的使用套路!_CMake_04

嵌入式必备工具 CMake 的使用套路!_CMake_05

CMake进阶技巧

1、 交叉编译:在顶层CMakeLists.txt中添加工具链配置,适配 ARM 等嵌入式平台。

set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
  • 1.
  • 2.

2、代码覆盖率分析:引入CodeCoverage模块,定位测试盲区

if(CMAKE_BUILD_TYPE MATCHES Coverage)
  include(CodeCoverage)
  append_coverage_compiler_flags()
  setup_target_for_coverage_lcov(
    NAME coverage
    EXECUTABLE ctest -j ${PROCESSOR_COUNT}
    DEPENDENCIES test_strutils
  )
endif()
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

3、自动化部署:通过install命令,一键将程序和库部署到目标系统

install(TARGETS myapp DESTINATION bin)
install(TARGETS strutils mathutils DESTINATION lib)
install(DIRECTORY include/ DESTINATION include)
  • 1.
  • 2.
  • 3.

分享一个我创建的实用开源项目汇总仓库:

 https://gitee.com/zhengnianli/EmbedSummary gitee.com/zhengnianli/EmbedSummary