使用Intel MPI与Intel编译器链接Fortran对象到C编译器时出现未定义引用
跨语言(C+Fortran)Intel MPI编译链接错误解决方案
问题背景
接手一个有10年历史的大型项目,在Ubuntu WSL环境下使用Intel OneAPI 2024.2.1编译器与Intel MPI编译,项目包含C和Fortran模块。两类模块单独编译正常,但用mpiicc链接时,Fortran模块出现大量MPI未定义引用错误,例如:
module_b.o:(.text+0x1838c): undefined reference to "mpi_send_" module_b.o:(.text+0x1838c): undefined reference to "mpi_abort_"
编译/链接命令
C模块编译
mpiicc -g -DUSE_MPI_IO -Dlinux -DUse_Intel_Fortran -MP -D_FILE_OFFSET_BITS=64 -w -DLONG64 -O -L/home/xxx/intel/2024.2.1/oneapi/mpi/latest/lib -D__MPI__ -I/home/xxx/intel/2024.2.1/oneapi/mpi/latest/include -I. -c -o module_a.o module_a.c
Fortran模块编译
mpiifort -g -c -I. -DUse_Intel_Fortran -MP -w -O -D__MPI__ -I/home/xxxx/intel/2024.2.1/oneapi/mpi/latest/include -L/home/xxx/intel/2024.2.1/oneapi/mpi/latest/lib module_b.f90
出错的链接命令
mpiicc -g -v -O -o final.x module_a.o module_b.o -lm -lmpi -L/home/xxx/intel/2024.2.1/oneapi/mpi/latest/lib
问题原因
mpiicc作为C语言编译器驱动,默认仅链接C版本的MPI库(libmpi.so),但Fortran代码生成的目标文件中包含带下划线后缀的Fortran风格MPI符号(如mpi_send_),这些符号需要Intel MPI提供的Fortran专用库才能解析。
解决方法
方法1:使用mpiifort作为链接器(推荐)
跨语言混合编译场景下,用Fortran编译器驱动作为最终链接器,会自动处理Fortran依赖的MPI库,同时兼容C生成的目标文件:
mpiifort -g -v -O -o final.x module_a.o module_b.o -lm -lmpi -L/home/xxx/intel/2024.2.1/oneapi/mpi/latest/lib
方法2:手动添加Fortran MPI库(需保留mpiicc链接)
如果必须使用mpiicc链接,需显式添加Intel MPI的Fortran专用库,链接参数中依次添加以下库(注意顺序):
mpiicc -g -v -O -o final.x module_a.o module_b.o -lm -lmpi -lmpi_mpifh -lmpi_usempi_ignore_tkr -lmpi_usempif08 -L/home/xxx/intel/2024.2.1/oneapi/mpi/latest/lib
libmpi_mpifh.so:对应传统include 'mpif.h'风格的Fortran MPI调用libmpi_usempi_ignore_tkr.so/libmpi_usempif08.so:对应use mpi/use mpi_f08模块风格的调用
额外提示
- 确保已正确加载Intel OneAPI环境变量:执行
source /home/xxx/intel/2024.2.1/oneapi/setvars.sh后再编译,避免手动指定路径出错。 - 用
nm module_b.o | grep mpi查看目标文件中的MPI符号,确认符号风格,对应选择所需库。 - 对于老项目,优先检查Fortran代码中MPI的引用方式,匹配对应的库文件。
内容的提问来源于stack exchange,提问作者yoc
相关产品推荐
相关产品推荐

