PlatformIO Community

Using .h and .cpp files from different folder

Hi!
(There already are some topics on similar questions, I read through them and attempted their advice, but I cannot make it work, so please bear with me :smiley: )

I made some algorithms/classes in .h/.cpp files that live in their own folders. These folders also have ‘main’ files in them, so that I can run the algorithms to test them/work on them. This all is NOT on platformIO, but simply using C++ in VSC.

Now I want to use these .h and .cpp files in a platformIO project, so that I can upload them to a MCU. The way I thought this would work is by using the platformio.ini file:

[env:ATmega4809]
platform = atmelmegaavr
board = ATmega4809
framework = arduino
lib_deps =
olikraus/U8g2@^2.33.15
lib_extra_dirs = C:/XXXXXX/XXXXXX/software/algorithms/Cplusplus/gravity_angle
lib_ldf_mode=chain+

In the gravity_angle file are the headerFile.h and Cplusplus.cpp files in question.

Now I thought, from reading the other forum questions, the c_cpp_properties.json file would now show this directory in its include path, and I would be able to use #include "headerFile.h" to link to this headerFile.
But it does not show up in c_cpp_properties.json, and the “#include errors detected.” error shows up :frowning:

What am I doing wrong here? And is this the correct way of doing what I want anyway? Or am I making it more complicated than needed?

Any help is greatly appreciated!
Chris

Wrong – As the docs say, lib_extra_dirs must point at folder containing the library folders. So, you would have to give

lib_extra_dirs = C:/XXXXXX/XXXXXX/software/algorithms/Cplusplus 

there.

Additionally, you must place an #include <some header file of a library of this folder> in your source file (src/main.cpp for example) and rebuild the intellisense (Ctrl+Shift+P → Rebuild Intellisense) for it to be picked up.

Hi Max, thanks for the reply.

The compiler is now indeed finding the files, and the folders show up in c_cpp_properties.json. However, I now get a new error:

C:\XXXXXX\XXXXXX\software\algorithms\Cplusplus\gravity_angle\someFunction_main.cpp:12:10: fatal error: iostream: No such file or directory
#include <iostream>
^~~~~~~~~~

#include <iostream> is indeed called in someFunction_main.cpp in lib_extra_dirs = C:/XXXXXX/XXXXXX/software/algorithms/Cplusplus/gravity_angle. This is the file that I use to test the algorithms in someFunction.h and someFunction.cpp.

However, it is not called in someFunction.h/someFunction.cpp, so I don’t understand why the compiler is having problems with it; I don’t need someFunction_main.cpp here at all.

Do you know if there is any way to make the compiler not try to compile this file, since it is not needed?

I don’t think that avr-g++ will give you iostream – STL implemenetation of the AVRs is very bad. So bad that you need filler libraries like GitHub - mike-matera/ArduinoSTL: An STL and iostream implementation based on uClibc++ that supports my CS-11M class..

Yes, I realize that I cannot use iostream with AVR, and I don’t want to. For some reason the compiler wants to compile someFunction_main.cpp, while I only need someFunction.

I don’t know how to stop it from doing that, since I am not calling someFunction_main.cpp at all. (But it is in the same folder as someFunction.h and someFunction.cpp.)

The LDF doesn’t have some crazy compile-what-you-use algorithm, if you have a gravity_angle library with some header files, and your main code includes one of those files, then the entire gravity_angle library (all .c/.cpp files with in it) will be compiled. You can prevent this if you give the library a library.json with a srcFitler (library.json — PlatformIO latest documentation).

Hi Max, I finally had time to look at this problem again. I tried making a library and could not figure out how to do it.

I made a ‘minimal example’, in order to show you where I am stuck:

The first directory is an attempt at making a library with a HelloWorld.cpp/.h, in it a simple class: HelloWorld. In this directory is also a main.cpp.
Uploading main.cpp to an Arduino works as expected: “Hello World!” is printed 5 times.

However, when I want to now use this library and class in using_library_test_project, I get some errors:

src\main.cpp: In function 'void setup()':
src\main.cpp:6:14: error: expected ';' before 'helloworld'
   HelloWorld helloworld;
              ^~~~~~~~~~
src\main.cpp:8:3: error: 'helloworld' was not declared in this scope
   helloworld.Statement(5);
   ^~~~~~~~~~
src\main.cpp:8:3: note: suggested alternative: 'HelloWorld'
   helloworld.Statement(5);
   ^~~~~~~~~~
   HelloWorld

Any help would be greatly appreciated :slight_smile:

edit: (maybe) an interesting detail: visual studio code is recognizing the path to #include "HelloWorld.h", but it does not seem to understand how to use the class.

I’m seeing multiple mistakes here.

When I compile your firmware I get

Linking .pio\build\nano_every\firmware.elf
C:\Users\MAXGER~1\AppData\Local\Temp\ccvlm0ib.ltrans0.ltrans.o: In function `main':
<artificial>:(.text.startup+0x160): undefined reference to `HelloWorld::Statement(int)'
collect2.exe: error: ld returned 1 exit status

because the library.json is misconfigured.

    "build": {
        "srcFilter": "src/main.*"
    }

As the documentation says, a source filter has to be a space-separated list of files to either exclude or include, which is determined based on the + or - in front of the <> enclosed path. So the syntax is wrong. Furhter, you have to do a +<*> to get a baseline of “by-default, build all files (except the ones excluded later)”. And lastly, the files are relative to the source directory of the library, which is src/ in your library, so you musn’t write src/ in the path.

So,

    "build": {
        "srcFilter": "+<*> -<main.*>"
    }

should be used instead.

Second of all, in the platformio.ini of the using project you use

lib_deps = C:\Users\chvan\Documents\PlatformIO\Projects\library_test_project

which will by default make a copy of whatever is that path when it’s compiled – it’s not auto-updating when the library changes. For that, you’d use a symlink:// as documented. So, I just corrected it to

lib_deps = symlink://../library_test_project

Doing these modifications, the main project does…

Dependency Graph
|-- HelloWorld
Building in release mode
Compiling .pio\build\nano_every\libfae\library_test_project\HelloWorld.cpp.o
Archiving .pio\build\nano_every\libfae\library_test_project.a
Linking .pio\build\nano_every\firmware.elf
Checking size .pio\build\nano_every\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   2.9% (used 177 bytes from 6144 bytes)
Flash: [=         ]   5.5% (used 2686 bytes from 48640 bytes)
Building .pio\build\nano_every\firmware.hex
============================================= [SUCCESS] Took 1.22 seconds =============================================

compile with 0 problems.