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

Fortran调用CGNS库存在对应符号却报未定义引用错误

GCC 13下CGNS库部分符号未定义引用问题

问题背景

将Fortran模块单独编译后链接CGNS库时,部分符号(如cg_nbases_f)明明存在于库中却抛出未定义引用错误。该代码在GCC 4~8版本可正常编译链接,但在GCC 13(搭配MPICH的mpif90编译器)环境下失败。

环境配置

  • Fedora 39
  • GCC 13:通过dnf install gcc gfortran安装
  • MPICH 4.1:通过dnf install mpich-devel安装
  • CGNS 4.4:通过dnf install cgnslib-mpich-devel安装
  • HDF5 1.12.1:通过dnf install hdf5-mpich-devel安装(不确定是否关联)

符号检查

执行以下命令确认cg_nbases_f存在于CGNS库中:

objdump -T $MPI_LIB/libcgns.so | grep cg_nbases_t

输出结果:

00000000000a44b0 g    DF .text  0000000000000055  Base        cg_nbases_f

测试代码

cgnsreading.f90(模块文件)

module cgnsreading
    implicit none

    private

    public talk_to_cgns

contains

    subroutine error_check()
        print *, 'hi I am the bane of arthropods'
    end subroutine error_check

    subroutine talk_To_cgns()
        character(100) :: errmsg
        integer :: i = 1
        integer :: nbases = 1
        integer :: ierr

        call cg_get_error_f(errmsg)
        print *, errmsg ! 应输出无错误信息
        call error_check() ! 应输出指定内容

        call cg_nbases_f(i,nbases,ierr) ! 此处抛出未定义引用错误

    end subroutine talk_To_cgns

end module cgnsreading

cgnsread.f90(主程序文件)

program cgnsread
    use cgnsreading
    implicit none

    call talk_to_cgns()
    
end program cgnsread

编译命令与错误信息

执行以下编译链接步骤:

mpif90 cgnsreading.f90 -c
mpif90 cgnsread.f90 -c
mpif90 cgnsreading.o cgnsread.o -lcgns -o cgnsread

出现错误:

/usr/bin/ld: cgnsreading.o: in function `__cgnsreading_MOD_talk_to_cgns':
cgnsreading.f90:(.text+0x95): undefined reference to `cg_nbases_f_'
collect2: error: ld returned 1 exit status

问题原因

  1. 符号命名不匹配:链接器寻找的是带后缀下划线的符号cg_nbases_f_,但CGNS库中实际存在的是无下划线的cg_nbases_f。
  2. 缺少CGNS接口声明:代码中未引入CGNS的Fortran接口(如use cgns或include 'cgnslib_f.h'),导致GCC 13的Fortran编译器对外部子程序的符号修饰规则与库中实际符号不匹配。旧版GCC(4~8)的隐式声明规则恰好能匹配库中符号,但新版GCC启用了更严格的符号修饰逻辑,导致不匹配。
  3. 部分符号巧合匹配:cg_get_error_f能正常链接,大概率是因为库中同时存在带下划线和不带下划线的该符号,或者旧版隐式声明规则恰好适配,属于巧合。

解决方案

1. 引入CGNS的Fortran接口

修改cgnsreading.f90模块,添加CGNS接口声明:

module cgnsreading
    implicit none

    private

    public talk_to_cgns

    ! 引入CGNS Fortran模块,让编译器知晓正确的符号规则与参数类型
    use cgns

contains

    ! 原有代码不变
    subroutine error_check()
        print *, 'hi I am the bane of arthropods'
    end subroutine error_check

    subroutine talk_To_cgns()
        character(100) :: errmsg
        integer :: i = 1
        integer :: nbases = 1
        integer :: ierr

        call cg_get_error_f(errmsg)
        print *, errmsg
        call error_check()

        call cg_nbases_f(i,nbases,ierr)

    end subroutine talk_To_cgns

end module cgnsreading

如果use cgns无效,可替换为包含CGNS的Fortran头文件:

! 在模块开头添加
include 'cgnslib_f.h'

此时编译时需通过-I参数指定CGNS头文件路径(若系统未自动配置):

mpif90 -I$MPI_INCLUDE cgnsreading.f90 -c

2. 确认链接参数正确性

确保编译时链接的是对应MPICH版本的CGNS库,可通过mpif90 -show查看默认链接参数,确认库路径与库名是否正确。

内容的提问来源于stack exchange,提问作者Mohammed Sayyari

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 08:47:35