web-dev-qa-db-ja.com

nmがこのシンボルが共有ライブラリに存在することを示している場合でも、シンボルへの未定義の参照

ここで何が間違っている可能性がありますか?私は次の簡単なクラスを持っています:

#include  "libmnl/libmnl.h"

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

そして、単純なgccコンパイル(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

共有ライブラリでnmを実行すると、実際に見つかったことがわかります。

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

これはUbuntu12.04で発生しています。 libmnl-devおよびlibmnlパッケージがインストールされます。 stracegcc出力は、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
28
user389238

ライブラリは、それらを使用するオブジェクトの後にリストする必要があります(より正確には、ライブラリは、検出時に既知の未定義の参照を満たすシンボルが含まれている場合にのみ使用されます)。 -lmnlをコマンドの最後に移動します。

40
geekosaur