了解为什么gcc / ld使用readelf链接特定库中的符号

时间:2014-08-14 23:20:19

标签: gcc linker static-libraries dynamic-library readelf

我包含了几个带有gcc(-llapacke -llapack -lcblas)的图书馆,我接收了"未定义的参考"错误除非我明确链接到其中一个的静态版本(lapacke)。我试图通过使用nmreadelf搜索有问题的库的各种变体来理解原因。让我们来看看" undefined"函数zsysv_rook_

% readelf -Wa /usr/lib/liblapacke.so | grep zsysv_rook_

00000000003c3978  000008d600000007 R_X86_64_JUMP_SLOT     000000000016e340 LAPACKE_zsysv_rook_work + 0
00000000003c5f20  000003c300000007 R_X86_64_JUMP_SLOT     0000000000000000 zsysv_rook_ + 0
   963: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND zsysv_rook_
  2262: 000000000016e340   884 FUNC    GLOBAL DEFAULT   11 LAPACKE_zsysv_rook_work

这是动态变体。这是静态变体:

% readelf -Wa /usr/lib/liblapacke.a | grep zsysv_rook_
00000000000000b2  0000000d00000004 R_X86_64_PLT32         0000000000000000 LAPACKE_zsysv_rook_work - 4
0000000000000146  0000000d00000004 R_X86_64_PLT32         0000000000000000 LAPACKE_zsysv_rook_work - 4
    13: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND LAPACKE_zsysv_rook_work
File: /usr/lib/liblapacke.a(lapacke_zsysv_rook_work.o)
0000000000000186  0000000f00000004 R_X86_64_PLT32         0000000000000000 zsysv_rook_ - 4
0000000000000264  0000000f00000004 R_X86_64_PLT32         0000000000000000 zsysv_rook_ - 4
     9: 0000000000000000   884 FUNC    GLOBAL DEFAULT    1 LAPACKE_zsysv_rook_work
    15: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND zsysv_rook_

为什么只使用静态版本进行编译?

1 个答案:

答案 0 :(得分:2)

符号zsysv_rook_未由任何库定义,因此库中的某些内容引用它。

静态库基本上是目标文件的存档,链接器会查看存档并链接到解析程序中未定义引用的每个对象。如果存在定义程序不需要的符号的对象,则不会链接这些对象。我假设发生的事情是引用zsysv_rook_的对象没有定义您需要的任何符号,因此该对象没有链接到,并且您的程序不需要解析zsysv_rook_符号。

当您链接到动态库时(默认情况下),您需要解析库中任何内容所需的所有未定义引用,因为库的某些部分引用zsysv_rook_,您需要链接到提供的任何内容它

因此,如果您想使用动态库,您需要确定哪个库定义zsysv_rook_并链接到它。它可能是其他LAPACK库中的一个,可能是您已经链接到的库,但您可能会将-l选项放在link命令中的错误位置 - 提供{{的库1}}需要在zsysv_rook_之后才能解析对它的引用。