查找“未定义引用”错误的根本原因
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
转储符号到该路径时,我可以找到标记为 T
的 pvPortMalloc
,这意味着该符号位于文本(代码)部分:
/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 函数的头文件。
我想了解为什么我在链接过程中遇到 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
转储符号到该路径时,我可以找到标记为 T
的 pvPortMalloc
,这意味着该符号位于文本(代码)部分:
/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 函数的头文件。