Allow header files in subdirectories of the library to be included
This content is intended for library developers.
Arduino libraries cannot directly include header files in subdirectories 1.
#include <MyLibrary/Algorithm/Math.hpp> // ERROR!
Also, files with extensions other than header files (.h .hpp .hh) are not allowed 2 3.
#include <iostream> // ERROR!
However, many C++ libraries out there use these methods. So, here is a trick(?) to allow Arduino libraries to be included in the same way. The following is a trick to make it possible to include Arduino libraries in the same way.
Configure library directories
Create an appropriate header file in the library include directory (src
).
The contents of the file can be an empty file. The file name is also arbitrary and does not have to be the same as the subdirectory name or library folder name.
~/Documents/Arduino/libraries
│
└─ MyLibrary
├─ src
│ ├─ MyLibrary
│ │ └─ Algorithm
│ │ └─ Math.hpp
│ └─ MyLibrary.hpp ## < this one
└─ library.properties
library.properties as follows. Each item should be filled in accordingly. See libraryproperties-file-format.
name=MyLibrary
version=1.0.0
author=HogeHoge
maintainer=HogeHoge
sentence=HogeHoge
paragraph=HogeHoge
category=Other
url=http://example.com/
architectures=*
Include the file you just created first
This will allow you to inkle header files in subdirectories.
// ~~.ino
#include <MyLibrary.hpp>
#include <MyLibrary/Algorithm/Math.hpp>
Completion
In this way, if you first include the “header directly under the include directory” from the sketch, you will be able to include headers from sub-directories.
Try to include files other than header files
Including MyLibrary.hpp
will allow you to include files other than header files. A practical example would be a C++ STL file without extension.
~/Documents/Arduino/libraries
│
└─ MyLibrary
├─ src
│ ├─ iostream ## < this one
│ └─ MyLibrary.hpp
└─ library.properties
#include <MyLibrary.hpp>
#include <iostream>
Finally・why can’t we include directly?
I am just guessing, but I think it is to save compile time. It would take a lot of time to search all the subdirectories of all the libraries.
So, initially, only headers directly under the include directory are searched, and when a header file directly under the include directory is included, it is marked as This library is in use and the subdirectories are searched as well.
Thank you for reading to the end.
Documentation - Library Specifications
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 ).
Documentation - Sketch Specifications
https://arduino.github.io/arduino-cli/0.35/sketch-specification/#additional-code-files ↩︎
arduino-cli Implementation - Header File Extension Definition
https://github.com/arduino/arduino-cli/blob/a527c7cdea0694da3034ba9995b7c9eaecfe074b/internal/arduino/globals/globals.go#L63-L68 ↩︎