Library Dependency Finder (LDF)¶
Library Dependency Finder is a core part of PlatformIO Build System that
operates with the C/C++ source files and looks for #include ...
directives to know what header directories to include for the compiler.
In spite of the fact that Library Dependency Finder is written in pure Python,
it evaluates C/C++ Preprocessor conditional syntax (#ifdef
, if
, defined
,
else
, and elif
) without calling gcc -E
. This approach allows
to significantly reduce the total compilation time. See Dependency Finder Mode for more
details.
Contents
Configuration¶
Library Dependency Finder can be configured from “platformio.ini” (Project Configuration File):
Storage¶
There are different storages where Library Dependency Finder looks for libraries. These storages (folders) have priority and LDF operates in the next order:
- lib_extra_dirs - extra storages per build environment
- lib_dir - own/private library storage per project
- libdeps_dir - project dependency storage used by Library Management
- “core_dir/lib” - global storage per all projects.
- Library storages built into frameworks, SDKs.
Dependency Finder Mode¶
Library Dependency Finder starts work from analyzing source files of the project (src_dir) and can work in the next modes:
off : | “Manual mode”, does not process source files of a project and dependencies.
Builds only the libraries that are specified in manifests
(library.json, module.json ) or using lib_deps
option. |
---|---|
chain : | [DEFAULT] Parses ALL C/C++ source files of the project and follows
only by nested includes (#include ... , chain…) from the libraries.
It also parses C, CC, CPP files from libraries which have the same name as
included header file. Does not evaluate C/C++ Preprocessor conditional syntax. |
deep : | Parses ALL C/C++ source files of the project and parses ALL C/C++ source files of the each found dependency (recursively). Does not evaluate C/C++ Preprocessor conditional syntax. |
chain+ : | The same behavior as for the chain but evaluates C/C++ Preprocessor conditional syntax. |
deep+ : | The same behavior as for the deep but evaluates C/C++ Preprocessor conditional syntax. |
The mode can be changed using lib_ldf_mode option in
“platformio.ini” (Project Configuration File). Default value is set to chain
.
Note
Usually, when the LDF appears to fail to identify a dependency of a library, it is because the dependency is only referenced from a library source file, and not a library header file (see example below). In this case, it is necessary to either explicitly reference the dependency from the project source or “platformio.ini” (Project Configuration File) (lib_deps option), or change the LDF mode to “deep” (not generally recommended).
A difference between chain/chain+
and deep/deep+
modes. For example,
there are 2 libraries:
- Library
Foo
with files:Foo/foo.h
Foo/foo.cpp
Foo/extra.cpp
- Library
Bar
with files:Bar/bar.h
Bar/bar.cpp
Case 1: |
Here the nested includes ( |
---|---|
Case 2: |
In this case, LDF will not find the |
Case 3: |
Firstly, LDF finds the |
Compatibility Mode¶
Compatibility mode allows one to control strictness of Library Dependency Finder.
If library contains one of manifest file (library.json,
library.properties
, module.json
), then LDF check compatibility of this
library with real build environment. Available compatibility modes:
off : | Does not check for compatibility (is not recommended) |
---|---|
soft : | [DEFAULT] Checks for the compatibility with framework from build environment |
strict : | Checks for the compatibility with framework and platform from build environment. |
This mode can be changed using lib_compat_mode option in
“platformio.ini” (Project Configuration File). Default value is set to soft
.
C/C++ Preprocessor conditional syntax¶
In spite of the fact that Library Dependency Finder is written in pure Python,
it evaluates C/C++ Preprocessor conditional syntax
(#ifdef
, if
, defined
, else
, and elif
) without calling
gcc -E
. For example,
platformio.ini
[env:myenv]
lib_ldf_mode = chain+
build_flags = -D MY_PROJECT_VERSION=13
mylib.h
#ifdef MY_PROJECT_VERSION
// include common file for the project
#include "my_common.h"
#endif
#if MY_PROJECT_VERSION < 10
// this include will be ignored because does not satisfy condition above
#include "my_old.h"
#endif