如何用CMake实现多芯片嵌入式项目的一体化构建?
用CMake实现多工具链跨架构构建的方案
核心思路:嵌套CMake构建(ExternalProject)
CMake的单工具链限制可通过官方的ExternalProject_Add模块绕开,这是多架构/多工具链构建的标准方案,无需改用Make。具体实现逻辑:
- 根CMakeLists.txt作为总控,不绑定具体工具链,分别引入AVR固件、ARM软件两个子项目,各自指定对应工具链
- 两个子项目独立编写CMake配置,分别适配AVR和ARM的交叉编译环境
- 根CMake中添加自定义目标,调用脚本将编译产物整合为SD镜像
关键代码示例
根CMakeLists.txt核心片段:
cmake_minimum_required(VERSION 3.14) project(RobotBuildSystem) include(ExternalProject) # 构建AVR固件 ExternalProject_Add( avr_firmware SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/avr-firmware CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/avr-gcc.toolchain.cmake BUILD_ALWAYS ON INSTALL_COMMAND "" # 无需安装,直接取编译产物 ) # 构建ARM SBC软件 ExternalProject_Add( arm_sbc_software SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/arm-sbc-software CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_CURRENT_SOURCE_DIR}/arm-linux-gnueabihf.toolchain.cmake BUILD_ALWAYS ON INSTALL_COMMAND "" ) # 整合SD镜像的自定义目标 add_custom_target( build_sd_image DEPENDS avr_firmware arm_sbc_software COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/pack_sd_image.sh $<TARGET_FILE_DIR:arm_sbc_software>/robot-service ${CMAKE_CURRENT_BINARY_DIR}/avr_firmware-prefix/src/avr_firmware-build/firmware.hex ${CMAKE_CURRENT_BINARY_DIR}/sd_image.img ) # 默认一键构建所有目标 add_custom_target(all DEPENDS build_sd_image)
AVR工具链文件示例(avr-gcc.toolchain.cmake):
set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR avr) set(AVR_GCC_PATH /path/to/avr-gcc/bin) set(CMAKE_C_COMPILER ${AVR_GCC_PATH}/avr-gcc) set(CMAKE_CXX_COMPILER ${AVR_GCC_PATH}/avr-g++) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # 指定AVR MCU型号及编译优化选项 add_compile_options(-mmcu=atmega328p -Os) add_link_options(-mmcu=atmega328p)
VS Code/Codium适配方案
VS Code的CMake扩展默认仅识别单配置,但可通过以下方式规避限制:
- 自定义任务触发构建:在
.vscode/tasks.json中定义构建任务,直接调用根目录的CMake命令,绕开扩展的自动配置逻辑:
{ "version": "2.0.0", "tasks": [ { "label": "Build All", "type": "shell", "command": "cmake --build ${workspaceFolder}/build --target all", "group": { "kind": "build", "isDefault": true }, "problemMatcher": [] } ] }
- 手动切换子项目配置:如需单独调试子项目,可在VS Code左下角CMake配置菜单中,手动选择子项目目录和对应工具链文件,完成单独配置。
参考方向(无外链)
- CMake官方
ExternalProject模块文档:重点掌握SOURCE_DIR、CMAKE_ARGS、DEPENDS参数用法,以及工具链文件的传递方式 - CMake交叉编译官方指南:学习工具链文件的标准写法,包括系统标识、编译器路径、查找规则的配置
- 社区AVR+CMake案例:参考MCU型号指定、固件格式(.hex)生成的具体实现
是否需要改用Make?
不需要。CMake的ExternalProject完全能满足多工具链构建需求,且在依赖管理、可读性、扩展性上优于Make脚本,更适合复杂项目的长期维护。
内容的提问来源于stack exchange,提问作者LostSnail
相关产品推荐
相关产品推荐

