I'm in the process of porting an application from Windows to Linux, and one component of my application is a shared library (a DLL on Windows) compiled with Intel Fortran and with heavy use of the BLAS and LAPACK libraries.
When trying to compile the library in Linux, my first preference was to link the MKL libraries to it statically. According to the link line advisor, the required definition for LINKLIBS in my makefile was to be:
$(MKLROOT)/lib/intel64/libmkl_blas95_lp64.a $(MKLROOT)/lib/intel64/libmkl_lapack95_lp64.a -Wl,--start-group $(MKLROOT)/lib/intel64/libmkl_intel_lp64.a $(MKLROOT)/lib/intel64/libmkl_core.a $(MKLROOT)/lib/intel64/libmkl_sequential.a -Wl,--end-group -lpthread -lm
Using this, I obtained the following error message:
ld: /opt/intel/composer_xe_2013_sp1.3.174/mkl/lib/intel64/libmkl_lapack95_lp64.a(dgesdd.o): relocation R_X86_64_32 against `__STRLITPACK_1' can not be used when making a shared object; recompile with -fPIC /opt/intel/composer_xe_2013_sp1.3.174/mkl/lib/intel64/libmkl_lapack95_lp64.a: could not read symbols: Bad value
What this implies is that libkml_lapack95_lp64.a is only intended for being linked to main applications or other static libraries, not to dynamic libraries. I verified this by typing:
readelf --relocs libmkl_lapack95_lp64.a | egrep '(GOT|PLT|JU?MP|SLOT)'
as suggested here and, sure enough, there is no offset table (even though most of the other MKL static libraries do in fact have them).
This is frustrating (I have another C shared library which I link with the static versions of the IPP libraries without any issues) but I can live with it. So, I went back to the MKL link-line advisor to find how to link the MKL dynamically, and the advice is:
"Use this link line:
$(MKLROOT)/lib/intel64/libmkl_blas95_lp64 $(MKLROOT)/lib/intel64/libmkl_lapack95_lp64 -L$(MKLROOT)/lib/intel64 -lmkl_intel_lp64 -lmkl_core -lmkl_sequential -lpthread -lm"
I obeyed this to the letter, and the result is:
ifort: error #10236: File not found: '/opt/intel/composer_xe_2013_sp1.3.174/mkl/lib/intel64/libmkl_blas95_lp64' ifort: error #10236: File not found: '/opt/intel/composer_xe_2013_sp1.3.174/mkl/lib/intel64/libmkl_lapack95_lp64'
Not altogether surprising, because indeed there aren't any files with these names that have either no suffix or a .so suffix. There are just the ".a" ones, and if I add the ".a" at the ends of the filenames in my link line then of course I'm using the same static libraries as before and I get the same relocation error as before. By the way, the same happens if I use the "-lmkl_blas95_lp64" syntax that I've seen documented elsewhere.
So, should I compile my own shared library? It seems that not even this is supported, since if I dig down into /opt/intel/composer_xe_2013_sp1.3.174/mkl/interfaces/blas95 and examine the makefile that is provided for doing a custom build, even that only supports static builds.
So, finally, my question: what should I do? I see three alternatives:
(1) Manually edit the Intel makefiles to recompile libmkl_blas95_lp64.a and libmkl_lapack95_lp64.a with the ifort equivalent to '-fPIC' (if there is one).
(2) Manually edit the Intel makefiles to create ibmkl_blas95_lp64.so and libmkl_lapack95_lp64.so.
(3) Conclude that I'm doing something which, for some reason I can't discern, is unsupported and inadvisable.
Hopefully, there is a fourth alternative which is simpler than any of the above, but I don't know what that may be. I'd very much appreciate some advice.