WSL2(Ubuntu)+VSCode+Poetry+fortlsでFortranのデバッグ環境構築

プログラミング
この記事は約21分で読めます。
当サイトには、広告及びアフィリエイトリンクが含まれ、それによって収益を得ています。記事の内容やリンクには、プロモーションが含まれる場合があります。詳細については、プライバシーポリシーをご覧ください。

Fortranの(モダンな)環境構築をWSL2+Visual Studio Code+Poetryでやる記事です。8時間かかった

概説

大きな流れとしては以下のようになります。

コンパイラのインストール

VSCode拡張機能のインストール

Pythonの仮想環境、ライブラリインストール

パスなどの設定

ビルドコマンドの設定

書きながらやったので、途中で諦めたり、やっぱりできるじゃんとなってあとから変更した部分がありますが、そこはアコーディオン要素で見えないようになっているので無視してください(記録のために残しています)。

Intelが作った高速なコンパイラであるifort(今後はifx)もありますが、そこまで速度は必要でないのと、授業でやっているので、コンパイラが速いと逆に困る(速すぎてアルゴリズムによる差が分かりにくくなる可能性)かもしれないと思い、今回はgfortranを採用しました。

手順

gfortranのインストール

Bash
sudo apt install gfortran

Ubuntuではこれを実行するだけ。

Bash
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のインストール先を設定

Bash
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デバッガを入れます。環境によっては既にインストールされている?ようですが、今回自分の環境では入ってなかったっぽいです。

Bash
sudo apt install gdb

pipを入れる

私はPoetryを使っていたのでpipはインストールしていなかったのですが、後述するようにPoetryを使うことは断念したので、pipをインストールします。

Bash
sudo apt install pip

fortls(とfprettify)を使えるようにする

VSCodeなどで支援機能を利用するには言語サーバーを使うことになります。Fortranの言語サーバーはfortlsで、fortlsはPythonで書かれているので、動作させるにはPythonの環境が必要になります。正直めんどくさい…

Pythonのパッケージ管理にはPoetryを使います。Poetryを使うのは諦めていたのですが、やっているうちに重要な事実に気づき、できるっぽいので試したらできました。ということで、Poetryを使ったパターンを最初に載せておきます。

Poetryのインストール

Poetryのインストールは公式サイトを参考にすればすんなり入るはずです。ターミナルで以下のコマンドを実行するだけです。

Bash
(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -

インストールできたら、ターミナルに入り直してから以下のコマンドを実行して正常にインストールできているか確認しましょう。バージョンが表示されればOKです。なお、ターミナルに入り直すだけでなく再起動が必要な場合もあります。

Bash
poetry --version

Poetryのプロジェクト作成

以下のコマンドでPoetryのプロジェクトを作成します。Gitのメアドとか諸々は好きなようにしましょう。依存関係を設定するか聞かれますが、今回はあとから追加するのでnoにします。ちなみに0から作成する用のコマンドではないっぽい(完全新規はpoetry newらしい?)2ですが、今回はPythonを使うわけではなく、むしろPythonプロジェクト用のファイルは無い方がいいので、分かりやすいこちらを使います。

Bash
poetry init # プロジェクトを作成したいディレクトリで実行すること

fortlsとfprettifyを追加

プロジェクトを作成したディレクトリ(pyproject.tomlが存在するディレクトリ)以下のコマンドでfortlsとfprettifyを追加します。

Bash
poetry add fortls
poetry add fprettify

仮想環境の実際のパスを表示

Poetryは仮想環境を提供するソフトウェアで、実際にファイルが存在する場所は分からないままです。そこで、Poetryのコマンドを利用して、実際のファイルの保存先ディレクトリを表示します。

Bash
poetry env info -p

これで、パッケージなどが保存されているディレクトリが表示されます。表示されるディレクトリは、先ほど作成したプロジェクトのルートディレクトリなので、実際のファイルはもう少し奥にあります。

私の場合は上記コマンドの実行結果が以下だったので、

Bash
/home/username/.cache/pypoetry/virtualenvs/fortran-assignment-2024-8FJrCrGC-py3.10

このディレクトリの下の/binの下、

Bash
/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"に指定しました。あとで必要になるのでメモしておきましょう。

追記(2024/04/22):
確かにfortran.formatting.pathを指定したのですが、なぜかフォーマッタだけ有効になりませんでした。同様にパスを指定したfortlsの機能は使えているので、パスの指定がおかしいことは考えにくく、なぜ使えないのか分からないのですが…

settings.jsonみたいな全体に影響を与えるファイルにそんなすぐ変わりそうな値を入れていいのか?と思うかもしれません(私もそうでした)。しかし、パッケージを入れ直したり、プロジェクトを作成し直したりしなければ、おそらくこのディレクトリは変わりません。また、VSCodeのsettings.jsonはディレクトリごとにsettings.jsonを作成することで、そのディレクトリでだけ有効な設定を作成可能なので、適切に設定すれば他の環境に悪影響を与えることはありません。

Bash
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")の記述を消して、以下のコマンドでパッケージを追加しました。

Bash
poetry add findent
poetry add fortls

Poetryを使おうとしたのですが、Poetryは仮想環境ごとにパッケージを個別でインストールするらしく、pnpmみたいに最終的な参照先が同一になるような仕組みではないらしいので、fortlsやfindentをPoetryで管理するのは諦めました。いや、poetry env info -pとかでインストール先を調べればできないことはなさそうだったのですが、この方法だと汎用性が無く3、事実上今回作ったFortranのディレクトリ以外ではfortlsが使えない4ため、現実的ではないと判断しました。→そういえばVSCodeはディレクトリごとに.vscodeディレクトリの中にsettings.jsonを設定できるので、それを使えばいちいちディレクトリを変えるたびにsettings.jsonを書き換えるようなことをしなくてもいいことに気がついた(書いたあとに)。まぁFortranは枯れた言語なので、当分更新はないでしょうしね…

以下のコマンドでfortlsとfprettifyをインストールします。fprettifyはフォーマッターで、Modern Fortranのデフォルトではfindentになっているようですが、今回参考にしたページがfprettifyを使っていて、設定をそのまま利用できるため、今回はfprettifyを採用しています。

Bash
pip install fortls
pip install fprettify

インストールできたら、インストール先を以下のコマンドで調べます。

Bash
which fortls
which fprettify

表示されたフルパスは後で使うので、適当な場所にメモっておきましょう。

.vscodeディレクトリを作成してビルドコマンド等を設定

プロジェクトの置き場にしたいPoetryのプロジェクトを作成したディレクトリ(pypoject.tomlがあるフォルダ)で以下のコマンドを実行し、.vscodeという名前のディレクトリを作成します。

Bash
mkdir .vscode

この.vscodeディレクトリの中に、launch.jsontasks.jsonsettings.jsonというファイルを作成し、ファイルの内容をリンク先記事を参考に記述します。

FortranをVSCodeで書くための環境構築

非常にありがたい記事で、JSONファイルの内容をだいたいそのまま使わせてもらうだけで動くはずです。ただし、settings.jsonのpathや、tasks.jsonargs(引数)などは、自分の環境に合ったものに書き換える必要があります。settings.jsonは先ほどwhichコマンドで調べたディレクトリに書き換えましょう。

参考までに、私が書き換えたファイルの中身を以下に残します。

.vscode/tasks.json
{
    // 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"
            ]
        }
    ]
}
.vscode/launch.json
{
    "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
                }
            ]
        }
    ]
}
.vscode/settings.json
{
    "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が親)で問題なく動くようにした感じです。

Bash
.
└── 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時っすよ、高等教育のつらいとこね、これ

参考情報

  1. Ubuntu + VSCodeでFortran開発環境を構築する(WSL2対応) ↩︎
  2. Poetryをサクッと使い始めてみる #Python – Qiita ↩︎
  3. インストール先として表示されたのは/home/username/.cache/pypoetry/virtualenvs/fortran-assignment-2024-8FJrCrGC-py3.10だった ↩︎
  4. 使うディレクトリをいちいちsettings.jsonを書き換える必要がある ↩︎

病気療養中のガジェットオタクです。PC、スマホからオーディオ、家電まで、デジモノ・IT系中心に自分の興味のあるものならなんでも記事にします。誤字脱字など、ミスの報告歓迎です。
お問い合わせは、当ブログのお問い合わせフォームにお願いします。レビュー依頼など、各種ご依頼承っています。

でじぃをフォローする↓
How toプログラミング
スポンサーリンク
でじぃをフォローする↓
タイトルとURLをコピーしました