OpenSiv3DのPKGBUILDを書いてみた

#はじめに

おはこんばんちわ。最近あまりLinux版の移植に時間を取れていないwyndです。
移植に全く興味がなくなった訳ではなく、単に第3四半期が想像以上に忙しくてダメでした。年明けから移植作業再開できたらいいなという感じです。がんばります。

というわけで軽めに思えるネタということで、普段自分が使っているArchLinuxでパッケージを作成するための記述ファイルであるPKGBUILDの作成をしてみることにしました。
OpenSiv3D Linux版の導入が面倒なのは前々からまずいなと思っていたところで、これが上手く完成すれば少なくともArchLinuxでは導入が相当簡単になるはずで、期待が高まりますね(フラグ)。

PKGBUILDはArchLinuxにおいてパッケージを作るためにパッケージのバージョンや依存関係、ビルドの手順等を記述するファイルです。今回は、砕いて言うと以下の内容を記述します。

- パッケージ名とバージョン情報
- 依存しているパッケージのリスト
- パッケージのソース
- ビルド手順(`build()`)
- パッケージ作成手順(`package()`)


#成果物

早速ですが今回書いたPKGBUILDを示します。[ここ]( https://github.com/wynd2608/opensiv3d_pkgbuild )に置いてあります。
実のところ、PKGBUILDを書くのは初めてだったので、mozcの辞書とlibc++あたりのPKGBUILDを参考に見様見真似で書きました。

```
_opencvrev=ab981c2c628168d5dd4acb979672305d7c9bdc07

pkgname=opensiv3d
pkgdesc="OpenSiv3D a C++ 17 framework for games and interactive media"
pkgver=r2626.ab981c2c
pkgrel=1
arch=('x86_64')
url="https://github.com/Siv3D/OpenSiv3D/"
license=('MIT')
depends=('boost' 'glew' 'glib2' 'libpng' 'libjpeg-turbo' 'libx11' 'libxi' 'libxrandr' 'libxinerama' 'libxcursor' 'freetype2' 'harfbuzz' 'openal' 'opencv' 'box2d' 'systemd' 'upower')
makedepends=('cmake' 'clang' 'pkg-config')
OPTIONS=(!strip docs !libtool staticlibs emptydirs zipman purge upx debug)

source=(opensiv3d::git+https://github.com/Siv3D/OpenSiv3D.git#commit=${_opencvrev})

sha1sums=('SKIP')

pkgver() {
	cd "$pkgname"
	printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}

build() {
	cd "${srcdir}/opensiv3d/Linux"
	git checkout linux

	[[ -d build ]] || mkdir build
	cd build

	sed -i -e 's/opencv/opencv4/' ${srcdir}/opensiv3d/Linux/CMakeLists.txt

	cmake \
	  -DCMAKE_BUILD_TYPE=Release \
	  -DCMAKE_INSTALL_PREFIX=/usr \
	  ${srcdir}/opensiv3d/Linux
	make
}

package() {
	install -Dm644 ${srcdir}/opensiv3d/LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
	
	cd "${srcdir}/opensiv3d/Linux/build"
	make DESTDIR="${pkgdir}/" install

	sed -i -e 's/opencv4/opencv/' ${srcdir}/opensiv3d/Linux/CMakeLists.txt
}
```

スタティックライブラリもインストールするために`OPTIONS`に`staticlibs`を指定して、ArchLinuxではOpenCVのバージョン4が降ってきた(早い)ので`sed`でCMakeLists.txtの依存パッケージチェック部分を書き換えるようにしました。

また、`make install`が動くようにCMakeLists.txtも書き換えましたが、ちょっと怪しいところがある(後述)ため、CMakeLists.txtもPKGBUILDを置いたリポジトリに入れました。

こうして、リポジトリにあるPKGBUILDとCMakeLists.txtの組み合わせで一応パッケージの作成とインストールはできるようになったのですが、めでたしめでたしとはいきませんでした。


# つまづいている事
ここでは、めでたしめでたしとはいかなかった理由を具体的に述べます。

## ヘッダの位置
OpenSiv3Dのヘッダの配置は以下のようになっています。

```
OpenSiv3D
└　Siv3D
　　└ include
　　　　├ Siv3D
　　　　├ HamFramework
　　　　├ ThirdParty
　　　　├ Siv3D.hpp
　　　　└ HamFramework.hpp
```

愚直に`include`以下を`/usr/include`にインストールすると`/usr/include/Siv3D.hpp`とかはいい感じですが`/usr/include/ThirdPaty`があまりよろしくないです。インストール先を`/usr/include/Siv3D`などにするか`ThirdParty`ディレクトリを動かすかする必要があると思います。

## `Warning: package contains reference to $srcdir`問題
PKGBUILDをもとにビルドをすると、ソースになるファイルは全て`src`というディレクトリに入れられ、そこでコンパイル等を行った後にパッケージとしてインストールするファイルを`pkg`というディレクトリに移しますが、移した後のファイルの内容に`src`ディレクトリへの参照が含まれていると出るのが見出しの警告です。どうやら、`__FILE__`マクロが悪さをしているようなのですが、上手く解決できず、結局Dオプションで`＿＿FILE＿＿`マクロを上書きして警告を消しました。
今回編集したCMakeLists.txtをOpenSiv3Dのリポジトリではなく、PKGBUILDと同じリポジトリの方に置いたのは上記の措置は流石に雑すぎると判断したからです。また、この問題の解決方法が分かる方がいらっしゃいましたら教えていただけると非常に助かります。

## OpenCV4だとリンクが通らない箇所がある
ArchLinuxでは既にOpenCV4のパッケージがインストール出来るのは既に述べたとおりですが、OpenSiv3Dで使っているOpenCVの関数の引数が一部異なっているため、パッケージはできたものの、最後に自作のプログラムをリンクしようとしたところでリンクエラーとなってしまいました。引数が`Mat`から`InputArray`と`OutputArray`に変わった関数がリンクできないようです。使うOpenCVのバージョンについても議論が必要そうです。


# おわりに

ここから先、問題解決の仕方はslack等で話し合ったほうがいいかなとも思いましたので、パッケージは一応作れたが、ちゃんと決めなければいけないところもまだあるという結論で締めさせていただきます。
この記事は不完全燃焼感ありありですみませんが、この結果を踏み台にLinux版をよりよいものにしていければと思います。

**Linux版の開発を手伝っていただける方も随時募集中です。slackのlinuxチャンネルでお待ちしておりますので興味があれば是非参加してください!**