Version Solver
This document describes how the version solver works in the IDF Component Manager. The version solver is responsible for determining the best component versions that satisfy the constraints defined in your project.
Version Solving
An ESP-IDF project declares its component dependencies through one or more manifest files (e.g., idf_component.yml
), where each dependency specifies a version or version range.
Version solving is the process of analyzing all component dependencies and determining the most suitable component version for each one. This process involves the following steps:
Collect all local manifest files from your main component and subcomponents.
Collect all root dependencies defined in those manifest files.
Recursively collect all available versions for each root dependency.
Calculate the final set of resolved component versions.
The IDF Component Manager uses the PubGrub algorithm to perform version solving. Once completed, the solver generates a Dependencies.lock File file that records the exact versions of the components selected by the version solver.
When Will the Version Solver Run?
The version solver is triggered by the ESP-IDF build system (e.g., via idf.py reconfigure
) under the following conditions:
When there is no
dependencies.lock
file in the project root.When the manifest_hash in the existing Dependencies.lock File file does not match the current manifest hash.
This can happen when components are added or removed, or when a manifest is modified.
When the target in the Dependencies.lock File does not match the current manifest target.
A common case is when the user runs
idf.py set-target
to change the target.When the user runs the project with a different ESP-IDF version.
When the user runs
idf.py update-dependencies
.
Note: The dependencies.lock
file will only be updated if the version solver produces a different result than the current contents.
Update Dependencies
By default, the version solver prefers to reuse component versions that already satisfy the constraints. This speeds up solving and reduces network usage.
If the solver fails to find a valid solution using the current versions, it will retry without using any presets to determine a suitable set of versions.
To manually update all dependencies, run:
$ idf.py update-dependencies
Environment Variables for the Version Solver
Some environment variables can be used to control the behavior of the version solver.
IDF_COMPONENT_CHECK_NEW_VERSION
By default, the IDF Component Manager checks for new versions of dependencies during the ESP-IDF project build process, even if the version solver is not triggered.
If newer versions are found, they will be displayed in the console, but the dependencies.lock
file will remain unchanged.
To disable this automatic version check, set the following environment variable IDF_COMPONENT_CHECK_NEW_VERSION
to 0
.
For instructions on explicitly updating dependencies, refer to the Update Dependencies section.
IDF_COMPONENT_CONSTRAINT_FILES
You can use constraint files to limit the versions of components that the version solver considers during dependency resolution.
When constraint files are specified, the version solver will check the version range not only from the dependencies
section in the manifest files, but also from the constraint files.
To use constraint files, set the IDF_COMPONENT_CONSTRAINT_FILES
environment variable to one or more constraint file paths separated by semicolons:
# Single constraint file
$ export IDF_COMPONENT_CONSTRAINT_FILES="/path/to/constraints.txt"
# Multiple constraint files (semicolon-separated)
$ export IDF_COMPONENT_CONSTRAINT_FILES="/path/to/base_constraints.txt;/path/to/project_constraints.txt"
Constraint File Format
Constraint files use a simple text format where each line specifies a component name and version constraint:
# This is a comment
espressif/esp_timer>=1.0.0
wifi_provisioning~=2.1.0
my_namespace/custom_component>=0.5.0,<1.0.0
# Components without namespace default to espressif namespace
led_strip==1.2.0
Version constraints follow the same format as dependency specifications in manifest files. For detailed information about supported version constraint formats, see Range Specifications.
Multiple Constraint Files
When multiple constraint files are specified, they are processed in order and later files override constraints from earlier files for the same component.
# Example: base constraints + project overrides
$ export IDF_COMPONENT_CONSTRAINT_FILES="org_constraints.txt;project_constraints.txt"
If org_constraints.txt
contains example/cmp>=1.0.0
and project_constraints.txt
contains example/cmp==1.2.3
, the final constraint will be example/cmp==1.2.3
.
IDF_COMPONENT_CONSTRAINTS
Moreover, you can specify component constraints directly in the environment variable IDF_COMPONENT_CONSTRAINTS
. This allows you to define version constraints without needing to create a separate constraint file.
Note
The IDF_COMPONENT_CONSTRAINTS
environment variable has higher priority than the IDF_COMPONENT_CONSTRAINT_FILES
variable. If both are set, the constraints in IDF_COMPONENT_CONSTRAINTS
will override those specified in the constraint files if the same component is listed in both.
Note
The IDF_COMPONENT_CONSTRAINTS
environment variable does NOT support comments.
# Single constraint
$ export IDF_COMPONENT_CONSTRAINTS="espressif/esp_timer>=1.0.0"
# Multiple constraints (separated by newlines or semicolons)
$ export IDF_COMPONENT_CONSTRAINTS="espressif/esp_timer>=1.0.0;wifi_provisioning~=2.1.0"
# Using newlines (in shell)
$ export IDF_COMPONENT_CONSTRAINTS="espressif/esp_timer>=1.0.0
wifi_provisioning~=2.1.0
my_namespace/custom_component>=0.5.0,<1.0.0"
The constraint format is the same as in constraint files. Components without a namespace default to the espressif
namespace.