背景:我遇到的情况是我必须在新的C ++项目中使用旧的Fortran95库。 F95库非常广泛,有大量的小模块,文档记录很少,而且大多数十年前由一些不起眼的计算机代数系统(由不同大陆的人)自动生成。所以基本上是传家宝代码,但它有效并且它目前是不可替代的。
幸运的是我有源代码,它可以使用当前版本的ifort进行编译,但我对Fortran不太熟悉,并且宁愿不以任何重要方式触及旧代码。
假设我有这个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(...)引入Fortran库的深海深度,它们包含在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_'