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

CMake重复汇编问题:汇编文件被两次汇编而非用objcopy生成最终二进制

CMake重复汇编NASM二进制文件的问题原因与解决方法

问题原因

你在NASM编译时使用了-f bin参数,这会直接生成最终的原始二进制镜像(也就是你说的512字节可启动文件),但CMake的ADD_EXECUTABLE逻辑是为常规可执行文件设计的:它会先将源文件编译为目标文件(.obj/.o),再调用链接器生成最终可执行文件。

由于你的项目指定了ASM_NASM作为唯一语言,CMake错误地认为“链接”步骤也需要用NASM来完成,于是把第一次生成的二进制文件当成了需要再次汇编的源文件,导致第二次调用NASM处理非汇编文件,最终输出0字节的无效文件和警告。

解决方法

方案1:通过ELF目标文件生成二进制(适合需要链接其他代码的场景)

先让NASM生成ELF格式的目标文件,让CMake完成正常的链接流程,再用objcopy提取纯二进制镜像:

CMAKE_MINIMUM_REQUIRED(VERSION 3.3.2)
PROJECT(bootloader ASM_NASM)

# 配置NASM生成ELF64目标文件(根据你的架构调整,比如elf32对应x86)
SET(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
SET(CMAKE_ASM_NASM_FLAGS "-g -F dwarf")

ADD_EXECUTABLE(bootloader 
    ${CMAKE_CURRENT_LIST_DIR}/arch/${ARCH}/boot.asm
)

# 编译完成后用objcopy生成原始二进制文件
ADD_CUSTOM_COMMAND(TARGET bootloader POST_BUILD
    COMMAND ${CMAKE_OBJCOPY} -O binary $<TARGET_FILE:bootloader> ${CMAKE_BINARY_DIR}/bootloader.bin
    COMMENT "Generating raw binary bootloader image..."
)

方案2:直接自定义命令生成二进制(适合纯汇编的MBR/bootloader)

跳过CMake的ADD_EXECUTABLE默认流程,直接调用NASM生成二进制文件:

CMAKE_MINIMUM_REQUIRED(VERSION 3.3.2)
PROJECT(bootloader ASM_NASM)

# 定义源文件和输出文件路径
SET(BOOT_ASM_SOURCE ${CMAKE_CURRENT_LIST_DIR}/arch/${ARCH}/boot.asm)
SET(BOOT_BINARY_OUTPUT ${CMAKE_BINARY_DIR}/bootloader.bin)

# 自定义汇编命令
ADD_CUSTOM_COMMAND(
    OUTPUT ${BOOT_BINARY_OUTPUT}
    COMMAND nasm -f bin -o ${BOOT_BINARY_OUTPUT} ${BOOT_ASM_SOURCE}
    DEPENDS ${BOOT_ASM_SOURCE}
    COMMENT "Assembling bootloader to raw binary..."
)

# 创建自定义目标,让构建系统可以直接触发这个任务
ADD_CUSTOM_TARGET(bootloader ALL DEPENDS ${BOOT_BINARY_OUTPUT})

说明

  • 方案1适合需要整合C/C++代码的复杂bootloader,保留CMake的依赖管理和链接能力。
  • 方案2更轻量,适合纯汇编编写的MBR等不需要链接的启动代码,完全避开CMake的可执行文件构建逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 23:10:53