我正在尝试理解为什么我在链接过程中遇到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找不到该函数的原因是什么? 如何进一步调试此错误?
答案 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>
是通过为库中的所有对象创建索引来解决此问题的工具,应该解决这个问题。