VTKFortranをWindowsでビルドする

# 概要
VTKファイルフォーマットをFortranで扱うためのオープンソースライブラリ[VTKFortran](https://github.com/szaghi/VTKFortran)をWindowsでビルドする手順を整理しました．
VTKFortranのリポジトリにも書かれていますが，Linux上で開発されており，他のOSはサポートされていません．
WSLやMacOSでは簡単にビルドできますが，Windowsでビルドするには色々と問題がありました．
いくつかの方法でビルドする方法を見つけたので，備忘録的にまとめます．

# 環境
- VTKFortran v2.0.1
- Windows 10 Pro 20H2
- cmake 3.14.5
- GNU Make 3.8.1
- gfortran 8.1.0
- git for Windows 2.29.2
- MinGW-W64 x86_64-8.1.0
- Python 3.8.5 (Anaconda individual edition 4.10.1)
- ParaView 5.8.0 for Windows
- Ubuntu 18.04 (on WSL)
- macOS 10.15.6

## ディレクトリ構成
下記のようなディレクトリ構成を想定して作業していきます．

```console
├── (ここにVTKFortranを持ってくる)
├── src
│   └── main.f90
├── include
└── lib
```

# VTKFortran
[VTK](https://vtk.org)とは，Visualization ToolKitの略で，3DCG，画像処理，科学的可視化のためのオープンソースソフトウェア（正確にはC++のクラスライブラリと， Tcl/Tk, Java, Python用のインタフェース）です．本記事で対象とするのは，オープンソースソフトウェアではなく，VTKで定められたファイルフォーマットです．以後，区別するために，VTKファイルフォーマットと称します．

VTKは，C++，Tcl/Tk, Java, Pythonを対象としているため，それぞれの言語のネイティブな記述で，VTKに定められたデータ構造の作成や入出力が可能です．一方，VTKにはFortran用のインタフェースが用意されていないので，FortranでVTKファイルフォーマットを取り扱うには，個々人で特定の形式に対する入出力ルーチンを作成するか，C++言語との混合言語プログラミングが必要になります[^jsces]．

[^jsces]: 計算工学会の学会誌に[ParaViewのチュートリアル記事](https://www.jsces.org/activity/journal/web_vol26no2_tutorial.pdf)が掲載されている．

VTKファイルフォーマットにはレガシー形式とXML形式があり，情報として入手できるのは主にレガシー形式の方でした．また，情報もほとんどがASCII形式で取り扱うように書かれており，それらを参考にすると，どうしてもファイルサイズが増加するという問題もありました．

VTKFortranは，XML形式のVTKファイルフォーマットを取り扱える，純粋なFortranのライブラリとして開発されました．開発にはFortran 2003が用いられており，ASCII形式, Base64エンコードのバイナリ形式，RAW形式をサポートしています．

ライセンスはいくつかあり，オープンソースのプロジェクトに対してはGPL v3，オープンソースでない，または商用のプロジェクトに対しては，BSD 2-Clause, BSD 3-Clause, MIT[^li]となっています．

[^li]: あなたの魂に最も合うするライセンスを選んでくださいと書いてある．

## VTKFortranコードの入手
VTKFortranのコードは，Githubから入手します．このとき，単純に`git clone`するのではなく，VTKFortranが参照する外部のリポジトリもまとめてクローンするようにします[^install]．

```console
> git clone --recursive https://github.com/szaghi/VTKFortran.git
```

そうすると，プロジェクトのルートにVTKFortranディレクトリが作られるので，そのディレクトリに移動して，`git submodule update`を実行します．

```console
> cd VTKFortran
VTKFortran> git submodule update --init --recursive
```

[^install]: https://qiita.com/yuyum/items/0a8b29d18f07309b050e

recursiveという表現が多いと思われるかも知れませんが，VTKFortranは外部のリポジトリを何重にも引っ張ってきているので，依存関係は結構面倒です．

## VTKFortranのビルド（macOS，WSL）
いわゆるUnix系のシェルとコマンドが使える環境では，ビルドは非常に簡単です．ルートに`makefile`が用意されているので，`make`を実行すると静的ライブラリ`libvtkfortran.a`が作成されます．

```console
VTKFortran$ make
 Compiler used  gnu => /usr/bin/gfortran
 Source dir     src/
  Lib dir        ./static/
  Libray         ./static/libvtkfortran.a
  Shared lib     no
  Debug          no
  F-standard     no
  Optimize       no
  OpenMP         no
  MPI            no

 Compile options
 [-cpp -c -J./static/mod/ ]

 Link options
 [ ]

 Compile penf_global_parameters_variables.F90
 Compile penf_b_size.F90
 Compile penf_stringify.F90
 Compile penf.F90
 Compile befor64_pack_data_m.F90
 Compile befor64.F90
 Compile face.F90
 Compile stringifor_string_t.F90
 Compile stringifor.F90
 Compile foxy_xml_tag.F90
 Compile foxy_xml_file.f90
 Compile foxy.f90
 Compile vtk_fortran_parameters.f90
 Compile vtk_fortran_vtk_file_xml_writer_abstract.f90
 Compile vtk_fortran_dataarray_encoder.f90
 Compile vtk_fortran_vtk_file_xml_writer_ascii_local.f90
 Compile vtk_fortran_pvtk_file.f90
 Compile vtk_fortran_vtk_file_xml_writer_appended.f90
 Compile vtk_fortran_vtk_file_xml_writer_binary_local.f90
 Compile vtk_fortran_vtk_file.f90
 Compile vtk_fortran_vtm_file.F90
 Compile vtk_fortran.f90
 Assemble VTKFortran
```

ただし，macOSの場合は長々と警告が出ます．

```console
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: ./static/libvtkfortran.a(foxy.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: ./static/libvtkfortran.a(vtk_fortran_parameters.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: ./static/libvtkfortran.a(foxy.o) has no symbols
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib: file: ./static/libvtkfortran.a(vtk_fortran_parameters.o) has no symbols
```

このとき，ビルドした結果は`VTKFortra/static`に出力されます．`libvtkfortran.a`は`static`ディレクトリに，オブジェクトファイルは`static/obj`に，モジュールファイルは`static/mod`に出力されます．`libvtkfortran.a`を`lib`に，`mod`ファイルを`include`ディレクトリにコピーして利用します．

```console
├── VTKFortran
├── src
│   └── main.f90
├── include
│   └── *.mod
└── lib
    └── libvtkfortran.a
```

## VTKFortranのビルド（Windows）
いわゆるUnix系のシェルとコマンドが使える環境では，ビルドは簡単だと述べました．Windows環境では，ビルドがかなりややこしくなります．VTKFortranは，何通りかのビルド方法を提供していますが，それぞれで問題が生じるためです．

### cmakeを使う
VTKFortranのルートに`CMakeLists.txt`があるので，`cmake`でビルドできそうなのですが，実際にはビルドできません．ルートにある`CMakeLists.txt`内では，`ADD_SUBDIRECTORY`で`VTKFortran\src\lib`と`VTKFortran\src\test`を追加していますが，`lib`ディレクトリに`CMakeLists.txt`が無く，また`test`ディレクトリ自体存在しません（`tests`はあるが，その中に`CMakeLists.txt`はない）．そのため，`cmake`を実行するとエラーが生じ，またコンパイルするソースファイルが一切指定されてないという状況になります．

```CMake
ADD_SUBDIRECTORY(${LIB_SRC_PATH})
ADD_SUBDIRECTORY(${TEST_SRC_PATH})
```

```console
VTKFortran> cmake -H. -B build -G "Unix Makefiles" -DCMAKE_Fortran_COMPILER=gfortran
-- The Fortran compiler identification is GNU 8.1.0
中略
CMake Error at CMakeLists.txt:154 (ADD_SUBDIRECTORY):
  The source directory

    中略/VTKFortran/src/lib

  does not contain a CMakeLists.txt file.


CMake Error at CMakeLists.txt:155 (ADD_SUBDIRECTORY):
  ADD_SUBDIRECTORY given source
  "中略/VTKFortran/src/test" which is not an
  existing directory.

以下省略
```

しかし，参照するべきソースファイルは判っていますし，コンパイルオプションも`CMakeLists.txt`で設定されているので，それらのソースを明記して`add_library`を呼べば，ライブラリは作成できます．

参照するべきソースファイルは，`VTKFortran\src\lib\*.f90`と`*.F90`，VTKFortranが参照するモジュールのソース`VTKFortran\src\third_party\BeFoR64\src\lib\*.F90`，`VTKFortran\src\third_party\FACE\src\lib\*.F90`，`VTKFortran\src\third_party\FoXy\src\lib\*.f90`と`*.F90`，
`VTKFortran\src\third_party\PENF\src\lib\*.F90`，`VTKFortran\src\third_party\StringiFor\src\lib\*.F90`です．

`ADD_SUBDIRECTORY`をコメントアウトして，（非常に適当ですが）以下のように`CMakeLists.txt`を修正すると，`libvtkfortran.a`と`mod`ファイルが作成されます．

```CMake
FILE(GLOB lib "${SRC_PATH}/lib/*.f90")
FILE(GLOB BeFoR64 "${SRC_PATH}/third_party/BeFoR64/src/lib/*.f90")
FILE(GLOB FACE "${SRC_PATH}/third_party/FACE/src/lib/*.f90")
FILE(GLOB FoXy "${SRC_PATH}/third_party/FoXy/src/lib/*.f90")
FILE(GLOB PENF "${SRC_PATH}/third_party/PENF/src/lib/*.f90")
FILE(GLOB StringiFor "${SRC_PATH}/third_party/StringiFor/src/lib/*.f90")


add_library(vtkfortran STATIC
${lib}
${BeFoR64}
${FACE}
${FoXy}
${PENF}
${StringiFor}
)
```

```console
VTKFortran> cmake -H. -B build -G "Unix Makefiles" -DCMAKE_Fortran_COMPILER=gfortran
-- The Fortran compiler identification is GNU 8.1.0
以下省略

VTKFortran> cmake --build build
以下省略
```

`VTKFortran\build\lib`に`libvtkfortran.a`が，`VTKFortran\build\modules`に`mod`ファイルが作成されます．

この方法は，一度`CMakeLists.txt`を書いてしまうと途中で警告も出ないのですが，6年前に作られて更新されていない`CMakeLists.txt`で本当に大丈夫なのか気になります．

### makefileを使う
GNU Make for Windows等をインストールしている場合，`make`コマンドが実行できるので，`makefile`を参照してビルドできると思うかもしれません．しかし，VTKFortranの`makefile`はLinuxで実行する事を前提に書かれているので，コマンドプロンプトで実行しても，構文エラーで止まってしまいます．

```console
VTKFortran> make
process_begin: CreateProcess(NULL, which gfortran, ...) failed.
ECHO は <OFF> です。
-e "\\033[1;31m Compiler used \\033[0m\\033[1m gnu => \\033[0m \n \\033[1;31mSource dir    \\033[0m\\033[1m src/\\033[0m \n \\033[1;31m Lib dir       \\033[0m\\033[1m ./static/\\033[0m \n \\033[1;31m Libray        \\033[0m\\033[1m ./static/libvtkfortran.a\\033[0m \n \\033[1;31m Shared lib    \\033[0m\\033[1m no\\033[0m \n \\033[1;31m Debug         \\033[0m\\033[1m no\\033[0m \n \\033[1;31m F-standard    \\033[0m\\033[1m no\\033[0m \n \\033[1;31m Optimize      \\033[0m\\033[1m no\\033[0m \n \\033[1;31m OpenMP        \\033[0m\\033[1m no\\033[0m \n \\033[1;31m MPI           \\033[0m\\033[1m no\\033[0m "
ECHO は <OFF> です。
-e "\033[1;31m Compile options\033[0m"
-e "\033[1m [-cpp -c -J./static/mod/ ]\033[0m"
ECHO は <OFF> です。
-e "\033[1;31m Link options \033[0m"
-e "\033[1m [ ]\033[0m"
ECHO は <OFF> です。
コマンドの構文が誤っています。
make: *** [static/obj] Error 1
```

Git for Windowsを利用している場合，git-bashの本体である`bash.exe`が利用できます．Git for Windowsを`C:\Program Files\Git`にインストールしているのであれば，下記のように`bash.exe`を起動できます．この状態で`make`を実行すると，構文エラーにならずに処理が進んでいきます．

```console
VTKFortran> "C:\Program Files\Git\bin\bash.exe"
 MINGW64 中略/VTKFortran (master)
$ make

 Compiler used  gnu => /c/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/gfortran
 Source dir     src/
  Lib dir        ./static/
  Libray         ./static/libvtkfortran.a
  Shared lib     no
  Debug          no
  F-standard     no
  Optimize       no
  OpenMP         no
  MPI            no

 Compile options
 [-cpp -c -J./static/mod/ ]

 Link options
 [ ]

 Compile penf_global_parameters_variables.F90
 Compile penf_b_size.F90
 Compile penf_stringify.F90
 Compile penf.F90
 Compile befor64_pack_data_m.F90
 Compile befor64.F90
 Compile face.F90
 Compile stringifor_string_t.F90
 Compile stringifor.F90
 Compile foxy_xml_tag.F90
 Compile foxy_xml_file.f90
 Compile foxy.f90
 Compile vtk_fortran_parameters.f90
 Compile vtk_fortran_vtk_file_xml_writer_abstract.f90
 Compile vtk_fortran_dataarray_encoder.f90
 Compile vtk_fortran_vtk_file_xml_writer_ascii_local.f90
 Compile vtk_fortran_pvtk_file.f90
 Compile vtk_fortran_vtk_file_xml_writer_appended.f90
 Compile vtk_fortran_vtk_file_xml_writer_binary_local.f90
 Compile vtk_fortran_vtk_file.f90
 Compile vtk_fortran_vtm_file.F90
 Compile vtk_fortran.f90
 Assemble VTKFortran
/usr/bin/link: extra operand './static/obj/befor64_pack_data_m.o'
Try '/usr/bin/link --help' for more information.
```

コンパイルは順調に進んでいきますが，最後の最後，`libvtkfortran.a`を作成する段階でエラーが出て止まります．この解決方法は判りませんが，`bash.exe`から抜けて，MinGW等の`ar.exe`を使って静的ライブラリを作成します．

```console
$ exit

VTKFortran> cd static\obj
VTKFortran\static\obj> ar cr libvtkfortran.a *.o
vtk_fortran_parameters.o : warning LNK4221: このオブジェクト ファイルは、以前に未定義であったパブリック シンボルを定義していないため、このライブラリを使用するリンク操作では使用されません
foxy.o : warning LNK4221: このオブジェクト ファイルは、以前に未定義であったパブリック シンボルを定義していないため、このライブラリを使用するリンク操作では使用されません
```

リンクの警告が出ますが，無事に`libvtkfortran.a`が作成されます．試したところ，動作も問題無いようです．

### FoBiS.pyを使う
VTKFortranの作者は，[FoBiS.py](https://github.com/szaghi/FoBiS)というFortran用のビルドシステムも作成しています．そのため，FoBiS.pyを利用したビルドも可能です．

FoBiS.pyは`pip`を用いてインストールできます．このとき，コマンドは`pip install FoBiS.py`で，.pyまで入力する必要があります．

FoBiS.pyでビルドする際は，ビルドの情報を記載した`fobos`というファイルをプロジェクトのルートに置き，その中でビルドモードを指定します．

ビルドモードを確認するには`FoBiS.py build -lmodes`を実行します．`.py`ファイルを`python.exe`あるいは`python3.exe`に関連付けており，FoBiS.pyのインストールディレクトリにパスが通っている場合は`FoBiS.py build -lmodes`で問題ありません．関連付けていない場合は，`python FoBiS.py build -lmodes`とする必要がありますし，FoBiS.pyのインストールディレクトリにパスが通っていない場合には，FoBiS.pyへのフルパスを指定する必要があります．

```console
VTKFortran> python C:\ProgramData\Anaconda3\Scripts\FoBiS.py build -lmodes
The fobos file defines the following modes:
  - "shared-gnu"
  - "static-gnu"
  - "tests-gnu"
  - "shared-gnu-debug"
  - "static-gnu-debug"
  - "tests-gnu-debug"
  - "shared-intel"
  - "static-intel"
  - "tests-intel"
  - "shared-intel-debug"
  - "static-intel-debug"
  - "tests-intel-debug"
```

`static-gnu`モードでビルドするには，`-mode`で指定します．

```console
VTKFortran> python C:\ProgramData\Anaconda3\Scripts\FoBiS.py build -mode static-gnu
Builder options
  Directories
    Building directory: "static"
    Compiled-objects .o   directory: "static\obj"
    Compiled-objects .mod directory: "static\mod"
  Compiler options
    Vendor: "gnu"
    Compiler command: "gfortran"
    Module directory switch: "-J"
    Compiling flags: "-cpp -c -frealloc-lhs -O2"
    Linking flags: "-O2"
    Preprocessing flags: ""
    Coverage: False
    Profile: False
  Preprocessor used: None
  Preprocessor output directory: None
  Preprocessor extensions processed: []

Building src\lib\vtk_fortran.f90
Compiling src\third_party\StringiFor\src\third_party\PENF\src\lib\penf_global_parameters_variables.F90 serially
Compiling src\third_party\StringiFor\src\third_party\PENF\src\lib\penf_b_size.F90 serially
Compiling src\third_party\StringiFor\src\third_party\PENF\src\lib\penf_stringify.F90 serially
Compiling src\third_party\StringiFor\src\third_party\PENF\src\lib\penf.F90 serially
Compiling src\third_party\StringiFor\src\third_party\BeFoR64\src\lib\befor64_pack_data_m.F90 serially
Compiling src\third_party\StringiFor\src\third_party\BeFoR64\src\lib\befor64.F90 serially
Compiling src\third_party\StringiFor\src\third_party\FACE\src\lib\face.F90 serially
Compiling src\third_party\StringiFor\src\lib\stringifor_string_t.F90 serially
Compiling src\third_party\StringiFor\src\lib\stringifor.F90 serially
Compiling src\third_party\FoXy\src\lib\foxy_xml_tag.F90 serially
Compiling src\third_party\FoXy\src\lib\foxy_xml_file.f90 serially
Compiling src\third_party\FoXy\src\lib\foxy.f90 src\lib\vtk_fortran_parameters.f90 using 2 concurrent processes
Compiling src\lib\vtk_fortran_vtk_file_xml_writer_abstract.f90 src\lib\vtk_fortran_dataarray_encoder.f90 using 2 concurrent processes
Compiling src\lib\vtk_fortran_vtk_file_xml_writer_ascii_local.f90 serially
Compiling src\lib\vtk_fortran_vtk_file_xml_writer_appended.f90 src\lib\vtk_fortran_vtk_file_xml_writer_binary_local.f90 using 2 concurrent processes
Compiling src\lib\vtk_fortran_pvtk_file.f90 src\lib\vtk_fortran_vtk_file.f90 src\lib\vtk_fortran_vtm_file.F90 using 3 concurrent processes
Compiling src\lib\vtk_fortran.f90 serially
Linking static\libvtkfortran.a
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\Scripts\FoBiS.py", line 29, in <module>
    main()
  File "C:\ProgramData\Anaconda3\lib\site-packages\fobis\fobis.py", line 51, in main
    run_fobis()
  File "C:\ProgramData\Anaconda3\lib\site-packages\fobis\fobis.py", line 77, in run_fobis
    run_fobis_build(configuration)
  File "C:\ProgramData\Anaconda3\lib\site-packages\fobis\fobis.py", line 109, in run_fobis_build
    build_pfile(configuration=configuration, pfile=pfile, pfiles=pfiles, nomodlibs=nomodlibs, submodules=submodules, builder=builder)
  File "C:\ProgramData\Anaconda3\lib\site-packages\fobis\fobis.py", line 328, in build_pfile
    builder.build(file_to_build=pfile, output=configuration.cliargs.output, nomodlibs=nomodlibs, submodules=submodules, mklib=configuration.cliargs.mklib, verbose=configuration.cliargs.verbose, log=configuration.cliargs.log, track=configuration.cliargs.track_build)
  File "C:\ProgramData\Anaconda3\lib\site-packages\fobis\Builder.py", line 627, in build
    result = syswork(link_cmd)
  File "C:\ProgramData\Anaconda3\lib\site-packages\fobis\utils.py", line 49, in syswork
    output = str(output, encoding='UTF-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 26: invalid start byte
```

実行すると，`make`を実行したときのようにコンパイルが進んでいきますが，最後の最後にエラーが出ます．しかし，このエラーは`UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 26: invalid start byte`とあるように，静的ライブラリの作成ではなく，画面表示に関係していると考えられます．実際，`VTKFortran\static`ディレクトリには`libvtkfortran.a`が作成されています．

そこで，ちょっと強引ですが，エラーの原因になっている`utils.py`の当該箇所（49行目）で，エラーを無視するようにしてみます．

```Python
    output = str(output, encoding='UTF-8', errors='ignore')
```

再び実行すると，[`makefile`の節](https://qiita.com/implicit_none/items/567732f30461db3a0b17#makefile%E3%82%92%E4%BD%BF%E3%81%86)で出ていた警告warning LNK4221が文字化けして表示されている事が確認できます．生じていたエラーは，S-JISで出力されたwarning LNK4221のメッセージをUTF-8として処理しようとしたことが原因であって，ビルドに関するエラーではないと推察されます．

```console
VTKFortran> python C:\ProgramData\Anaconda3\Scripts\FoBiS.py build -mode static-gnu
Builder options
  Directories
    Building directory: "static"
    Compiled-objects .o   directory: "static\obj"
    Compiled-objects .mod directory: "static\mod"
  Compiler options
    Vendor: "gnu"
    Compiler command: "gfortran"
    Module directory switch: "-J"
    Compiling flags: "-cpp -c -frealloc-lhs -O2"
    Linking flags: "-O2"
    Preprocessing flags: ""
    Coverage: False
    Profile: False
  Preprocessor used: None
  Preprocessor output directory: None
  Preprocessor extensions processed: []

Building src\lib\vtk_fortran.f90
Nothing to compile, all objects are up-to-date
Linking static\libvtkfortran.a
static\obj\penf_global_parameters_variables.o u
static\obj\vtk_fortran_vtk_file_xml_writer_ascii_local.o u
static\obj\befor64.o u
static\obj\foxy.o u
static\obj\penf_b_size.o u
static\obj\foxy_xml_file.o u
static\obj\stringifor_string_t.o u
static\obj\vtk_fortran_vtm_file.o u
static\obj\stringifor.o u
static\obj\vtk_fortran_dataarray_encoder.o u
static\obj\vtk_fortran_parameters.o u
static\obj\penf.o u
static\obj\vtk_fortran_vtk_file_xml_writer_abstract.o u
static\obj\vtk_fortran.o u
static\obj\face.o u
static\obj\penf_stringify.o u
static\obj\foxy_xml_tag.o u
static\obj\vtk_fortran_vtk_file_xml_writer_appended.o u
static\obj\vtk_fortran_pvtk_file.o u
static\obj\vtk_fortran_vtk_file_xml_writer_binary_local.o u
static\obj\vtk_fortran_vtk_file.o u
static\obj\befor64_pack_data_m.o u
vtk_fortran_parameters.o : warning LNK4221: ̃IuWFNg t@ĆAȑOɖ`łpubN V{`ĂȂ߁ÃCugp郊Nł͎gp܂
foxy.o : warning LNK4221: ̃IuWFNg t@ĆAȑOɖ`łpubN V{`ĂȂ߁ÃCugp郊Nł͎gp܂

Target src\lib\vtk_fortran.f90 has been successfully built
```

出力ディレクトリはmakeを使う場合と同じで，`VTKFortran\static`に`libvtkfortran.a`が，`VTKFortran\static\mod`に`mod`ファイルが作成されます．

# テスト実行
作成した静的ライブラリが本当に動作しているかを確認するため，VTKFortranが用意しているテストを一つ実行してみます．
`VTKFortran\src\tests`にある`vtk_fortran_write_pvts.f90`を`src\main.f90`としてコピーし，コンパイル，実行してファイルが出力されるかを確認します．

ディレクトリ構造は下記のようになっているのでした．

```console
├── src
│   └── main.f90
├── include
│   └── *.mod
└── lib
    └── libvtkfortran.a
```

下記のように`include`および`lib`ディレクトリを指定して，`-l`オプションでVTKFortranの静的ライブラリを指定します．

```
> gfortran src\main.f90 -Iinclude -Llib -lvtkfortran
```

実行ファイルが作成されるので，それを実行すると，`XML_STRG-binary.vts`および`XML_STRG-raw.vts`が作成されます．

ParaViewで開いてみると，無事に開くことができ，正しく出力できていることが確認できました．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/fee90f95-cd45-ccad-1e60-f2856ff138d5.png)


# まとめ
VTKFortranをWindowsでビルドする方法を紹介しました．それぞれに問題がありますが，FoBiS.pyを使うのが比較的簡単だと思います．

## cmakeを使う場合

1. VTKFortranのルートにあるCMakeLists.txtを編集する．
    1. CMakeLists.txt末尾にある`ADD_DIRECTORY`をコメントアウトする．
    1. コンパイルするソースファイルをリストに格納し，`add_library`に追加する．
1. cmakeでビルドする

## makefileを使う場合
1. コマンドプロンプトでGit for Windowsに付属している`bash.exe`を起動する．
1. `make`する．コンパイルは無事できてオブジェクトファイルが作られるが，静的ライブラリの作成に失敗する．
1. `bash.exe`を抜けてコマンドプロンプトに戻り，MinGW等に付属している`ar.exe`で静的ライブラリを作成する．

## FoBiS.pyを使う場合
1. `pip`でFoBiS.pyをインストールする．
1. `FoBiS.py build -lmodes`でビルドモードを確認する．
1. `FoBiS.py build -mode ビルドモード`でビルドする．
    1. 最後にスクリプトエラーが出てくる場合があるが，それはリンクの警告を異なるエンコーディングで処理しようとしてるために生じている．
    1. 気になる場合は，FoBiS.pyの`utils.py`のエラーを無視するようにスクリプトを修正する．