Compile a portable executable with lapack

The following sample program calls DGEEV from lapack:

       program main
       Implicit None
       external :: DGEEV       
       Real :: VL(4,4),VR(4,4),WORK(4),eigenvalues_R(4),eigenvalues_I(4),companion_matrix(4,4)
       Integer (kind=4) :: LWORK,INFO,Var               
       companion_matrix(4,4)=1.D0
       LWORK=-1
       call DGEEV( 'N', 'N', 4, companion_matrix, 4, eigenvalues_R, eigenvalues_I, VL, 4, &
     &           VR, 4, WORK, LWORK, INFO )
       print*,"DGEEV called",LWORK
       end

ifort -o test.exe main.f90 /lib64/liblapack.so.3
compiles it fine, but test.exe is not portable to a computer that does not have lapack installed. I tried:
ifort -static -o test.exe main.f90 /lib64/liblapack.so.3
ld: attempted static link of dynamic object `/lib64/liblapack.so.3’
and with (/usr/lib64/liblapack_pic.a has the correct rights)
ifort -static -o test.exe main.f90 /usr/lib64/liblapack_pic.a
ld: cannot find -lm
ld: cannot find -lpthread
ld: cannot find -lc
ld: cannot find -ldl
ld: cannot find -lc
What am I doing wrong?

Either ship liblapack.so with your program or link against the static library liblapack.a instead.

Also, make sure the linker can find the other shared libraries by passing the library search path through command-line argument -L.

To compile try this:

ifort -o test.exe main.f90 -L/usr/lib64 -llapack

where /usr/lib64 contains the liblapack.so.

For shipping, you can compile the lapack library in the current directory containing the main.f90 or any other location in the shipped directory.

With ifort -static -o test.exe main.f90 /usr/lib64/liblapack_pic.a you are trying to statically link all libraries into your executable. That includes the system’s C library, most likely GLIBC on a GNU-derived system. Linking GLIBC statically has many issues (c++ - Why is statically linking glibc discouraged? - Stack Overflow), but foremost, you need to install the static version of the libraries in question. That means libm, libpthread, libc. For my distribution, they are in the glibc-devel-static repository package.

I am not actually sure to what extent an ifort-compiled code needs those libraries and to what extent the need only comes from the liblapack library. You may also try linking with MKL instead.

E.g.,

ifort -static main.f90  -Wl,--start-group ${MKLROOT}/lib/intel64/libmkl_intel_lp64.a ${MKLROOT}/lib/intel64/libmkl_sequential.a ${MKLROOT}/lib/intel64/libmkl_core.a -Wl,--end-group -lpthread -lm -ldl
/usr/lib64/gcc/x86_64-suse-linux/7/../../../../x86_64-suse-linux/bin/ld: /data-disk2/opt/intel/oneapi/mkl/2023.0.0/lib/intel64/libmkl_core.a(mkl_memory_patched.o): in function `mkl_serv_set_memory_limit':
mkl_memory.c:(.text+0x5d1): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

and run

> ./a.out 
 DGEEV called          -1

You have to observe the limitations given by that warning about the necessary GLIBC version.

After I installed the static versions of liblapack and libblas for my distribution, I can also try to link with the distribution LAPACK. But be careful, they were compiled for gfortran and yours may be as well. I can manage to link the code using

ifort -static main.f90  -llapack -lblas -lgfortran -lquadmath

but the executable will just crash

./a.out 
 DGEEV called          -1
forrtl: severe (174): SIGSEGV, segmentation fault occurred

Stack trace terminated abnormally.

This can be done with: ifort -qmkl -static main.f90

There are also options -static-intel and -static-libgcc for the base runtime libraries.

Yes, that is a shorthand for the basic options, thanks. For more involved cases one should follow the Link Line Advisor Link Line Advisor for Intel® oneAPI Math Kernel Library

1 Like