Фон: Я нахожусь в ситуации, когда мне приходится использовать старую библиотеку Fortran95 в новом проекте C ++. Библиотека F95 обширна, имеет множество небольших модулей, плохо документирована, и она была в основном автоматически сгенерирована около десяти лет назад какой-то непонятной системой компьютерной алгебры (людьми на другом континенте). Так что в основном код семейной реликвии, но он работает, и в настоящее время он незаменим.
К счастью, у меня есть исходный код, и он может быть скомпилирован с текущими версиями ifort, но я не слишком знаком с Fortran и предпочел бы не трогать старый код каким-либо существенным образом.
Предположим, у меня есть этот код на Фортране (pes_shell.f90):
subroutine pes_init()
use pes,wp=>pes_wp
implicit none
real,parameter::auang=0.5291772083
call pes0_init (dir='coef')
call pes1_init (pes_x3y1z1u1_sysall)
return
end subroutine pes_init
Функции pes0_init (…) и pes1_init (…) ведут в бездонные глубины библиотеки Фортрана и содержатся в модуле pes.
Я могу скомпилировать это в объектный файл, если я дам ifort путь для модулей:
ifort -r8 -O2 -c pes_shell.f90 -I/home/debianuser/PES/PES_library/lib/mod
Мой код POC C ++, вызывающий pes_init ():
extern "C"{
void pes_init_();
}
int main(){
pes_init_();
return 0;
}
Это также можно скомпилировать в объектный файл с помощью icpc:
icpc -c PEStest.cpp
Однако я не могу понять, как связать два объектных файла, а также загруженный модуль fortran, в конечный исполняемый файл.
Я попытался просто использовать icpc, но он не может найти функции Fortran, даже если я указываю расположение файлов модуля:
icpc -I/home/debianuser/PES/PES_library/lib/mod -o test.x pes_shell.o PEStest.o
pes_shell.o: In function `pes_shell_mp_f_':
pes_shell.f90:(.text+0x595): undefined reference to `pes_x3y1z1u1_mp_pes_x3y1z1u1_pot_'
pes_shell.o: In function `pes_shell_mp_pes_init_':
pes_shell.f90:(.text+0x5f0): undefined reference to `pes0_mp_pes0_init_'
pes_shell.f90:(.text+0x603): undefined reference to `pes1c_mp_pes1_init_'
PEStest.o: In function `main':
PEStest.cpp:(.text+0x2b): undefined reference to `pes_init_'
РЕДАКТИРОВАТЬ:
Указание компоновщика на каталог, в котором находится libpes.a, устраняет проблему с поиском функции, на которую есть ссылка в коде c ++, но icpc все еще не может найти функции fortran, которые вызываются из кодов fortran:
icpc -I/home/debianuser/PES/PES_library/lib/mod -L/home/debianuser/PES/PES_library/lib/pes-xyz -lpes -o test.x PEStest.o pes_shell_new.o
pes_shell_new.o: In function `f_':
pes_shell_new.f90:(.text+0x585): undefined reference to `pes_x3y1z1u1_mp_pes_x3y1z1u1_pot_'
pes_shell_new.o: In function `pes_init_':
pes_shell_new.f90:(.text+0x5e0): undefined reference to `pes0_mp_pes0_init_'
pes_shell_new.f90:(.text+0x5f3): undefined reference to `pes1c_mp_pes1_init_'
Задача ещё не решена.
Других решений пока нет …