Playground(Android)のJenkins環境を整える
ハッカソンに行ってきた。
そのときにjenkinsである程度動いたかと思ったら動いておらず
いろんな罠にハマっていたらえらく日数がかかってしまいました。
セットアップ方法とハマりそうなエラーとその原因を軽くまとめようと思います
monoまわりをセットアップしていないので
運用としてはAppAssets.zipは作ってレポジトリに置くような感じになります。
環境のセットアップ
OS:ubuntu 12.04 64bit(12.10や13.04は苦労する可能性が大きいです)
githubに解説がありますがいくつか不足があるのと英語です。
https://github.com/KLab/PlaygroundOSS/blob/master/Doc/Android_Build.md
大きくは
必要なライブラリとツールのインストール
aaptがなぜか32bitバイナリーなのでia32libsとzipなどのコマンド類をいれます。
PlaygroundOSSのビルド
最終目的地です
では順番に
必要なライブラリとツールのインストール
aptで一発ワンライナーです。
sudo apt-get install libgd2-xpm ia32-libs ia32-libs-multiarch zip git
androidの開発環境のインストール
javaは以下からダウンロードできます。
http://www.oracle.com/technetwork/jp/java/javase/downloads/index.html
展開してパスを通しましょう。
sdkは以下からダウンロードできます。
http://developer.android.com/sdk/index.html
sdkはちょくちょくかわるのでとんでダウンロードしてください。
ndkは以下からダウンロードできます。
64 bit : http://dl.google.com/android/ndk/android-ndk-r9-linux-x86_64.tar.bz2
例として$HOME以下に展開します。
パスを通します。
その際にANDROID_NDK_ROOTは必ず定義してください。
無いとビルド時にエラーになります。
export ANDROID_NDK_ROOT=$HOME/android-ndk-r9/ export PATH=$PATH:$ANDROID_NDK_ROOT:$HOME/android-sdk-linux/tools:$HOME/android-sdk-linux/platform-tools
sdkはandroidコマンドを使ってビルドツールとかをインストールしましょう。
GUIでもできますがコマンドでやると以下のようになります。
echo 'y' | android update sdk --filter platform-tools,android-17,extra-android-support,android-17,sysimg-17 --no-ui --force echo 'y' | android update sdk -a --filter `android list sdk --extended -a | grep \"build-tools-18.1.0\" |cut -d ' ' -f 2` --no-ui --force echo 'y' | android update sdk -a --filter `android list sdk --extended -a | grep \"build-tools-19.0.0\" |cut -d ' ' -f 2` --no-ui --force
PlaygroundOSSのビルド
以下のページからダウンロードするかgitでクローンしてチュートリアルのプログラムをビルドします。
https://github.com/KLab/PlaygroundOSS
git clone https://github.com/KLab/PlaygroundOSS.git cd $HOME/PlaygroundOSS/Tutorial/01.SimpleItem/.publish/android/ zip -r -0 $HOME/PlaygroundOSS/Engine/porting/Android/GameEngine-android/assets/AppAssets.zip ./* echo -n "1" > $HOME/PlaygroundOSS/Engine/porting/Android/GameEngine-android/assets/version ./* $HOME/PlaygroundOSS/Engine/porting/Android/GameEngine-android/build.py --rebuild --assemble --project SampleProject
これでサンプルプログラムが動きます。
jenkinsはshellでEngine以下をコピーしてAppAssets.zipを入れてビルドする
以下のようになります。
cp -r $HOME/PlaygroundOSS/Engine/ ./ mkdir -p `pwd`/Engine/porting/Android/GameEngine-android/assets/ mv android-assets/AppAssets.zip Engine/porting/Android/GameEngine-android/assets/ sum Engine/porting/Android/GameEngine-android/assets/AppAssets.zip > Engine/porting/Android/GameEngine-android/assets/version cd Engine/porting/Android/GameEngine-android/ ./gradlew assemble
こんな感じでビルドがまわせると思うので、後はお好みのテストツールと組み合わせるといいでしょう。
トラブルシュート
エラーが出てしまった人たち用にエラーメッセージと解決法を書いておきます
32bitライブラリーが入っていない編(必要なライブラリとツールのインストールをやってない)
まず、64bitの場合、ubuntuバージョンは12.04を使いましょう。
その上でia32libを入れないと以下のようにおこられます。
+ ./gradlew assemble :preBuild UP-TO-DATE :preDebugBuild UP-TO-DATE :prepareDebugDependencies :compileDebugAidl :compileDebugRenderscript :generateDebugBuildConfig :mergeDebugAssets :mergeDebugResources /home/jenkins/workspace/playgroundthon/Engine/porting/Android/GameEngine-android/res/drawable-mdpi/ic_launcher.png: Error: Cannot run program "/home/jenkins/tools/android-sdk/build-tools/19.0.0/aapt": error=2, そのようなファイルやディレクトリはありません :mergeDebugResources FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':mergeDebugResources'. > /home/jenkins/workspace/playgroundthon/Engine/porting/Android/GameEngine-android/res/drawable-mdpi/ic_launcher.png: Error: Cannot run program "/home/jenkins/tools/android-sdk/build-tools/19.0.0/aapt": error=2, そのようなファイルやディレクトリはありません
ファイルはあるのですが32bitのバイナリを実行しようとしてこんな感じに怒られます。
13.04は確実にパッケージが無いのでia32libでインストールされるパッケージ類を調べてインストールするしかないです。
12.10は分かりません。
ANDROID_NDK_ROOTが設定されていない編
以下のような感じで怒られます。
>> Compile++ x86 : Game <= FileDelete.cpp >> Compile++ x86 : Game <= KLBOpenSLSoundAssetLoader.cpp >> Compile++ x86 : Game <= CSampleProjectEntrance.cpp >> Compile++ x86 : jniproxy <= jniproxy.cpp >> Compile arm : Game <= hash_sha1.c >> Compile arm : Game <= ldebug.c >> Compile arm : Game <= lstrlib.c >> Compile arm : Game <= lgc.c >> Compile arm : Game <= lfunc.c >> Compile arm : Game <= loadlib.c >> jni/Android/CSockWriteStream.cppCompile arm : Game <= lopcodes.c >> Compile arm : Game <= ldblib.c >> :42:22: error: use of undeclared identifier 'write' >> int result = write(m_fd, buffer + pos, sndSize - pos); >> ^ >> jni/source/Core/DebugTracker.cpp:221:2: error: use of undeclared identifier 'sleep' >> sleep(1000); // waiting for client receive CMD_END. >> ^ >> 1Compile arm : Game <= lctype.c >> Compile arm : Game <= lmathlib.c >> 1 error generated. >> make: *** [obj/local/x86/objs/Game/source/Core/DebugTracker.o] Error 1 >> make: *** Waiting for unfinished jobs.... >> Compile arm : Game <= lzio.c >> error generated. >> make: *** [obj/local/x86/objs/Game/Android/CSockWriteStream.o] Error 1 >> jni/Android/CAndroidWriteFileStream.cppjni/Android/CSockReadStream.cpp:42:14: error: use of undeclared identifier 'close' >> if(m_fd) close(m_fd); >> ^ >> jni/Android/CSockReadStream.cpp:41:9: error: use of undeclared identifier 'close' >> close(m_fd); >> ^ >> :81:6: error: use of undeclared identifier 'close' >> close(dstSocket); >> ^ >> jni/Android/CSockReadStream.cpp:100:11: error: use of undeclared identifier 'close' >> close(m_fd); >> ^ >> jni/Android/CSockReadStream.cpp1 error generated. >> make: *** [obj/local/x86/objs/Game/Android/CAndroidWriteFileStream.o] Error 1 >> jni/Android/CAndroidReadFileStream.cpp:110:17: error: use of undeclared identifier 'close' >> close(m_fd); >> ^ >> jni/Android/CSockReadStream.cpp:86:6: error: use of undeclared identifier 'close' >> close(pStream->m_fd); >> ^ >> 1:127:22: error: use of undeclared identifier 'read' >> int result = read(m_fd, m_readBuf + m_lastPos, READ_BUFSIZ - m_lastPos); >> ^ >> jni/Android/CSockReadStream.cpp:132:22: error: use of undeclared identifier 'read' >> int result = read(m_fd, m_readBuf, m_getPos); >> ^ >> jni/Android/CSockReadStream.cpp:136:22: error: use of undeclared identifier 'read' >> int result = read(m_fd, m_readBuf + m_lastPos, m_getPos - m_lastPos); >> ^ >> error generated. >> make: *** [obj/local/x86/objs/Game/Android/CAndroidReadFileStream.o] Error 1 >> jni/Android/CSockReadStream.cpp:141:22: error: use of undeclared identifier 'read' >> int result = read(m_fd, m_readBuf, READ_BUFSIZ); >> ^ >> jni/source/Assets/CKLBTexturePacker.cpp:367:80: warning: format specifies type 'unsigned long' but the argument has type 'uintptr_t' (aka 'unsigned int') [-Wformat] >> fprintf(pFile, "==== Surface Alloc %8lX Size W:%i, H:%i Byte/Pix: %i ====\n", reinterpret_cast<uintptr_t>(this), m_width, m_height, m_currFormat); >> ~~~~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> %8X >> 8 errors generated. >> make: *** [obj/local/x86/objs/Game/Android/CSockReadStream.o] Error 1 >> 1 warning generated. >> jni/Android/KLBOpenSLEngine.cpp:140:9: error: use of undeclared identifier 'usleep' >> usleep(16000); >> ^ >> 1 error generated. >> make: *** [obj/local/x86/objs/Game/Android/KLBOpenSLEngine.o] Error 1 >> jni/Android/KLBOpenSLSoundAssetLoader.cpp:38:26: error: use of undeclared identifier 'F_OK' >> if (access(target_path, F_OK) != -1) { >> ^ >> jni/Android/KLBOpenSLSoundAssetLoader.cpp:67:3: error: use of undeclared identifier 'usleep' >> usleep(30000); // sleep for 30ms >> ^ >> 2 errors generated. >> make: *** [obj/local/x86/objs/Game/Android/KLBOpenSLSoundAssetLoader.o] Error 1 >> jni/Android/CAndroidTmpFile.cpp:43:9: error: use of undeclared identifier 'close' >> close(m_fd); >> ^ >> jni/Android/CAndroidTmpFile.cpp:51:12: error: use of undeclared identifier 'write' >> return write(m_fd, ptr, size); >> ^ >> 2 errors generated. >> make: *** [obj/local/x86/objs/Game/Android/CAndroidTmpFile.o] Error 1 >> jni/Android/CAndroidRequest.cpp:221:3: error: use of undeclared identifier 'unlink'; did you mean 'inline'? >> unlink(fullpath); >> ^ >> jni/Android/CAndroidRequest.cpp1 warning generated. >> :505:15: error: use of undeclared identifier 'ioctl' >> int result = ioctl(fd, _IOW('a', 4 | (ANDROID_ALARM_ELAPSED_REALTIME << 4), struct timespec), ts); >> ^ >> jni/Android/CAndroidRequest.cpp:507:2: error: use of undeclared identifier 'close' >> close(fd); >> ^ >> jni/Android/CAndroidRequest.cpp:646:9: warning: enumeration value 'BGMOVIEPLAYER' not handled in switch [-Wswitch] >> switch(type) >> ^ >> 1 warning and 3 errors generated. >> make: *** [obj/local/x86/objs/Game/Android/CAndroidRequest.o] Error 1 >> 4 warnings and 18 errors generated. >> make: *** [obj/local/x86/objs/Game/libs/SQLite/sqlite3.o] Error 1 >> >> FAILURE: Build failed with an exception. >>