Amir Gonnen
Amir Gonnen

Reputation: 3727

Finding the root cause of `undefined reference` error

I'm trying to understand why I'm getting an undefined reference error during linking:

/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 complains it could not find the function pvPortMalloc.
However, I can confirm this function exists in libmain.a!

In the command line above, libmain is referenced by -lmain and library path is set to -L/home/amirgon/projects/esp8266/esp-open-sdk/sdk/lib. When I dump symbols from libmain.a on that path I can find pvPortMalloc marked as T, which means that the symbol is in the text (code) section:

/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

So, did I miss something? what could be the reason that gcc does not find the function although it exists in libmain.a?
How can I further debug this error?

Upvotes: 7

Views: 3537

Answers (2)

nos
nos

Reputation: 229058

Mixing of C++ and C code causes your issue.

This error:

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

Does not say that the symbol pvPortMalloc cannot be found. It says that the symbol pvPortMalloc(unsigned int, char const*, int) cannot be found, and that is a C++ symbol.

This means that somewhere you are compiling C++ code which thinks there is a C++ pvPortMalloc function, whose symbol also includes its signature, but you only have a pvPortMalloc C function.

Likely your C++ code is including a header file that is not C++ clean, and you will need to do something like this:

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

Where some_header.h is the header file declaring the pvPortMalloc function.

Upvotes: 9

tofro
tofro

Reputation: 6063

Not only order of object files and libraries on the command line is important, but also the order of object files within a library.

Anything that resolves a reference must come after the symbol is used, otherwise you might get strange linking problems.

The effect you see is a typical problem of a library that has been built with ar and the wrong object file order (some .o file using an external function that is defined in some .o file before the one that uses this symbol in the lib).

ranlib <libfile> is the tool that fixes this by creating an index for all objects in the library and should get rid of this problem.

Upvotes: 2

Related Questions