CMake编译无报错但build目录未生成hex/elf文件解决方法
嵌入式CMake构建不生成elf/hex文件修复方案
现有配置的核心错误
- 交叉编译配置顺序错误:
CMAKE_SYSTEM_NAME、CMAKE_C_COMPILER等交叉编译核心参数必须放在project()命令前。当前配置将这类参数放在project()之后,CMake执行project()时会默认调用主机本地x86架构gcc做编译器检测,不会按裸机嵌入式流程生成目标文件,还可能自动给可执行文件添加主机平台后缀(如Windows环境下生成blink_cortex_m0plus.elf.exe,导致按文件名查找不到)。 - 语法错误:
include_directories语句的闭合括号被注释,后续add_executable、自定义构建命令会被异常解析,目标文件无法正常生成。 - 输出路径硬编码错误:hex、bin、map文件的输出路径被硬编码为
${PROJECT_SOURCE_DIR}/build/,如果采用外部构建、自定义构建目录,该路径可能不存在,objcopy写入文件失败时不会中断构建流程,最终无对应输出文件。需替换为CMake内置变量${CMAKE_BINARY_DIR}指向当前实际构建目录。 - 链接参数引用未定义变量:设置
CMAKE_EXE_LINKER_FLAGS时引用了从未定义的${LINKER_FLAGS}变量,可能导致链接脚本路径、参数未正确传入,链接流程异常。 - 工具路径未校验:直接写
arm-none-eabi-objcopy调用,如果系统PATH未配置工具链路径,会导致命令静默执行失败。
具体修改方法
- 调整配置顺序,将交叉编译相关参数移到
project()之前,同时添加编译器检测跳过配置,避免嵌入式平台检测报错:
cmake_minimum_required(VERSION 3.7.2) # 交叉编译配置必须在project()之前声明 set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_VERSION 1) set(CMAKE_C_COMPILER arm-none-eabi-gcc) find_program(OBJCOPY arm-none-eabi-objcopy REQUIRED) # 跳过编译器可执行文件检测,适配裸机平台 set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) project(blink_cortex_m0plus) enable_language(ASM)
- 修复
include_directories语法错误,放开被注释的闭合括号:
include_directories( ${PROJECT_INCLUDE_DIRS} ${CYPRESS_PERIPHERAL_DRIVERS_LIBRARY_INCLUDE_DIRS} )
- 修正链接参数和输出路径配置,删除未定义变量引用,替换硬编码路径:
# 架构、编译警告等原有flag配置保持不变 set(PROJECT_FLAGS_ARCH "-mcpu=cortex-m0plus \ -mthumb" ) set(PROJECT_LINKER_FLAGS "-Wl,-Map=${PROJECT_NAME}.map \ -L${PROJECT_SOURCE_DIR}/../config/ \ -Tlinker.ld" ) set(PROJECT_C_FLAGS_WARNINGS "${COMMON_FLAGS_WARNINGS} ${C_FLAGS_WARNINGS_EXTRA}") set(PROJECT_INCLUDE_DIRS ${PROJECT_CONFIG_DIR} ${BLINK_DIR}/../ ${CYPRESS_CORE_LIBRARY} ) set(PROJECT_SRCS ${PROJECT_SOURCE_DIR}/main_cm0plus.c ${CYPRESS_PERIPHERAL_DRIVERS_LIBRARY}system_tviibe1m_cm0plus.c ${CYPRESS_PERIPHERAL_DRIVERS_LIBRARY}startup_cm0plus.S ) set (CMAKE_C_FLAGS "${C_FLAGS} ${C_FLAGS_WARNINGS} ${FLAGS_OPTIMIZATION} ${PROJECT_FLAGS_ARCH}") set (CMAKE_ASM_FLAGS "${C_FLAGS} ${C_FLAGS_WARNINGS} ${FLAGS_OPTIMIZATION} ${PROJECT_FLAGS_ARCH}") # 去掉未定义的${LINKER_FLAGS}引用 set (CMAKE_EXE_LINKER_FLAGS "${PROJECT_LINKER_FLAGS} ${FLAGS_OPTIMIZATION} ${PROJECT_FLAGS_ARCH}") add_executable(${PROJECT_NAME}.elf ${PROJECT_SRCS} ${CYPRESS_PERIPHERAL_DRIVERS_LIBRARY_SRCS}) # 禁止CMake自动添加.exe等主机平台可执行后缀 set_target_properties(${PROJECT_NAME}.elf PROPERTIES SUFFIX "") # 所有输出文件统一使用CMAKE_BINARY_DIR路径 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Map=${CMAKE_BINARY_DIR}/${PROJECT_NAME}.map") set(HEX_FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.hex) set(BIN_FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin) add_custom_command(TARGET ${PROJECT_NAME}.elf POST_BUILD COMMAND ${OBJCOPY} -Oihex $<TARGET_FILE:${PROJECT_NAME}.elf> ${HEX_FILE} COMMAND ${OBJCOPY} -Obinary $<TARGET_FILE:${PROJECT_NAME}.elf> ${BIN_FILE} COMMENT "Building ${HEX_FILE} \nBuilding ${BIN_FILE}")
构建验证
删除原有构建目录后重新执行构建,避免旧缓存影响:
rm -rf build cmake -B build cmake --build build -j
构建完成后,直接在build目录下即可找到生成的elf、hex、bin、map文件。
内容的提问来源于stack exchange,提问作者mrm
相关产品推荐
相关产品推荐

