標準的なAndroidプロジェクトのcircle.yml
2015/5/12現在では、公式サイトによると主要なAndroidSDKは、VMにプリインストールされているとのことです。 そのため、以下のような非常にすっきりしたYAMLファイルで、Androidプロジェクトをビルドすることが出来るようになっています。(テストは省略しています。)
machine: java: version: openjdk7 test: override: - echo "Nothing to do here" deployment: master: branch: master commands: - ./gradlew assemble
もしプリインストールされたSDKに、使用したいものが無い場合だけアップデート処理を追記してあげればいいみたいです。
dependencies: pre: - echo y | android update sdk --no-ui --all --filter "package-name"
AndroidNDKを使用する場合のcircle.yml
公式によると、
We also preinstall the Android NDK; it can be found at $ANDROID_NDK.
とあるので、AndroidNDKもプリインストールされてるようです。 ところが、そのままAndroidNDKを使ったプロジェクトをビルドさせると、以下のようなエラーが出てNDKのタスクで失敗してしまいました。
> Building 2%NDK not configured. > Building 2% Download the NDK from http://developer.android.com/tools/sdk/ndk/.Then add ndk.dir=path/to/ndk in local.properties. > Building 2% (On Windows, make sure you escape backslashes, e.g. C:\\ndk rather than C:\ndk)
失敗する原因は、$ANDROID_NDK
ではAndroidNDKのホームディレクトリとして認識出来ないことでした。
そのため以下のように、$ANDROID_NDK_HOME
にプリインストールされているAndroidNDKを指定するとうまくいきました。($ANDROID_NDK_HOMEに言及した元ソースは、思い出せませんでした…)
machine: java: version: openjdk7 environment: ANDROID_NDK_HOME: /usr/local/android-ndk test: override: - echo "Nothing to do here" deployment: master: branch: master commands: - ./gradlew assemble
ビルド中の突然死を予防するcircle.yml
特に具体的なエラーを吐くことなく、ビルドが失敗するケースがありました。 主な対策としては、下記2点が有効なようです。
- JVMのHeapSizeを制限する
- PreDexingを無効化する
machine: java: version: openjdk7 environment: ANDROID_NDK_HOME: /usr/local/android-ndk JAVA_OPTS: "-Xmx2048m -XX:MaxPermSize=1024m" test: override: - echo "Nothing to do here" deployment: master: branch: master commands: - ./gradlew assembleDogfood -PdisablePreDex
JVMのHeapSizeを制限する
JAVA_OPTS: "-Xmx2048m -XX:MaxPermSize=1024m"
ある程度の規模のプロジェクトになると、仮想マシンのメモリを食い尽くしてしまうことが多々あるので、Gradleが使えるリソースに制限をかけてあげると安定します。
PreDexingを無効化する
これは公式サイトのDisable Pre-Dexing to Improve Build Performanceの部分に、詳細が書かれています。 その部分を一部引用すると、以下のように書かれています。
Because CircleCI always runs clean builds this pre-dexing has no benefit; in fact it makes compilation slower and can also use large quantities of memory. We recommend disabling pre-dexing for Android builds on CircleCI.
CircleCIでビルドするときは、PreDexingを無効化してねということらしいです。 やり方は、GradleAndroidPluginのサイトに載ってます。(上記CircleCIのサイトからもリンクが貼られてました。)
まずプロジェクトの直下にあるbuild.gradle
に、以下のGradleタスクを追加します。
project.ext.preDexLibs = !project.hasProperty('disablePreDex') subprojects { project.plugins.whenPluginAdded { plugin -> if ("com.android.build.gradle.AppPlugin".equals(plugin.class.name)) { project.android.dexOptions.preDexLibraries = rootProject.ext.preDexLibs } else if ("com.android.build.gradle.LibraryPlugin".equals(plugin.class.name)) { project.android.dexOptions.preDexLibraries = rootProject.ext.preDexLibs } } }
次にcircle.yml
でビルドコマンドを叩く箇所に、dsablePreDexプロパティを付与してあげます。
これでpreDexタスクは実行されなくなります。
./gradlew clean assemble -PdisablePreDex
参考にさせて頂いたサイト
まとめ
AndroidNDKを使う場合は、$ANDROID_NDK_HOME
の設定が必要でした。
JVMのHeapSize制限は必要に応じて使えばいいけど、PreDexingの無効化はやっておいたほうがよさそうです。
またcircle.ymlの書き方は、まだまだ変わっていきそうなので、定期的に公式サイトをチェックした方がよさそうだなと思いました。 この記事では触れませんでしたが、エミュレーターの起動やテストまわりも書きやすくなってました。