ビルドツールのベンチマーク試行

# ビルドとは
コンパイル＋リンク（ライブラリの関連付け）を実行し、ファイルを生成すること
※ コンパイルとは ... コンピュータが実行するのに適した形式に変えて実行可能なファイルに変換すること

# ビルドツールとメタビルドシステム
* ビルドツール
  * 依存関係を解決しながらコマンドを実行するツール
  * 依存するファイルが更新されるとコマンドを再実行する
  * 例；make, ninja, scons など
* メタビルドツール
  * ビルドに必要なファイルを生成するツール
  * 環境に応じたmakefileを作成する
  * 例：autotools, cmake

# ビルドツールの実行時間測定
## ゴール
各ビルドツールのビルド時間、使い勝手の比較 

## 対象ビルドツール
[make](https://www.gnu.org/software/make/), [scons](http://scons.org/), [ninja](https://ninja-build.org/)

## ビルド時間測定
4つの条件からソフトウェアのビルド時間を測定。
1. cold start（最初のビルド）
2. full rebuild（ソースファイルすべてに変更を加えてビルド）
3. leaf build（特定ソースファイルだけ変更を加えてビルド）
4. nothing to do（ソースファイル変更がない状態でのビルド）

### ビルド対象のソフトウェア
main関数は、用意されたサブディレクトリのグローバル関数を再帰的に呼び出す。
各サブディレクトリに定義されている関数はメッセージ出力するだけ。

### 測定方法
サブディレクトリ数を10, 100, 1000 に変更して time コマンドでビルド時間を測定する。

### 結果
結論、ninjaが圧倒的なビルド時間の速さを示した。

#### 測定環境
* OS: Ubuntu 14.04.4 LTS, x86_64
* CPU: Intel(R) Xeon(R) CPU E5-2630 0 @ 2.30GHz (24 core)
* RAM: 128GB

#### 各ビルドツールのバージョン
* make 3.81
* scons v2.3.0
* ninja 1.3.4

#### 測定結果
5回測定した平均、最小、最大ビルド時間を示す。単位は"秒"

<table border=1>
<tr>
  <th>ビルドツール/サブディレクトリ数: 10</th>
  <th>cold_start</th>
  <th>full rebuild </th>
  <th>leaf rebuild</th>
  <th>nothing to build</th>
</tr><tr>
  <td>make</td>
  <td>avg 0.39<br>min 0.38<br>max 0.40</td>
  <td>avg 0.41<br>min 0.41<br>max 0.41</td>
  <td>avg 0.08<br>min 0.07<br>max 0.08</td>
  <td>avg 0.01<br>min 0.01<br>max 0.01</td>
</tr><tr>
  <td>scons</td>
  <td>avg 0.79<br>min 0.72<br>max 0.89</td>
  <td>avg 0.73<br>min 0.60<br>max 0.81</td>
  <td>avg 0.27<br>min 0.23<br>max 0.33</td>
  <td>avg 0.23<br>min 0.18<br>max 0.27</td>
</tr><tr>
  <td>ninja</td>
  <td>avg 0.07<br>min 0.06<br>max 0.08</td>
  <td>avg 0.00<br>min 0.00<br>max 0.00</td>
  <td>avg 0.00<br>min 0.00<br>max 0.00</td>
  <td>avg 0.00<br>min 0.00<br>max 0.00</td>
</tr>
</table>

<table border=1>
<tr>
  <th>ビルドツール/サブディレクトリ数: 100</th>
  <th>cold_start</th>
  <th>full rebuild </th>
  <th>leaf rebuild</th>
  <th>nothing to build</th>
</tr><tr>
  <td>make</td>
  <td>avg 3.25<br>min 3.23<br>max 3.26</td>
  <td>avg 3.44<br>min 3.43<br>max 3.45</td>
  <td>avg 0.16<br>min 0.16<br>max 0.16</td>
  <td>avg 0.04<br>min 0.04<br>max 0.04</td>
</tr><tr>
  <td>scons</td>
  <td>avg 4.74<br>min 4.68<br>max 4.85</td>
  <td>avg 4.94<br>min 4.91<br>max 4.99</td>
  <td>avg 0.91<br>min 0.85<br>max 0.97</td>
  <td>avg 0.91<br>min 0.85<br>max 0.97</td>
</tr><tr>
  <td>ninja</td>
  <td>avg 0.23<br>min 0.23<br>max 0.24</td>
  <td>avg 0.12<br>min 0.02<br>max 0.26</td>
  <td>avg 0.02<br>min 0.00<br>max 0.07</td>
  <td>avg 0.00<br>min 0.00<br>max 0.00</td>
</tr>
</table>

<table border=1>
<tr>
  <th>ビルドツール/サブディレクトリ数: 1000</th>
  <th>cold_start</th>
  <th>full rebuild </th>
  <th>leaf rebuild</th>
  <th>nothing to build</th>
</tr><tr>
  <td>make</td>
  <td>avg 32.97<br>min 32.93<br>max 33.05</td>
  <td>avg 35.75<br>min 35.49<br>max 36.15</td>
  <td>avg 1.75<br>min 1.74<br>max 1.78</td>
  <td>avg 0.34<br>min 0.28<br>max 0.39</td>
</tr><tr>
  <td>scons</td>
  <td>avg 53.32<br>min 53.20<br>max 53.55</td>
  <td>avg 55.17<br>min 54.94<br>max 55.37</td>
  <td>avg 10.50<br>min 10.45<br>max 10.58</td>
  <td>avg 5.34<br>min 5.31<br>max 5.36</td>
</tr><tr>
  <td>ninja</td>
  <td>avg 2.72<br>min 2.57<br>max 2.86</td>
  <td>avg 2.67<br>min 2.64<br>max 2.72</td>
  <td>avg 1.27<br>min 1.20<br>max 1.35</td>
  <td>avg 0.01<br>min 0.01<br>max 0.01</td>
</tr>
</table>

## 使い勝手
あくまで個人的な意見です。

<table border=1>
<tr>
  <th>ビルドツール</th>
  <th>pros</th>
  <th>cons</th>
</tr>
<tr>
  <td>make</td>
  <td>暗黙的表記によって記述を最小限にできる</td>
  <td>学習コストが高い</td>
</tr>
<tr>
  <td>scons</td>
  <td>pythonスクリプト感覚で記述できる</td>
  <td>ドキュメントが少ない</td>
</tr>
<tr>
  <td>ninja</td>
  <td>makeと比較すると直感的</td>
  <td>記述量が多くなりがち<br>ドキュメントが少ない</td>
</tr>
</table>

# 結論
無難どころは make という印象が調査結果。
ninjaは記述量が多くなるので、build.ninja作る部分はスクリプト化しないとメンテナンスが難しそう

* ビルド時間
 1. ninja 2. make 3. scons
* 使い勝手
 1. scons 2. make 3. ninja

# 感想
bazelも気になる

# ソースコード
https://github.com/aoimidori27/buildtool_test

# reference
* https://qiita.com/rico/items/9ab8aa110e757a13ef37
* https://www.slideshare.net/makotoshimazu/ss-53999001
* https://github.com/kaizouman/build-benchmark