我包含了几个带有gcc(-llapacke -llapack -lcblas
)的图书馆,我接收了"未定义的参考"错误除非我明确链接到其中一个的静态版本(lapacke
)。我试图通过使用nm
和readelf
搜索有问题的库的各种变体来理解原因。让我们来看看" 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_
为什么只使用静态版本进行编译?
答案 0 :(得分:2)
符号zsysv_rook_
未由任何库定义,因此库中的某些内容引用它。
静态库基本上是目标文件的存档,链接器会查看存档并链接到解析程序中未定义引用的每个对象。如果存在定义程序不需要的符号的对象,则不会链接这些对象。我假设发生的事情是引用zsysv_rook_
的对象没有定义您需要的任何符号,因此该对象没有链接到,并且您的程序不需要解析zsysv_rook_
符号。
当您链接到动态库时(默认情况下),您需要解析库中任何内容所需的所有未定义引用,因为库的某些部分引用zsysv_rook_
,您需要链接到提供的任何内容它
因此,如果您想使用动态库,您需要确定哪个库定义zsysv_rook_
并链接到它。它可能是其他LAPACK库中的一个,可能是您已经链接到的库,但您可能会将-l
选项放在link命令中的错误位置 - 提供{{的库1}}需要在zsysv_rook_
之后才能解析对它的引用。