找到“未定义引用”错误的根本原因

时间:2016-11-04 20:55:57

标签: c gcc linker linker-errors elf

我正在尝试理解为什么我在链接过程中遇到undefined reference错误:

/home/amirgon/projects/esp8266/esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf-gcc -L/home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib -T/home/amirgon/projects/esp8266/esp-open-sdk/sdk/ld/eagle.app.v6.cpp.ld -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -Wl,--start-group -lc -lgcc -lhal -lphy -lpp -lnet80211 -llwip -lwpa -lmain build/app_app.a -Wl,--end-group -o build/app.out
build/app_app.a(routines.o):(.text+0x4): undefined reference to `pvPortMalloc(unsigned int, char const*, int)'

gcc抱怨它无法找到函数pvPortMalloc 但是,我可以确认此功能存在于libmain.a

在上面的命令行中,-lmain引用了libmain,库路径设置为-L/home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib。 当我从该路径上的libmain.a转储符号时,我会发现pvPortMalloc标记为T,这意味着该符号位于文本(代码)部分中:

/home/amirgon/projects/esp8266/esp-open-sdk/xtensa-lx106-elf/bin/xtensa-lx106-elf-nm -g /home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib/libmain.a | grep pvPortMalloc
         U pvPortMalloc
0000014c T pvPortMalloc
         U pvPortMalloc

所以,我错过了什么吗? 可能是因为它存在于libmain.a中,gcc找不到该函数的原因是什么? 如何进一步调试此错误?

2 个答案:

答案 0 :(得分:3)

混合使用C ++和C代码会导致您的问题。

此错误:

undefined reference to `pvPortMalloc(unsigned int, char const*, int)'

不说无法找到符号pvPortMalloc。它说无法找到符号pvPortMalloc(unsigned int, char const*, int), 那是一个C ++符号。

这意味着您正在编译C ++代码的某个地方,它认为有一个C ++ pvPortMalloc函数,其符号也包含其签名,但您只有pvPortMalloc C函数。

可能你的C ++代码包含一个不是C ++干净的头文件,你需要做这样的事情:

extern "C" {
#include "some_header.h"
}

其中some_header.h是声明pvPortMalloc函数的头文件。

答案 1 :(得分:1)

不仅命令行上的目标文件和库的顺序很重要,而且库中的目标文件的顺序也很重要。

解析引用的任何内容必须在使用符号后,否则您可能会遇到奇怪的链接问题。

您看到的效果是使用ar和错误的目标文件顺序构建的库的典型问题(某些.o文件使用某些.o文件中定义的外部函数之前在lib中使用此符号的那个。)

ranlib <libfile>是通过为库中的所有对象创建索引来解决此问题的工具,应该解决这个问题。