概要
- VSCodeにあるFortran向けの拡張は,Modern Fortran拡張に一本化できるようになりました.
- fortran-language-serverは,それから派生したfortlsに置き換えられます.
- Anacondaユーザは,pipではなくcondaでfortls, fprettifyをインストールできます.
テスト環境
- Windows 10 64 bit 21H2
- Fortranコンパイラ
- gfortran 10.3 (quickstart fortran bundle)
- Intel OneAPI 2021.5.0
- conda 4.13.0
- VSCode 1.68
- VSCode拡張
- Modern Fortran v3.1.0
- C/C++ v1.10.5
- fortls 2.9.0
- fprettify 0.3.7
- Visual Studio 2017
背景
VSCodeには非常に多くの拡張が存在しており,それらを用いることでプログラミングの体験を大きく改善できます.Fortranも例外ではなく,VSCodeと拡張機能を利用することで,開発の効率化を実現できます.
一方で,Fortranには万能な拡張がなく,色々な拡張を併用する必要がありました.例えば,以下の拡張機能が有名です.
- Modern Fortran: プログラミング言語モードの設定,Lint,シンタックスハイライト,コードスニペット
- FORTRAN IntelliSense: 言語サーバの利用,コードナビゲーション
- Fortran breakpoint Support: デバッグ時のブレークポイントの設定
- vscode-modern-fortran-formatter: ソースコードの自動整形
これら以外にも,重複する拡張機能がいくつかあります.残念ながら上記の拡張より機能が少なく,開発も早期に停滞しました.
- fortran: プログラミング言語モードの設定,シンタックスハイライト,コードスニペット
- fortran - ekon: 同上
- fprettify: ソースコードの自動整形
- fixedformfortranlinter: Lint
これらの拡張のうち,Modern Fortran拡張は開発が続けられ,言語サーバの利用,デバッグ,ソースコードの自動整形の機能を取り込んできました.また,Modern Fortran拡張はfortran-langに取り込まれ,fortran-langのプロジェクトの一つして開発が継続されることになりました.そのため,今後も精力的な開発が続けられると期待されます.
この記事では,これまで複数利用していた拡張をModern Fortran拡張に一本化し,その設定について解説します.また,Modern Fortran拡張が利用していたPythonパッケージについても,最新版に変更します.
Modern Fortran拡張が利用するPythonパッケージの更新
Modern Fortran拡張は,言語サーバの利用,およびソースコードの自動整形のためにPythonパッケージを利用します.
言語サーバ
言語サーバは,fortrran-language-serverという名前のパッケージを利用していました.Modern Fortran拡張の開発者は,fortran-language-serverから派生したプロジェクトを立ち上げ,fortlsという名前で開発を進めています.
fortlsは,pipまたはcondaを用いてインストールできます.
pip
pip install fortls
conda
conda install -c conda-forge fortls
fortran-language-serverはpipからしかインストールできなかったため,Anacondaユーザはpipとcondaを混ぜて利用する事に苦悩していたと思います.fortlsはcondaでインストールできるので,この苦悩から解放されます.
自動整形
ソースコードの自動整形には,fprettifyおよびfindentが利用できます.fprettifyはvscode-modern-fortran-formatterからも利用されていたので,利用している人は多いと思います.
fprettifyもpipまたはcondaを用いてインストールできます.
pip
pip install fprettify
conda
conda install -c programfan fprettify
Modern Fortran拡張の最新化
Modern Fortran拡張の最新バージョンはv3.1.0です.VSCodeのバージョンが最新になっていれば,自動的に最新バージョンに更新されます.
上述のとおり,Modern Fortran拡張がfortran-langに取り込まれたことに伴い,Modern Fortran拡張に割り当てられている拡張機能IDがkrvajalm.linter-gfortran
からfortran-lang.linter-gfortran
に変更されました.
extensions.jsonの"recommendations"
に拡張機能IDを記述していた場合は,それを修正しないと,marketplaceに拡張機能が無いという警告を見続けることになります.
また,いくつかのオプション名が変更になったため,バージョンを上げた際にdepricated optionとして表示されます.
旧 | 新 |
---|---|
fortran.gfortranExecutable |
fortran.linter.compilerPath |
fortran.includePaths |
fortran.linter.includePath |
fortran.linterExtraArgs |
fortran.linter.extraArgs |
fortran.provideCompletion |
fortran.provide.autocomplete |
fortran.provideHover |
fortran.provide.hover |
fortran.provideSymbols |
fortran.provide.symboles |
linterの設定
Modern Fortranは,lintにgfortranを用いていました.そのため,Intel Fortranユーザもgfortranをインストールする必要がありました.現在のModern Fortranは,gfortranに加えて,ifortおよびifxもlintに利用できるようになりました.
Modern Fortranは,ソースファイルを開いた際に,.modファイルを作成してそれをlintに利用します.Fortranの.modファイルはコンパイラ間で互換性がないため,外部ライブラリをシステムにインストールして利用する際に,当該ライブラリが持つモジュールや,定数,手続をModern Fortranに認識させるためには,不要であってもgfortranで一度ビルドして.modファイルを作成するなどの手間が必要でした.
現状では,Intel Fortran利用者はその手間がなくなりました.今はgfortranおよびIntel Fortranだけですが,NAG fortranやflangをlintに利用できるようにする開発計画があるようです.
lintに利用するコンパイラは,Fortran › Linter: Compiler
でプルダウンメニューから選択し,その実行ファイルのフルパスをFortran › Linter: Compiler Path
で指定します1.
gfortranとifortを切り替えてみると,表示されるエラーが変化することが確認できます.
lintのためにFortranコンパイラを実行する際のオプションは,Fortran › Linter: Extra Args
で指定します.
Formatterの設定
ソースの自動整形に使うFormatterも,linterと同じように設定します.
整形に利用するFormatterは,Fortran › Formatting: Formatter
でプルダウンメニューから選択し,その実行ファイルがあるディレクトリのパスをFortran › Formatting: Path
で指定します.本記事ではfprettifyを利用します.
fprettifyに渡すオプションは,Fortran › Formatting: Fprettify Args
に記述します.設定の記述にはかなりクセがあり,スペースを区切りとして全て別々の項目として書いていきます.例えば,--indent 4 --enable-decl --strip-comments --case 1 1 1 1
というオプションを記述するには,"--indent","4","--line-length","256","--enable-decl","--strip-comments","--case","1","1","1","1"
と区切る必要があります.
自動整形を有効にするには,VSCode自体の設定も必要です.
Editor: Format On Save
を有効(チェックボックス☑にチェックを入れる)にし,Editor: Default Formatter
をなし
に設定します.
言語サーバの設定
最後に,Modern Fortranから呼び出す言語サーバの設定を行います.
言語サーバは,Fortran › Fortls: Path
にfortls(実行ファイル)のフルパスを指定します.
その他,非常に多くの項目を設定できますが,基本的には標準設定のままで問題ありません.プリプロセスをよく利用する場合は,プリプロセスに関する設定や,ファイル拡張子に関する設定をしておくと便利です.fortlsの分析の対象にする/しないといったディレクトリの指定については,各プロジェクトに固有の設定ファイルを用意して,そこに設定を書いた方が柔軟に対応できます.設定ファイルは,標準ではプロジェクトのルートに.fortls
という名前で置く必要があります.それ以外の名前についてはFortran › Fortls: Configure
で設定します.
デバッグの設定
Modern Fortranは,C/C++拡張のデバッグの機能を利用して,Fortranプログラムのデバッグ実行を可能にします.デバッガには,gdbもしくはVisual Studioのデバッガが必要です.Windowsの場合,gfortranでコンパイルしたプログラムにはgdb,ifortでコンパイルしたプログラムにはVisual Studioのデバッガを利用します.
デバッグの例のために,下記のような構成でプログラムを作成します.main.f90を含むフォルダをVSCodeで開いているとします.
.
└── main.f90
program main
use, intrinsic :: iso_fortran_env
implicit none
real(real32) :: f(4) = [1.0, 2.0, 3.0, 4.0]
block
integer(int32) :: i
do i = 1, size(f)
f(i) = f(i)*2
end do
end block
print *, f
end program main
VSCodeでデバッグ実行するには,.vscode/launch.json
ファイルにデバッグ実行の設定を記述します.プロジェクトルートに.vscode
ディレクトリを作成し,空のlaunch.json
ファイルを作成します.
.
├── main.f90
└── .vscode
└── launch.json
VSCodeでそのファイルを開くと,[構成の追加]ボタンが現れるので,それを押すといくつかの既存構成が一覧で現れます.
gfortran用の(gdbを使う)設定は,C/C++: (gdb) 起動
,ifort用の(Visual Studioを使う)設定は,C/C++: (Windows) 起動
を選択します.launch.json
には複数の構成情報を書くことができます.
gfortran用の設定
C/C++: (gdb) 起動
を選択して既存構成を読み込むと,下記のような内容が挿入されます.
{
"configurations": [
{
"name": "(gdb) 起動",
"type": "cppdbg",
"request": "launch",
"program": "プログラム名を入力してください (例: ${workspaceFolder}/a.exe)",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/path/to/gdb",
"setupCommands": [
{
"description": "gdb の再フォーマットを有効にする",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "逆アセンブリ フレーバーを Intel に設定",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
ここで編集する必要がある項目は,"program"
, "cwd"
, "miDebuggerPath"
です.それぞれ下記のように編集します.
- "program": "プログラム名を入力してください (例: ${workspaceFolder}/a.exe)",
+ "program": "${workspaceFolder}/a.exe",
- "cwd": "${fileDirname}",
+ "cwd": "${workspaceFolder}",
- "miDebuggerPath": "/path/to/gdb",
+ "miDebuggerPath": "gdb",
Windowsであっても,パスの区切りは/
でよいようです.a.exe
としているのは,gfortranを用いたときに標準で付けられる実行ファイル名だからという単純な理由です.-o
オプションで実行ファイルの名前を指定する場合は,その指定した名前を利用してください.
{
"configurations": [
{
"name": "(gdb) 起動",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/a.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "gdb",
"setupCommands": [
{
"description": "gdb の再フォーマットを有効にする",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "逆アセンブリ フレーバーを Intel に設定",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
ifort用の設定
C/C++: (Windows) 起動
を選択して既存構成を読み込むと,下記のような内容が挿入されます.
{
"configurations": [
{
"name": "(Windows) 起動",
"type": "cppvsdbg",
"request": "launch",
"program": "プログラム名を入力してください (例: ${workspaceFolder}/a.exe)",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"console": "externalTerminal"
}
]
}
編集する項目はgfortran用の設定とほぼ同じで,ここで編集する必要がある項目は,"program"
, "cwd"
です.それぞれ下記のように編集します.
- "program": "プログラム名を入力してください (例: ${workspaceFolder}/a.exe)",
+ "program": "${workspaceFolder}/main.exe",
- "cwd": "${fileDirname}",
+ "cwd": "${workspaceFolder}",
main.exe
は,ファイル名(main.f90
)から採用しており,ifortを用いたときの標準の実行ファイル名(ソースファイルと同じ名前になる)です./exe:
や-o
オプションで実行ファイルの名前を指定する場合は,その指定した名前を利用してください.
{
"configurations": [
{
"name": "(Windows) 起動",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceFolder}/main.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"console": "externalTerminal"
}
]
}
デバッグの実行
プログラムのビルド
デバッグの前に,プログラムをデバッグ用にビルドします.
gfortran -g main.f90
ifort /debug:full main.f90
ブレークポイントの設定
デバッグの最中に,変数の値を確認等を行うためのに,プログラムを一時的に停止するブレークポイントの設定も行います.ブレークポイントは,エディターウィンドウに表示されているプログラムの行番号の左側をクリックすることで設定できます.ブレークポイントが設定できていると,行番号の左側に赤い丸が付き,デバッグ実行した際にこの赤丸の行でプログラムが一時停止します.
デバッグの実行
デバッグを実行するには,上部メニューの[実行]→[デバッグの開始]を選択するか,F5
キーを押すか,サイドバーの[実行とデバッグ]を選択します.
デバッグが無事実行されると,ブレークポイントを設定した行が黄色くハイライトされ,デバッグウィンドウに情報が表示されます.変数と書かれている項目を展開していくと,配列f
やループカウンタi
の数値を見ることができます.
変数名が大文字になっているのは,おそらくifortが内部的に変数を全て大文字として扱っている(FORTRAN 77までは大文字しか扱えなかった)ことに起因していると考えられます.
エディターウィンドウに重なって表示されるツールバーから,[続行]をクリックすると,次のブレークポイントまで実行され,再び停止します.何度か[続行]をクリックしていくと,ループが進み,配列の値が変化していくことが確認できます.
上記の画像は,ifortでビルドしたプログラムをVisual Studioのデバッガでデバッグしたときの結果です.gfortranでビルドしたプログラムをgdbでデバッグしても,同じような結果が得られます.
複数のデバッグ構成がある場合
launch.json
に複数のデバッグ構成が書かれている場合,上部メニューの[実行]→[デバッグの開始]を選択する方法と,F5
キーを押す方法では,どうやらファイルの前の方に書かれている構成に沿ってデバッグが行われるようです.
デバッグウィンドウではプルダウンメニューから構成を選択してデバッグを実行できます.
まとめ
VSCodeのFortran向け拡張の現状を整理し,2022年6月時点で最新の状況に情報を更新しました.これまで複数の拡張を併用していた機能
- プログラミング言語モードの設定
- Lint
- シンタックスハイライト
- コードスニペット
- 言語サーバの利用
- コードナビゲーション
- デバッグ時のブレークポイントの設定
- VSCodeのデバッグウィンドウとの統合
- ソースコードの自動整形
については,Modern Fortran拡張に一本化できました.これにより,VSCodeとFortranを併用する際の環境構築が簡略化され,よりFortranを利用しやすくなりました.
fortran-langに合流したModern Fortran拡張には今後も大いに期待しています.
-
v3.1.0
より前のバージョンでは,実行ファイル指定の設定が異なっており,実行ファイルが置かれているディレクトリのパスを指定しないと正しく認識されませんでした.これがバグなのか挙動を変更したのかは判りません.設定の説明が変わっていないように見えるので,私はバグだと判断しています. ↩