ELF: linking: Why do I get undefined references in .so files
I'm trying to build a program against wxWidgets, and I get a linker error. I'd like to really understand what it means. The error is:
/usr/lib/libwx_baseu-2.8.so:开发者_运维知识库 undefined reference to `std::ctype<char>::_M_widen_init() const@GLIBCXX_3.4.11'
What I don't understand is why the error is at libwx_baseu-2.8.so
. I thought that .so
files had all its symbols resolved, contrary to .o
files that still need linking.
When I ldd
the .so
, I get can resolve all its linked libraries, so there is no problem there:
$ ldd /usr/lib/libwx_baseu-2.8.so
linux-gate.so.1 => (0x00476000)
libz.so.1 => /lib/libz.so.1 (0x00d9c000)
libdl.so.2 => /lib/libdl.so.2 (0x002a8000)
libm.so.6 => /lib/libm.so.6 (0x00759000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x002ad000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x0068d000)
libpthread.so.0 => /lib/libpthread.so.0 (0x006f0000)
libc.so.6 => /lib/libc.so.6 (0x00477000)
/lib/ld-linux.so.2 (0x007f6000)
Does it means that the .so
file was not compiled correctly (in that case, it's a bug in my distribution package) or does it means that there are missing libraries on the linker command line for my particular program?
Additionally, do you know how I can get a list on undefined symbols in an ELF file. I tried readelf -s
but I can't find the missing symbol.
Thank you.
Mildred
I thought that .so files had all its symbols resolved, contrary to .o files that still need linking.
Shared libraries can be incomplete, that is OK.
do you know how I can get a list on undefined symbols in an ELF file
Use
nm -C -u libwx_baseu-2.8.so
I think you don't link to some of the libraries when linking your program.
You should link in your program to all shared libraries you link to in your .so
If the .so is linked to some static libraries - it's not required in the program to link to them if all needed symbols are found in the .so
You may use nm
linux command to see the symbols in object file, library or binary
Edit
Your particular problem can be described here: http://old.nabble.com/-Bug-49433--gcc4.4,-NEW:-gcc4.4-misses-std::endl-implementation-at--O2%2B-td22836171.html
When you link a shared library against other shared libraries (e.g. link libwx_baseu-2.8.so
against libstdc++.so
), the linker records versioned symbols used by libwx_baseu
and provided by libstdc++
.
If at runtime you use a different copy of libstdc++
(one which doesn't provide the same versioned symbol(s)), you get a (dynamic) liking error and the program doesn't run at all (this is preferable to a "mystery" crash later on).
But what's happening here is that you try to link an executable, which means the (static) linker wants to find all symbols which will be required at runtime. Again, you are linking the executable against a different (older) libstdc++.so
, and so the linking fails.
There are two usual root causes:
- either you linked libwx_baseu-2.8.so
on a different system (one with newer version of GCC), and copied it to the current system, or
- you've linked libwx_baseu-2.8.so
with a newer GCC on the same system, but now are trying to link the executable with an older GCC.
Try : putting -fno-inline in your flags in Makefile. Basically g++4.4 is having issues without it. Try to put it OR remove the -O option. It solved the same problem I had.
精彩评论