Include nightmare

I have multiple projects that share some include files. I didn’t think this would be a problem, but here I am. I tried platformio.ini:

build_flags = -I../shared
lib_ldf_mode = chain+

Then I have #include "server.h". The file is included, but it contains #include <WiFi.h> which fails. Why does the nested include fail? :frowning:

I tried lib_extra_dirs = ../shared and #include <server.h>. The file is included and it includes WiFi.h, however somewhere deep in the WiFi stuff it includes a Server.h which finds MY server.h and then of course compilation fails. Why would there be such a naming conflict? It does not seem reasonable that everything must use unique header file names.

How can I set up my projects to simply share a few include files in a sane way?

I found the second method works if I rename my server.h to something else. I also had a print.h which had a name conflict. I hate that I need to rename my things. :angry: I don’t understand why there must be so much magic for what should be simple includes.

My #include <lan.h> line is marked as an error in the IDE, though it compiles and runs fine.

Are you using the Arduino framework? If so, Print.h is part of its Print class. However, that has an uppercase ‘P’ unlike yours, but I suspect you are on Windows, so letter case is ignored. Likewise with your server.h and Server.h.

lib_extra_dirs is for libraries. There needs to be a separate folder for each library, and this must contain the headers and sources for the library. All the shared libraries would be in separate folders beneath your defined lib_extra_dirs. I have not tried, but maybe you might get away with creating dummy folders and putting your shared headers in a “library” each? Or maybe a single “library” with all your headers?

The best solution is the build_flags that you mention above. With the caveat that, as you have found, your naming convention might interfere with other headers elsewhere in the framework/libraries used – especially on Windows where letter case is ignored.



1 Like

Yep, using the Arduino framework and Windows, so a (ridiculous) case insensitive filesystem. Regardless, needing to have unique header file names seems insane to me.

Using each of my headers like a library (in a subfolder with lib_extra_dirs) is working, but I had to rename my headers and I greatly dislike that.

Using build_flags = -I../shared did not work. As mentioned, the file was included, but when the included file tries to include another file, such as #include <WiFi.h>, that fails. Why would that be?

Including a file should be equivalent to pasting the contents of that file. This is not the case because #include <WiFi.h> works in my ino file, but not the included file. There’s some sort of terrible magic happening.

If I use build_flags = -I.. then I can avoid header file name conflicts by using #include "shared/server.h". I still have the problem with includes in server.h not working, so I have to copy those includes to my ino file. If that could be solved, I’d feel better!

Oook, great success! There is a “dependency scanner” that looks in my ino file but apparently not the included shared/server.h. The fix is to specify the dependencies in platformio.ini:

lib_deps =

Now my includes work in server.h and I’m happy.

I’d argue that a dependency scanner is unnecessary. Dependencies are important and not something that needs to happen automatically. Probably that was done to help noobs, but that actually adds to the complexity and makes it harder to understand what is going on.

Sort of!

That is telling the system that you want to use those libraries. Similar to adding a library when using the Arduino IDE.

Any missing libraries will be downloaded and any dependencies resolved. Those headers for the libraries would then be able to be included

Glad you got sorted.


I ended up using:

lib_ldf_mode = off
lib_compat_mode = off
lib_extra_dirs = ../shared
lib_deps = <list>

I really don’t want magic. If I need deps, I don’t mind downloading them and putting them in a folder, or at least I should have to specify them explicitly. A magic scanner that guesses at the deps I want is just not a great idea.

I’m happy with how it’s working now! Thanks for your input. :smiley: Getting the CLI build to work was a pleasure, it just worked. See, I’m not all complaints. :wink:

1 Like