Linux 即使 nm 指示此符号存在于共享库中,也未定义对符号的引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10456581/
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-06 06:10:34  来源:igfitidea点击:

undefined reference to symbol even when nm indicates that this symbol is present in the shared library

linuxgcclinkershared-libraries

提问by user389238

What could be wrong here? I have the following simple class:

这里可能有什么问题?我有以下简单的类:

#include  "libmnl/libmnl.h"

int main() {
    struct mnl_socket *a = mnl_socket_open(12);
}

And after running a simple gcccompile (gcc -lmnl main.c) I get the following errors:

在运行一个简单的gcccompile ( gcc -lmnl main.c) 后,我收到以下错误:

/tmp/cch3GjuS.o: In function `main':
main.c:(.text+0xe): undefined reference to `mnl_socket_open'
collect2: ld returned 1 exit status

Running nm on the shared library shows that it's actually found:

在共享库上运行 nm 显示它确实找到了:

aatteka@aatteka-Dell1:/tmp$ nm -D /usr/lib/libmnl.so | grep mnl_socket_open
0000000000001810 T mnl_socket_open

This is happening on Ubuntu 12.04. The libmnl-devand libmnl0packages are installed. The straceoutput of gccindicates that ldis using exactly that *.so file:

这发生在 Ubuntu 12.04 上。该libmnl-dev的libmnl0包安装。的strace输出gcc表明ld正在使用该 *.so 文件:

[pid 10988] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/libmnl.so", 0x7fff2a39b470) = -1 ENOENT (No such file or directory)
[pid 10988] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/libmnl.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 10988] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/libmnl.a", 0x7fff2a39b4d0) = -1 ENOENT (No such file or directory)
[pid 10988] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/libmnl.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 10988] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libmnl.so", 0x7fff2a39b470) = -1 ENOENT (No such file or directory)
[pid 10988] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libmnl.so", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 10988] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libmnl.a", 0x7fff2a39b4d0) = -1 ENOENT (No such file or directory)
[pid 10988] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../x86_64-linux-gnu/libmnl.a", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 10988] stat("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libmnl.so", {st_mode=S_IFREG|0644, st_size=18608, ...}) = 0
[pid 10988] open("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libmnl.so", O_RDONLY) = 7

采纳答案by geekosaur

Libraries must be listed after the objects that use them (more precisely, a library will be used only if it contains a symbol that satisfies an undefined reference known at the time it is encountered). Move the -lmnlto the end of the command.

库必须在使用它们的对象之后列出(更准确地说,只有当库包含满足在遇到时已知的未定义引用的符号时才会使用库)。将 移动-lmnl到命令的末尾。