Undefined reference errors during linking

I've seen a number of reports and resolutions for "undefined reference" errors during linking, but none that seem to address the issue I am having. I know some of why I am having it but... not the why of the why (if that makes sense).

Some background. I'm building two static libraries, say libfoo.a and libbar.a. libfoo.a has classa.o, classb.o and classc.o in it and libbar.a has classd.o, classe.o and classf.o in it.

Now I have three cpp programs. sample1.cpp and sample2.cpp only need libfoo.a to resolve any references. But sample3.cpp needs both libfoo.a and libbar.a in order to resolve all references. But... The wrinkle in all this that I am having is... classe.o in libbar.a also needs libfoo.a to resolve a class calls classe is making to classb in libfoo.a. Say methods in classe.o call ClassB::Method1(); and so forth. I hope this makes sense.

So now when I try to link sample3.o to create sample3 executable, I get a ton of "undefined references" for (classe.o) at line (whatever) in classe.cpp. Here is the link command I am issuing:

$ /usr/local/bin/g++ -g -DPD_CSTRING_COMPATIBLE -D_NO_LONGLONG -I/usr/local/include/g++-3 -I../lib -I../include -o sample3 sample3.o -L../lib -L/usr/local/lib -static -lfoo -lbar /usr/lib/gcc/x86_64-redhat-linux/4.1.1/libstdc++.a

libfoo.a and libbar.a both live in ../lib from where I am issuing the g++ command.

So my question is, why doesn't the linker scan all the static libraries given to it to resolve all references, even from the libraries themselves? So again, continuing with the example, I can us nm -C classe.o and see that:

0000000000000000 U ClassB::Method1
0000000000000000 U ClassB::Method2

Those are undefined -- they are in classb.o which is part of libfoo.a and that link command above is the first that the linker has seen of ClassB method calls outside of classa.o, classb.o and classc.o in libfoo.bar. But why doesn't it just resolve it since -lfoo and -lbar both are in the link command?

sample1.cpp and sample2.cpp both compile and link fine. They only need -lfoo on the link command line and only make calls to ClassA, ClassB and ClassC. It's the call in classe.o (which is in libbar.a) to ClassB::Method1() and ::Method2() that are causing the issue.

I hope this makes sense?

-eriks
Because GCC's linker is stupid.

To solve the problem, just include the libraries twice on the link line.

/usr/local/bin/g++ -g -DPD_CSTRING_COMPATIBLE -D_NO_LONGLONG -I/usr/local/include/g++-3 -I../lib -I../include -o sample3 sample3.o -L../lib -L/usr/local/lib -static -lfoo -lbar -lfoo /usr/lib/gcc/x86_64-redhat-linux/4.1.1/libstdc++.a
I'm stupefied. No... I'm numb. I don't even want to say how many hours I've worked on this. I've changed the order, but never thought to include them 2x. It worked. I would be embarrassed if I had anything to do with the GCC linker. Thanks a mill. Linked in no time flat. Unbelievable.

-eriks
You're welcome!
You've got to love that one! :P
Topic archived. No new replies allowed.