STM32 CMake构建报错bad defsym格式错误如何解决
问题描述
- 基于CMake搭建STM32跨平台构建项目,目标输出
.hex、.bin、.elf格式产物,已完成基础CMake配置与工具链设置,构建临近结束时触发报错。
现有链接器配置
链接器标志存放在compiler_flags.cmake文件中,配置内容如下:
... set(LD_FLAGS "-Wl,-Map=${PROJECT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.map,--cref -T${LD_SCRIPT} -Wl,--gc-sections -static,--specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -Wl,--defsym,__cxa_pure_virtual=1 -Wl,--start-group -lc -lm -Wl,--end-group")
报错输出
... ... ... Assembler messages: Fatal error: bad defsym; format is --defsym name=value ninja: build stopped: subcommand failed.
故障原因
报错由两个配置错误共同导致:
- 参数分隔符使用错误:
-static与--specs=nano.specs是两个独立的GCC前端参数,二者之间错误使用逗号连接,导致GCC参数解析错位,后续本应由GCC识别处理的参数被错误透传给汇编器as。 - 链接选项作用域配置错误:仅应在最终链接ELF阶段生效的链接器标志,被错误加入了全局C/C++/汇编编译选项中,汇编器收到不属于自身处理的
--defsym参数,且因参数错位无法识别到合法的name=value格式定义值,最终触发致命错误。
修复方法
- 修正链接参数的分隔错误,移除
-static和--specs=nano.specs之间的错误逗号,同时将--defsym的传参格式改为等号连接避免参数拆分,修正后的链接参数写法如下:
set(LD_FLAGS -Wl,-Map=${PROJECT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.map,--cref -T${LD_SCRIPT} -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -Wl,--defsym=__cxa_pure_virtual=1 -Wl,--start-group -lc -lm -Wl,--end-group )
- 调整链接选项的作用域:不要将
LD_FLAGS加入全局编译选项(即不要通过add_compile_options、全局CMAKE_C_FLAGS/CMAKE_ASM_FLAGS传入链接参数),仅通过target_link_options将链接参数绑定到最终生成ELF的目标上,避免编译、汇编阶段收到无关的链接器参数。
*补充说明:不建议通过defsym将__cxa_pure_virtual符号定义为地址1,该符号是C++纯虚函数调用的错误处理钩子,直接绑定到地址1会在触发纯虚函数调用时直接跳转到0x1地址触发硬错误,更稳妥的方式是自行实现一个钩子函数:
extern "C" void __cxa_pure_virtual(void) { // 可在此处加入错误日志、死循环等错误处理逻辑 while(1); }
内容的提问来源于stack exchange,提问作者user11786049
相关产品推荐
相关产品推荐

