Can't get PIO converted project to compile

I am in the process of trying to convert one of my Arduino/ESP32 project to a PlatformIO project, but can’t get it to compile for the life of me…
The project is made up of several private libraries (with their own c/h files in the lib// subfolder) and of several 3rd party/external libraries, the challenge (I believe) is that the private libraries have some dependencies on eachother as well as on some of the 3rd party libs. Changing some of the platformio.ini parameters (tried including the directories using build_flags=, different lib_ldf_mode= parameters, and changing the #include <libname.h> to #include "libname.h" and vice-versa) seems to cause different error at different locations.

The project is located here: GitHub - vyruz1986/FlyballETS-Software at feature/SyncStarting
Make sure you checkout the feature/SyncStarting branch

Currently it’s failing on this file/line:
In file included from lib\LightsController\LightsController.h:22:0,
from lib\LightsController\LightsController.cpp:19:
lib\RaceHandler/RaceHandler.h:3:27: fatal error: LCDController.h: No such file or directory

LCDController.h is created in the same way

Have you, as the first line of defense, tried to add all library folder names to the lib_deps list?

The 3rd party libraries are listed, yes. Do you mean to also list the private libraries? Wouldn’t that cause PIO to go look for them in the library registry and fail to find them?

Local lib/ folders should have priority. Have you tried it?

Aside from the PIO specific configuration issues, here are a few tips for future projects:

  • Your code has a high so called cyclomatic complexity, i.e. instead of being built from several mostly independent modules everything is interwoven and depends on each other. Think about how you would need to change the classes (or groups of classes) such that they are more independent. Then it will make more sense to turn part of the code into independent libraries. At the moment, the code is not ready for it and it would have been easier to put everything into src.

  • Header file should include as few other header files as possible. The reason is that a header file included by another header file will also be indirectly included by all code that includes the latter one. So it’s like mulitiplicator. Suddenly, every .cpp file indirectly includes most of the header files. It increases compile time because a change to a header file will require a recompilation of most files as they all indirectly depend on it. And it increases mutual dependencies. So try to move as many #include directives from the header to the .cpp file.

  • In order to minimize the dependencies, you can also use incomplete declarations where appropriate. It usually works if a header file only uses pointers to a class. An incomplete declarations looks like class LiquidCrystal; That’s sufficient to now use delcarations such as void init(LiquidCrystal *Clcd1, LiquidCrystal *Clcd2);. So #include "LiquidCrystal.h" is no longer needed in the header file. It will still be needed in the .cpp file.

And speific to your current project: The header file index.html.gz.h is special. It does not contain declarations but definitions. As such it may only appear once in the entire code base. Otherwise, the same data will be included more than once and the linker will fail because of duplicate definitions. So this file must only be included from a single .cpp file and not from any header file.

An even better approach would be to embedded the binary file directly. Have a look Espressif 32 — PlatformIO latest documentation to see how it’s done.

1 Like

Thanks, this is really helpful. I wondered if including the libraries in eachother was a good idea, it seems it wasn’t :slight_smile: I don’t really see how to split up the code so this is not required anymore. I mainly divided the code into classes for readability purposes. Take the RaceHandlerClass and LightsControllerClass for example, the functions in LightsControllerClass need to be driven by events which occur in the RaceHandlerClass, however I really don’t want to combine both classes into one, as that will result in large, hard to read source files…
I am wondering whether it would be better to put all my private classes into src, I just thought using lib was the ‘platformio’ way to do this. Would it be better to have all classes in src, given that I don’t want to (since I don’t know a better way atm) restructure them right now?

Thanks for the clarification on #include in cpp vs h files, I think I should be able to optimize quite a few things using that insight.

There can be good reasons why the code has strong mutual dependencies. In fact, that’s what you’d expect for a small number of central classes of an application.

So you are probably better off putting the code into the src folder. Libraries (and the lib folder) are for independent pieces of code that can be reused in other projects. I don’t think that’s what you have.

And I certainly don’t recommend to combine classes and files. You want to keep them in manageable pieces – the way you have them now.

1 Like