I just wonder if there is an effective technique to troubleshoot undefined symbols in gcc. Sometimes one of my projects fails to link and I usually spend a lot of time finding why. Usually it is a typo in a deeply hidden makefile, incorrect environment variable or something like this. What method do you use if your build suddenly dies with "undefined symbol" and it is not obvious why?
Say this is my start configuration:
/usr/lib/gcc/i486-linux-gnu/4.3.2/../../../../lib/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
bar.o: In function `baz()':
bar.cpp:(.text+0xd): undefined reference to `Foo::bar()'
collect2: ld returned 1 exit status
I start with looking up the missing symbol with grep to all .o and .lib files.
$ grep 'Foo.*bar' *.o *.lib *.so
Binary file bar.o matches
Binary file foo.o matches
Then I use th nm
Tool to inspect each object file if the symbol there is missing or implemented.
$ nm foo.o
00000000 T _ZN3Foo3barEv
$ nm bar.o
00000000 T _Z3bazv
U _ZN3Foo3barEv
U __gxx_personality_v0
Now I know that Foo::bar() is implemented in foo.o and can link this file into the executable. So the next part is to inspect why foo.o is not included in the link command.
Sometimes you don't find any implementing symbol. This is usually the case when the implementation unit is not build, or does not include the symbol (#ifdef
, symbol visibility). In such a case I search for the .cpp file where the symbol is defined, run make $file.o
to generate the file, and inspect the file afterwards. When the smbol is there, I continue to build the library or executable where this file is placed into.