Ошибка компоновки Lapack, перекомпилируйте с -fPIC

У меня есть сложная программа для подгонки нелинейных функций по методу Левенберга-Марквардта.

В программе используется решатель системы линейных уравнений из библиотеки Lapack, где я использовал:

extern "C" ...

Для связи с внешними библиотеками fortran. Программа работала на моем ноутбуке без проблем (который использует Ubuntu 12.04), и я уже некоторое время использую ее для тестов.

Проблема:

Теперь я перешел на большой жирный 64-ядерный компьютер, чтобы начать делать некоторые настоящие расчеты, на нем стоит научный Linux 6. Выяснилось, что на большом компьютере не установлен lapack, поэтому я взял lapack 3.4.2, скомпилировал его и, следуя инструкциям отсюда, собрал:

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

После этого я абсолютно ничего не изменил в своем файле cmake, который работал раньше, а просто добавил параметр связывания:

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

Теперь я получаю сообщение об ошибке:

/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

И просто для записи, мой скрипт cmake везде имеет -fPIC и -fPIE... Связку, которую я использую:

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)

Что я сделал не так? Пожалуйста, порекомендуйте.

Спасибо.


person The Quantum Physicist    schedule 16.09.2013    source источник


Ответы (2)


Решение состояло в том, чтобы перекомпилировать сам lapack с параметром -fPIC. Итак, в вашем make.inc измените на следующее:

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

И вы также можете использовать -O3 для лучшей оптимизации, он отлично работает!

Параметр -m64 зависит от того, хотите ли вы использовать 64-битную систему. Твой выбор!

Ваше здоровье!

person The Quantum Physicist    schedule 17.09.2013

Если используется маршрут mkdir build; cd build; cmake ..; make, используйте cmake .. -DBUILD_SHARED_LIBS=ON.

Почему это сработает? Опция -fPIC заставляет gcc использовать относительные адреса. один и тот же адрес в обоих. Если бы код не был независимым от позиции, то каждому процессу потребовалась бы собственная копия "- Саймон Рихтер
[1] Опция GCC -fPIC

person user2966394    schedule 05.06.2019