mirror of
https://github.com/espressif/esp-idf.git
synced 2026-05-28 16:46:31 +03:00
Merge branch 'task/cmakev2_internal_fixes' into 'master'
fix(cmakev2): internal bug fixes — kconfgen warnings, dep parsing, managed-deps ordering, link templates See merge request espressif/esp-idf!48740
This commit is contained in:
@@ -532,6 +532,13 @@ function(idf_component_register)
|
||||
PRIV_REQUIRES REQUIRED_IDF_TARGETS EMBED_FILES EMBED_TXTFILES)
|
||||
cmake_parse_arguments(ARG "${options}" "${one_value}" "${multi_value}" ${ARGN})
|
||||
|
||||
# Some managed components pass their REQUIRES / PRIV_REQUIRES as a single
|
||||
# quoted space-separated string (e.g. PRIV_REQUIRES "log esp_eth").
|
||||
# cmake_parse_arguments stores that as one list element. Normalise the
|
||||
# lists so that each component name is a separate element.
|
||||
separate_arguments(ARG_REQUIRES)
|
||||
separate_arguments(ARG_PRIV_REQUIRES)
|
||||
|
||||
# Initialize and include commonly required components.
|
||||
__init_common_components()
|
||||
|
||||
@@ -592,7 +599,7 @@ function(idf_component_register)
|
||||
endforeach()
|
||||
|
||||
if(sources OR ARG_EMBED_FILES OR ARG_EMBED_TXTFILES)
|
||||
add_library("${COMPONENT_TARGET}" STATIC "${sources}")
|
||||
add_library("${COMPONENT_TARGET}" STATIC ${sources})
|
||||
|
||||
foreach(include_dir IN LISTS include_dirs)
|
||||
target_include_directories("${COMPONENT_TARGET}" PUBLIC "${include_dir}")
|
||||
@@ -660,6 +667,55 @@ function(idf_component_register)
|
||||
idf_component_set_property("${COMPONENT_NAME}" COMPONENT_TYPE "${component_type}")
|
||||
endfunction()
|
||||
|
||||
#[[
|
||||
.. cmakev2:function:: idf_component_add_link_dependency
|
||||
|
||||
Backward-compatible shim for ``idf_component_add_link_dependency()`` used
|
||||
by some managed components (e.g. espressif__esp_flash_nor).
|
||||
#]]
|
||||
function(idf_component_add_link_dependency)
|
||||
set(single_value FROM TO)
|
||||
cmake_parse_arguments(_ "" "${single_value}" "" ${ARGN})
|
||||
|
||||
idf_component_get_property(from_lib ${__FROM} COMPONENT_LIB)
|
||||
if(__TO)
|
||||
idf_component_get_property(to_lib ${__TO} COMPONENT_LIB)
|
||||
else()
|
||||
set(to_lib ${COMPONENT_LIB})
|
||||
endif()
|
||||
set_property(TARGET ${from_lib} APPEND PROPERTY INTERFACE_LINK_LIBRARIES $<LINK_ONLY:${to_lib}>)
|
||||
endfunction()
|
||||
|
||||
#[[
|
||||
.. cmakev2:macro:: register_component
|
||||
|
||||
Backward-compatible shim for the legacy ``register_component()`` macro used
|
||||
by some older ESP-IDF examples (ULP apps, BLE mesh demos, etc.). It converts
|
||||
the old-style ``COMPONENT_*`` variables to ``idf_component_register()`` calls.
|
||||
#]]
|
||||
macro(register_component)
|
||||
# Convert space-separated variables to CMake lists.
|
||||
foreach(_var COMPONENT_SRCS COMPONENT_SRCDIRS COMPONENT_ADD_INCLUDEDIRS
|
||||
COMPONENT_PRIV_INCLUDEDIRS COMPONENT_REQUIRES COMPONENT_PRIV_REQUIRES
|
||||
COMPONENT_ADD_LDFRAGMENTS COMPONENT_EMBED_FILES COMPONENT_EMBED_TXTFILES
|
||||
COMPONENT_SRCEXCLUDE)
|
||||
if(DEFINED ${_var})
|
||||
separate_arguments(${_var})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
idf_component_register(SRCS "${COMPONENT_SRCS}"
|
||||
SRC_DIRS "${COMPONENT_SRCDIRS}"
|
||||
INCLUDE_DIRS "${COMPONENT_ADD_INCLUDEDIRS}"
|
||||
PRIV_INCLUDE_DIRS "${COMPONENT_PRIV_INCLUDEDIRS}"
|
||||
REQUIRES "${COMPONENT_REQUIRES}"
|
||||
PRIV_REQUIRES "${COMPONENT_PRIV_REQUIRES}"
|
||||
LDFRAGMENTS "${COMPONENT_ADD_LDFRAGMENTS}"
|
||||
EMBED_FILES "${COMPONENT_EMBED_FILES}"
|
||||
EMBED_TXTFILES "${COMPONENT_EMBED_TXTFILES}"
|
||||
EXCLUDE_SRCS "${COMPONENT_SRCEXCLUDE}")
|
||||
endmacro()
|
||||
|
||||
#[[
|
||||
.. cmakev2:function:: idf_build_component
|
||||
|
||||
|
||||
@@ -94,7 +94,9 @@ function(__init_idf_path)
|
||||
endif()
|
||||
|
||||
idf_build_set_property(IDF_PATH "${idf_path}")
|
||||
# Components reference either ${IDF_PATH} or ${idf_path}; publish both.
|
||||
set(IDF_PATH ${idf_path} PARENT_SCOPE)
|
||||
set(idf_path ${idf_path} PARENT_SCOPE)
|
||||
set(ENV{IDF_PATH} ${idf_path})
|
||||
endfunction()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -835,6 +835,17 @@ endfunction()
|
||||
function(target_add_binary_data target embed_file embed_type)
|
||||
cmake_parse_arguments(_ "" "RENAME_TO" "DEPENDS" ${ARGN})
|
||||
idf_build_get_property(build_dir BUILD_DIR)
|
||||
|
||||
# In cmakev1, the executable target was named "${project}.elf".
|
||||
# In cmakev2, the executable is named "${project}" and ".elf" is just the
|
||||
# output suffix. Strip the ".elf" suffix if the target does not exist but
|
||||
# the bare name does. This keeps existing app CMakeLists.txt files working.
|
||||
if(NOT TARGET "${target}")
|
||||
string(REGEX REPLACE "\\.elf$" "" target_bare "${target}")
|
||||
if(TARGET "${target_bare}")
|
||||
set(target "${target_bare}")
|
||||
endif()
|
||||
endif()
|
||||
idf_build_get_property(idf_path IDF_PATH)
|
||||
|
||||
get_filename_component(embed_file "${embed_file}" ABSOLUTE)
|
||||
|
||||
Reference in New Issue
Block a user