如何通过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" )
流程说明
调整后的代码会按以下顺序执行:
- 生成空的
dummy.c,满足可执行目标的源文件要求 - 遍历每个组件,将其输出的二进制文件转换为ARM架构的ELF目标文件
- 链接所有目标文件(包括
dummy.o)成一个完整的ELF文件 - 最后将ELF文件导出为单一的二进制ROM镜像
内容的提问来源于stack exchange,提问作者Tintin
相关产品推荐
相关产品推荐

