1

我在 gcc ( -llapacke -llapack -lcblas) 中包含了几个库,并且我收到“未定义的引用”错误,除非我明确链接到其中一个库的静态版本 ( lapacke)。我试图通过使用nm和搜索有问题的库的各种变体来理解原因readelf。让我们来看看“未定义”的功能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_

为什么它只编译静态版本?

4

1 回答 1

2

该符号zsysv_rook_不是由任何一个库定义的,因此库中的某些内容会引用它。

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

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

所以如果你想使用动态库,你需要弄清楚哪个库定义zsysv_rook_并链接到它。它可能是其他 LAPACK 库之一,可能是您已经链接到的库之一,但您可能将-l选项放在链接命令中的错误位置 -zsysv_rook_需要提供的库-llapacke才能解决对它的引用。

于 2014-08-14T23:52:40.160 回答