命令行正常运行的Fortran可执行文件通过Python脚本调用报错排查
问题现象
- 通过Python脚本调用Fortran编译生成的可执行文件
genex时,直接在命令行运行该可执行文件无异常,但在Spyder中运行对应调用脚本时,提示无法找到指定依赖文件。 - 调用所用代码如下:
process = subprocess.Popen(["./genex"])
- 运行后抛出的错误信息:
dyld: Library not loaded: @rpath/libgfortran.3.dylib Referenced from: /Users/Austin/tycho-1-14/run/./genex Reason: image not found
- 已验证的临时规避方式:不在Spyder环境内触发运行,直接在命令行执行对应Python脚本可绕过该报错。
问题原因
这是macOS下典型的环境变量不一致导致的动态库加载失败:从Launchpad/应用图标直接启动的Spyder,不会加载终端shell中配置的DYLD_LIBRARY_PATH动态库搜索路径,subprocess拉起genex进程时,动态链接器顺着@rpath找不到libgfortran.3.dylib文件就会报错。而直接在终端运行Python脚本时,进程会完整继承终端里配置好的gfortran库搜索路径,所以可以正常加载依赖。
解决方法
- 临时方案:直接在系统终端执行调用
genex的Python脚本,不通过Spyder内置运行器触发执行。 - 永久修复方案(三选一即可):
- 从终端启动Spyder:打开系统终端,激活当前使用的Python环境后直接输入
spyder回车启动,不要点击应用图标启动,这样Spyder会完整继承终端的环境变量配置,动态库搜索路径可正常生效。 - 在Python代码中手动注入环境变量:调用subprocess时把gfortran的库路径加到动态库搜索变量中,参考代码如下:
import os import subprocess # 替换为你本机libgfortran.3.dylib实际所在目录 # 官方gfortran安装包默认路径为/usr/local/gfortran/lib # Homebrew安装的gfortran路径一般为/usr/local/opt/gcc/lib/gcc/<gcc主版本号>(Intel芯片) # 或/opt/homebrew/opt/gcc/lib/gcc/<gcc主版本号>(Apple Silicon芯片) # 可在终端执行find / -name "libgfortran.3.dylib"查询具体路径 gfortran_lib_dir = "/usr/local/gfortran/lib" current_env = os.environ.copy() current_env["DYLD_LIBRARY_PATH"] = f"{gfortran_lib_dir}:{current_env.get('DYLD_LIBRARY_PATH', '')}" process = subprocess.Popen(["./genex"], env=current_env) - 编译Fortran程序时固化rpath:重新编译
genex时,给链接器加参数指定gfortran库的绝对路径,比如在编译参数中追加-Wl,-rpath,/你的gfortran库实际路径,编译出的可执行文件会自带依赖库搜索路径,不依赖外部环境变量配置,任何场景下启动都能正常找到依赖。
- 从终端启动Spyder:打开系统终端,激活当前使用的Python环境后直接输入
内容的提问来源于stack exchange,提问作者Austin Ware
相关产品推荐
相关产品推荐

