PlatformIO forgetting about #include paths?

I am trying to solve a problem involving compiling identical code to either use EthernetClient or WiFiClient on arduino-esp32.
I wrote two sets of source files for EthernetClient and WiFiClient, that will #define CLIENTTYPE to either EthernetClient or WiFiClient and then include the core file proper that has CLIENTTYPE for the client data type. The files are looking like this (Ethernet variant shown here):

#ifndef _MODBUS_SERVER_ETHERNET_H
#define _MODBUS_SERVER_ETHERNET_H
#include <Ethernet.h>

#define CLIENTTYPE EthernetClient
#include "ModbusServerTCP.h"

#endif

The inner source is protected by #ifdef CLIENTTYPE/#endif against compilation without the wrapper files including them.

The problem now arises if I will compile a program using this - say, we are to use the EthernetClient variant, then main.cpp will do a #include "ModbusServerEthernet.h" and most likely a #include <Ethernet.h>`` as well. The compile then will fail with

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

for the file ModbusServerWiFi.h, where the line #include <Wifi.h> is to be found. But why does that happen?

If I add the #include <Wifi.h> to the main.cpp file, compile will run fine.

If I use the full path to the Wifi.h file, it works as well (#include <C:\Users\Micha\.platformio\packages\framework-arduinoespressif32\libraries\WiFi\src\WiFi.h>) .

It looks like PlatformIO is forgetting about the include paths in this constellation.

Looks like the library dependency finder couldn’t find the WiFi dependency when placed inside this library code. Have you tried more aggressive lib_ldf_mode values like chain+, deep+?

1 Like

chain+ did not change the behaviour, whereas deep+ did. Thanks for the hint, but how should I know when to use either one?

Some pointers are here:
https://docs.platformio.org/en/latest/librarymanager/ldf.html#ldf-mode

Someone may get it better than me, but as far as I understand it, it only makes a difference when you are using a library that is defined outside the project:

  • chain means chaining #includes starting from your project files and from included files only.
  • deep means following all #includes in any of your project files and in any of the libraries files your project depends upon, even if your project doesn’t include some of the files from that library.

For example, if a library you are using has 10 files but you only include one of those, the #includes of the 9 other files will be found only in deep mode.

So, basically, if the libraries you are using are well defined, chain should be sufficient, but otherwise, you may need deep.

The final + means parsing pre-processor directives (most notably #ifdef and #ifndef).

1 Like

I might be misunderstanding the question, however, just in case I’m not …

The definition of CLIENTTYPE is only visible in the header file, plus main.cpp, plus any sources that #include this header.

I suspect the error is coming from another source file which hasn’t yet defined CLIENTTYPE?

As I said (typed) I might be misunderstanding here, if so, my apologies. Please ignore me.

Cheers,
Norm.

No, I am afraid I was not clear enough - CLIENTTYPE really is visible at exact those places you mentioned and is supposed just so.
The problem is solved with @maxgerhardt’s hint.

1 Like