使用VS Code编写Fortran程序时,一直不太会使用调试功能,都是在各个位置使用print
打印结果。为了提高工作效率,研究了下如何配置Fortran调试环境,为此看了不少博客,在这里做下笔记和总结。
注:最初是为了M1芯片Mac配置Fortran调试环境写的这篇博客,但M1芯片不支持
gdb
,而lldb
作为调试工具无法正常查看中间变量的数值,所以对于M1芯片Mac,目前无法使用VSCode正常搭建Fortran调试环境。
本文使用的是Intel
出的ifort
编译器,对于gcc
中的gfortran
编译器也是可行的。
前往VS Code官网下载安装,完成后,打开VS Code,点击左侧扩展,安装插件。
名称 | 作者 | 图标 | 用途 | 安装位置 |
---|---|---|---|---|
Remote - SSH | Microsoft | 远程连接SSH服务器 | 本地 | |
C/C++ | Microsoft | Modern Fortran插件依赖项 | 服务器 | |
Modern Fortran | The Fortran Programming Language | Fortran语法支持、高亮、调试等 | 服务器 |
- 如果不使用服务器,只需在本地安装后两个插件;
- 此处仅介绍了必须安装的插件,对于其他辅助类插件如
Code Runner
、Makefile Tools
等,可自行摸索使用。
不使用服务器可跳过本节。
Remote - SSH
插件后,左侧导航栏会多出一个远程资源管理器SSH
命令即可,如SSH -P 1233 [email protected]
,其中-P
后为端口号,可以不指定。打开文件夹,如TEST_FORTRAN
,在该文件夹下建立.vscode
文件夹,在.vscode
文件夹新建launch.json
和tasks.json
两个文件,两个文件的配置如下:
本文件大多数情况下使用如下配置即可。
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "cppdbg",
"request": "launch",
"name": "Debug",
"program": "${workspaceFolder}/${fileBasenameNoExtension}",
"args": [],
"cwd": "${workspaceFolder}",
"preLaunchTask": "build"
}
]
}
type
: 指定调试编译器
name
: 左侧运行和调试窗口显示的配置名
program
: Fortran生成的可执行文件绝对路径
preLaunchTask
: 调试运行前执行的命令,命令标签build
在tasks.json文件中配置
用来配置调试前执行的命令,以及调试窗口部分参数。此处使用的配置如下
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "ifort",
"args": [
"-g",
"${fileDirname}/${fileBasename}",
"-o",
"${workspaceFolder}/${fileBasenameNoExtension}"
]
}
]
}
label
: 对应launch.json中preLaunchTask
设置的标签
type
: 此处使用shell
类型
command
: 调用终端时执行的命令
args
: 执行command
时传递的参数
-g
: 启用调试${fileDirname}/${fileBasename}
: 单个for文件编译;多个for文件编译时,修改为*.f*
-o
: 输出可执行文件${workspaceFolder}/${fileBasenameNoExtension}
: 输出可执行文件的名称,${fileBasenameNoExtension}
表示使用被调试文件去除后缀的名称。(注意:此处可执行文件的名称需要与launch.json文件中program
设置的参数相匹配)
Test_Fortran
文件夹下新建test01.f90
文件,写入如下内容program name
implicit none
real a,b,c
a = 1.0
b = 2.0
c = 3.0
print *,a,b,c
end program name
F10
),运行至第7行时,可以在左侧看到变量a
和b
的数值已更新为程序中赋值的1
和2
,变量c
仍为初始值0
,如下图所示test02.f90
,编写子例程如下subroutine test_add(a, b, c)
real, intent(in) :: a,b
real, intent(out) :: c
c = a + b
return
end subroutine test_add
test01.f90
,调用test02.f90
中的test_add
,如下program name
implicit none
real a,b,c
a = 1.0
b = 2.0
call test_add(a,b,c)
print *,a,b,c
end program name
tasks.json
文件,使其支持同时编译多个文件,修改后如下{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "ifort",
"args": [
"-g",
"${fileDirname}/*.f*",
"-o",
"${workspaceFolder}/${fileBasenameNoExtension}"
]
}
]
}
使用
*.f*
是为了匹配后缀为.f90
和.for
的文件,也可使用其他的书写方式,能够正常匹配需要编译的文件即可。