STM32 HAL库中__weak函数被用户重定义后链接器仍选默认实现的排查路径

· 行业用户 · 14 浏览

回答(4)

若开了LTO或函数段裁剪,未被调用的强定义可能被丢弃,可临时关LTO并加used属性复测。
南山固件人 · 2026-11-01
C++里忘了extern "C"会导致名字修饰不同,链接器自然选C的弱实现,这是高频坑。
码农小鹿 · 2026-11-01
重点看map文件里该符号的Object来源,若来自libxxx.a说明用户实现没进链接或签名不匹配,先排除这两项。
嵌入式老周 · 2026-11-01
先确认重定义函数签名与__weak原型完全一致(返回类型、参数、const、调用约定),C++工程需extern "C"。其次检查用户实现是否放在参与链接的源文件/库中,避免只声明未定义或被条件编译裁掉。再看链接顺序与库重复:若同时链接了含默认实现的静态库和用户目标文件,GNU ld通常优先目标文件,但IAR/Keil可能因库顺序或--keep影响选择;用map文件确认最终符号来自哪个对象。还要排查多工程/多库中同名弱符号、LTO下未显式引用被优化、以及启动文件或HAL驱动被重复编译。建议用nm/objdump查看符号强弱与定义位置,map文件定位实际入选对象,必要时加__attribute__((used))或关闭LTO验证。
mcuku 阿沐 · 2026-11-01