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

Finding the root cause of `undefined reference` error

我想了解为什么我在链接过程中遇到 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!

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

/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

所以,我错过了什么吗? 尽管 gcc 存在于 libmain.a 中,但 gcc 找不到该函数的原因可能是什么?
我怎样才能进一步调试这个错误?

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

任何解决引用必须使用符号之后,否则你可能会遇到奇怪的链接问题。

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

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

混合使用 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 函数的头文件。