読者です 読者をやめる 読者になる 読者になる

non vorrei lavorare

ブログ名の通りです。javascript three.js mruby rust OCaml golang julialang blender

WebGLを使ったElectronアプリをTravis CIで動かすまで

こんにちは、iPhone 7 Plusで息子たちの写真をまた撮る回数が増えた気がしています。kjunichiです。

背景

WebGLを使ったデスクトップマスコットアプリのGopheronを開発しており、これまでノーテストだったのだけど、 さすがに2年連続で東京Node学園祭で@t_wadaさんのセッションを聞いたら、テスト書かずにはいられなくなった。

実は

CI環境のNightmareでWebGLを動かす方法や、NightmareでWebGL 2.0を動かす方法

なる記事もすでに書いており、今回は実際にうごかすだけ、楽勝のはずだった。。。

必要な物たち

Xvfb

これは、「Electronアプリ」、 「Travis CI」程度のキーワードでググれば出てる。

Electron公式にも

electron/testing-on-headless-ci.md at master · electron/electron

なるページがあり、Travis CIでのXvfbの動かし方まで解説してくれている。

libmesa.so

XvfbでElectronでWebGLを使う際にOpenGL周りの処理をソフト的に処理するライブラリ。 Chromiumのソースツリーから生成出来る。Travis CIでは以下の様にして、生成出来た。

savedDir=`pwd`
mkdir chromium
cd chromium
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
export PATH=$PATH:$savedDir/chromium/depot_tools
fetch --nohooks --no-history chromium
./build/install-build-deps.sh
gclient runhooks
cd src
gn gen out/Default
ninja -C out/Default osmesa
cd $savedDir
cp $savedDir/chromium/src/out/Default/libosmesa.so .

Electronで使える場所におく

libosmesa.soをelectronのバイナリと同一階層のディレクトリに置けば、--use-gl=osmesaでElectronを起動した際に 読み込んでくれる。このあたりは、Chromiumと同じがコード動いているからと思われる。

gopheronはelectronをグローバルにインストールしている環境を想定しているので、travis CIのnode.jsのインストールディレクトリが どこか分からないと、このlibosmesa.soを配置できない。

まぁ、Travis CIはnode.jsはnvmベースで入れているようなので、.nvm配下を探っても割り出せるが、 npmで便利なコマンドが用意されていた。

npm config get prefix

これで、node.jsがどこにインストールされているか分かるので、

cp libosmesa.so `npm config get prefix`/lib/node_modules/electron/dist

これでlibosmesa.soが無事Electronが読み込めるディレクトリに配置できた。

Travis ciでの表示確認

当初はImageMagickで差分をとることで、Xvfb起動直後の何もない画面とElectronアプリ起動後の画面を比較し 差分が出れば、Electronアプリが起動しているとみなせると考えており、実際差分がでており、これでめでたくテスト と成功としようとした。

ImageMagickの差分は

で初めて知って以来、お世話になってます。

なんか怪しいかも

念のため、imgcat系のコマンドでログに画面のダンプを表示を試みた。

なにも考えずimgcatでググるとiTerm2用のコマンドの紹介出てくるが、これらではなく、でLinuxで動く文字ベースのツールを 探し、以下を見つけた。

画像処理は最近はやってるヘッダライブラリ形式のライブラリを使ってるみたいだった。pngやjpgが表示出来た。

すると以下のような有様。

f:id:kjw_junichi:20161123134749p:plain

macOS上でVirtualBoxを動かし、これにUbuntuを入れてTravisと同等の環境をつくって試すと、コンソール表示でも それなりにGopher君の水色の表示が確認できる。

[f:id:kjw_junichi:20161123135707p:plain:w:500]

何か変だ

Travis CIで生成した画像ファイルを確認したい

Travis CIでの表示を画像ファイルベースで確認したくなる。 テスト時に生成したファイルをTravis CIから別の場所に置く必要がある。

Travis CIでcurlコマンドが使えそうなので、Herokuでアップロードファイルの受け口を 用意して、Travis CIで画像生成後このcurlコマンドでアップロードすることで確認した。

と、さっと書いてるが今回、、これやる為にDocker対応しているものの当初から扱いが微妙に変更になった Herokuのdocker周りとい、戦ったり、別の記事が出来るくらいだった。

やはり、、真っ白。

試行錯誤

gopheron側でElectronのdevToolを有効にして、何かエラーが出ていないかを見ようとしてみた。 が、CSSのツールが表示され、Consoleタブへのプログラムでの切り替え方が分からなかった。。

electron自体は動いていることが確認できたので、可能性としては、 OpenGL周りのライブラリが入っていないことを疑ってみたが、 最終的にはlibosmesa.soの依存関係をlddコマンドで調べ、依存が未解決だったlibbase.soなる ライブラリをlibosmesa.soライブラリ生成ディレクトリ内に見つけた。 これをelectronのパスに以下の様にlibmesa.so同様にコピー。

cp libbase.so `npm config get prefix`/lib/node_modules/electron/dist

無事Gopher君がTravis CI環境のXvfb上に表示されることを確認できた。

f:id:kjw_junichi:20161123140642p:plain

ただし、残念ながらGohperonはElectronの透明ウィンドウの機能を使っており、元々macOSのみだったものがWindowsには辛うじている対応して いるものの、LinuxではGPUアクセラレーションを切らないと透明ウィンドウが表示できないなようで、デスクトップマスコットしてはLinuxでは実用的につかなさそう。(VirtualBoxでosmesaで動かすと劇重、Xvfbに至っては、前回描画が残ってる感じ)

学べたこと

  • npmでインストールするグローバルモジュールのパスの取得方法
    • npm config get prefix とすることで、-g nvm等のenv系ツール環境下でもnode.jsのインストールパスが取得できる
  • シェルスクリプトで小数点以下を丸めるには  - echo 3.14 |awk '{printf("%d",$1 + 0.5)}'
  • 画像の差分だけだと初期段階だと危険、目視でも確認したほうが安全
    • curlで画像ファイルを外部のサイトにアップロードしてこれを確認
  • libosmesa.soの他にlibbase.soが必要だった

関連記事