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

ARM交叉编译时GCC链接器报重复定义与符号缺失错误

符号查询工具

可使用ARM交叉编译工具链自带的工具排查符号问题,常用工具如下:

  • arm-none-eabi-nm:用于查看目标文件、静态库的符号表,常用参数:
    • -A:显示符号所属的文件名
    • -C:自动解析C++符号(可直接将mc::mutex::lock这类mangled符号转为可读形式)
    • -u:仅筛选未定义符号
    • 示例命令:arm-none-eabi-nm -AC testdir/libmbed.a | grep __wrap__malloc_r,输出中带大写T表示符号在代码段已定义,带U表示符号未定义。
  • arm-none-eabi-objdump:全能目标文件分析工具,加-t参数可输出符号表,还支持查看段属性、反汇编代码。
  • arm-none-eabi-readelf:ELF格式专用分析工具,加-s参数可打印符号表,可用于确认库的编译架构、参数是否匹配。
问题根因与解决方案

重复定义错误修复

你在链接命令中重复写了所有.o目标文件:目标文件的所有符号会被链接器全量加载,重复写入必然触发重复定义报错。解决循环依赖仅需要重复静态库或使用组包裹,目标文件绝对不能重复写,直接删掉第二份.o文件即可解决所有重复定义报错。

未定义符号错误修复

你的链接顺序完全不符合GCC的规则:GCC链接器从左到右扫描输入文件,依赖方必须放在被依赖方前面,扫描过程中记录的未定义符号,只能由后面的输入文件填补。
你当前把库放在了目标文件前面:扫描库的时候还没有出现未定义符号,所以不会加载库中mbed_alloc_wrappers.o这类目标单元;等到后面扫描到你的.o文件出现__wrap__malloc_r这类未定义符号时,链接器不会回头检索前面的库,自然报未定义。

具体修正步骤

  1. 保留一份.o目标文件,放在链接命令最靠前的位置
  2. 调整库的顺序到目标文件之后,存在循环依赖的静态库用-Wl,--start-group和-Wl,--end-group包裹(直接用完整参数即可避免-(/-)的转义问题),无需重复写库
  3. 系统库放在链接命令最后即可

修正后的链接命令模板如下:

$(GCC_ARM) $(LD_FLAGS) -T $(BINARY_NAME).link_script.ld $(LIBRARY_PATHS) --output $$@ $(src) -Wl,--start-group $(LIBRARIES) -Wl,--end-group $(LD_SYS_LIBS)

如果调整后仍有未定义符号,可先通过nm确认对应库的编译参数是否和目标文件一致:比如浮点ABI、CPU架构、宏定义必须完全匹配,否则即使符号名称一致也无法识别。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:15:04