使用PGI Fortran子程序编译C++程序时遇链接错误求助
解决Fortran与C++耦合编译时的链接错误及LAPACK/BLAS查找问题
问题分析
当前遇到的链接错误包含两类未定义引用:
- PGI编译器的CUDA运行时函数(如
__pgi_dev_cublasddot_hhpm、cusparseSetMatFillMode):说明原Fortran代码使用了PGI的GPU加速特性,单独编译时mpif90会自动链接相关CUDA库,但CMake未配置。 - LAPACK/BLAS函数(如
dgeqrf_):CMake无法找到系统中的LAPACK库,但mpif90能编译成功,说明MPI编译器套件自带了优化的BLAS/LAPACK,无需依赖系统库。
解决方案
1. 跳过CMake自带的BLAS/LAPACK查找,直接使用编译器自带库
因为单独编译Fortran代码成功,说明编译器已经内置了所需的BLAS/LAPACK,无需通过find_package查找。替换原有查找代码为:
# 直接指定编译器自带的BLAS/LAPACK库 set(BLAS_LIBRARIES "-lblas") set(LAPACK_LIBRARIES "-llapack") # 如果是PGI编译器,额外添加CUDA相关依赖库 if(CMAKE_Fortran_COMPILER_ID MATCHES "PGI") set(PGI_GPU_LIBS "-lcublas -lcusparse -lpgiomp -lnvToolsExt") endif()
2. 调整链接顺序并添加Fortran运行时库
CMake的链接顺序严格遵循依赖者在前,被依赖者在后,同时C++主程序需要链接Fortran运行时库才能调用Fortran子程序:
target_link_libraries( <c++ program name> # C++主程序作为最终目标,放在最前面 <fortran program name> # Fortran模块/库,依赖的目标放在后面 ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES} ${PGI_GPU_LIBS} ${CMAKE_Fortran_IMPLICIT_LINK_LIBRARIES} # 自动引入Fortran运行时库 )
3. 确保编译器一致性
在CMake配置开头明确指定使用MPI套件的编译器,避免混合不同版本的编译工具链:
# 必须在project命令前设置编译器 set(CMAKE_C_COMPILER mpicc) set(CMAKE_CXX_COMPILER mpic++) set(CMAKE_Fortran_COMPILER mpif90) project(YourCoupledProject)
4. 手动提取mpif90的链接参数(备选方案)
如果以上方法仍有问题,先通过mpif90的 verbose 输出查看实际链接的库:
mpif90 your_fortran_source.f90 -o test -v
从输出中找到所有-l开头的库(如-llapack -lblas -lcublas等),直接复制到CMake的target_link_libraries中。
内容的提问来源于stack exchange,提问作者KSJ
相关产品推荐
相关产品推荐

