プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

Windows 11 の WSL に Fortran をインストールして VSCode で開発する環境を整える

何十年ぶりになるか、ずいぶんと久しぶりに Fortran を使った仕事をすることになりました。学生時代以降 Fortran なんて触ったことなかったですが、まだまだ一部の業界では Fortran も現役なんですよねー。

仕事に先立ち、とりあえず手元の環境でも簡単な検証ができるように Fortran の開発環境を整えてみました。

ということで、昨今の Fortran 開発環境なども調べつつ、試したことをまとめておきます。

WSL に gfortran をインストール

まずは gfortran (GNU Fortran) をインストールしておきます。

mor@DESKTOP-DE7IL4F:~$ sudo apt install gfortran

インストールできていれば、バージョン情報がでます。

mor@DESKTOP-DE7IL4F:~$ gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-linux-gnu/13/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 13.3.0-6ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-13/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-13 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-13-fG75Ri/gcc-13-13.3.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 13.3.0 (Ubuntu 13.3.0-6ubuntu2~24.04)
mor@DESKTOP-DE7IL4F:~$

コンパイルもしてみます。 FORTRAN 77 で書いてみます。

      PROGRAM HELLO
      PRINT *, "HELLO WORLD"
      END PROGRAM HELLO

懐かしの固定形式ですね。コンパイルして、実行します。

mor@DESKTOP-DE7IL4F:~/tmp/fortran$ gfortran test.f
mor@DESKTOP-DE7IL4F:~/tmp/fortran$ ./a.out
 HELLO WORLD
mor@DESKTOP-DE7IL4F:~/tmp/fortran$

実行できますね。

同じことを、自由形式の Fortran 90 でも試します。

program hello
    print *, "hello world"
end program hello
mor@DESKTOP-DE7IL4F:~/tmp/fortran$ gfortran test.f90
mor@DESKTOP-DE7IL4F:~/tmp/fortran$ ./a.out
 hello world
mor@DESKTOP-DE7IL4F:~/tmp/fortran$

こちらも問題なしですね。

VSCode の設定

WSL 上で Fortran コンパイラが動くようになったので、次は VSCode で開発できるようにします。

拡張機能もいろいろと紹介されていますが今回は下記の記事を参考にして、

VSCodeのFortran向け拡張を整理,最新化する(2022年6月) #VSCode-Extension - Qiita

下記1つだけインストールすることにしました。

Modern Fortran

ただ、『この拡張機能は拡張機能マーケットプレースによって署名されていません。』と表示されてて、インストールボタンが無効になっています。

少し調べてみると、以前にも同様の問題があったようで、

Can't install VSCode Modern Fortran - not signed by marketplace - #20 by Abhi_dev - Visual Studio Code - Fortran Discourse

こんなディスカッションもありました。公式の issues も見てみると

feat: Please sign the fortran-language vscode-extension on vscode market place · Issue #1200 · fortran-lang/vscode-fortran-support · GitHub

あー、既知の問題になってるようですね。次のメジャーアップデートでは解決されるようなので、現時点ではこの状態でインストールするしかなさそうです。

ということで、先ほどのディスカッションのところに載ってるように歯車アイコンをクリックして、

このメニューからインストールすることにします。すると、下記のように

警告が出ますが、『インストールする』を選択します。

再度確認を求められるので『発行元を信頼してインストールする』を押して進めば、問題なくインストールできます。

この状態で VSCode で先ほどのソースファイルを表示すると

おぉ、こんな感じにハイライトされるようになりました。

ツールのインストール

Modern Fortran の説明を読んでいくと、

  • fortls
  • findent
  • fprettify

といった、言語サーバーや整形ツールを利用できるようになっているそうです。当初はこれらも一緒にインストールされるのかと思っていたのですが、 VSCode の画面の下部の通知を見ると、

と表示されているように、これらは自分でインストールする必要があるようです。

ただ、これらのツールは python 製のようでインストールは pip で行う必要があります。どこに入れようか少し迷うところではあるのですが、 Fortran の作業の時に Python のバージョンなどは考えたくないので、 pyenv / venv で指定した場所ではなく、システムの pip 環境に入れることにします。

ということで、インストールすると

mor@DESKTOP-DE7IL4F:~$ pip install fortls
error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.

    If you wish to install a non-Debian-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
    sure you have python3-full installed.

    If you wish to install a non-Debian packaged Python application,
    it may be easiest to use pipx install xyz, which will manage a
    virtual environment for you. Make sure you have pipx installed.

    See /usr/share/doc/python3.12/README.venv for more information.

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
mor@DESKTOP-DE7IL4F:~$

おっと、なんかエラーがでてきました。

調べてみると Python 3.12 以降はシステム領域に pip でパッケージをインストールすることが原則禁止になったようですね。そういや、最近は venv を使っているので、 Python 3.12 にアップデート後(WSL の Ubuntu 22.04 -> 24.04 で上がりました)はひょっとしたら一度も pip install をやってなかったのかもしれません。

さて、どうしたものかと思いつつ、調べてみると正攻法は venv を使う方法のようです。

でも、今回は一つのプロジェクトではなく全体的に使いたいので pipx を使う方法にします。

mor@DESKTOP-DE7IL4F:~$ sudo apt install pipx
mor@DESKTOP-DE7IL4F:~$ pipx install fortls
  installed package fortls 3.2.2, installed using Python 3.12.3
  These apps are now globally available
    - fortls
done! ✨ 🌟 ✨
mor@DESKTOP-DE7IL4F:~$

同様に findent と fprettify もインストールしておきます。どっちか一方でもいいはずです。 findent は固定形式の扱いに強いらしいので、一応両方入れてみました。

mor@DESKTOP-DE7IL4F:~$ pipx install findent
  installed package findent 4.3.1, installed using Python 3.12.3
  These apps are now globally available
    - findent
done! ✨ 🌟 ✨
mor@DESKTOP-DE7IL4F:~$ pipx install fprettify
  installed package fprettify 0.3.7, installed using Python 3.12.3
  These apps are now globally available
    - fprettify
done! ✨ 🌟 ✨
mor@DESKTOP-DE7IL4F:~$

VSCode 側では特に設定は変更しませんでした(fortls, findent, fprettify にパスが通っていればデフォルトでいいみたいです)。手元の環境では ~/.local/bin に実行ファイルへのシンボリックリンクが作られていて、ここにパスが通っていました。

なお、フォーマッタはデフォルトでは findent が使われるみたいなので、 必要に応じて fprettify と切り替えて使おうと思います。

実行とデバッグ

Modern Fortran は Microsoft C/C++ 拡張機能 を使っているようです、これはインストール済みなので、飛ばします。

ついでに、 WSL 側に gdb がインストールされていることも確認しておきます。

mor@DESKTOP-DE7IL4F:~$ which gdb
/usr/bin/gdb
mor@DESKTOP-DE7IL4F:~$

さて、これで実行できるかな?と思い、さきほどのファイルを選択して『デバッグなしで実行』としても、

のように『デバッガの選択』が表示されるだけで何も起きません。こちらの記事などによると Fortran ではこのあたりをちゃんと設定してあげないとコンパイルもしてくれないようです。

というわけで設定ファイルを作成する必要があるようですね。

デバッグ設定ファイル launch.json

VSCode でプロジェクトフォルダを開いて .vscode / launch.json を作成するか、 VSCode の『実行とデバッグ』サイドメニューから『 launch.json の作成』をクリックして C/C++ を選択して、ファイルを作ってもらいます。 launch.json の内容は Modern Fortran の説明にあるサンプル(下記の Formatting の少し上に畳まれています)

をそのまま流用しました(一部日本語にしました)。

{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
    {
        "name": "(gdb) Fortran",
        "type": "cppdbg",
        "request": "launch",
        "program": "${workspaceFolder}/a.out",
        "args": [], // Possible input args for a.out
        "stopAtEntry": false,
        "cwd": "${workspaceFolder}",
        "environment": [],
        "externalConsole": false,
        "MIMode": "gdb",
        "setupCommands": [
            {
                "description": "gdb の再フォーマットを有効にする",
                "text": "-enable-pretty-printing",
                "ignoreFailures": true
            }
        ]
    }
    ]
}

ビルド設定ファイル tasks.json

さて、最初に参考にしたと書いた記事は Fortran プログラムのビルドはコマンドラインからやってました。ビルドをコマンドラインから呼び出すのはちょっとなー、と思うので、これを VSCode で実行するため、

などを参考にして、ビルドを行うための設定を tasks.json に書いておきます。

メニューの『ターミナル』から

『タスクの構成』を選択し、

『テンプレートから tasks.json を生成』を選び

『Others 』を選択すると、 tasks.json のひな形が作られます。これを元に、

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "FORTRAN77 のビルド",
            "type": "shell",
            "command": "gfortran",
            "args": [
                "-g",
                "-O0",
                "${workspaceFolder}/*.f",
                "-o",
                "${workspaceFolder}/a.out"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared",
                "showReuseMessage": true,
                "clear": false
            }
        },
        {
            "label": "Fortran のビルド",
            "type": "shell",
            "command": "gfortran",
            "args": [
                "-g",
                "${workspaceFolder}/*.f90",
                "-o",
                "${workspaceFolder}/a.out"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared",
                "showReuseMessage": true,
                "clear": false
            }
        }
    ]
}

という感じにしました。設定内容は必要に応じて、順次見直していくことになると思います。

テスト

さて、これでビルドとデバッグができるはずです。

まずは、 FORTRAN77 のファイルを開いて『ターミナル』から『ビルドタスクの実行』を選択します。

のように表示されるので、ここは『FORTRAN77 のビルド』を選ぶと、画面下部に

と表示されました。実際、 a.out ファイルも作成されているので、ビルド出来ているようです。

次に、先ほどのファイルにブレークポイントを設定して、デバッグ実行をしてみます。すると、

こんな感じに、ブレークポイントで止まったことがわかります。

次に同じことを .f90 のファイルを対象にしてやっても、特に問題も起きず同じ結果になりました。

とりあえずこれで最小限の設定はできたようです。

まとめ

まさか VSCode で Fortran を触る日が来るとは夢にも思いませんでした。でも、これはこれで楽しい仕事になりそうな予感がしています。