I'm including several libraries with gcc (-llapacke -llapack -lcblas
) and I'm receiving "undefined reference" errors unless I explicitly link to the static version of one them (lapacke
). I'm trying to understand why by searching the various variants of the offending library with nm
and readelf
. Let's take the "undefined" function 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
That's the dynamic variant. This is the static variant:
% 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_
Why does it compile only with the static version?
The symbol zsysv_rook_
is not defined by either library, so something in the library references it.
A static library is basically an archive of object files and the linker looks into the archive and links to each object that resolves an undefined reference in your program. If there are objects that define symbols that your program doesn't need, those objects will not be linked to. I assume what is happening is that the object that references zsysv_rook_
doesn't define any symbols you need, so that object isn't linked to, and your program doesn't need to resolve the zsysv_rook_
symbol.
When you link to a dynamic library (by default) you need to resolve all the undefined references needed by anything in the library, so because some part of the library refers to zsysv_rook_
you need to link to whatever provides it.
So if you want to use the dynamic library you need to figure out which library defines zsysv_rook_
and link to it. It's probably one of the other LAPACK libs, maybe one you're already linking to but you might be putting the -l
option in the wrong place in the link command - the library that provides zsysv_rook_
needs to come after -llapacke
in order to resolve the reference to it.