PlatformIO Community

LDF Chain Mode Clarification


I’m having a lot of trouble making sense of the chain rules here.

It says

It also parses C, CC, CPP files from libraries which have the same name as included header file.

I am interpreting this as “it parses the sources files whose names prior to the extension match the name of the header prior to its extension,” i.e. foo.cpp for foo.h, regardless of library name. An alternate interpretation is that it parses all source files of library foo if a file foo.h is included, but based on the example, it seems to be the former.

Speaking of the example, it has furthered some of my confusion. In my testing, the name of the source file seemed not to be considered when the header was included. So I specced out the example:

[ben:testing]$ tree
├── lib
│   └── Foo
│       ├── extra.cpp
│       ├── foo.cpp
│       └── foo.h
├── platformio.ini
└── src
    └── main.cpp

3 directories, 5 files

All files are empty except for main.cpp and platformio:

[ben:testing]$ cat src/main.cpp
#include <Arduino.h>

#include "foo.h"

void setup() {}
void loop() {}
[ben:testing]$ cat platformio.ini
platform = atmelavr
board = uno
framework = arduino
lib_ldf_mode = chain

All three files are successfully found and compiled:

avr-g++ -o .pio/build/uno/src/main.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega328p -Os -Wall -ffunction-sections -fdata-sections -flt
o -DPLATFORMIO=60104 -DARDUINO_AVR_UNO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -Isrc -Ilib/Foo -I/home/ben/.platformio/packages/framework-arduino-avr/cores/arduino
-I/home/ben/.platformio/packages/framework-arduino-avr/variants/standard src/main.cpp
avr-g++ -o .pio/build/uno/libeb0/Foo/extra.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega328p -Os -Wall -ffunction-sections -fdata-secti
ons -flto -DPLATFORMIO=60104 -DARDUINO_AVR_UNO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -Ilib/Foo -I/home/ben/.platformio/packages/framework-arduino-avr/cores/arduin
o -I/home/ben/.platformio/packages/framework-arduino-avr/variants/standard lib/Foo/extra.cpp
avr-g++ -o .pio/build/uno/libeb0/Foo/foo.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega328p -Os -Wall -ffunction-sections -fdata-section
s -flto -DPLATFORMIO=60104 -DARDUINO_AVR_UNO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -Ilib/Foo -I/home/ben/.platformio/packages/framework-arduino-avr/cores/arduino
-I/home/ben/.platformio/packages/framework-arduino-avr/variants/standard lib/Foo/foo.cpp

Can someone help me find where my understanding is wrong?

If you #include "foo.h", and PlatformIO finds that this comes from the library as defined in lib/Foo, the entire library folder lib/Foo will be compiled – it doesn’t do some scanning to filter out potentially unused code files.

You can have more fine-grained control over compiled sources by e.g. adding a library.json file with srcFilter.

The “chain” is for detecting dependencies from one library to another – say if in lib/Foo, you had a dependency on lib/Bar. If you want to evaluate C/C++ macros / #ifdefs, then you need chain+. The LDF chain mode isn’t there for detecting dependencies on code files within one library, only between different libraries. (In fact, as said before, none of the ldf_modes do this as this is generally not done in PlatformIO)

Thank you, this description is much more in tune with my understanding of how it works. However, this understanding doesn’t seem to match the documentation. Is it my understanding of the documentation that’s wrong or is the documentation wrong? What does this line mean, what is it doing with the name of the header file?

It also parses C, CC, CPP files from libraries which have the same name as included header file.

If #include <foo.h> is encoutered in src/main.cpp which it identifies in lib/Foo, then all C/CPP files in lib/Foo will be further scanned for includes (say, lib/Foo/foo.cpp, lib/Foo/extra.cpp), as one of its source files could possibly depend on another library which needs to be resolved.