Search code examples
c++linkermakefilecmakelapack

Lapack linking error, recompile with -fPIC


I have a sophisticated program for fitting nonlinear functions with the Levenberg-Marquardt's method.

The program uses a solver for a system of linear Equations from the Lapack library, where I have used:

extern "C" ...

To link to external fortran libraries. The program worked on my laptop with no problems (which uses Ubuntu 12.04), and I've been using it for tests for a while.

The problem:

Now I moved to the big fat 64-core computer in order to start doing some real calculations, the computer has a scientific linux 6 on it. It turned out that the big computer doesn't have lapack installed, so I got lapack 3.4.2, compiled it, and followed the instructions from here to build it:

http://matrixprogramming.com/2011/04/using-lapack-from-c/comment-page-1

After that, I changed absolutely nothing in my cmake file which worked before, and just added the linking option:

-L/xdata/Compilers/Sources/lapack-3.4.2

Now I get the error:

/usr/bin/ld: /xdata/Compilers/Sources/lapack-3.4.2/liblapack.a(dsytrf.o): relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC

And just for the record, my cmake script is has -fPIC and -fPIE everywhere... The linking I use it:

target_link_libraries(LibsModule -lgsl)
target_link_libraries(LibsModule -lgslcblas)
target_link_libraries(LibsModule -lrt)
target_link_libraries(LibsModule -lpthread)
target_link_libraries(LibsModule -pie)
target_link_libraries(LibsModule -fPIC)
target_link_libraries(LibsModule -L/xdata/Compilers/Sources/lapack-3.4.2)
target_link_libraries(LibsModule -lgfortran)
target_link_libraries(LibsModule -llapack -fPIC)
target_link_libraries(LibsModule -lblas -fPIC)

What did I do wrong? Please advise.

Thank you.


Solution

  • The solution was to recompile lapack itself with -fPIC. So in your make.inc change to the following:

    FORTRAN  = gfortran -m64 -fPIC
    OPTS     = -O2 -m64 -fPIC
    DRVOPTS  = $(OPTS)
    NOOPT    = -O0 -m64 -fPIC
    LOADER   = gfortran -m64 -fPIC
    

    And you may also use -O3 for better optimization, it works fine!

    The option -m64 depends whether you wanna use a 64-bit system. Your choice!

    Cheers!