ライブラリのサブディレクトリにあるヘッダーファイルをインクルードできるようにする
ライブラリ開発者向けの内容です。
Arduino のライブラリの仕様上、ユーザーが作成したライブラリのサブディレクトリにあるヘッダーファイルをインクルードすることができません 1 。
#include <MyLibrary/Algorithm/Math.hpp> // ERROR!
また、ヘッダーファイル (.h .hpp .hh) 以外の拡張子を持つファイルも不可です 2 3。ボードにデフォルトで組み込まれているライブラリは例外です。
#include <iostream> // ERROR!
しかし、巷の C++ ライブラリはこれらの方式を取っているものが多いです。そこで Arduino のライブラリでも同じようにインクルードできるようにする裏技(?)を紹介します。
ライブラリのディレクトリを構成
ライブラリのインクルードディレクトリ(src
)に、適当なヘッダーファイルを作成します。
中身は空ファイルで大丈夫です。またファイル名も任意で、サブディレクトリ名やライブラリフォルダ名と同じでなくて大丈夫です。
~/Documents/Arduino/libraries
│
└─ MyLibrary
├─ src
│ ├─ MyLibrary
│ │ └─ Algorithm
│ │ └─ Math.hpp
│ └─ MyLibrary.hpp ## < これ
└─ library.properties
library.properties は次のようにしておきます。各項目は適宜埋める必要があります。libraryproperties-file-format を参照ください。
name=MyLibrary
version=1.0.0
author=HogeHoge
maintainer=HogeHoge
sentence=HogeHoge
paragraph=HogeHoge
category=Other
url=http://example.com/
architectures=*
先ほど作成したファイルを先にインクルードする
これでサブディレクトリのヘッダーファイルをインクスルードできるようになります。
// ~~.ino
#include <MyLibrary.hpp>
#include <MyLibrary/Algorithm/Math.hpp>
おわり
このようにスケッチから インクルードディレクトリ直下のヘッダーを先にインクルードすると、サブディレクトリのヘッダーをインクルードできる ようになります。
ヘッダーファイル以外のファイルをインクルードしてみる
MyLibrary.hpp
をインクルードすると、ヘッダーファイル以外のファイルもインクルードできるようになります。実用的なものですと C++ STL の拡張子なしファイルでしょうか。
~/Documents/Arduino/libraries
│
└─ MyLibrary
├─ src
│ ├─ iostream ## < これ
│ └─ MyLibrary.hpp
└─ library.properties
#include <MyLibrary.hpp>
#include <iostream>
おわり・なぜ直接インクルード出来ないのか (想像)
あくまで想像ですが、コンパイル時間短縮のためだと思います。全てのライブラリのサブディレクトリまで検索するとなると、かなり時間がかかると思います。
そこで初期状態では、インクルードディレクトリ直下のヘッダーのみを検索し、直下のヘッダーファイルがインクルードされると、このライブラリは使用中 とマークされ、サブディレクトリ下も検索されるのではないでしょうか。
最後までご覧頂き有難うございました。
Arduino ドキュメント - ライブラリの仕様
https://arduino.github.io/arduino-cli/0.35/library-specification/#source-code
↩︎the default behavior is for an #include statement to be added for all header (.h) files in the src/ directory ( but not its subfolders ).
Arduino ドキュメント - スケッチの仕様
https://arduino.github.io/arduino-cli/0.35/sketch-specification/#additional-code-files ↩︎
arduino-cli 実装 - ヘッダーファイル拡張子の定義
https://github.com/arduino/arduino-cli/blob/a527c7cdea0694da3034ba9995b7c9eaecfe074b/internal/arduino/globals/globals.go#L63-L68 ↩︎