fix(cmakev2/kconfig): suppress transient kconfgen warnings during component manager runs

kconfgen runs while the component manager iterates to convergence.
Those passes operate on partial component sets and emit "unknown
kconfig symbol" warnings for symbols defined in not-yet-downloaded
components — idf-build-apps treats those as build failures.

Suppress kconfgen output on the intermediate passes; only the final
pass against the converged set emits warnings.
This commit is contained in:
Sudeep Mohanty
2026-05-25 12:27:44 +02:00
parent a25c1f5476
commit 9e20c3ba57
3 changed files with 59 additions and 7 deletions

View File

@@ -752,14 +752,45 @@ function(__run_kconfgen)
set(kconfgen_cmd ${base_kconfgen_cmd} ${kconfgen_outputs_cmd})
idf_dbg("Running kconfgen: ${kconfgen_cmd}")
execute_process(
COMMAND ${kconfgen_cmd}
--env-file "${config_env_path}"
RESULT_VARIABLE kconfgen_result
)
if(kconfgen_result)
idf_die("Failed to run kconfgen: ${kconfgen_result}")
# kconfgen runs once during the bootstrap pass (before the component
# manager fetches managed components) and again on every iteration of
# the component-manager loop in __fetch_components_from_registry. Every
# pass except the converged one operates on an incomplete component
# set and can emit spurious "unknown kconfig symbol" warnings for
# symbols defined in not-yet-downloaded components, which
# idf-build-apps would otherwise treat as build failures. The quiet
# path captures stdout/stderr instead of streaming them; the
# converged pass flips __KCONFGEN_QUIET to NO and reaches the else
# branch, where warnings are emitted normally.
idf_build_get_property(quiet __KCONFGEN_QUIET)
if(quiet)
# Capture stdout/stderr into variables instead of discarding them.
# On success the captured output is dropped (so transient warnings
# never reach the build log). On non-zero exit we re-emit both
# streams so genuine errors (Kconfig parse errors, FatalError, etc.)
# remain debuggable.
execute_process(
COMMAND ${kconfgen_cmd}
--env-file "${config_env_path}"
RESULT_VARIABLE kconfgen_result
OUTPUT_VARIABLE kconfgen_stdout
ERROR_VARIABLE kconfgen_stderr
)
if(kconfgen_result)
message("${kconfgen_stdout}")
message("${kconfgen_stderr}")
idf_die("Failed to run kconfgen: ${kconfgen_result}")
endif()
else()
execute_process(
COMMAND ${kconfgen_cmd}
--env-file "${config_env_path}"
RESULT_VARIABLE kconfgen_result
)
if(kconfgen_result)
idf_die("Failed to run kconfgen: ${kconfgen_result}")
endif()
endif()
endfunction()

View File

@@ -51,6 +51,14 @@ endfunction()
3. If the component manager run failed, error out.
#]]
function(__fetch_components_from_registry)
# __KCONFGEN_QUIET stays YES (set by the bootstrap path in project.cmake)
# across intermediate iterations of the loop below, because each
# iteration's kconfgen pass runs against a partial component set when the
# component manager exits 10. Warnings from those passes are transient.
# We only flip the flag to NO on the iteration where the component
# manager succeeds, so the final kconfgen pass against the complete
# component set emits genuine warnings.
# Iteratively run the component manager and Kconfig until stable or error out.
set(__cmgr_round 0)
while(TRUE)
@@ -60,6 +68,11 @@ function(__fetch_components_from_registry)
# Run the component manager for all discovered components
__download_component_level_managed_components(RESULT cmgr_result)
# Only the final (successful) iteration should emit kconfgen warnings.
if(cmgr_result EQUAL 0)
idf_build_set_property(__KCONFGEN_QUIET NO)
endif()
# Re-collect Kconfig and regenerate sdkconfig with managed components included
__generate_sdkconfig()

View File

@@ -592,6 +592,14 @@ macro(idf_project_init)
# Only creates a backup when the component manager is enabled.
__create_sdkconfig_orig_copy()
# When the component manager is enabled, suppress kconfgen warnings
# on this initial pass. Managed component symbols are unknown at this
# stage and will be resolved after __fetch_components_from_registry().
idf_build_get_property(idf_component_manager IDF_COMPONENT_MANAGER)
if(idf_component_manager EQUAL 1)
idf_build_set_property(__KCONFGEN_QUIET YES)
endif()
# Generate initial sdkconfig with discovered components
__generate_sdkconfig()