M5StackやM5StickCなどEPS32環境をArduinoでビルドするときのコンパイルオプション


ほぼ自分用メモ。


どうも調べても設定方法しか見つからず。それを把握したとしても、その設定がどう渡るかに疑念が残ります。
実際にコンパイラに渡されるオプションはどうなってんのよ、ということでプロセスの実行を捕まえて調べてみました。

#実行プロセス

MacのArduino環境で、M5StickC をターゲットにして TFT_Starfield/TFT_Starfield.ino というサンプルをコンパイルしたときにOSが実行するコマンドを、シェルスクリプト形式に直した（一部を変数化して文字数を減らした）ものが以下です。

```
ESP32=/Users/$USER/Library/Arduino15/packages/esp32
CC=$ESP32/tools/xtensa-esp32-elf-gcc/1.22.0-80-g6c4433a-5.2.0/bin/xtensa-esp32-elf-g++
INCLUDE=$ESP32/hardware/esp32/1.0.2/tools/sdk/include

$CC -DESP_PLATFORM -DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h" -DHAVE_CONFIG_H -I$INCLUDE/config -I$INCLUDE/app_trace -I$INCLUDE/app_update -I$INCLUDE/asio -I$INCLUDE/bootloader_support -I$INCLUDE/bt -I$INCLUDE/coap -I$INCLUDE/console -I$INCLUDE/driver -I$INCLUDE/esp-tls -I$INCLUDE/esp32 -I$INCLUDE/esp_adc_cal -I$INCLUDE/esp_event -I$INCLUDE/esp_http_client -I$INCLUDE/esp_http_server -I$INCLUDE/esp_https_ota -I$INCLUDE/esp_ringbuf -I$INCLUDE/ethernet -I$INCLUDE/expat -I$INCLUDE/fatfs -I$INCLUDE/freemodbus -I$INCLUDE/freertos -I$INCLUDE/heap -I$INCLUDE/idf_test -I$INCLUDE/jsmn -I$INCLUDE/json -I$INCLUDE/libsodium -I$INCLUDE/log -I$INCLUDE/lwip -I$INCLUDE/mbedtls -I$INCLUDE/mdns -I$INCLUDE/micro-ecc -I$INCLUDE/mqtt -I$INCLUDE/newlib -I$INCLUDE/nghttp -I$INCLUDE/nvs_flash -I$INCLUDE/openssl -I$INCLUDE/protobuf-c -I$INCLUDE/protocomm -I$INCLUDE/pthread -I$INCLUDE/sdmmc -I$INCLUDE/smartconfig_ack -I$INCLUDE/soc -I$INCLUDE/spi_flash -I$INCLUDE/spiffs -I$INCLUDE/tcp_transport -I$INCLUDE/tcpip_adapter -I$INCLUDE/ulp -I$INCLUDE/vfs -I$INCLUDE/wear_levelling -I$INCLUDE/wifi_provisioning -I$INCLUDE/wpa_supplicant -I$INCLUDE/xtensa-debug-module -I$INCLUDE/esp32-camera -I$INCLUDE/esp-face -I$INCLUDE/fb_gfx -std=gnu++11 -fno-exceptions -O3 -g3 -Wpointer-arith -fexceptions -fstack-protector -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -mlongcalls -nostdlib -w -Wno-error=unused-function -Wno-error=unused-but-set-variable -Wno-error=unused-variable -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-sign-compare -fno-rtti -c -w -x c++ -E -CC -DF_CPU=240000000L -DARDUINO=10802 -DARDUINO_M5Stick_C -DARDUINO_ARCH_ESP32 -DARDUINO_BOARD="M5Stick_C" -DARDUINO_VARIANT="m5stick_c" -DESP32 -DCORE_DEBUG_LEVEL=0 -I$ESP32/hardware/esp32/1.0.2/cores/esp32 -I$ESP32/hardware/esp32/1.0.2/variants/m5stick_c /var/folders/zc/abcdefghijklmnopqrstuvwx0000yz/T/arduino_build_186590/sketch/TFT_Starfield.ino.cpp -o /dev/null
```

##整形

見やすいように、space区切りを改行に変換するとこう。

```
ESP32=/Users/$USER/Library/Arduino15/packages/esp32
CC=$ESP32/tools/xtensa-esp32-elf-gcc/1.22.0-80-g6c4433a-5.2.0/bin/xtensa-esp32-elf-g++
INCLUDE=$ESP32/hardware/esp32/1.0.2/tools/sdk/include

$CC
-DESP_PLATFORM
-DMBEDTLS_CONFIG_FILE="mbedtls/esp_config.h"
-DHAVE_CONFIG_H
-I$INCLUDE/config
-I$INCLUDE/app_trace
-I$INCLUDE/app_update
-I$INCLUDE/asio
-I$INCLUDE/bootloader_support
-I$INCLUDE/bt
-I$INCLUDE/coap
-I$INCLUDE/console
-I$INCLUDE/driver
-I$INCLUDE/esp-tls
-I$INCLUDE/esp32
-I$INCLUDE/esp_adc_cal
-I$INCLUDE/esp_event
-I$INCLUDE/esp_http_client
-I$INCLUDE/esp_http_server
-I$INCLUDE/esp_https_ota
-I$INCLUDE/esp_ringbuf
-I$INCLUDE/ethernet
-I$INCLUDE/expat
-I$INCLUDE/fatfs
-I$INCLUDE/freemodbus
-I$INCLUDE/freertos
-I$INCLUDE/heap
-I$INCLUDE/idf_test
-I$INCLUDE/jsmn
-I$INCLUDE/json
-I$INCLUDE/libsodium
-I$INCLUDE/log
-I$INCLUDE/lwip
-I$INCLUDE/mbedtls
-I$INCLUDE/mdns
-I$INCLUDE/micro-ecc
-I$INCLUDE/mqtt
-I$INCLUDE/newlib
-I$INCLUDE/nghttp
-I$INCLUDE/nvs_flash
-I$INCLUDE/openssl
-I$INCLUDE/protobuf-c
-I$INCLUDE/protocomm
-I$INCLUDE/pthread
-I$INCLUDE/sdmmc
-I$INCLUDE/smartconfig_ack
-I$INCLUDE/soc
-I$INCLUDE/spi_flash
-I$INCLUDE/spiffs
-I$INCLUDE/tcp_transport
-I$INCLUDE/tcpip_adapter
-I$INCLUDE/ulp
-I$INCLUDE/vfs
-I$INCLUDE/wear_levelling
-I$INCLUDE/wifi_provisioning
-I$INCLUDE/wpa_supplicant
-I$INCLUDE/xtensa-debug-module
-I$INCLUDE/esp32-camera
-I$INCLUDE/esp-face
-I$INCLUDE/fb_gfx
-std=gnu++11
-fno-exceptions
-Os
-g3
-Wpointer-arith
-fexceptions
-fstack-protector
-ffunction-sections
-fdata-sections
-fstrict-volatile-bitfields
-mlongcalls
-nostdlib
-w
-Wno-error=unused-function
-Wno-error=unused-but-set-variable
-Wno-error=unused-variable
-Wno-error=deprecated-declarations
-Wno-unused-parameter
-Wno-sign-compare
-fno-rtti
-c
-w
-x
c++
-E
-CC
-DF_CPU=240000000L
-DARDUINO=10802
-DARDUINO_M5Stick_C
-DARDUINO_ARCH_ESP32
-DARDUINO_BOARD="M5Stick_C"
-DARDUINO_VARIANT="m5stick_c"
-DESP32
-DCORE_DEBUG_LEVEL=0
-I$ESP32/hardware/esp32/1.0.2/cores/esp32
-I$ESP32/hardware/esp32/1.0.2/variants/m5stick_c
/var/folders/zc/abcdefghijklmnopqrstuvwx0000yz/T/arduino_build_186590/sketch/TFT_Starfield.ino.cpp
-o
/dev/null
```

なるほどなるほど。

## プラットフォーム分岐

プログラムでM5StackとM5StickCを同一に扱いたいのなら、

```:C++
#ifdef ESP_PLATFORM
```

が良さそうです。

M5StickCだけに限定したいなら、

```:C++
#ifdef ARDUINO_M5Stick_C
```

で良さそうです。

#まだ完全ではない

得られたコマンドを実行してもエラーが出ちゃいます。まだいくつか include path が足りていないようです。なぜだろう？
具体的には

```
/Users/$USER/Documents/Arduino/libraries/M5StickC/src
$ESP32/hardware/esp32/1.0.2/libraries以下
```

などが必要でした。これらはどうやって渡されてるんですかね？


# おまけ
-Os というオプションが見えます。デフォルトではサイズ優先になってるんですね。ここを -O3 にすると高速化が望めます（手元のプログラムでは10%ほど高速化しました）。まあ通常はサイズ優先が正しいでしょう。

なおオプションの変更は、手元のMac環境ですとここ：
/Users/$USER/Library/Arduino15/packages/esp32/hardware/esp32/1.0.2/platform.txt

# おまけ２

-fexceptions というオプションが見えます。例外必要かなあ。サイズを気にするのであれば -fno-exceptions を試したいところ。試してませんが。

# おまけ３
ついでにリンカ実行も載せておきます。

```
ESP32=/Users/$USER/Library/Arduino15/packages/esp32
WORK=/var/folders/zc/abcdefghijklmnopqrstuvwx0000yz/T/arduino_build_186590
CC=$ESP32/tools/xtensa-esp32-elf-gcc/1.22.0-80-g6c4433a-5.2.0/bin/xtensa-esp32-elf-gcc

$CC -nostdlib -L$ESP32/hardware/esp32/1.0.2/tools/sdk/lib -L$ESP32/hardware/esp32/1.0.2/tools/sdk/ld -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld -T esp32.rom.spiram_incompatible_fns.ld -u ld_include_panic_highint_hdl -u call_user_start_cpu0 -Wl,--gc-sections -Wl,-static -Wl,--undefined=uxTopUsedPriority -u __cxa_guard_dummy -u __cxx_fatal_exception -Wl,--start-group $WORK/sketch/TFT_Starfield.ino.cpp.o $WORK/libraries/M5StickC/AXP192.cpp.o $WORK/libraries/M5StickC/IMU.cpp.o $WORK/libraries/M5StickC/M5Display.cpp.o $WORK/libraries/M5StickC/M5StickC.cpp.o $WORK/libraries/M5StickC/RTC.cpp.o $WORK/libraries/M5StickC/Fonts/Font16.c.o $WORK/libraries/M5StickC/Fonts/Font32rle.c.o $WORK/libraries/M5StickC/Fonts/Font64rle.c.o $WORK/libraries/M5StickC/Fonts/Font72rle.c.o $WORK/libraries/M5StickC/Fonts/Font7srle.c.o $WORK/libraries/M5StickC/Fonts/glcdfont.c.o $WORK/libraries/M5StickC/utility/qrcode.c.o $WORK/libraries/M5StickC/utility/In_eSPI.cpp.o $WORK/libraries/M5StickC/utility/Sprite.cpp.o $WORK/libraries/Wire/Wire.cpp.o $WORK/libraries/SPI/SPI.cpp.o $WORK/libraries/FS/FS.cpp.o $WORK/libraries/FS/vfs_api.cpp.o $WORK/core/core.a -lgcc -lopenssl -lbtdm_app -lfatfs -lwps -lcoexist -lwear_levelling -lesp_http_client -lprotobuf-c -lhal -lnewlib -ldriver -lbootloader_support -lpp -lfreemodbus -lmesh -lsmartconfig -ljsmn -lwpa -lethernet -lphy -lfrmn -lapp_trace -lfr_coefficients -lconsole -lulp -lwpa_supplicant -lfreertos -lbt -lmicro-ecc -lesp32-camera -lcxx -lxtensa-debug-module -ltcp_transport -lmdns -lvfs -lmtmn -lesp_ringbuf -lsoc -lcore -lfb_gfx -lsdmmc -llibsodium -lcoap -ltcpip_adapter -lprotocomm -lesp_event -limage_util -lc_nano -lesp-tls -lasio -lrtc -lspi_flash -lwpa2 -lwifi_provisioning -lesp32 -lface_recognition -lapp_update -lnghttp -lspiffs -lface_detection -lespnow -lnvs_flash -lesp_adc_cal -llog -ldl_lib -lsmartconfig_ack -lexpat -lfd_coefficients -lm -lmqtt -lc -lheap -lmbedtls -llwip -lnet80211 -lesp_http_server -lpthread -ljson -lesp_https_ota -lstdc++ -Wl,--end-group -Wl,-EL -o $WORK/TFT_Starfield.ino.elf
```

#まとめ
マクロで分岐するときの参考になると思います。
そしてアセンブラ出力の確認もできました(-c -E オプションを取って -S オプションを加える。include path を足す必要あり）。どんなコードが吐かれてるのか気になる方は（そんなにいないと思いますが）参考にしていただければ。