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

gfortran编译错误:_gfortran_set_options等符号多重定义问题

解决gfortran 8.1.0 + CMake拆分exe与DLL时的符号多重定义问题

问题根源

gfortran 8.1.0默认会将Fortran运行时库静态链接到每个编译目标(exe和dll),导致_gfortran_set_options这类运行时符号在两个目标中都被重复定义,链接阶段触发冲突错误。

解决方案

1. 强制使用动态链接的Fortran运行时库

给gfortran添加-shared-libgfortran编译选项,让exe和DLL共享同一个动态版本的运行时库,避免静态库符号重复嵌入。

2. 调整CMake配置

确保DLL正确导出符号,同时让主程序能找到DLL的模块文件。以下是完整的CMake配置示例:

cmake_minimum_required(VERSION 3.10)
project(FortranDLLDemo Fortran)

# 全局设置gfortran使用动态运行时库
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -shared-libgfortran")

# 编译DLL目标
add_library(mydll SHARED src/dll_source.f90)
# 指定模块输出目录,主程序需引用此目录找到模块
set_target_properties(mydll PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/modules)

# 编译主程序
add_executable(main_exe src/main_source.f90)
# 链接DLL库
target_link_libraries(main_exe PRIVATE mydll)
# 让主程序能找到DLL导出的模块
target_include_directories(main_exe PRIVATE ${CMAKE_BINARY_DIR}/modules)

3. 修正DLL与主程序源码

  • DLL源码(dll_source.f90):明确导出需要被主程序调用的符号
module mydll_mod
    implicit none
    ! 使用gfortran的属性标记导出子程序
    !GCC$ ATTRIBUTES DLLEXPORT :: hello_from_dll
contains
    subroutine hello_from_dll()
        print *, "Hello from DLL!"
    end subroutine hello_from_dll
end module mydll_mod
  • 主程序源码(main_source.f90):正常引用DLL的模块即可
program main
    use mydll_mod
    implicit none
    call hello_from_dll()
    print *, "Main program running!"
end program main

错误日志解释

编译日志中出现的_gfortran_set_options等符号多重定义,本质是静态链接的运行时库在exe和DLL中都包含了相同的符号实现,导致链接器判定符号重复。启用-shared-libgfortran后,两个目标都会动态链接到系统的libgfortran动态库,从根本上避免符号重复问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:07:01