OkBuckを使ってAndroidアプリを高速にビルドする

こんにちは。ビルドしてますか？

最近は「Bazel」なんかが話題ですよね。

https://github.com/bazelbuild/bazel

Bazelの記事は比較的あったのですが「Buck」についての記事をあまり見かけなかったので、書こうと思います。

# Buckとは

https://github.com/facebook/buck

https://buckbuild.com

Facebookが公開しているビルドシステムです。

コードやリソースから小さいモジュールを作成してそれを再利用することでビルドを高速化しているそうです。Android以外のプラットフォームでも利用可能です。

# OkBuckとは

https://github.com/uber/okbuck

Uberが公開しているGradelのプラグインです。Buckのラッパーのようなものです。今回はこれを利用していきます。


## OkBuckをインストールする

### Buckに必要なものを予めインストールする

```bash
$ brew update
$ brew install android-ndk
$ brew install ant
$ brew install watchman
```

* BuckはOkBuckが自動でインストールしてくれるため必要ありません

### Rootのbuild.gradleファイルにokbuckを設定する

```root.build.gradle
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.3'
        classpath 'com.uber:okbuck:0.17.1'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

apply plugin: 'com.uber.okbuck'

```

OkBuckのバージョンによってgradeのバージョンを書き換える必要があります。`0.17.1`なら3.3を要求されるので `gradle-wrapper.properties`の`distributionUrl`を編集します。

```
$ vim gradle-wrapper.properties
```

```gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
```

```
$ ./gradlew wrapper
```


どうしてもバージョンをアップデートしたくないけどOkBuckを使ってみたいという人はOkBuckのバージョンを変更してみましょう。

https://github.com/uber/okbuck/blob/v0.10.2/gradle/wrapper/gradle-wrapper.properties

`v0.10.2`なら `gradle-2.14.1`を利用しています。


#### signingConfigsを設定する

いつも通りな感じに設定します。以下は最低限の設定なのでカスタマイズはもちろん自由です。

```app.build.gradle
signingConfigs {
    release {
        storeFile file("RELEASE_KEY_STORE_FILE_PATH")
        storePassword "RELEASE_KEY_STORE_PASSWORD"
        keyAlias "RELEASE_KEY_ALIAS"
        keyPassword "RELEASE_KEY_PASSWORD"
    }
}
buildTypes {
    release {
        signingConfig signingConfigs.release
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
```

### buckwコマンドでビルドする

ここまで設定できたら `buckWrapper` タスクを実行します。

```bash
$ ./gradlew :buckWrapper
```

これでbuckwコマンドが使用できるようになります。

```bash

# ビルドできるターゲットの一覧
./buckw targets

# ターゲットをビルド
./buckw build <target>

# ターゲットのAPKをインストール
./buckw install --run <apk-target>
```

`.buckconfig.local`にaliasを指定しておくとコマンド操作が楽です。

```.buckconfig.local
[alias]
	appDebug = //app:bin_debug
	appRelease = //app:bin_release
```

```bash
$ ./buckw install --run appDebug
```

個人的にはMakefileが好きなので以下のようにaliasはっておくと更に楽です。

```Makefile
installDebug:
	./buckw install --run //app:bin_debug
```

```bash
$ make installDebug
```

OkBuckの各種設定は以下を参考にしてください。

https://github.com/uber/okbuck/blob/master/Usage.md


### 実行結果

#### gradlew
<img width="361" alt="スクリーンショット 2017-02-07 14.57.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/73483/6b31fd1d-c612-6aa3-6cd9-4847af3aecf9.png">

#### OkBuck
<img width="576" alt="スクリーンショット 2017-02-07 14.58.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/73483/5ef1b19b-c04e-d86d-c29a-eddfdc7a0054.png">


単純なActivityしかない場合は少しだけ早い（体感的には）っていう感じでした。AndroidStudioにはInstantRunとかありますしね...。複雑に絡み合ったプロジェクトで計測してみたいです。

### 追記

* DataBinding対応がされていないようです

* ベンチマーク
http://tkruse.github.io/build-bench/2016_10_commons-math.html