mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
fix(cmakev2/kconfig): preserve sdkconfig options from managed components
The sdkconfig file may contain configuration options defined in Kconfig
files of managed components. Since kconfgen runs before the component
manager fetches these components, the Kconfig definitions for managed
component options are not yet available. The kconfgen --output config
flag regenerates sdkconfig from kconfiglib's internal state, which only
knows about options with loaded Kconfig definitions. This causes unknown
options (i.e., those from managed components) to be silently dropped
from sdkconfig during intermediate regeneration rounds.
Note that kconfgen's --config flag (used for reading sdkconfig) only
performs deprecated option name replacement and does NOT drop unknown
options. The problem is exclusively in --output config, which writes a
fresh sdkconfig from the parsed Kconfig tree state.
Fix this by introducing a __SDKCONFIG_ORIG build property that provides
an indirection layer for the --config input path:
- Before the component manager runs: __SDKCONFIG_ORIG points to a copy
of the original sdkconfig (build/sdkconfig.orig), created by the new
__create_sdkconfig_orig_copy() function. This copy preserves all
original options, including those from managed components.
- During intermediate kconfgen runs: --config reads from the preserved
copy (so unknown options survive as input), while --output config
writes to the real sdkconfig (unknown options may be dropped there,
but this is harmless since kconfgen always reads from the copy).
- After the component manager completes: __SDKCONFIG_ORIG is reset to
point to the real sdkconfig and __BASE_KCONFGEN_CMD is rebuilt, so
that subsequent operations (menuconfig, save-defconfig, confserver)
read and write the actual sdkconfig file directly.
The flow is:
__create_sdkconfig_orig_copy()
-> __SDKCONFIG_ORIG = build/sdkconfig.orig
__generate_sdkconfig()
-> --config build/sdkconfig.orig --output config project/sdkconfig
__fetch_components_from_registry():
loop:
download_components()
__generate_sdkconfig()
-> --config build/sdkconfig.orig --output config project/sdkconfig
if success: break
endloop
-> __SDKCONFIG_ORIG = project/sdkconfig
-> rebuild __BASE_KCONFGEN_CMD
idf_create_menuconfig() / save-defconfig / confserver
-> uses --config project/sdkconfig (the real file)
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
# SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from test_build_system_helpers import IdfPyFunc
|
||||
from test_build_system_helpers import file_contains
|
||||
|
||||
|
||||
def test_sdkconfig_preserves_managed_component_options(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
|
||||
logging.info('sdkconfig options from managed components should be preserved during reconfigure')
|
||||
|
||||
# Create a local managed component outside the project directory.
|
||||
# Since it is referenced via path in idf_component.yml, the component
|
||||
# manager processes it as a managed component whose Kconfig is only
|
||||
# available after the CM run -- i.e. after the initial kconfgen round.
|
||||
managed_comp_dir = test_app_copy / '..' / 'managed_comp'
|
||||
managed_comp_dir.mkdir(parents=True)
|
||||
(managed_comp_dir / 'CMakeLists.txt').write_text('idf_component_register()\n')
|
||||
(managed_comp_dir / 'Kconfig').write_text(
|
||||
'config MANAGED_COMP_TEST_OPTION\n int "Managed component test option"\n default 10\n'
|
||||
)
|
||||
|
||||
# Reference the local component as a managed dependency
|
||||
(test_app_copy / 'main' / 'idf_component.yml').write_text(
|
||||
'dependencies:\n managed_comp:\n path: "../../managed_comp"\n'
|
||||
)
|
||||
|
||||
# Write a non-default value directly into sdkconfig (not sdkconfig.defaults).
|
||||
# Before the fix, kconfgen would drop this unknown option via --output config
|
||||
# during the first generation round (before the component manager makes the
|
||||
# managed component's Kconfig available), causing the value to revert to the
|
||||
# default (10) in the final sdkconfig.
|
||||
(test_app_copy / 'sdkconfig').write_text('CONFIG_MANAGED_COMP_TEST_OPTION=30\n')
|
||||
|
||||
idf_py('reconfigure')
|
||||
|
||||
assert file_contains(test_app_copy / 'sdkconfig', 'CONFIG_MANAGED_COMP_TEST_OPTION=30')
|
||||
Reference in New Issue
Block a user