PIO does not compile all included library classes which leads to linker errors

Hi everyone,

I have a problem with compilation of source files in a subdirectory of an included extra_lib folder.

This is my project file structure:

project_dir
     |  /libs
     |     | /lib1
     |     | /lib2
     |     | /myCustomLib
     |        /foo
     |        /bar
     |  /myApplication <-- the actual pio project with src, lib and the other files

This is my platformio.ini:

[env:nanoatmega328]
platform = atmelavr
board = nanoatmega328
framework = arduino
lib_extra_dirs = ../libs

In the main class I include

 #include "foo/ClassToBeIncluded.h"

According to Eclipse this file is properly recognized as “Include”. The problem is: foo/ClassToBeIncluded.cpp gets not compiled. In the .pioenvs folder under /lib/MyCustomLib there are only compiled .o files of the main folder - the subdirectories /foo and /bar are not existing. Seems that the subfolders are ignored.

Did I miss to insert an option to tell PIO to include all lib directories recursively?

Best regards,
Thomas

Please provide simple project in archive to reproduce this issue

Here I uploaded an example project with the descibed folder structure.

https://ufile.io/b2916

Thanks for your support :slight_smile:

That is OK. You use #include <Arduino.h> within a library and keep it in old 1.0 format. See Arduino IDE 1.5: Library specification · arduino/Arduino Wiki · GitHub

According to Arduino v1.0 specification only the source files from ROOT of the library should be built.


Solution - convert Arduino library to 1.5 format. In other words, move all source files to src folder.

Ah, small cause but big effect :slight_smile:

After moving all my source files to a “src” subfolder of my common library it starts compiling the files there. But now I have another little issue: In the commons library there are source files which have to be excluded in some projects. So i tried to add a source filter:

src_filter = +<*> -<.git/> -<svn/> -<example/> -<examples/> -<test/> -<tests/> -<../../libs/myCustomLib/src/foo/SourceToBeExcluded.cpp>

But avr-gcc ignores the filter and tries to compile that particular cpp nevertheless. In the documentation it is written that the exclude PATH command must be relative to src_dir. So I think the pattern should be correct. Or is it impossible to exclude source files from libraries?

You are right. You can filter with src_filter only project source files but not outside libraries. If you need to filter some files from a library, see Redirecting...

So as far as I understand my common classes folder (used by many similar Arduino projects) is treated as a library by PIO and I can filter source files via library.json file - is that correct?

I just created this minimal json.library:

{
  "name": "PiduinoCommons",
  "version": "1.0.0",
  "build": {
    "srcFilter": [
      "+<*.c>",
      "+<*.cpp>",
      "+<*.h>",
      "-<src/Applications/DallasTemperatureSensor.cpp>"
    ]
  }
}

The result is that none of the lib classes are compiled anymore. Can you tell me what parameters are missing for a valid minimal library.json for source file filtering?

  1. Manifest shuld have a name library.json
  2. Try to filter without src, for example, `"-<Applications/DallasTemperatureSensor.cpp>"

I think finally I found a better solution for my usecase.

As I do not want to maintain a proper Arduino library for several platforms, I created a symbolic link within the project src folder which points to my CommonsProject/src folder. With this construction I now can use the project specific src_filter to control which source files should be compiled or excluded.

Do you think this is a viable solution for commonly used source files?

  1. You can split big library that has different code for the different platforms to a few components/libraries
  2. You can use #ifdef syntax and show/hide code using macro.