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

如何通过add_subdirectory()整合构建输出,解决CMake ROM镜像构建报错

遇到这个问题很正常,CMake的add_executable命令有个硬性要求——必须给它至少一个源文件,哪怕是个空文件也可以。你现在的代码里add_executable(rom_image.bin)没有指定任何源,CMake自然会报错。

接下来给你调整后的完整方案,一步步解决问题:

1. 添加占位源文件

我们用CMake自动生成一个空的占位源文件,满足add_executable的源文件要求,不用手动创建文件:

# 生成一个空的占位源文件,解决add_executable必须有源文件的问题
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.c "")

2. 创建ELF格式的中间目标

先构建一个ELF格式的可执行目标,后续我们会把各个组件的目标文件链接到这个ELF里:

# 创建ELF格式的可执行目标,以dummy.c作为占位源
add_executable(rom_image.elf ${CMAKE_CURRENT_BINARY_DIR}/dummy.c)

3. 转换组件二进制为目标文件并添加到ELF目标

修改你的循环逻辑,生成每个组件的目标文件后,将其添加到ELF目标的源列表中,让CMake自动处理依赖和链接流程:

foreach (COMPONENT ${COMPONENTS})
    set(COMPONENT_BINARY_FILENAME "${CMAKE_BINARY_DIR}/${COMPONENT}/output.bin")
    # 将生成的.o文件放到当前构建目录,避免和组件目录混淆
    set(COMPONENT_OBJECT_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/${COMPONENT}.o")
    
    add_custom_command(
        OUTPUT ${COMPONENT_OBJECT_FILENAME}
        DEPENDS ${COMPONENT_BINARY_FILENAME}
        COMMAND ${OBJCOPY_PROGRAM}
        ARGS --input-target=binary --output-target=elf32-littlearm --binary-architecture=arm ${COMPONENT_BINARY_FILENAME} ${COMPONENT_OBJECT_FILENAME}
        COMMENT "Converting ${COMPONENT} binary to object file"
    )
    
    # 将生成的目标文件添加到ELF目标中,CMake会自动处理链接
    target_sources(rom_image.elf PRIVATE ${COMPONENT_OBJECT_FILENAME})
endforeach()

4. 生成最终的ROM镜像

在ELF目标构建完成后,用objcopy将其转换为单一的二进制ROM镜像:

# 从链接好的ELF文件生成最终的二进制ROM镜像
add_custom_command(
    TARGET rom_image.elf POST_BUILD
    COMMAND ${OBJCOPY_PROGRAM}
    ARGS -O binary $<TARGET_FILE:rom_image.elf> rom_image.bin
    COMMENT "Generating final ROM image: rom_image.bin"
)

流程说明

调整后的代码会按以下顺序执行:

  1. 生成空的dummy.c,满足可执行目标的源文件要求
  2. 遍历每个组件,将其输出的二进制文件转换为ARM架构的ELF目标文件
  3. 链接所有目标文件(包括dummy.o)成一个完整的ELF文件
  4. 最后将ELF文件导出为单一的二进制ROM镜像

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:23:00