C++ ELF:链接:为什么我在 .so 文件中得到未定义的引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2643738/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:11:50  来源:igfitidea点击:

ELF: linking: Why do I get undefined references in .so files

c++linkershared-librariessymbolself

提问by Mildred

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:

我正在尝试针对 wxWidgets 构建程序,但出现链接器错误。我想真正理解这意味着什么。错误是:

/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 .sofiles had all its symbols resolved, contrary to .ofiles that still need linking.

我不明白的是为什么错误在libwx_baseu-2.8.so. 我认为.so文件的所有符号都已解析,这与.o仍需要链接的文件相反。

When I lddthe .so, I get can resolve all its linked libraries, so there is no problem there:

当我ldd.so,我得到能够解决所有的链接库,所以有没有问题:

$ 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 .sofile 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?

这是否意味着.so文件没有正确编译(在这种情况下,它是我的分发包中的一个错误)还是意味着我的特定程序的链接器命令行上缺少库?

Additionally, do you know how I can get a list on undefined symbols in an ELF file. I tried readelf -sbut I can't find the missing symbol.

此外,您知道我如何获得 ELF 文件中未定义符号的列表。我试过了,readelf -s但找不到丢失的符号。

Thank you.

谢谢你。

Mildred

米尔德里德

回答by Mildred

I thought that .so files had all its symbols resolved, contrary to .o files that still need linking.

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

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

nm -C -u libwx_baseu-2.8.so

回答by Employed Russian

When you link a shared library against other shared libraries (e.g. link libwx_baseu-2.8.soagainst libstdc++.so), the linker records versioned symbols used by libwx_baseuand provided by libstdc++.

当您将共享库链接到其他共享库(例如链接libwx_baseu-2.8.solibstdc++.so)时,链接器会记录 使用libwx_baseu和提供的版本化符号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).

如果在运行时您使用不同的副本libstdc++(一个不提供相同版本符号的副本),您会得到一个(动态)喜欢错误并且程序根本不运行(这比“神秘“稍后崩溃)。

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.

但是这里发生的事情是您尝试链接一个可执行文件,这意味着(静态)链接器想要找到运行时需要的所有符号。同样,您将可执行文件链接到不同的(较旧的)libstdc++.so,因此链接失败。

There are two usual root causes:
- either you linked libwx_baseu-2.8.soon a different system (one with newer version of GCC), and copied it to the current system, or
- you've linked libwx_baseu-2.8.sowith a newer GCC on the same system, but now are trying to link the executable with an older GCC.

有两个常见的根本原因:
- 您链接libwx_baseu-2.8.so到不同的系统(一个具有较新版本的 GCC),并将其复制到当前系统,或者
- 您已链接libwx_baseu-2.8.so到同一系统上的较新 GCC,但现在是尝试将可执行文件与较旧的 GCC 链接。

回答by Dmitry Yudakov

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

您应该在您的程序中链接到您在 .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

如果 .so 链接到某些静态库 - 如果在 .so 中找到所有需要的符号,则程序中不需要链接到它们

You may use nmlinux command to see the symbols in object file, library or binary

您可以使用nmlinux 命令查看目标文件、库或二进制文件中的符号

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

编辑
您的特定问题可以在这里描述:http: //old.nabble.com/-Bug-49433--gcc4.4,-NEW: -gcc4.4-misses-std:: endl-implementation-at--O2 %2B-td22836171.html

回答by siddhusingh

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.

尝试:将 -fno-inline 放在 Makefile 的标志中。基本上 g++4.4 没有它就会有问题。尝试放置它或删除 -O 选项。它解决了我遇到的同样问题。