Arduino IDE でのビルドを速くするためにccacheというc/c++向けのコンパイル高速化ツールを使って高速化する方法をご紹介します。


ccacheのインストール

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

Arduino IDE の前準備

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

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を作成する方法」くらいの意味ですね。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 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を付け加えるだけです。 必ずコマンドの先頭につけてくださいね。下記の例を参考にしてください。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 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が呼ばれていたら成功です!!

Arduino IDEのビルド出力でccacheが呼ばれている様子

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

念のためccacheの統計情報(キャッシュヒット率などの情報)をみて、ちゃんとccacheが実行されているか確認しておきましょう。 今回はWindows にて解説しますが、Linuxでも Mac OS Xでも同じです。

また、Arduino IDEのビルドを速くする|オブジェクトファイルの出力先を固定するで作った出力ディレクトリはC:\Users\username\AppData\Local\Temp\arduino_buildとしおきます。 まず、確認がしやすいようにccacheのキャッシュをクリアしておきます。

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

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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回目のビルドはキャッシュが空っぽなのでキャッシュヒットしようがありませんので、期待した動作ですね。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15

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                            2
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です)

1
2
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です!!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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くらいの規模だとビルド時間は軽視されがちですが、ビルドは何度もするので、必ず役に立ちますよ

追記:さらに高速化するためにCCACHEを使う方法があります。 Arduino IDEのビルドを速くする|オブジェクトファイルの出力先を固定するの記事をご参考ください!