背景
PlatformIOで複数のサンプルコードを用意したり、 試行錯誤している際に、 似たような構成のプロジェクトを複数用意することになります。
そのような時に、似たようなプロジェクトがいくつもできてしまうのを避けるために、
ビルド時に setup()
や loop()
などのメインのコードだけを差し替えることで、
同じプロジェクトを使い回す方法を調査したので書いていこうと思います。
解決方法1(platformio.iniでビルド対象のファイルを切り変える)
platformio.ini
の
build_src_filterを
設定することでビルド対象のファイルをフィルタリングすることができます。
なので、環境ごとにビルド対象のファイルを変えることでメインのファイルを切り替えます。
具体的には以下のような構成になります。 ここではESP32の例を載せています。 また、この記事では PlatformIO Core 6.1.18 を使用しています。
.
├── platformio.ini
└── src
├── main1.cpp
└── main2.cpp
platformio.ini
[platformio]
default_envs=esp32dev1 ;ここでビルドする環境を切り替える
; 環境共通の設定
[env]
platform = espressif32
board = esp32dev
framework = arduino
build_src_filter =
-<**/main*.cpp> ;ここで **/main*.cpp をビルド対象から除外する
lib_deps =
z3t0/IRremote@^4.4.1 ;ここに共通で使うライブラリを記述する
; 環境1(esp32dev1)
[env:esp32dev1]
build_src_filter =
${env.build_src_filter}
+<main1.cpp> ;ここで main1.cpp をビルド対象とする
lib_deps =
${env.lib_deps}
hideakitai/ArduinoOSC@^0.5.1 ;ここに環境固有のライブラリを記述する
; 環境2(esp32dev2)
[env:esp32dev2]
build_src_filter =
${env.build_src_filter}
+<main2.cpp> ;ここで main2.cpp をビルド対象とする
lib_deps =
${env.lib_deps}
main1.cpp
#include <Arduino.h>
void setup() {
Serial.begin(115200);
Serial.println("main1.cpp");
}
void loop() {}
main2.cpp
#include <Arduino.h>
void setup() {
Serial.begin(115200);
Serial.println("main2.cpp");
}
void loop() {}
解決方法2(extra_scriptsでbuild_src_filterを更新する)
もう少しスマートに解決する方法として、
ビルド前にスクリプトを実行して build_src_filter
を更新する方法が考えられます。
この方法のメリットは、 platform.ini
がすっきりする点と、
ビルド対象のファイル名と環境名を関連付けられる点です。
以下に具体的な構成を載せます。
.
├── platformio.ini
├── pre_extra_script.py
└── src
├── esp32dev1_main.cpp
└── esp32dev2_main.cpp
platform.ini
platform.ini
では build_src_filter
で全ての **/main*.cpp
をビルド対象から除外し、
extra_scripts
のみを記述します。
[platformio]
default_envs=esp32dev1 ;ここでビルドする環境を切り替える
; 環境共通の設定
[env]
platform = espressif32
board = esp32dev
framework = arduino
build_src_filter =
-<**/main*.cpp> ;ここで **/main*.cpp をビルド対象から除外する
lib_deps =
z3t0/IRremote@^4.4.1 ;ここに共通で使うライブラリを記述する
extra_scripts =
pre:pre_extra_script.py ;ビルド前に実行するスクリプトを指定する
; 環境1(esp32dev1)
[env:esp32dev1]
lib_deps =
${env.lib_deps}
hideakitai/ArduinoOSC@^0.5.1 ;ここに環境固有のライブラリを記述する
; 環境2(esp32dev2)
[env:esp32dev2]
lib_deps =
${env.lib_deps}
pre_extra_script.py
ビルド前に実行される pre_extra_script.py
は以下のようになります。
platfomio.ini
で記述されている build_src_filter
に ${環境名}_main.cpp
を追加しています。
Import('env')
env.Replace(SRC_FILTER=env['SRC_FILTER'] + [f'+<{env["PIOENV"]}_main.cpp>'])
esp32dev1_main.cpp
#include <Arduino.h>
void setup() {
Serial.begin(115200);
Serial.println("esp32dev1_main.cpp");
}
void loop() {
}
esp32dev2_main.cpp
#include <Arduino.h>
void setup() {
Serial.begin(115200);
Serial.println("esp32dev2_main.cpp");
}
void loop() {
}
まとめ
とりあえず思いついた方法はこんな感じです。 やりすぎかな?と思いつつも、個人的には二番目の方法がスマートでいいなと思います。
extra_scriptsは初めて書いたのですが env.Dump()
でキーの名前を調べたり、
デバッガーを使って調査できなかったり少し大変だなーと思いました。
ですが使い慣れると便利そうです。
この辺はそのうち使うかもしれないのでメモしておきます。