Msys2 の mingw64 で Visualization Toolkit (vtk) のビルドメモ

#Visualization Toolkit (vtk) 導入の動機#
最近の OpenCV には3次元点群の表示や視点操作を行う Viz モジュールが追加されている。しかし、Viz モジュールは内部的に vtk のライブラリを使っているため、vtk を導入する必要がある。今回は、Msys2 の mingw64 での vtk 導入及び、その最新版ビルドをやってみた。

#pacman を使った導入#
Msys2 の mingw64 と mingw32 のリポジトリにはすでに vtk があるので導入は簡単。

```bash:terminal
$ pacman -S mingw-w64-x86_64-vtk # mingw64
```

だが、共有ライブラリのみしかインストールできないし、バージョンが少し古い可能性がある。よって、静的ライブラリを使いたい場合、最新版をいち早く使いたい場合はソースからビルドする必要がある。

注：蛇足）導入した vtk には cmake 用のファイルがついてくるが、パスがハードコーディングされている部分があり、その部分を自分の環境に書き換える必要がある。 `find` と `sed` を使うと楽に書き換えられる。

```bash:terminal
# "D:" の部分は Msys2 をどこにインストールしたかで変わる
# 例) "C:\hogehoge\fugafuga\msys64" なら C:\/hogehoge\/fugafuga
$ find /mingw64/lib/cmake/vtk-6.3 -type f -exec sed -i 's/C:\/building/D:/g' {} +
```

#mingw64 での vtk のビルド#

以下の環境で検証

* Windows 7、msys2 (mingw64_shell.bat で起動したシェルを使用)

① build に必要なものをインストール(他にも必要なものはあるかも知れない)

```bash:terminal
$ pacman -S git mingw-w64-x86_64-gcc mingw-w64-x86_64-cmake mingw-w64-x86_64-qt5
```
注) git の設定は省略

② vtk のソースをダウンロード(結構時間がかかる 30分～1時間？)

```bash:terminal
# 適当な directory に移動
$ cd ~/git_clone

# vtk のソースをダウンロード
$ git clone https://gitlab.kitware.com/vtk/vtk.git

# ビルド用 directory を作成 & 移動
$ mkdir ./vtk/build; cd ./vtk/build
```

③ cmake を使って configure

```bash:terminal
# PATH を一時的に /mingw64/bin に (必須)
$ export PATH=/mingw64/bin

# cmake gui の起動
$ cmake-gui
```

cmake gui が起動する。ソースディレクトリとビルドディレクトリを指定し、`Configure`。`MinGW Makefiles` を選択して `Finish`。設定項目が出てくるので以下の項目を変更。それ以外はデフォルトのままでOK。

```
BUILD_SHARED_LIBS -> on : *.dll / off : *.a
CMAKE_BUILD_TYPE -> Release
CMAKE_INSTALL_PREFIX -> (ソースディレクトリ)/install
VTK_Group_Imaging -> on
VTK_RENDERING_BACKEND -> OpenGL (opencv のビルドに使う場合)
```

再度 `Configure`。エラーが出なければ、`Generate` して、 cmake gui を閉じる。

(2016/01/03 追記)
vtk-7.1 + opencv-3.1.0 の組み合わせでプログラムをビルドすると以下のエラーが発生する模様

```bash:terminal
(vtkのインストールディレクトリ)/lib\libvtkzlib-7.1.a(zutil.obj):zutil.c:(.rdata+0x80): multiple definition of `z_errmsg'
(zlibのインストールディレクトリ)/lib\libz.a(zutil.o):(.rdata+0x80): first defined here
collect2.exe: error: ld returned 1 exit status
Makefile:42: ターゲット '(ビルド中のプログラム名)' のレシピで失敗しました
make: *** [(ビルド中のプログラム名)] エラー 1
```

原因，opencv がリンクする `libz.a` と vtk がリンクする `libvtkzlib-7.1.a` でグローバル変数`z_errmsg`が競合している。libvtkzlib-7.1.a のソースを一部変更して再ビルドすれば解決。
`(vtkのソースディレクトリ)/ThirdParty/zlib/vtkzlib/`内の

```bash:
./zutil.c:17:z_const char * const z_errmsg[10] = {
./zutil.h:47:extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
./zutil.h:50:#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
```
において`z_errmsg`を競合しない適当な名称に変更 (例：vtk_z_errmsg とか) すればおk。

④ make コマンドを実行してビルド & インストール

```bash:terminal
# make コマンドを実行
$ mingw32-make -j6 # CPU のコア数が 4 なら "-j4"

# インストール
$ mingw32-make install
```

(2015/9/27 現在、以下のエラーは修正された模様)
注) ビルド中に以下のリンカエラー

```
undefined reference to `__imp_SymSetOptions'
undefined reference to `__imp_SymInitialize'
undefined reference to `__imp_SymFromAddr'
undefined reference to `__imp_SymGetLineFromAddr64'
```

libimagehlp.a と libpsapi.a がリンク時に必要 (D:\msys64\mingw64\x86_64-w64-mingw32\libに存在)

別なシェルを立ち上げて、以下のコマンドを実行。各 "linklibs.rsp" の末尾に "-limagehlp -lpsapi" が追記されるので、再ビルド。

```bash:terminal
$ find ~/git_clone/vtk/build -name "linklibs.rsp" -exec sed -i 's/$/-limagehlp\ -lpsapi/g' {} +
```

make install コマンドが完了すると`CMAKE_INSTALL_PREFIX`で指定したディレクトリにライブラリが格納されるので、ディレクトリごと `/msys64/mingw64/local` 以下に移動し、`vtk-6.3` にリネーム。

⑤ sample program のコンパイルと実行
以下の URL に vtk の c++ サンプルがある。
http://www.vtk.org/Wiki/VTK/Examples/Cxx

"A hello world example" のコンパイルと実行を行う。
ソース (Cylinder.tar) をダウンロードして展開。build フォルダへ移動し以下のコマンドを実行。

```bash:terminal
# PATH を一時的に /mingw64/bin に (必須)
$ export PATH=/mingw64/bin

# cmake で configure
$ cmake -G'MinGW Makefiles' -DCMAKE_PREFIX_PATH=/mingw64/local/vtk-6.3 ..

# make コマンドを実行
$ mingw32-make -j6 # CPU のコア数が 4 なら "-j4"

# program 実行
./Cylinder
```
![vtk.PNG](https://qiita-image-store.s3.amazonaws.com/0/88260/12b89a6f-963a-9e65-59ea-7d59aad93a6a.png)