Only one header that includes many others

Hi guyz,

I would like to include many headers in only one to simply include the final one in my sketches.

Say I’ve many classes A, B, C,…that are related in some way (one can inherit from another or more and so on) and I would like to include all of them in my sketch without insert an #include statements for each one.

How can i do this?
Is it possible?

Just to try I’ve written only two classes, a.cpp and b.cpp with their respective headers (suppose I’ve many others classes).

a.h

#ifndef A_H
#define A_H

class A {

    protected:
        bool imA;

    public:
        A();
        int doA();
};

#endif /* A_H */

a.cpp

#include "a.h"

A::A() {
    imA = true;
}

int A::doA() {
    return 1;
}

b.h

#ifndef B_H
#define B_H

#include "a.h"

class B : public A {

    private:
        bool imB;

    public:
        B();
        int doB();
};

#endif /* B_H */

b.cpp

#include "b.h"

B::B() : A() {
    imA = false;
    imB = true;
}

int B::doB() {
    return 2;
}

Then, I’ve written the final header MyLib.h which includes the others

MyLib.h

#ifndef MYLIB_H
#define MYLIB_H

#include "src/a.h"
#include "src/b.h"

#endif /* MYLIB_H */

As you can see from the last header, I’ve placed both classes in the src subdirectory of my library under the standard directory of Arduino libraries.
So, my directories tree is:

Arduino
`-libraries
   `-MyLib
      |-src
      |  |-a.cpp
      |  |-a.h
      |  |-b.cpp
      |  `-b.h
      `-MyLib.h

Then I’ve written a trivial demo.cpp program to test if everything works.

demo.cpp

#include "MyLib.h"
#include <stdio.h>

int main() {

    A *b = new B();

    printf("%i\n", b->doA());
}

Once placed the previous program into the directory MyLib, It can be compiled (and then executed) without problems with this commad:

ervito@tecra:~/Arduino/libraries/MyLib$ g++ demo.cpp $(for header in $(ls src | grep "\.h$"); do printf "src/${header/%.h/.cpp} "; done;) -Wall -o demo

At the end I’ve tried to write a similar demo sketch for Arduino (test.ino)

test.ino

#include "MyLib.h"

void setup() {
  A *b = new B();

  b->doA();
}

void loop() {
  // put your main code here, to run repeatedly:

}

TO BE CONTINUED…

it's common for header file to include other header files needed for elements in that header file

see Arduino/hardware/arduino/avr/cores/arduino/Arduino.h

Naturally the previous sketch doesn't compile with Arduino IDE and the console outputs:

/home/ervito/Scrivania/arduino-1.8.12/arduino-builder -dump-prefs -logger=machine -hardware /home/ervito/Scrivania/arduino-1.8.12/hardware -hardware /home/ervito/.arduino15/packages -hardware /home/ervito/Arduino/hardware -tools /home/ervito/Scrivania/arduino-1.8.12/tools-builder -tools /home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -tools /home/ervito/.arduino15/packages -built-in-libraries /home/ervito/Scrivania/arduino-1.8.12/libraries -libraries /home/ervito/Arduino/libraries -fqbn=arduino:avr:uno -ide-version=10812 -build-path /tmp/arduino_build_57341 -warnings=all -build-cache /tmp/arduino_cache_257862 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -prefs=runtime.tools.arduinoOTA-1.3.0.path=/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -prefs=runtime.tools.avrdude.path=/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -prefs=runtime.tools.avr-gcc.path=/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -verbose /home/ervito/Arduino/test/test.ino
/home/ervito/Scrivania/arduino-1.8.12/arduino-builder -compile -logger=machine -hardware /home/ervito/Scrivania/arduino-1.8.12/hardware -hardware /home/ervito/.arduino15/packages -hardware /home/ervito/Arduino/hardware -tools /home/ervito/Scrivania/arduino-1.8.12/tools-builder -tools /home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -tools /home/ervito/.arduino15/packages -built-in-libraries /home/ervito/Scrivania/arduino-1.8.12/libraries -libraries /home/ervito/Arduino/libraries -fqbn=arduino:avr:uno -ide-version=10812 -build-path /tmp/arduino_build_57341 -warnings=all -build-cache /tmp/arduino_cache_257862 -prefs=build.warn_data_percentage=75 -prefs=runtime.tools.arduinoOTA.path=/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -prefs=runtime.tools.arduinoOTA-1.3.0.path=/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -prefs=runtime.tools.avrdude.path=/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -prefs=runtime.tools.avrdude-6.3.0-arduino17.path=/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -prefs=runtime.tools.avr-gcc.path=/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -prefs=runtime.tools.avr-gcc-7.3.0-atmel3.6.1-arduino5.path=/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr -verbose /home/ervito/Arduino/test/test.ino
Using board 'uno' from platform in folder: /home/ervito/Scrivania/arduino-1.8.12/hardware/arduino/avr
Using core 'arduino' from platform in folder: /home/ervito/Scrivania/arduino-1.8.12/hardware/arduino/avr
Detecting libraries used...
/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/ervito/Scrivania/arduino-1.8.12/hardware/arduino/avr/cores/arduino -I/home/ervito/Scrivania/arduino-1.8.12/hardware/arduino/avr/variants/standard /tmp/arduino_build_57341/sketch/test.ino.cpp -o /dev/null
Alternatives for MyLib.h: [MyLib]
ResolveLibrary(MyLib.h)
  -> candidates: [MyLib]
/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/ervito/Scrivania/arduino-1.8.12/hardware/arduino/avr/cores/arduino -I/home/ervito/Scrivania/arduino-1.8.12/hardware/arduino/avr/variants/standard -I/home/ervito/Arduino/libraries/MyLib /tmp/arduino_build_57341/sketch/test.ino.cpp -o /dev/null
Generating function prototypes...
/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -flto -w -x c++ -E -CC -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/ervito/Scrivania/arduino-1.8.12/hardware/arduino/avr/cores/arduino -I/home/ervito/Scrivania/arduino-1.8.12/hardware/arduino/avr/variants/standard -I/home/ervito/Arduino/libraries/MyLib /tmp/arduino_build_57341/sketch/test.ino.cpp -o /tmp/arduino_build_57341/preproc/ctags_target_for_gcc_minus_e.cpp
/home/ervito/Scrivania/arduino-1.8.12/tools-builder/ctags/5.8-arduino11/ctags -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives /tmp/arduino_build_57341/preproc/ctags_target_for_gcc_minus_e.cpp
Sto compilando lo sketch...
/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr/bin/avr-g++ -c -g -Os -Wall -Wextra -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10812 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -I/home/ervito/Scrivania/arduino-1.8.12/hardware/arduino/avr/cores/arduino -I/home/ervito/Scrivania/arduino-1.8.12/hardware/arduino/avr/variants/standard -I/home/ervito/Arduino/libraries/MyLib /tmp/arduino_build_57341/sketch/test.ino.cpp -o /tmp/arduino_build_57341/sketch/test.ino.cpp.o
Compiling libraries...
Compiling library "MyLib"
Compiling core...
Using precompiled core: /tmp/arduino_cache_257862/core/core_arduino_avr_uno_337b23f6c4efdc1acb3ba64e19baed72.a
Linking everything together...
/home/ervito/Scrivania/arduino-1.8.12/hardware/tools/avr/bin/avr-gcc -Wall -Wextra -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o /tmp/arduino_build_57341/test.ino.elf /tmp/arduino_build_57341/sketch/test.ino.cpp.o /tmp/arduino_build_57341/../arduino_cache_257862/core/core_arduino_avr_uno_337b23f6c4efdc1acb3ba64e19baed72.a -L/tmp/arduino_build_57341 -lm
/tmp/ccZnG9ai.ltrans0.ltrans.o: In function `setup':
/home/ervito/Arduino/test/test.ino:4: undefined reference to `B::B()'
/home/ervito/Arduino/test/test.ino:6: undefined reference to `A::doA()'
collect2: error: ld returned 1 exit status
Uso la libreria MyLib nella cartella: /home/ervito/Arduino/libraries/MyLib (legacy)
exit status 1
Errore durante la compilazione per la scheda Arduino Uno.

Is there anything wrong with my code?
Is there any way to compile it with Arduino IDE?
Thank you in advance for you attention and collaboration.

Best regards
Marco

You should either move all the source files up to Arduino/libraries/MyLib (the 1.0 Arduino library format), or else move MyLib.h into the Arduino/libraries/MyLib/src folder and add a library.properties file to Arduino/libraries/MyLib (the 1.5 Arduino library format).

The reason this is necessary is because recursive compilation of the src subfolder of the library is only done for libraries in the 1.5 format and your library is currently in the 1.0 format.

All the information on this subject:
https://arduino.github.io/arduino-cli/latest/library-specification/

Hi pert,

thanks for the answer.
I've written a library.properties and now my library compiles fine.
Thank you!

Best regards
Marco