githubのレポジトリと簡単に連携できる継続的インテグレーションサービスであるTravis CIを使って、C++11で書かれたソースコードをテストできるようにしました。想像以上に大変だったのでメモしておきます。
ソースコードとテストコードの準備
Travis CIで提供される仮想マシンはLinuxかOS Xなので、Visual Studio向けのコードはビルドできません。MakefileやCMakeなどコンソールからビルドできる仕組みを用意する必要があります。
今回は以下のような簡単なMakefileを用意しました。
CXX = g++ CPPFLAGS = -I3rdparty/catch -IMyVector CXXFLAGS = -std=c++11 TARGET = test $(TARGET): MyVectorTest/main.cpp MyVectorTest/test_constructor.cpp $(CXX) $(CXXFLAGS) $(CPPFLAGS) $^ -o $@ clean: rm -r $(TARGET)
単に
$ make
とすればg++でビルドできますし、
$ make CXX=clang++
などと変数を引数で指定すればclangでもビルドできます。
今回は、このMakefileを使い、gccとclangの両方でC++11のコードをビルドすることを目標にします。
参考までに、テストフレームワークには、最近人気があるphilsquared/Catchを使っています。ただし本編には関係ありません。
.travis.ymlの作成
Travis CIで提供されるUbuntuマシンで使えるg++とclang++のバージョンは現時点でそれぞれg++ 4.6.3とclang++ 3.4と古く、C++11には対応してません。そこで、Travis CIの設定ファイル.travis.ymlに、新しいバージョンのg++とclang++が使えるよう設定を加える必要があります。
Web検索をしまくった結果できあがったのが以下の設定ファイルです。g++ 5とclang++ 3.7を使ってC++11のコードがビルドできるようになりました。
sudo: false language: cpp compiler: - clang++ - g++ install: - if [ "$CXX" = "g++" ]; then export CXXFLAGS="-std=c++11"; fi - if [ "$CXX" = "g++" ]; then export CXX="g++-5" CC="gcc-5"; fi - if [ "$CXX" = "clang++" ]; then export CXXFLAGS="-std=c++11"; fi - if [ "$CXX" = "clang++" ]; then export CXX="clang++-3.7" CC="clang-3.7"; fi - make CXXFLAGS="${CXXFLAGS}" CXX="${CXX}" addons: apt: sources: - ubuntu-toolchain-r-test - llvm-toolchain-precise-3.7 - llvm-toolchain-precise packages: - clang-3.7 - g++-5 - gcc-5 script: - ./test
addonsの項で何が起こっているのか正確に理解していませんが、とにかくこれがミソのようです。後は変数CXX, CXXFLAGSに適当な変数を代入して、makeの引数として渡せばOKです。
蛇足ですが、このコードにたどり着く前は、以下のようにapt-getや自力ビルドを駆使してg++とclang++を用意していました。複雑な上に時間もかかり不経済なので、このコードを使う必要はまったくありません。
language: cpp compiler: - clang++ - g++ before_install: # g++4.8.1 - if [ "$CXX" == "g++" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi # clang 3.4 - if [ "$CXX" == "clang++" ]; then sudo add-apt-repository -y ppa:h-rayflood/llvm; fi - sudo apt-get update -qq install: # g++4.8.1 - if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.8; fi - if [ "$CXX" = "g++" ]; then export CXXFLAGS="-std=c++11"; fi - if [ "$CXX" = "g++" ]; then export CXX="g++-4.8"; fi # clang 3.4 - if [ "$CXX" == "clang++" ]; then sudo apt-get install --allow-unauthenticated -qq clang-3.4; fi - if [ "$CXX" == "clang++" ]; then export CXXFLAGS="-std=c++0x -stdlib=libc++"; fi - if [ "$CXX" == "clang++" ]; then svn co --quiet http://llvm.org/svn/llvm-project/libcxx/trunk libcxx; fi - if [ "$CXX" == "clang++" ]; then cd libcxx/lib && bash buildit; fi - if [ "$CXX" == "clang++" ]; then sudo cp ./libc++.so.1.0 /usr/lib/; fi - if [ "$CXX" == "clang++" ]; then sudo mkdir /usr/include/c++/v1; fi - if [ "$CXX" == "clang++" ]; then cd .. && sudo cp -r include/* /usr/include/c++/v1/; fi - if [ "$CXX" == "clang++" ]; then cd /usr/lib && sudo ln -sf libc++.so.1.0 libc++.so; fi - if [ "$CXX" == "clang++" ]; then sudo ln -sf libc++.so.1.0 libc++.so.1 && cd $cwd; fi - if [ "$CXX" == "clang++" ]; then export CXX="clang++-3.4"; fi - cd ${TRAVIS_BUILD_DIR} - ls - make CXXFLAGS="${CXXFLAGS}" CXX="${CXX}" - ls script: - chmod ugo+x test - ./test
ビルド例
githubのminus9d/MyVectorをTravis CIでテストできるようにしています。この記事執筆時点でのテスト成功例は Build #34 - minus9d/MyVector - Travis CI です。
参考リンク
- C++14 on Travis CI with CMake
- もっとも参考になりました。ただし、llvm-toolchain-precise-3.7 を加えないとビルドできなかった気がします。
- c++ - Travis CI with Clang 3.4 and C++11 - Stack Overflow