Android上でBoost.Testを使ったテストをしてみました。
Android NDKでは通常のAndroidアプリケーションではない、main()から始まるネイティブの実行ファイル(つまりWindowsで言うところのコンソールアプリと言えば良い?)をビルドできるようになっています。これを使えばAndroid端末上でテストを実行できます。
以下に例を書いておきます。hello_testというディレクトリを作って、以下のファイルを用意し、run.shを実行するとテストをビルドして端末へアップロードして実行します。ライブラリをビルドするのは面倒くさいので、Boostはヘッダーだけの使用にとどめてあります。
hello_test/jni/Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_CPP_FEATURES += exceptions LOCAL_CPP_FEATURES += rtti LOCAL_MODULE := hello_test #←実行ファイル名になる。 # ソースファイルはワイルドカードで取得してみる。 # LOCAL_PATHはjniディレクトリを指している。 # カレントディレクトリは一つ上なので注意。 # LOCAL_SRC_FILESにはjniディレクトリからの相対パスで指定する必要がある。 SRC_FILES = $(wildcard $(LOCAL_PATH)/*.cpp) LOCAL_SRC_FILES := $(SRC_FILES:$(LOCAL_PATH)/%=%) # Boost C++ Libraryヘッダーファイルへのパスを指定する。 LOCAL_C_INCLUDES += c:/boost_he_no_path_wo_shiteisuru/boost_1_56_0 # これが無いとAndroid 5.0以降で実行できない。 LOCAL_CFLAGS += -pie -fPIE LOCAL_LDFLAGS += -pie -fPIE include $(BUILD_EXECUTABLE) #実行ファイルをビルドする。
実行ファイルを生成するには、最後に include $(BUILD_EXECUTABLE)
を指定するのがミソです。
LOCAL_MODULE
は実行ファイルの名前になります。
Boostのヘッダーへのパスは LOCAL_C_INCLUDES
で指定してください。
実行時に"error: only position independent executables (PIE) are supported" というエラーが出ることがあります。Android 5.0以降だと出るようです。 -pie -fPIE
というオプションを指定すると大丈夫なようです。
hello_test/jni/Application.mk
APP_ABI := all APP_STL := c++_static APP_PLATFORM := android-14 #低いとコンパイルが通らない
APP_PLATFORM
を指定しなかったり、APIレベルが低いと必要な関数が無いためにコンパイルエラーにとなります。
hello_test/jni/main.cpp
#define BOOST_TEST_MAIN #include <boost/test/included/unit_test.hpp>
hello_test/jni/test_hoge.cpp
#define BOOST_TEST_NO_LIB #include <boost/test/unit_test.hpp> BOOST_AUTO_TEST_SUITE(hoge_test) BOOST_AUTO_TEST_CASE(test1) { int a = 1; int b = 2; BOOST_CHECK_EQUAL(a + b, 3); BOOST_CHECK_EQUAL(a - b, -1); BOOST_CHECK_EQUAL(a / b, 0); } BOOST_AUTO_TEST_CASE(test2) { double a = 1.0; double b = 2.0; BOOST_CHECK_EQUAL(a + b, 3.0); BOOST_CHECK_EQUAL(a - b, -1.0); BOOST_CHECK_EQUAL(a / b, 0.5); } BOOST_AUTO_TEST_SUITE_END()
hello_test/run.sh
#!/usr/bin/env bash dir=/data/local/tmp/hello_test bin=hello_test # Build ndk-build # Detect Device's ABI abi=$(adb shell getprop ro.product.cpu.abi | cut -d, -f1 | tr -d '\r') echo "abi=$abi" # Make directory echo "mkdir $dir" adb shell "mkdir $dir 2>/dev/null" # Upload adb push libs/$abi/$bin $dir # Execute adb shell "chmod 755 $dir/$bin" adb shell $dir/$bin # Delete adb shell rm $dir/$bin adb shell rmdir $dir
接続している端末のABIを取得するには、 adb shell getprop ro.product.cpu.abi
を実行すればよいみたいです。カンマ区切りで複数列挙される場合があります。
/data/local/tmp
というディレクトリにアップロードして実行し、終わったら削除します。