最近はマイコンも多機能になってきて、ビルド時間もバカにならなくなってきています。 そこで今回はC/C++のコンパイルを爆速にするccacheというツールをご紹介します。
ビルド時間は短いほうが正義
開発途中は単純化すると「コード修正」→「単体テスト」→「デバッグ」のサイクルの繰り返しとなるかと思います。 このサイクルにはビルドという作業が必要です。もし仮にビルドに30分かかるとしたら、1営業日に最大16回しかこのサイクルを回せんません(8時間/1営業日と仮定)。 16回でバグを全部なくせ、というのは結構しんどいですよね。
もしこのビルド時間が10倍速くになればどうでしょうか。最大で160回もサイクルを回せます。 前者と後者とでどちらが生産性が高いかは比べるまでもないですよね。 これはものすごく単純化した例ですが基本的な考えは一般化できます。
ccacheとはなんですか?
ccache とはC/C++のコンパイル速度を高速化するツールです。 オープンソースであり、LinuxはもちろんWindowsでも動作します。 また、導入方法も簡単です。例えば、Androidのccacheを利用したビルドの効果測定が京都マイクロコンピュータ社のAndroidのビルドでccacheを使うに載っています。
コンパイル速度にはHDD/SSDのアクセス速度やコンパイラライセンスの取得時間も関わるため一概には言えませんが、個人の経験では悪くても2倍は余裕で早くなるかともいます。環境との相性がよければ目を疑うほどの爆速になります。
ccache の仕組みは?
make の原理のおさらい
ビルドを効率化するためのツールとして、一番基本的なツールは Makefileですよね。 もしmakeを使わなければ、ビルドするために毎回すべてのソースコードをコンパイルしなければなりません。 一方makeは、ソースコード(.c/.cpp、インクルードしている.h/.hpp)の最終修正時刻とそれから生成される.oファイルの生成時刻を比較して、 ソースコードの修正時刻の方が新しい場合のみソースコードをコンパイルします。 つまり修正したソースコードだけをコンパイルすることで全体のビルド時間を短縮します。
ccache の原理の概要
ccache はそこからさらに高速化をすすめます。 ソースコードをコンパイルするとき、コンパイラはまずマクロの展開などのプリプロセッサ処理を行います。 次に、そのプリプロセス済みのコードをコンパイルしてオブジェクトファイル(.o)に変換します。
ccacheは、その「プリプロセス済みのコード」と「コンパイルずみのオブジェクトファイル(.o)」の2種類のファイルをキャッシングします。 ここでいうキャッシングとはCPUのキャッシュメモリとは関係ありません。広義のキャッシュのことです。 具体的にいうと、ビルド時に生成したそれら中間ファイルをPCのHDD/SSDに保存します。 そして次回以降、その保存した中間ファイルが使えそうだったらそれを利用します。 これにより実際にコンパイルする回数が減り飛躍的にビルド時間を短縮します。
ものすごく単純な例でいうと、make → make clean → 再度 make とした場合、1度目の make と2度目に make のビルド時間はほぼ同じになるはずです(I/Oバッファの分だけ2回目の方が早いかもですが)。
一方、ccacheを使っている場合は、1度目より2度目の方が何倍も早くなります。
1度目の make 時にキャッシングしたデータを流用してコピーするだけでコンパイルはしないのであっという間に終わります。
びっくりするくらい早くなります。
どのようにしてccacheが再コンパイルが必要かどうか判断しているかは、ソースコードファイルのハッシュ値を使っているようです。 興味のある方はGitHub - ccacheのコードを見てみてください。コード量はそれほど多くないので、頑張れば読めるかなと思います。
また、コンパイラを実行する回数が減る副次的な効果として、ライセンスの消費量が減ります。 例えば armcc などの有償のコンパイラをフローティングライセンスで使用している場合、開発チームが一度に使えるライセンス数には上限があります。 例えばライセンス数の上限が50で、100人の開発者が同時にビルドを始めると、ライセンスが枯渇してしまいライセンスがあくまで待たされたり、最悪ビルドに失敗したりしてしまう可能性が高くなります。 しかしccacheを使えば、キャッシングしたファイルが流用できる場合はコンパイラを実行せずに単にそのファイルをコピーするだけなのでライセンスを使用しません。よって使用するライセンス数を抑えることができます。
ccacheのインストール
Linuxの場合はパッケージマネージャでサクッとインストールできるかと思います。もしできなければソースコードからビルドすればOKです。
Linux でのインストール
大抵のディストリビューションにて、パッケージマネージャからインストールできると思います。下記のような感じでしょうかね。お使いの環境に合わせてパッケージマネージャでインストールしてください。
| |
| |
Mac OS X でのインストール
homebrew でのインストールが一番楽でしょう。homebrewを導入した上で、下記のように実行するだけです。
| |
MSYS2@Windows でのインストール
WindowsでかつMSYS2(やGit for Windows)をお使いの方もパッケージマネージャからインストールできます。
| |
パッケージマネージャが使えない場合@Linux
仕方ないので自分でソースコードからインストールしましょう。と言っても簡単ですが。下記のようにすればOKです。最初にソースコードを落としてくるところは、バージョンによってファイル名が違うので、そのときの最新版を持ってきてください。
| |
ccacheを使う
ccacheが動作するようにしましょう。gccなどのコンパイラコマンドの前にccaheを追加するだけです。つまり、たとえば
| |
としてコンパイルしていたなら
| |
とするだけです。 ccacheが動作しているか確認するには、キャッシュのヒット情報をみてみればわかります。-sオプションでこれまでのキャッシュヒット率などの統計情報が表示されます。一度目はcache miss が増えると思いますが、2度目以降はcache hitのところがどんどん増えていくはずです。
| |
ccacheを使うためのMakefileの変更例
Makefile を使っている場合は、下記のようなパターンルールがどこかに記載されているはずです。
| |
これを下記のようにしてあげればOKですね。.cpp でも要領は同じです。
| |
これじゃちょっとわかりづらいかもしれないので、Makefileの具体例を下記のところに置いています。 ccache が使えればccache を有効に、cchacheがインストールされていなければ普通にgccを使うようにしています。
まとめ
今回はC/C++のコンパイルを高速化するツールccacheについてご紹介しました。Windows、Linux、Mac OS Xそれぞれでのインストール方法と、Makefileの修正方法を説明しました。これでビルド時間が数倍になります! ccacheのオプションの詳細はccache公式ドキュメントをご参照ください。