PlatformIO Community

Problems with library, #include and #ifdef

Hello guys,
I have a problem with the use of a custom library.
On the one hand I have a project that only contains classes and a “definitions.h” file that contains the following:

typedef enum {INO = 10, ESP32WROOM} platform_t;
#define PLATFORM INO

(among other things I need)

All classes include this file “definitions.h”.

On the other hand I have a project for an Arduino nano, in which I include the classes of the previous project, through lib_extra_dirs in platformio.ini.
And I have another project for an ESP32 with esp-idf that, like the previous one, I include the classes, but in the main one I indicated the following:

#ifdef PLATFORM
    #undef PLATFORM
    #define PLATFORM ESP32WROOM
#else
    #define PLATFORM ESP32WROOM
#endif

All classes contain this at the beginning:

#if PLATFORM == INO
  #include <Arduino.h>
#else
  extern "C" {
      #include <stdint.h>
      #include <stdio.h>
  }
#endif

The arduino project works perfectly, but in the project for ESP32 it tells me the following:

fatal error: Arduino.h: No such file or directory

It seems that it does not take into account the platform field indicated in the main file using #define PLATFORM ESP32WROOM
What is this about?

Thanks for everything.

There are two levels involved here:

  1. Preprocessor
  2. C/C++

The preprocessor is run first and takes care of all the directives starting with #. It will replace macros defined with #define, evaluated the #ifs and #ifdefs and basically remove the text in the if or else blocks evaluating to false. The preprocessor has no understanding of C/C++. It could be used for any programming language.

The resulting text text will then be processed by the C/C++ compiler.

Your code mixes the two levels. Therefore it doesn’t work. In particular:

typedef enum {INO = 10, ESP32WROOM} platform_t;
#define PLATFORM INO

The preprocessor is run first. It doesn’t know about C and therefore doesn’t understand typedefs and enum. So the first line has no effect for the preprocessor. And the second line just tells the preprocessor the replace all occurrences of PLATFORM with INO (text substituation).

Later the preprocessor encounters:

#if PLATFORM == INO

It understand that PLATFORM is a macro that has been defined earlier. But INO is just some text. Now, the next issue is that in the preprocessor comparision (==) only works for integer numbers. I’m not sure if it is defined which part of the if clause is now applied. But the bottom line is, it will always be the same no matter what the value PLATFORM is.

You can go with a much simpler solution. Whenever you build an Arduino project, a macro ARDUINO is defined. You can check for that:

#ifdef ARDUINO
#include <Arduino.h>
#else
extern “C” {
#include <stdint.h>
#include <stdio.h>
}
#endif
2 Likes

Thanks you manuelbl,

using #ifdef ARDUINO is not suitable for me because I must use these classes in Attinys and use the I2C bus, therefore I must differentiate between the 3 or more, in the future.

I solves my problem as follows:

#define INO 10
#define ESP32WROOM 11
#define ATTINY 12

#if PLATFORM==INO
  #include <Arduino.h>
#else
  extern "C" {
      #include <stdint.h>
      #include <stdio.h>
  }
#endif

Or if need Attiny:

#if PLATFORM==INO
  #include <Arduino.h>
#elif PLATFORM==ATTINY
 (includes or others for attiny)
#else
  extern "C" {
      #include <stdint.h>
      #include <stdio.h>
  }
#endif

Thanks you!!!

1 Like