#これまでのあらすじ
Arduino-ESP32 で書いたプログラムを ESP-IDF でビルドしたいのだ。しかしAruino IDE で作成した .ino ファイルは .cpp じゃないので、ESP-IDF の C++コンパイラではコンパイルできない。
#言うてもArduino IDE だって C++コンパイラ通してるんでしょう?
ログを詳細に見ればわかるとおり、Arduino IDE だって avr-g++ とか xtensa-esp32-elf-g++ とか C/C++コンパイラを通しているのである。
さらに良く見ると sketch.ino 等の拡張子ではない、 sketch.ino.cpp とかいうファイルをコンパイルしているので、そんなファイルがあるならそいつを ESP-IDF に持って行けば絶対コンパイルできるはず。
#C++コンパイラ通せる sketch.ino.cpp ってどこにある?
探すのが面倒な場所にあるので、場所を変えておくのが楽。
参考サイト:Arduino IDEのビルドを速くする|オブジェクトファイルの出力先を固定する
変更の方法。まずファイル-環境設定を開くと下の方に**「以下のファイルを直接編集すれば、より多くの設定を行うことが出来ます。」**との文言とpreferences.txt のフルパスが書いてあって、ファイル名をクリックするとそのフォルダが開く。
Arduino IDE を一応終了させてから preferences.txt を編集。build.path の行を探して
build.path=c:\arduino_b
とでも指定して保存して終了。ディレクトリは自分で作っておく。
改めて Arduino IDE を起動して適当な sketch.ino をコンパイルすれば、 c:\arduino_b\sketch\sketch.ino.cpp が生成されている。
#一部ライブラリも持って行かないといけない
ESP32 特有じゃない Arduino ライブラリ(LiquidCrystal とか) は、ESP-IDF にも Arduino-ESP32 にも無いライブラリなので自分で持って行く必要がある。
ESP32特有の(もっていかなくてもいい)ライブラリは Windows に Arduino-ESP32 1.0.1 を入れた場合なら下記場所にある。
C:\Users\uesrname\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.1\libraries
ESP-IDF の components として Arduino-ESP32 を入れてるなら、そのディレクトリに libraries というディレクトリがあり、中に同じ物が入っている。
LiquidCrystal のようなものも、libraries に置けば済むのであれば楽なのだが、 CMakeLists.txt とか書き直さないといけないようで面倒だ。
自分は sketch.ino.cpp と同じ所に LiquidCrystal.h と LiquidCrystal.cpp を置いて、sketch.ino.cpp の中に #include <LiquidCrystal.h>
と書いてあったら #include "LiquidCrystal.h"
に直すことで対応している。(ダブルクオートであれば、.cppファイルと同じフォルダにある .h を読んでくれるが、<> だと読んでくれない)
あとは ESP-IDF のバージョンが Arduino-ESP32 と整合していて、sdkconfig が適切で、partitions.csv も適切なら make が通って make flash で書き込める。
ESP-IDF のバージョンが Arduino-ESP32 と整合 についてはすでに書いた記事 の通りだが、他はまた別の記事として書く、かも。
#ちなみに .ino.cpp への変換は何をやってるかというと
Arduino IDE の Build process - Pre-Processing
.ino ファイルは以下の プリプロセスを経て .ino.cpp ファイルに変換されてから c++コンパイラでコンパイルされます。
・スケッチフォルダの中の全ての .ino ファイル(IDEにてタブ表示されているもの。タブ名=拡張子なしのファイル名)は1つに統合される。
先頭はスケッチフォルダと同じ名前で拡張子 .ino のファイル。その後は残りのファイルを abc 順に。そして、.ino.cpp ファイルとして一旦保存する。
・もしなければ #include "Arduino.h" を .ino.cpp ファイルの先頭に。このヘッダは 選択されているボードの core フォルダにあり、Arduino Core に必要な定義をしています。
・プロトタイプ宣言の無い関数すべてについてプロトタイプ宣言が作成され、.ino.cpp の最初の関数定義の前に挿入されます。
・コンパイラの warning や error が元々のファイルの名前と行番号で出力されるように #line ディレクティブが必要箇所に挿入されます。
つまり、ハードウェアに関係無いお話、だったりします。