Travis CIでOpenCV + GTest + Coverallsを実行する方法
こんにちはtatsyです。
最近、これまでに作ったプログラムをまとめてGithub上で公開する作業を行っていたのですが、その際にOpenCV + GTestをTravis上でテストするのに結構苦労したのでやり方をまとめておきます。
Travis上でやりたいことは次の4つです。
- OpenCVをwgetしてきて、Travis上でビルドする
- GTestをapt-get installしてTravis上でビルドする
- 自分の書いたプログラムをCMakeでビルドする
- Coverallsにカバレッジを送信する
それでは個々のやり方についてみていきます。
1. OpenCVのビルド
実際のビルドに行く前に1点確認ですが、TravisサーバーはOSにUbuntu 12.04 LTSを使っているらしいです(2015年2月現在)。
ですので少し昔のバージョンで良ければ、apt-getをしてOpenCVをインストールすることも可能ですが、僕が作成中のライブラリはOpenCV 3.0ベースだったので、ソースをOpenCVのページからwgetしてきてビルドしました。
sudo apt-get update
sudo apt-get -y install libopencv-dev build-essential cmake git libgtk2.0-dev pkg-config python-dev python-numpy libdc1394-22 libdc1394-22-dev libjpeg-dev libpng12-dev libtiff4-dev libjasper-dev libavcodec-dev libavformat-dev libswscale-dev libxine-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev libv4l-dev libtbb-dev libqt4-dev libfaac-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libtheora-dev libvorbis-dev libxvidcore-dev x264 v4l-utils unzip
mkdir opencv
cd opencv
wget https://github.com/Itseez/opencv/archive/3.0.0-beta.zip
unzip 3.0.0-beta.zip
cd opencv-3.0.0-beta
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local -D WITH_TBB=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D WITH_V4L=ON -D WITH_QT=ON -D WITH_OPENGL=ON ..
make
sudo make install
sudo /bin/bash -c 'echo "/usr/local/lib" > /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig
ちなみにビルドのためのスクリプトは以下のページを参考にさせていただきました(というかほぼコピー)
Installing OpenCV 3.0.0 on Ubuntu 14.04
2. GTestのインストール
GTestはUbuntuだとlibgtest-devというパッケージからインストールできるのですが、インストールされるのはヘッダとソースなので、これを自分でビルドしないといけません。
ちなみにインストールされる場所はヘッダが/usr/incllude/gtest、ソースが/usr/src/gtestです。
以下ビルドのためのスクリプトです。ビルド後にできるライブラリlibgtest.aとlibgtest_main.aは/usr/local/libに移動しています。
sudo apt-get install libgtest-dev
cd /usr/src/gtest
sudo cmake .
sudo cmake --build .
sudo mv libg* /usr/local/lib
3. CMakeファイルの用意
通常CMakeでfind_packageを呼べばおおよそのファイルは見つけてくれるはずなのですが、Travis上ではOpenCVは見つかってもGTestは見つけてくれません。
そこで、必要な変数を環境変数にエクスポートしてCMakeファイル内で使うということをします。
まずcmakeを実行する前に、以下のエクスポートを行います。
export GTEST_LIBRARY=/usr/local/lib/libgtest.a
export GTEST_MAIN_LIBRARY=/usr/local/lib/libgtest_main.a
export GTEST_INCLUDE_DIRS=/usr/include
これができたら次のコードをCMakeLists.txtに追加します。
# Test for Point
set(POINT_SOURCE_FILES test_source.cpp)
add_executable(test_program ${POINT_SOURCE_FILES})
target_link_libraries(test_program ${GTEST_LIBRARY})
target_link_libraries(test_program ${GTEST_MAIN_LIBRARY})
target_link_libraries(test_program ${OpenCV_LIBS})
add_test(NAME test_program COMMAND test_program)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} DEPENDS test_point test_random)
# Include directories
include_directories(${CMAKE_CURRENT_LIST_DIR})
include_directories(${GTEST_INCLUDE_DIRS})
include_directories(${OpenCV_INCLUDE_DIRS})
上記のコードの中でtest_programというのが実際に作られるプログラム名になりますので、適宜読み替えていただけると助かります。
おおむねコード内容はお分かりいただけるかと思うのですが、大事なポイントは2つあります。
- GTestをOpenCVよりも先にリンクする
- add_custom_testを使ってmake checkからテストが走るようにする
1つ目のポイントについてですが、OpenCVはGTestを一部用いてテストしているためか、OpenCVを先にリンクすると、GTestの関数が重複定義でリンクエラーになります。
2つ目のポイントは僕の理解不足かもしれませんが、CMakeからmake testが呼び出されなかったため、custom testを使ってテストを呼び出しているというだけです。
これでcmakeを実行すればプログラムがビルドでき、さらにmake checkでテストが走ります。
4. Code Coverageを取る
Web上でいろいろ調べてみるとcpp-coverallsというPythonのプログラムが見つかるのですが、サンプル通りに書いても動かないのと、使い方についての解説が少なすぎるのとであきらめました。
これとは別にrubygemから落とせるlcov-coverallsというプログラムを使ってカバレッジをCoverallsに送信します。
やらなければならないことは大きく分けて2つです。
1つ目はgccのコンパイル時引数に–coverageというのを追加し、さらに-g -O0で最適化をオフにすることです。
これはCMakeLists.txtに次のコードを追加すればOKです。
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
2つ目は当たり前ですがgemからlcov-coverallsを落とす必要があります。
まず、lcov-coverallsをwgetしてきて、そのあとでgem installです。
wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz
tar xf lcov_1.11.orig.tar.gz
sudo make -C lcov-1.11/ install
gem install coveralls-lcov
ここまでできたら、テスト実行後にlcov-coverallsを使ってカバレッジを送るだけです。
lcov --directory . --capture --output-file coverage.info
lcov --remove coverage.info 'tests/*' 'examples/*' '/usr/*' 'opencv/*' 'CMakeFiles/*' --output-file coverage.info
lcov --list coverage.info
coveralls-lcov --repo-token (Coverallsのトークン) coverage.info
まとめ
これでめでたく、OpenCV + GTestでテストを走らせてなおかつカバレッジも取れます!
結構さらっと書いてますが、サイドワークでちょこちょこやって1週間以上はかかったんじゃないかな?
実際の.travis.ymlを見たい方はこちらからどうぞ → https://github.com/tatsy/lime
かなり用途が限られている気もしますが、何かの参考にしていただければ幸いです。
それでは、最後までおよみいただきありがとうございました。