You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 08:30:49