Skip to content

Commit

Permalink
Merge branch 'docs/edit_kconfig_docs' into 'master'
Browse files Browse the repository at this point in the history
docs(kconfiglib): Make a detailed docs section about Kconfig

See merge request espressif/esp-idf!32995
  • Loading branch information
Jan Beran committed Nov 11, 2024
2 parents 7bc8b99 + dbc6be3 commit 0650832
Show file tree
Hide file tree
Showing 24 changed files with 445 additions and 198 deletions.
Binary file added docs/_static/menuconfig-screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 15 additions & 9 deletions docs/en/api-guides/build-system.rst
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ This example "myProject" contains the following elements:

- A top-level project CMakeLists.txt file. This is the primary file which CMake uses to learn how to build the project; and may set project-wide CMake variables. It includes the file :idf_file:`/tools/cmake/project.cmake` which implements the rest of the build system. Finally, it sets the project name and defines the project.

- "sdkconfig" project configuration file. This file is created/updated when ``idf.py menuconfig`` runs, and holds the configuration for all of the components in the project (including ESP-IDF itself). The ``sdkconfig`` file may or may not be added to the source control system of the project.
- "sdkconfig" project configuration file. This file is created/updated when ``idf.py menuconfig`` runs, and holds the configuration for all of the components in the project (including ESP-IDF itself). The ``sdkconfig`` file may or may not be added to the source control system of the project. More information about this file can be found in the :ref:`sdkconfig file <sdkconfig-file>` section in the Configuration Guide.

- "dependencies.lock" file contains the list of all managed components, and their versions, that are currently in used in the project. The ``dependencies.lock`` file is generated or updated automatically when IDF Component Manager is used to add or update project components. So this file should never be edited manually! If the project does not have ``idf_component.yml`` files in any of its components, ``dependencies.lock`` will not be created.

Expand Down Expand Up @@ -364,7 +364,7 @@ The following component-specific variables are available for use inside componen

The following variables are set at the project level, but available for use in component CMakeLists:

- ``CONFIG_*``: Each value in the project configuration has a corresponding variable available in cmake. All names begin with ``CONFIG_``. :doc:`More information here </api-reference/kconfig>`.
- ``CONFIG_*``: Each value in the project configuration has a corresponding variable available in cmake. All names begin with ``CONFIG_``. More information on how the project configuration works, please visit :ref:`Project Configuration Guide <project-configuration-guide>`.
- ``ESP_PLATFORM``: Set to 1 when the CMake file is processed within the ESP-IDF build system.


Expand Down Expand Up @@ -430,7 +430,7 @@ These settings are found under the "Component Settings" menu when menuconfig is

To create a component Kconfig file, it is easiest to start with one of the Kconfig files distributed with ESP-IDF.

For an example, see `Adding conditional configuration`_.
For an example, see `Adding conditional configuration`_. For a more detailed guide, see :ref:`Component Configuration Guide <component-configuration-guide>`.


Preprocessor Definitions
Expand Down Expand Up @@ -463,7 +463,7 @@ When Writing a Component

- ``PRIV_REQUIRES`` should be set to all components whose header files are #included from *any source files* in this component, unless already listed in ``REQUIRES``. Also, any component which is required to be linked in order for this component to function correctly.

- The values of ``REQUIRES`` and ``PRIV_REQUIRES`` should not depend on any configuration choices (``CONFIG_xxx`` macros). This is because requirements are expanded before the configuration is loaded. Other component variables (like include paths or source files) can depend on configuration choices.
- The values of ``REQUIRES`` and ``PRIV_REQUIRES`` should not depend on any configuration options (``CONFIG_xxx`` macros). This is because requirements are expanded before the configuration is loaded. Other component variables (like include paths or source files) can depend on configuration options.

- Not setting either or both ``REQUIRES`` variables is fine. If the component has no requirements except for the `Common component requirements`_ needed for RTOS, libc, etc.

Expand Down Expand Up @@ -726,13 +726,14 @@ Note that ``project_include.cmake`` isn't necessary for the most common componen
Take great care when setting variables or targets in a ``project_include.cmake`` file. As the values are included in the top-level project CMake pass, they can influence or break functionality across all components!


KConfig.projbuild
Kconfig.projbuild
-----------------

This is an equivalent to ``project_include.cmake`` for :ref:`component-configuration` KConfig files. If you want to include configuration options at the top level of menuconfig, rather than inside the "Component Configuration" sub-menu, then these can be defined in the KConfig.projbuild file alongside the ``CMakeLists.txt`` file.
This is an equivalent to ``project_include.cmake`` for :ref:`component-configuration` Kconfig files. If you want to include configuration options at the top level of menuconfig, rather than inside the "Component Configuration" sub-menu, then these can be defined in the Kconfig.projbuild file alongside the ``CMakeLists.txt`` file.

Take care when adding configuration values in this file, as they will be included across the entire project configuration. Where possible, it's generally better to create a KConfig file for :ref:`component-configuration`.
Take care when adding configuration values in this file, as they will be included across the entire project configuration. Where possible, it's generally better to create a Kconfig file for :ref:`component-configuration`.

For more information, see :ref:`Kconfig Files <kconfig-files>` section in the Configuration Guide.

Wrappers to Redefine or Extend Existing Functions
-------------------------------------------------
Expand Down Expand Up @@ -798,7 +799,7 @@ See :example:`custom_bootloader/bootloader_extra_dir` for an example of adding e
Configuration-Only Components
=============================

Special components which contain no source files, only ``Kconfig.projbuild`` and ``KConfig``, can have a one-line ``CMakeLists.txt`` file which calls the function ``idf_component_register()`` with no arguments specified. This function will include the component in the project build, but no library will be built *and* no header files will be added to any included paths.
Special components which contain no source files, only ``Kconfig.projbuild`` and ``Kconfig``, can have a one-line ``CMakeLists.txt`` file which calls the function ``idf_component_register()`` with no arguments specified. This function will include the component in the project build, but no library will be built *and* no header files will be added to any included paths.


Debugging CMake
Expand Down Expand Up @@ -1076,6 +1077,10 @@ The best of these approaches for building an external project will depend on the
Custom Sdkconfig Defaults
=========================

.. note::

For more detailed information about ``sdkconfig.defaults`` file, please visit :ref:`sdkconfig.defaults file <sdkconfig-defaults-file>` in Project Configuration section.

For example projects or other projects where you don't want to specify a full sdkconfig configuration, but you do want to override some key values from the ESP-IDF defaults, it is possible to create a file ``sdkconfig.defaults`` in the project directory. This file will be used when creating a new config from scratch, or when any new config value hasn't yet been set in the ``sdkconfig`` file.

To override the name of this file or to specify multiple files, set the ``SDKCONFIG_DEFAULTS`` environment variable or set ``SDKCONFIG_DEFAULTS`` in top-level ``CMakeLists.txt``. File names that are not specified as full paths are resolved relative to current project's directory.
Expand All @@ -1094,6 +1099,7 @@ If ``SDKCONFIG_DEFAULTS`` is used to override the name of defaults file/files, t

For example, if ``SDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig_devkit1"``, and there is a file ``sdkconfig.defaults.esp32`` in the same folder, then the files will be applied in the following order: (1) sdkconfig.defaults (2) sdkconfig.defaults.esp32 (3) sdkconfig_devkit1.

You can find more detailed information on how the project configuration works in the :ref:`Project Configuration Guide <project-configuration-guide>`. In the :ref:`Configuration Files Structure and Relationships <configuration-structure>`, you can find lower-level information about the configuration files.

.. _flash_parameters:

Expand Down Expand Up @@ -1681,7 +1687,7 @@ Application Examples

- :example:`build_system/wrappers` demonstrates how to use a linker feature to redefine or override any public function in both ESP-IDF and the bootloader, allowing modification or extension of a function's default behavior.

- :example:`custom_bootloader/bootloader_override` demonstrates how to override the second stage bootloader from a regular project, providing a custom bootloader that prints an extra message on startup, with the ability to conditionally override the bootloader based on certain conditions like target-dependency or KConfig options.
- :example:`custom_bootloader/bootloader_override` demonstrates how to override the second stage bootloader from a regular project, providing a custom bootloader that prints an extra message on startup, with the ability to conditionally override the bootloader based on certain conditions like target-dependency or Kconfig options.

- :example:`build_system/cmake/import_lib` demonstrates how to import and use third-party libraries using ExternalProject CMake module.

Expand Down
1 change: 1 addition & 0 deletions docs/en/api-guides/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ API Guides
hardware-abstraction
:CONFIG_IDF_TARGET_ARCH_XTENSA: hlinterrupts
jtag-debugging/index
kconfig/index
linker-script-generation
low-power-mode/index
lwip
Expand Down
99 changes: 99 additions & 0 deletions docs/en/api-guides/kconfig/component-configuration-guide.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
.. _component-configuration-guide:

Component Configuration Guide
=============================

This guide is intended to describe how to define configuration options for components in ESP-IDF. Following topics will be covered:

- How to define new configuration options for components.
- Basic syntax of Kconfig language.
- How to ensure backward compatibility.

How Configuration Works in ESP-IDF
----------------------------------

.. note::

More detailed information about the configuration system in ESP-IDF can be found in the :ref:`configuration-overview`.


ESP-IDF uses unified way to configure the project, build system, ESP-IDF framework itself and external components. This configuration tool is called `Kconfig <https://docs.espressif.com/projects/esp-idf-kconfig/en/latest/kconfiglib/index.html>`_.

Configuration options are **defined** in ``Kconfig`` files. ESP-IDF contains the top-level ``Kconfig`` file in the root of the framework. Each component can have its own ``Kconfig`` file defining configuration options specific to that component, as well as relations between the options. Relations between config options can spread across multiple Kconfig files from different sources. In other words, configuration option from ``Component_A`` can depend on a configuration option from ``Component_B``, even if ``Component_B`` is e.g. maintained by another developer.

When the configuration is saved (for more information about configuration editing, see e.g. :ref:`project-configuration-guide`), the **values** in the ``sdkconfig`` file are updated, as well as those in ``sdkconfig.h``, ``sdkconfig.cmake`` and ``sdkconfig.json``.

How to Define New Configuration Options for Your Component
----------------------------------------------------------
.. note::

If you plan to write ``Kconfig`` configuration files for your component, but you are not familiar with ``Kconfig language`` it is recommended to refer to the `esp-idf-kconfig Documentation <https://docs.espressif.com/projects/esp-idf-kconfig/en/latest/index.html>`_, where an in-depth guide is provided.

To define new configuration options for components, you need to:

1. Create the ``Kconfig`` and/or ``Kconfig.projbuild`` in the root folder of the component.
2. Define the configuration options in the ``Kconfig`` and/or ``Kconfig.projbuild`` file. It is generally a good practice to wrap them in the ``menu-endmenu`` block. You can see a minimal example below. Complete documentation of the Kconfig language can be found in the `Kconfig Documentation <https://docs.espressif.com/projects/esp-idf-kconfig/en/latest/kconfiglib/language.html>`_.

When your component is used in a project, the ``Kconfig`` and/or ``Kconfig.projbuild`` will be automatically discovered and shown in the ``menuconfig`` tool.

.. note::

**Difference between Kconfig and Kconfig.projbuild files**:

- ``Kconfig``: configuration options in this file will be shown under ``Component configuration`` in the ``menuconfig`` tool.
- ``Kconfig.projbuild``: configuration options in this file will be shown in the top menu of the ``menuconfig`` tool.

Example:

.. code-block:: kconfig
menu "Motors configuration"
config SUBLIGHT_DRIVE_ENABLED
bool "Enable sublight drive"
default n
depends on SPACE_SHIP
help
This option enables sublight on our spaceship.
endmenu
.. note::

**Visibility and dependencies**:

In the example above, the ``SUBLIGHT_DRIVE_ENABLED`` configuration option has a dependency on the ``SPACE_SHIP`` configuration option. This option can origin from a different component. If the ``SPACE_SHIP`` option is not set or is not defined in the current configuration (e.g. the component containing this option was not included in the project), the dependency will not be satisfied and the ``SUBLIGHT_DRIVE_ENABLED`` option will not be shown in the ``menuconfig`` tool.

For more information about the visibility and dependencies, please refer to the `Kconfig Documentation <https://docs.espressif.com/projects/esp-idf-kconfig/en/latest/kconfiglib/language.html>`_.


.. _configuration-options-compatibility:

How to Ensure Backward Compatibility
------------------------------------

In general, renaming a Kconfig option of a component is a breaking API change, just like renaming a function is. ESP-IDF contains a mechanism which makes it possible to maintain backward compatibility when renaming configuration options. This mechanism is based on ``sdkconfig.rename`` files which include pairs of configuration option names. File structure is described below.

When renaming configuration options of a component, create the ``sdkconfig.rename`` file in the root folder of the component. Every line in this file should contain one of the following pairs:

* ``CONFIG_OLD_NAME CONFIG_NEW_NAME`` if the new option is a direct replacement of the old option.
* ``CONFIG_OLD_NAME !CONFIG_NEW_NAME`` if the new option is a Boolean inversion of the old option.

The project configuration tool (invoked by ``idf.py menuconfig``) will automatically find it and generate the compatibility statements in ``sdkconfig`` for the user.

For more information about the ``sdkconfig.rename`` file, please refer to the :ref:`sdkconfig.rename <sdkconfig-rename-file>` section of Configuration Structure.

Detailed explanation of the backward compatibility mechanism:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. note::

This part of the guide is intended to explain the behavior of the backward compatibility mechanism in ESP-IDF in greater detail. It is not necessary to understand this mechanism as it it done automatically, but it is described here for the sake of completeness.

If the user has set any value for the old config option (e.g. old config name is used in ``sdkconfig`` or ``sdkconfig.defaults``) without ``sdkconfig.rename`` file provided, this value would be **silently ignored**. This behavior is the default of the Kconfig system and is not a bug. In the original project (configuration of the linux kernel) this behavior was desired and is still desired in many projects.

This behavior is suppressed in ESP-IDF by the the configuration tool (invoked by ``idf.py menuconfig``). This tool generates compatibility statements for all the renamed options in the ``sdkconfig`` file. In more detail, the following approach is used to prevent the above mentioned situation:

1. Configuration tool searches the whole ESP-IDF folder for ``sdkconfig.rename`` files. If the project target (``<chip>``) matches the last suffix of any ``sdkconfig.rename.<chip>`` file, the file will be used in the next step as well.

2. After collecting all the relevant files, the ``sdkconfig`` file (and ``sdkconfig.h/json/cmake`` files if any) is post-processed. A block of compatibility statements for all the renamed options is added during the post-process to the end of the file(s). The block starts with ``# Deprecated options for backward compatibility`` and ends with ``# End of deprecated options``.
Loading

0 comments on commit 0650832

Please sign in to comment.