Arduinoでccacheを使ってビルドを高速化!

シェアする

Arduino IDE でビルドしたとき「コンパイル遅いなぁ」と思ったことはありませんか?今回は ccache というc/c++向けのコンパイル高速化ツールを使って、Arduino IDEでのビルドを高速化する方法をご紹介します。

ccache の説明は他の記事で行っており、しかるべきタイミングでその記事へのリンク貼っておりますので、「ccacheナニそれ?」というかたもひとまずそのまま読み進めてくださいませ。

スポンサーリンク

ccahceのインストール

まずは ccache をインストールします。下記の記事にてccache の簡単な説明とインストール方法(Windows、Linux、Mac OS X)を書いています。インストールは簡単ですのでサクッと終わると思います。

C/C++のコンパイルを高速化する|ccache
C/C++のコンパイルを高速化するccacheについて、Linux, Windows, Macそれぞれでのインストール方法を紹介しています。また、実際にMakefile の修正例もあげています。これでビルド時間が数分の一に短縮されます!

Arduino IDE の前準備

次に、Arduino IDEの前準備をします。Arduino IDEのデフォルトのコンパイルの挙動は「ランダムな名前でディレクトリを作りそこに.oファイルを出力する。かつ、その出力先をコマンドオプションで指定する」という(個人的には)あまり使いやすいものではない設定になっています。その挙動ではccacheを動かすのは大変なので、下記の記事を参考に出力ディレクトリを固定してください

Arduino IDEのビルドを速くする|オブジェクトファイルの出力先を固定する
Arduino IDE はデフォルトの設定ではコンパイルに時間がかかってしまいます。これはオブジェクトファイルの出力ディレクトリ名をランダムに生成しているためです。これを設定ファイルpreferences.txtの編集により回避する方法を説明します。

Arduino IDE にてccacheを使う設定

この時点でccacheを使う準備は整いました。あとはArduino IDE 設定ファイルを少し書き換えるだけです。具体的には、コンパイラのオプションが書かれている「platform.txt」を修正します。コンパイラの設定が書かれているので使用するマイコンによってファイルがある場所が異なります。ここでは例として、Atmel AVR マイコンが搭載されているArduino UNO を例に説明します。Arduino Nano も同マイコンなので全く同じ手順です。
「ほかのマイコンが載ってるよ!」という方も、おいてあるフォルダは違えどplatform.txtという同じなまえでどこかにあるはずなので、探してみてください。

Windowsにてc:\Programs\arduino\に Arduino IDE をインストールした場合は、設定ファイルは下記の場所にあります。
c:\Programs\arduino\hardware\arduino\avr\platform.txt

LinuxやMac OS X もだいたい同じような場所にあるはずです。Arduinoのあるフォルダからみてhardware\arduino\avr\platform.txtにあると思います。

platform.txt を見つけたら、お好きなエディタで開いてください。そしてコンパイラオプションを設定しているところを探してください。
「recipe.c.o.pattern」,「recipe.cpp.o.pattern」で検索するとヒットするはずです。ここでいうrecipe(レシピ)とは、Makefileで言えばパタンルールに該当します。「.c から.oを作成する方法」くらいの意味ですね。

# AVR compile patterns
# --------------------

## Compile c files
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}"
{compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu}
-DARDUINO={runtime.ide.version} -DARDUINO_{build.board}
-DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags}
{build.extra_flags} {includes} "{source_file}" -o "{object_file}"


## Compile c++ files
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}"
{compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu}
-DARDUINO={runtime.ide.version} -DARDUINO_{build.board}
-DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags}
{build.extra_flags} {includes} "{source_file}" -o "{object_file}"

ccache を使うには、このレシピにccacheを付け加えるだけです。必ずコマンドの先頭につけてくださいね。下記の例を参考にしてください。

# AVR compile patterns
# --------------------

## Compile c files
recipe.c.o.pattern=ccache "{compiler.path}{compiler.c.cmd}"
{compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu}
-DARDUINO={runtime.ide.version} -DARDUINO_{build.board}
-DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags}
{build.extra_flags} {includes} "{source_file}" -o "{object_file}"


## Compile c++ files
recipe.cpp.o.pattern=ccache "{compiler.path}{compiler.cpp.cmd}"
{compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu}
-DARDUINO={runtime.ide.version} -DARDUINO_{build.board}
-DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags}
{build.extra_flags} {includes} "{source_file}" -o "{object_file}"

Arduino IDE にてccacheが動いているか確認

実際にArduino IDEで任意のスケッチをビルドしてみます。下記の赤枠のようにccacheが呼ばれていたら成功です!!

ccacheの統計情報にてccacheが動いているか確認

念のため、ccacheの統計情報(キャッシュヒット率などの情報)をみて、ちゃんとccacheが実行されているか確認しておきましょう。今回はWindows DOS(cmd)にて解説しますが、Linuxでも Mac OS Xでも同じです。
また、Arduino IDE の前準備で作った出力ディレクトリはC:\Users\username\AppData\Local\Temp\arduino_buildとしおきます。

まず、確認がしやすいようにccacheのキャッシュをクリアしておきます。

C:\Users\username\AppData\Local\Temp>ccache -c -C -z

この状態で統計情報を表示させると、下記のようにヒット数、ヒット率、ミスヒット数など全部が0になっているはずです。

C:\Users\username\AppData\Local\Temp>ccache -s
cache directory                     C:\Users\username\AppData\Roaming/.ccache
primary config
C:\Users\username\AppData\Roaming/.ccache/ccache.conf
secondary config      (readonly)    C:/Programs/msys64/mingw64/etc/ccache.conf
stats zero time                     04/14/21 01:39:37
cache hit (direct)                     0
cache hit (preprocessed)               0
cache miss                             0
cache hit rate                      0.00 %
cleanups performed                     0
files in cache                         0
cache size                           0.0 kB
max cache size                       5.0 GB

この状態で、Arduino IDEにて任意のスケッチをビルドしてみてください。そして再度、ccacheの統計情報を表示させてみてください。スケッチによると思いますがミスヒット数(cache miss)が増えているはずです。最初の1回目のビルドはキャッシュが空っぽなのでキャッシュヒットしようがありませんので、期待した動作ですね。


C:\Users\username\AppData\Local\Temp>ccache -s
cache directory                     C:\Users\username\AppData\Roaming/.ccache
primary config
C:\Users\username\AppData\Roaming/.ccache/ccache.conf
secondary config      (readonly)    C:/Programs/msys64/mingw64/etc/ccache.conf
stats zero time                     04/14/21 01:39:37
cache hit (direct)                     0
cache hit (preprocessed)               0
cache miss                            25
cache hit rate                      0.00 %
cleanups performed                     0
files in cache                        74
cache size                         392.2 kB
max cache size                       5.0 GB

さらにもう一度ビルドすると、出力ディレクトリの.oファイルが普通に使われるだけなので出力ディレクトリの中身を削除してしまいましょう。
(エクスプローラーからザクっとディレクトリごと消しちゃってももちろんOKです。とにかく出力ディレクトリの.oを消せばOKです)

C:\Users\username\AppData\Local\Temp>cd arduino_build
C:\Users\username\AppData\Local\Temp\arduino_build>del /s/q *

.oファイルを全部消したところで、再度、 Arduino IDEにてビルドしてみましょう。普通ならフルビルドが始まるところですが、先ほどccacheにてキャッシングしているので、今回はコンパイルは実際は行いません。すぐにビルドも終わるはずです。

さて、ではccacheの統計情報をみてみましょう。今回はミスヒット(cache miss)数は増えていませんね。その代わりキャッシュヒット数(direct, preprocessed)が増えています。つまりキャッシュがヒットしているということですね。このようにキャッシュヒット数が増えていることが確認できればOKです!!

C:\Users\username\AppData\Local\Temp>ccache -s
cache directory                     C:\Users\username\AppData\Roaming/.ccache
primary config
C:\Users\username\AppData\Roaming/.ccache/ccache.conf
secondary config      (readonly)    C:/Programs/msys64/mingw64/etc/ccache.conf
stats zero time                     04/14/21 01:39:37
cache hit (direct)                    24
cache hit (preprocessed)               1
cache miss                            25
cache hit rate                     50.00 %
cleanups performed                     0
files in cache                        74
cache size                         392.2 kB
max cache size                       5.0 GB

この例くらいの規模ではファイル数が少ないのであまり恩恵を感じられないかもしれませんが、ファイル数が増えれば増えるほど効果は増していきますよ!

まとめ

今回は、c/c++ コンパイル高速化ツール ccache を Arduino IDEでも使えるようにすることで、コンパイルを高速化する方法をご紹介しました。これで開発が効率化できるはずです!Arduinoくらいの規模だとビルド時間は軽視されがちですが、ビルドは何度もするので、必ず役に立ちますよ

今回の説明の例としてあげたのは Arduino UNO です。

純正じゃなくてもいいやすい方がいい!という方はこういうのもありますね。
(なんか操作を間違えたのかブートローダーがぶっとんだりしたことありますが…まあ壊す前提ならこれもありかも)