Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 375
The Quantum Physicist Avatar asked Sep 16 '13 13:09

The Quantum Physicist


2 Answers

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!

like image 161
The Quantum Physicist Avatar answered Oct 19 '22 03:10

The Quantum Physicist


If the mkdir build; cd build; cmake ..; make route is used, use cmake .. -DBUILD_SHARED_LIBS=ON.

Why would this work? The -fPIC option makes gcc use relative addresses [1]
Comment on accepted answer: "To be more specific, the shared library is supposed to be shared between processes, but it may not always be possible to load the library at the same address in both. If the code were not position independent, then each process would require its own copy" - Simon Richter
[1] GCC -fPIC option

like image 35
user2966394 Avatar answered Oct 19 '22 05:10

user2966394