You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CMake编译多核心FreeRTOS遇ninja重复生成文件错误

解决方案

方案1:序列化构建步骤,避免并发修改

冲突根源是两个核的编译任务并发修改同一SDK文件,直接让它们按顺序执行即可禁止并行冲突。

具体实现

  1. 为每个核的SDK编译创建独立自定义目标
  2. 让第二个目标依赖第一个目标的完成,确保同一时间只有一个任务修改SDK头文件
  3. 保留备份-替换-恢复流程,通过CMake的DEPENDS控制执行顺序

示例CMake代码:

# 第一个核的编译目标
add_custom_target(build_sdk_core1
  COMMAND cp ${SDK_DIR}/freertos/config/FreeRTOSConfig.h ${SDK_DIR}/freertos/config/FreeRTOSConfig.h.bak
  COMMAND cp ${CMAKE_SOURCE_DIR}/config/core1/FreeRTOSConfig.h ${SDK_DIR}/freertos/config/FreeRTOSConfig.h
  COMMAND make -C ${SDK_DIR}
  COMMAND cp ${SDK_DIR}/freertos/config/FreeRTOSConfig.h.bak ${SDK_DIR}/freertos/config/FreeRTOSConfig.h
  COMMAND rm ${SDK_DIR}/freertos/config/FreeRTOSConfig.h.bak
  BYPRODUCTS ${SDK_DIR}/libfreertos_core1.a # 替换为实际生成的库文件名
)

# 第二个核的编译目标,依赖第一个目标完成
add_custom_target(build_sdk_core2
  DEPENDS build_sdk_core1
  COMMAND cp ${SDK_DIR}/freertos/config/FreeRTOSConfig.h ${SDK_DIR}/freertos/config/FreeRTOSConfig.h.bak
  COMMAND cp ${CMAKE_SOURCE_DIR}/config/core2/FreeRTOSConfig.h ${SDK_DIR}/freertos/config/FreeRTOSConfig.h
  COMMAND make -C ${SDK_DIR} clean # 清理前一次编译产物
  COMMAND make -C ${SDK_DIR}
  COMMAND cp ${SDK_DIR}/freertos/config/FreeRTOSConfig.h.bak ${SDK_DIR}/freertos/config/FreeRTOSConfig.h
  COMMAND rm ${SDK_DIR}/freertos/config/FreeRTOSConfig.h.bak
  BYPRODUCTS ${SDK_DIR}/libfreertos_core2.a
)

# 导入为IMPORTED目标
add_library(freertos_core1 STATIC IMPORTED)
set_target_properties(freertos_core1 PROPERTIES
  IMPORTED_LOCATION ${SDK_DIR}/libfreertos_core1.a
)
add_dependencies(freertos_core1 build_sdk_core1)

add_library(freertos_core2 STATIC IMPORTED)
set_target_properties(freertos_core2 PROPERTIES
  IMPORTED_LOCATION ${SDK_DIR}/libfreertos_core2.a
)
add_dependencies(freertos_core2 build_sdk_core2)

方案2:修改SDK的Makefile,支持外部配置文件(推荐)

如果允许修改SDK的Makefile,这是最干净的方案,无需替换任何SDK文件,直接通过编译参数指定自定义配置。

具体实现

  1. 打开SDK中FreeRTOS模块的Makefile,找到CFLAGS定义部分
  2. 添加可配置参数CONFIG_INCLUDE_DIR,默认指向SDK原config目录,允许外部覆盖
  3. 修改CFLAGS,把自定义目录加到头文件搜索路径最前面,确保优先使用外部配置

示例修改SDK的Makefile:

# 新增:允许外部传入配置目录,默认用SDK自带路径
CONFIG_INCLUDE_DIR ?= $(CURDIR)/config

# 修改CFLAGS,优先使用自定义配置目录
CFLAGS += -I$(CONFIG_INCLUDE_DIR)

CMake中为每个核指定不同配置目录:

add_custom_target(build_sdk_core1
  COMMAND make -C ${SDK_DIR} CONFIG_INCLUDE_DIR=${CMAKE_SOURCE_DIR}/config/core1
  BYPRODUCTS ${SDK_DIR}/libfreertos_core1.a
)

add_custom_target(build_sdk_core2
  COMMAND make -C ${SDK_DIR} CONFIG_INCLUDE_DIR=${CMAKE_SOURCE_DIR}/config/core2 clean
  COMMAND make -C ${SDK_DIR} CONFIG_INCLUDE_DIR=${CMAKE_SOURCE_DIR}/config/core2
  BYPRODUCTS ${SDK_DIR}/libfreertos_core2.a
)

# 导入IMPORTED目标的代码同方案1

此方案支持并行编译,因为不会修改SDK任何文件,仅通过编译参数指定不同配置路径。

方案3:用-include编译参数强制覆盖配置

如果无法修改SDK的Makefile,可在调用make时通过CFLAGS传递-include参数,强制所有编译单元先包含自定义配置文件,覆盖SDK原有配置。

具体实现

CMake代码示例:

add_custom_target(build_sdk_core1
  COMMAND make -C ${SDK_DIR} CFLAGS="-include ${CMAKE_SOURCE_DIR}/config/core1/FreeRTOSConfig.h"
  BYPRODUCTS ${SDK_DIR}/libfreertos_core1.a
)

add_custom_target(build_sdk_core2
  COMMAND make -C ${SDK_DIR} clean
  COMMAND make -C ${SDK_DIR} CFLAGS="-include ${CMAKE_SOURCE_DIR}/config/core2/FreeRTOSConfig.h"
  BYPRODUCTS ${SDK_DIR}/libfreertos_core2.a
)

# 导入IMPORTED目标的代码同前

注意:自定义配置文件需包含FreeRTOS所需的所有宏定义,确保功能完整。


内容的提问来源于stack exchange,提问作者NetoBF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 06:34:51