Fortranの(モダンな)環境構築をWSL2+Visual Studio Code+Poetryでやる記事です。8時間かかった
概説
大きな流れとしては以下のようになります。
コンパイラのインストール
↓
VSCode拡張機能のインストール
↓
Pythonの仮想環境、ライブラリインストール
↓
パスなどの設定
↓
ビルドコマンドの設定
書きながらやったので、途中で諦めたり、やっぱりできるじゃんとなってあとから変更した部分がありますが、そこはアコーディオン要素で見えないようになっているので無視してください(記録のために残しています)。
Intelが作った高速なコンパイラであるifort(今後はifx)もありますが、そこまで速度は必要でないのと、授業でやっているので、コンパイラが速いと逆に困る(速すぎてアルゴリズムによる差が分かりにくくなる可能性)かもしれないと思い、今回はgfortranを採用しました。
手順
gfortranのインストール
sudo apt install gfortran
Ubuntuではこれを実行するだけ。
username@LAPTOP-********:~/dev/fortran/assignment$ gfortran --version
GNU Fortran (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
上記のようにgfortran
とだけ実行して、こういう出力が出ればインストールが完了しています。
Visual Studio Codeの拡張機能のインストール
拡張機能のインストール自体は、VSCodeの左ペインにある拡張機能のボタンから、Fortran
で検索し、Modern FortranをインストールすればOKです。入っていない場合は、Microsoft公式のC/C++の拡張機能(ms-vscode.cpptools)も同時にインストールしましょう。
なんでC++の拡張機能が必要なんだ?と思いますが、デバッガがこの拡張機能を使っているかららしいです1。
ただし、このままではシンタックスハイライトくらいしか使えないので、別途設定を行います。
拡張機能の設定画面を開く
Modern Fortranの設定画面を開きます。VSCodeの設定画面で@ext:fortran-lang.linter-gfortran
と検索してもよいですし、拡張機能のペインから右クリックしてもよいです。
gfortranのインストール先を設定
username@LAPTOP-********:~/dev/fortran/assignment/2024-04-19$ which gfortran
/usr/bin/gfortran
username@LAPTOP-********:~/dev/fortran/assignment/2024-04-19$ file /usr/bin/gfortran
/usr/bin/gfortran: symbolic link to gfortran-11
username@LAPTOP-********:~/dev/fortran/assignment/2024-04-19$ file /usr/bin/gfortran-11
/usr/bin/gfortran-11: symbolic link to x86_64-linux-gnu-gfortran-11
username@LAPTOP-********:~/dev/fortran/assignment/2024-04-19$ file /usr/bin/x86_64-linux-gnu-gfortran-11
/usr/bin/x86_64-linux-gnu-gfortran-11: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=02630a15d850c72b1e49e228614b7d503b18a3ef, for GNU/Linux 3.2.0, stripped
コマンドの実行ファイルがどこを参照しているかを表示するwhich
コマンドと、ファイルのフォーマットを表示するfile
コマンドでインストール先を調べました。今回apt install gfortran
で入れたので、おそらくたいていこのディレクトリになっていると思いますが、念の為調べるのもありです。
シンボリックリンクが張られているようで、リンク先の設定としては/usr/bin/gfortran
で良さそうです。
拡張機能のFortran › Linter: Compiler Path
に、/usr/bin/gfortran
を入力し保存します。
GDBを入れる
GNUデバッガを入れます。環境によっては既にインストールされている?ようですが、今回自分の環境では入ってなかったっぽいです。
sudo apt install gdb
pipを入れる
私はPoetryを使っていたのでpipはインストールしていなかったのですが、後述するようにPoetryを使うことは断念したので、pipをインストールします。
sudo apt install pip
fortls(とfprettify)を使えるようにする
VSCodeなどで支援機能を利用するには言語サーバーを使うことになります。Fortranの言語サーバーはfortlsで、fortlsはPythonで書かれているので、動作させるにはPythonの環境が必要になります。正直めんどくさい…
Pythonのパッケージ管理にはPoetryを使います。Poetryを使うのは諦めていたのですが、やっているうちに重要な事実に気づき、できるっぽいので試したらできました。ということで、Poetryを使ったパターンを最初に載せておきます。
Poetryのインストール
Poetryのインストールは公式サイトを参考にすればすんなり入るはずです。ターミナルで以下のコマンドを実行するだけです。
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -
インストールできたら、ターミナルに入り直してから以下のコマンドを実行して正常にインストールできているか確認しましょう。バージョンが表示されればOKです。なお、ターミナルに入り直すだけでなく再起動が必要な場合もあります。
poetry --version
Poetryのプロジェクト作成
以下のコマンドでPoetryのプロジェクトを作成します。Gitのメアドとか諸々は好きなようにしましょう。依存関係を設定するか聞かれますが、今回はあとから追加するのでno
にします。ちなみに0から作成する用のコマンドではないっぽい(完全新規はpoetry new
らしい?)2ですが、今回はPythonを使うわけではなく、むしろPythonプロジェクト用のファイルは無い方がいいので、分かりやすいこちらを使います。
poetry init # プロジェクトを作成したいディレクトリで実行すること
fortlsとfprettifyを追加
プロジェクトを作成したディレクトリ(pyproject.toml
が存在するディレクトリ)以下のコマンドでfortlsとfprettifyを追加します。
poetry add fortls
poetry add fprettify
仮想環境の実際のパスを表示
Poetryは仮想環境を提供するソフトウェアで、実際にファイルが存在する場所は分からないままです。そこで、Poetryのコマンドを利用して、実際のファイルの保存先ディレクトリを表示します。
poetry env info -p
これで、パッケージなどが保存されているディレクトリが表示されます。表示されるディレクトリは、先ほど作成したプロジェクトのルートディレクトリなので、実際のファイルはもう少し奥にあります。
私の場合は上記コマンドの実行結果が以下だったので、
/home/username/.cache/pypoetry/virtualenvs/fortran-assignment-2024-8FJrCrGC-py3.10
このディレクトリの下の/bin
の下、
/home/username/.cache/pypoetry/virtualenvs/fortran-assignment-2024-8FJrCrGC-py3.10/bin/fortls
/home/username/.cache/pypoetry/virtualenvs/fortran-assignment-2024-8FJrCrGC-py3.10/bin/fprettify
このディレクトリを、このあと設定するsettings.json
の"fortran.fortls.path"
や"fortran.formatting.path"
に指定しました。あとで必要になるのでメモしておきましょう。
settings.json
みたいな全体に影響を与えるファイルにそんなすぐ変わりそうな値を入れていいのか?と思うかもしれません(私もそうでした)。しかし、パッケージを入れ直したり、プロジェクトを作成し直したりしなければ、おそらくこのディレクトリは変わりません。また、VSCodeのsettings.json
はディレクトリごとにsettings.jsonを作成することで、そのディレクトリでだけ有効な設定を作成可能なので、適切に設定すれば他の環境に悪影響を与えることはありません。
username@LAPTOP-********:~/dev/fortran/assignment$ poetry init
This command will guide you through creating your pyproject.toml config.
Package name [assignment]: fortran-assignment-2024
Version [0.1.0]:
Description []:
Author [username <[email protected]m>, n to skip]:
License []:
Compatible Python versions [^3.10]:
Would you like to define your main dependencies interactively? (yes/no) [yes] yes
You can specify a package in the following forms:
- A single name (requests): this will search for matches on PyPI
- A name and a constraint (requests@^2.23.0)
- A git url (git+https://github.com/python-poetry/poetry.git)
- A git url with a revision (git+https://github.com/python-poetry/poetry.git#develop)
- A file path (../my-package/my-package.whl)
- A directory (../my-package/)
- A url (https://example.com/packages/my-package-0.1.0.tar.gz)
Package to add or search for (leave blank to skip): fortls finden
Adding fortls findent
Add a package (leave blank to skip):
Would you like to define your development dependencies interactively? (yes/no) [yes] yes
Package to add or search for (leave blank to skip):
Generated file
[tool.poetry]
name = "fortran-assignment-2024"
version = "0.1.0"
description = ""
authors = ["username <[email protected]>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10"
fortls = "findent"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Do you confirm generation? (yes/no) [yes] yes
PoetryでPythonの依存関係を管理します。Poetryのインストールは先に別途行っておきます。
poetry init
で対話型のプロジェクト作成を行います。Pythonのバージョンは3.7以上ならいいっぽいので、とりあえず3.10にしておきました。
あとから気づいたんですが、これはインストールできてなかったので(poetry add fortls findent
じゃダメで1つづつ追加しないとダメだった)、あとからpyproject.toml
の該当部分(fortls = "findent"
)の記述を消して、以下のコマンドでパッケージを追加しました。
poetry add findent
poetry add fortls
Poetryを使おうとしたのですが、Poetryは仮想環境ごとにパッケージを個別でインストールするらしく、pnpmみたいに最終的な参照先が同一になるような仕組みではないらしいので、fortlsやfindentをPoetryで管理するのは諦めました。いや、→そういえばVSCodeはディレクトリごとにpoetry env info -p
とかでインストール先を調べればできないことはなさそうだったのですが、この方法だと汎用性が無く3、事実上今回作ったFortranのディレクトリ以外ではfortlsが使えない4ため、現実的ではないと判断しました。.vscode
ディレクトリの中にsettings.json
を設定できるので、それを使えばいちいちディレクトリを変えるたびにsettings.json
を書き換えるようなことをしなくてもいいことに気がついた(書いたあとに)。まぁFortranは枯れた言語なので、当分更新はないでしょうしね…
以下のコマンドでfortlsとfprettifyをインストールします。fprettifyはフォーマッターで、Modern Fortranのデフォルトではfindentになっているようですが、今回参考にしたページがfprettifyを使っていて、設定をそのまま利用できるため、今回はfprettifyを採用しています。
pip install fortls
pip install fprettify
インストールできたら、インストール先を以下のコマンドで調べます。
which fortls
which fprettify
表示されたフルパスは後で使うので、適当な場所にメモっておきましょう。
.vscodeディレクトリを作成してビルドコマンド等を設定
プロジェクトの置き場にしたいPoetryのプロジェクトを作成したディレクトリ(pypoject.toml
があるフォルダ)で以下のコマンドを実行し、.vscode
という名前のディレクトリを作成します。
mkdir .vscode
この.vscode
ディレクトリの中に、launch.json
、tasks.json
、settings.json
というファイルを作成し、ファイルの内容をリンク先記事を参考に記述します。
非常にありがたい記事で、JSONファイルの内容をだいたいそのまま使わせてもらうだけで動くはずです。ただし、settings.json
のpathや、tasks.json
のargs
(引数)などは、自分の環境に合ったものに書き換える必要があります。settings.json
は先ほどwhich
コマンドで調べたディレクトリに書き換えましょう。
参考までに、私が書き換えたファイルの中身を以下に残します。
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build fortran",
"type": "shell",
"command": "gfortran",
"args": [
"-g",
"${fileDirname}${/}${fileBasename}",
"-o",
"${fileDirname}${/}${fileBasenameNoExtension}.out"
]
}
]
}
{
"configurations": [
{
"name": "build and debug fortran file with gdb",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}${/}${fileBasenameNoExtension}.out",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"preLaunchTask": "build fortran",
"setupCommands": [
{
"description": "gdb の再フォーマットを有効にする",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "逆アセンブリ フレーバーを Intel に設定",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
{
"fortran.linter.compiler": "gfortran",
"fortran.linter.compilerPath": "/usr/bin/gfortran",
"fortran.fortls.path": "/home/username/.cache/pypoetry/virtualenvs/fortran-assignment-2024-8FJrCrGC-py3.10/bin/fortls",
"fortran.formatting.formatter": "fprettify",
"fortran.formatting.path": "/home/username/.cache/pypoetry/virtualenvs/fortran-assignment-2024-8FJrCrGC-py3.10/bin/fprettify",
"fortran.formatting.fprettifyArgs": [
"--indent",
"4",
"--enable-decl",
"--strip-comments",
"--case",
"1",
"1",
"1",
"1"
],
"fortran.preferredCase": "lowercase",
"[FortranFreeForm]": {
"files.autoGuessEncoding": true,
"files.encoding": "shiftjis"
},
}
オリジナルとの差分
オリジナルとの差分は以下の通りです。
- プロジェクトの配下に更にディレクトリを作ってもビルドが通るように、オリジナルとは異なる変数を利用した(
${workspaceFolder}
→${fileDirname}
)/
も${/}
にした(特に意味はないが汎用的な変数を知ったので使いたくて)
"MIMode"
を"gdb"
に(Linux対応)"miDebuggerPath"
を"/usr/bin/gdb"
に(Linux対応)- コンパイル後ファイル名に
.out
を付加(Windowsと違ってLinuxだとデフォルトが拡張子無しなので)
分かりやすく言うと、以下のようなディレクトリ構造(assignment
が親)で問題なく動くようにした感じです。
.
└── assignment
├── .vscode
│ ├── launch.json
│ ├── settings.json
│ └── tasks.json
├── 2024-04-19
│ └── program-2024-04-19.f90
├── fortran-sample
│ ├── main.f90
│ └── main.out
├── poetry.lock
└── pyproject.toml
設定が終わったら、念の為一旦VSCodeを終了して、再度ディレクトリを開き直すのがおすすめです。F5キーを押せば自動でコンパイルまで済む環境ができあがっているはず…
なんつってたら6時っすよ、高等教育のつらいとこね、これ
参考情報
- WSL2 による gfortran と intel fortran の環境構築 #初心者 – Qiita
- FortranをVSCodeで書くための環境構築
- VSCodeのlaunch.jsonおよびtask.jsonで使用可能な変数
- Visual Studio Code Variables Reference
- VSCodeのFortran向け拡張を整理,最新化する(2022年6月) #VSCode – Qiita
- ifxに備えよう #Fortran – Qiita
- VSCodeでFortranのプログラムをコンパイル・デバッグするための設定 #VSCode – Qiita
- Ubuntu + VSCodeでFortran開発環境を構築する(WSL2対応) ↩︎
- Poetryをサクッと使い始めてみる #Python – Qiita ↩︎
- インストール先として表示されたのは
/home/username/.cache/pypoetry/virtualenvs/fortran-assignment-2024-8FJrCrGC-py3.10
だった ↩︎ - 使うディレクトリをいちいち
settings.json
を書き換える必要がある ↩︎