Arduino IDE でビルドしたとき「コンパイル遅いなぁ」と思ったことはありませんか?1行しかソースコードを修正していないのにフルビルドが始まってイライラすること、ありませんか?
ためしに手元の ESP-WROOM-02 にてテキトウなプロジェクトをビルドしてみたところ、2分30秒近くかかりました。個人的にはソースコード量から考えるとかなり遅いという印象です。
この記事ではこのビルド時間を短縮する方法をご紹介します!
どうしてビルドに時間がかかっているの?
これは、Arduino IDE のデフォルトの挙動によるものです。コンパイルしたファイル(オブジェクトファイル .o)の出力先ディレクトリが、IDE立ち上げたりターゲットを切り替えたりした時に異なるディレクトリに設定するためです。もう少し具体的にいうと、Arduino IDE はランダムな数字列を含んだディレクトリを作成し、その中にオブジェクトファイルを出力します。このランダムな数字列がちょくちょく変更されるため、以前にコンパイルしたオブジェクトファイルを再利用できずに、再度フルビルドをすることになりビルドに時間がかかるわけです。
ちなみに、Windows では下記のディレクトリを利用します。「XXXXXX」がランダムな数字列になるところです。
C:\Users\username\AppData\Local\Temp\arduino_build_XXXXXX\
逆にいえば、オブジェクトファイルの出力先を毎回同じになるようにすれば、ソースコードを修正しない限りはリコンパイルしないので、ビルド時間が短縮できます!
オブジェクトファイル出力先を確認する
まず、現在の設定でどこにオブジェクトファイルが出力されるかを確認してみましょう。確認するために、IDEのコンパイル結果出力部分にコンパイラのメッセージを出力するようにします。
まずはIDEを起動し、メニューより「ファイル」→「環境設定」を選択します。
次に、環境設定のウィンドウが開きますので、設定タブを選択し、「より詳細な情報を表示する」というところを探します。そこに「コンパイル」と書かれたチェックボックスがあるので、これをチェックします。IDEのバージョンや設定言語によって微妙に場所が異なるかもしれませんが、下記の図を参考にしていただければわかると思います。
これで、IDEでビルドした時にどこにオブジェクトファイルを出力しているかがわかるようになります。下記のようにコンパイルメッセージ出力までのコンパイラの実行コマンドが出力されます。下の画像ではコマンドが長すぎて見切れてしまっていますが、垢枠のところにコンパイルコマンドが表示されています。そのコマンドのオプションでオブジェクトファイルの出力先を指定していますので、そのオプション部分を見ればOKです。
そこには、細かいところはターゲットによりますが、下記のようなコマンド列がずらずらと並んでいるはずです。オブジェクトファイルの指定は「-o」オプションです。下記の例でいうと一番最後の「-o “C:\Users\\AppData\Local\Temp\arduino_build_925358\core\WInterrupts.c.o”」がそれです。この arduino_build_925358がランダムに変わってしまう箇所です。
"C:\Programs\arduino\hardware\tools\avr/bin/avr-gcc" -c -g -Os -Wall -Wextra -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Programs\arduino\hardware\arduino\avr\cores\arduino" "-IC:\Programs\arduino\hardware\arduino\avr\variants\standard" "C:\Programs\arduino\hardware\arduino\avr\cores\arduino\WInterrupts.c" -o "C:\Users\\AppData\Local\Temp\arduino_build_925358\core\WInterrupts.c.o"
一度IDEを終了させてからもう一度ビルドを実行すると、その数字列が変わるはずです。
オブジェクトファイル出力先を固定する
IDEを再起動したりターゲットを切り替えたりするたびにせっかくコンパイルしたオブジェクトファイルが無駄になるのを避けるため、オブジェクトファイルの出力先をランダムでなく固定します。
その方法は、preferences.txt ファイルを編集します。このファイルを開くために、まずはIDEを起動し、メニューより「ファイル」→「環境設定」を選択します。
すると下記のようなウィンドウが開きます。赤枠のところにpreferences.txtのパスが書いてあります。ここをクリックするとそこのフォルダが開きます。
この preferences.txt を編集するのですが、このファイルを開くまえに必ずIDEを終了してください!このファイルはIDE終了時に更新されますので、IDEを終了させずにファイルを編集しても、変更内容が破棄されてしまいます!
IDE を終了させたらお好きなエディタでpreferences.txtを開いてください。メモ帳でもなんでもOKです。ファイルはこんな感じのテキストファイルです。
このファイルにビルドパスを追記します。下記のような1行を追加して、build.pathを指定してください。
build.path=C:\Users\username\AppData\Local\Temp\arduino_build
パスは任意で構いませんが、存在しないディレクトリを指定するとエラーが発生しますのでご注意ください。特にこだわりがなければ、システムの TEMP ディレクトリの下にサブディレクトリを作成して、そこを指定すればよいでしょう。Windows の場合は上記の例のようにしておけばよいかと思います(username のところはご自身のユーザー名に置き換えてください)
上記の例では、下記のようにDOSでディレクトリを作成すれば良いでしょう。システムのTMPディレクトリに移動して、任意の名前のディレクトリを作成しています。
C:\Users\username>cd %TMP% C:\Users\username\AppData\Local\Temp>mkdir arduino_build
これで、ランダムでなく毎回おなじディレクトリにオブジェクトファイルが生成されるようになります!
オブジェクトファイル出力先を確認する
これでオブジェクトファイルがおなじ場所に生成されるようになります。念のため、IDEを再度立ち上げて確認してみましょう。
これまで述べた設定例にした場合、コンパイルコマンドが下記のようになっているはずです。「-o “C:\Users\\AppData\Local\Temp\arduino_build\core\WInterrupts.c.o”」となっています。ランダムであった数字列がなくなっているのがわかると思います。
"C:\Programs\arduino\hardware\tools\avr/bin/avr-gcc" -c -g -Os -Wall -Wextra -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10805 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR "-IC:\Programs\arduino\hardware\arduino\avr\cores\arduino" "-IC:\Programs\arduino\hardware\arduino\avr\variants\standard" "C:\Programs\arduino\hardware\arduino\avr\cores\arduino\WInterrupts.c" -o "C:\Users\\AppData\Local\Temp\arduino_build\core\WInterrupts.c.o"
一度コンパイルすれば、ソースコードを修正しない限り再度コンパイルすることはなくなりました。例えば一度IDEを終了してから再度立ち上げてビルドした場合、下記のようにほとんどコンパイル処理が走りません(「オブジェクトファイル出力先を確認する」のところで示したキャプチャと比較すれば処理の短さがわかるかとおもいます)。
これでソースを変更していないのにフルビルドが走って待たされることがなくなります!お疲れ様でした!
まとめ
ArduinoIDE にてビルドが遅い原因とその回避方法を示しました。オブジェクトファイルの出力ディレクトリ名をランダムに生成しているため、IDEを再起動したりするとフルコンパイルになります。これを設定ファイルpreferences.txtの編集により回避できます。開発速度を加速したい方は試してみると良いかもですね!
FYI
ちなみに ESP-WROOM-02 で遊ぶために下記のキットを使用しています。Arduino UNO とおなじ形状になったやつです。ご参考まで。。
ESP-WROOM-02単体だと下記のような形状です、このままだとちょっと面倒ですね笑
コメント
[…] https://nagayasu-shinya.com/arduino-buildpath-fix/ […]
情報公開ありがとうございます。
単一スケッチ(同一名)の場合は有効ですが、複数スケッチ(異なるスケッチ名)の場合、一度クリアされてしまいますが解決法はありますでしょうか?