mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
Merge branch 'task/buildv2_shim_and_ci_v6.1' into 'release/v6.1'
feat(cmakev2): IDF_BUILD_V2 shim + v1-compat layer + buildv2 CI (v6.1) See merge request espressif/esp-idf!49725
This commit is contained in:
@@ -1,6 +1,101 @@
|
||||
# Designed to be included from an IDF app's CMakeLists.txt file
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
# When the IDF_BUILD_V2 environment variable is set, transparently delegate
|
||||
# to Build system v2 (cmakev2). This allows existing Build system v1 projects
|
||||
# to be built with Build system v2 without modifying their CMakeLists.txt.
|
||||
# The project() macro is wrapped to automatically call idf_project_default()
|
||||
# after the real CMake project() call, bridging the API difference between
|
||||
# Build system v1 and Build system v2.
|
||||
#
|
||||
# Build system v1 pattern (no changes needed):
|
||||
# include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
# idf_build_set_property(...) # optional, works with Build system v2 infra
|
||||
# project(my_app)
|
||||
#
|
||||
# With IDF_BUILD_V2=y set in the environment, this becomes equivalent to:
|
||||
# include($ENV{IDF_PATH}/tools/cmakev2/idf.cmake)
|
||||
# idf_build_set_property(...)
|
||||
# project(my_app C CXX ASM)
|
||||
# idf_project_default()
|
||||
if($ENV{IDF_BUILD_V2})
|
||||
message(STATUS "IDF Build System V2 (cmakev2) activated via IDF_BUILD_V2 shim")
|
||||
|
||||
# Include the Build system v2 (cmakev2) entry point. This sets up all
|
||||
# Build system v2 infrastructure (build properties, target, toolchain,
|
||||
# kconfig, etc.). idf.cmake's file-level __init_idf_path() call publishes
|
||||
# ${idf_path} to this scope, so no further set() is needed here.
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../cmakev2/idf.cmake)
|
||||
|
||||
# Mark that we are running through the Build system v1 compatibility shim
|
||||
# so that Build system v2 internals can enable backward-compatible build
|
||||
# properties.
|
||||
idf_build_set_property(__V1_COMPAT_SHIM 1)
|
||||
|
||||
# Use the standard CMake trick to save the real project() command.
|
||||
# After these two overrides, __project() calls the original CMake
|
||||
# project(). See https://cmake.org/pipermail/cmake/2015-October/061751.html
|
||||
function(project)
|
||||
endfunction()
|
||||
|
||||
function(_project)
|
||||
endfunction()
|
||||
|
||||
macro(project project_name)
|
||||
# Call the real CMake project() with the languages required by cmakev2.
|
||||
__project(${project_name} C CXX ASM)
|
||||
|
||||
# Restore project() for sub-projects and third-party libraries that
|
||||
# may call project() themselves (e.g. components/mbedtls calls
|
||||
# add_subdirectory(mbedtls) which runs `project("Mbed TLS")`).
|
||||
#
|
||||
# The override is a function() (own variable scope), so PROJECT_*
|
||||
# variables set by __project() must be explicitly propagated to
|
||||
# PARENT_SCOPE — otherwise the caller (and any subsequent
|
||||
# add_subdirectory() within that caller) sees the IDF top-level
|
||||
# project's source/binary dirs instead of the third-party project's.
|
||||
# See tools/cmake/project.cmake's mature override at the Build
|
||||
# system v1 path for the full set of mirrored variables.
|
||||
function(project)
|
||||
set(project_ARGV ARGV)
|
||||
__project(${${project_ARGV}})
|
||||
|
||||
set(PROJECT_NAME "${PROJECT_NAME}" PARENT_SCOPE)
|
||||
set(PROJECT_BINARY_DIR "${PROJECT_BINARY_DIR}" PARENT_SCOPE)
|
||||
set(PROJECT_SOURCE_DIR "${PROJECT_SOURCE_DIR}" PARENT_SCOPE)
|
||||
set(PROJECT_VERSION "${PROJECT_VERSION}" PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}" PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_MINOR "${PROJECT_VERSION_MINOR}" PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_PATCH "${PROJECT_VERSION_PATCH}" PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_TWEAK "${PROJECT_VERSION_TWEAK}" PARENT_SCOPE)
|
||||
set(PROJECT_DESCRIPTION "${PROJECT_DESCRIPTION}" PARENT_SCOPE)
|
||||
set(PROJECT_HOMEPAGE_URL "${PROJECT_HOMEPAGE_URL}" PARENT_SCOPE)
|
||||
|
||||
set(${PROJECT_NAME}_BINARY_DIR "${${PROJECT_NAME}_BINARY_DIR}" PARENT_SCOPE)
|
||||
set(${PROJECT_NAME}_SOURCE_DIR "${${PROJECT_NAME}_SOURCE_DIR}" PARENT_SCOPE)
|
||||
set(${PROJECT_NAME}_VERSION "${${PROJECT_NAME}_VERSION}" PARENT_SCOPE)
|
||||
set(${PROJECT_NAME}_VERSION_MAJOR "${${PROJECT_NAME}_VERSION_MAJOR}" PARENT_SCOPE)
|
||||
set(${PROJECT_NAME}_VERSION_MINOR "${${PROJECT_NAME}_VERSION_MINOR}" PARENT_SCOPE)
|
||||
set(${PROJECT_NAME}_VERSION_PATCH "${${PROJECT_NAME}_VERSION_PATCH}" PARENT_SCOPE)
|
||||
set(${PROJECT_NAME}_VERSION_TWEAK "${${PROJECT_NAME}_VERSION_TWEAK}" PARENT_SCOPE)
|
||||
set(${PROJECT_NAME}_DESCRIPTION "${${PROJECT_NAME}_DESCRIPTION}" PARENT_SCOPE)
|
||||
set(${PROJECT_NAME}_HOMEPAGE_URL "${${PROJECT_NAME}_HOMEPAGE_URL}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# If the app set COMPONENTS before project(), forward it to Build
|
||||
# system v2 via a build property so __project_default() can use the
|
||||
# correct component list instead of the hardcoded "main".
|
||||
if(DEFINED COMPONENTS)
|
||||
idf_build_set_property(__SHIM_COMPONENTS "${COMPONENTS}")
|
||||
endif()
|
||||
|
||||
# Initialize and build the project using Build system v2.
|
||||
idf_project_default()
|
||||
endmacro()
|
||||
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Get the currently selected sdkconfig file early, so this doesn't
|
||||
# have to be done multiple times on different places.
|
||||
if(SDKCONFIG)
|
||||
|
||||
@@ -83,7 +83,12 @@ function(idf_build_get_property variable property)
|
||||
cmake_parse_arguments(ARG "${options}" "${one_value}" "${multi_value}" ${ARGN})
|
||||
|
||||
if("${property}" STREQUAL BUILD_COMPONENTS)
|
||||
idf_die("Build property 'BUILD_COMPONENTS' is not supported")
|
||||
# BUILD_COMPONENTS is populated by the Build system v1 compatibility
|
||||
# shim; reject only when running as a native Build system v2 project.
|
||||
idf_build_get_property(_v1_compat __V1_COMPAT_SHIM)
|
||||
if(NOT _v1_compat)
|
||||
idf_die("Build property 'BUILD_COMPONENTS' is not supported")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(genexpr)
|
||||
@@ -356,11 +361,25 @@ function(idf_build_library library)
|
||||
|
||||
# Include the requested components and link their interface targets to the
|
||||
# library.
|
||||
#
|
||||
# On the GNU linker, bracket the component interface list with
|
||||
# --start-group/--end-group so the linker re-scans archives until all
|
||||
# symbols resolve. Required when the archive defining a __wrap_*
|
||||
# implementation is encountered after the archive consuming the wrapped
|
||||
# symbol on the link line; without group iteration the wrap symbol is
|
||||
# unresolved.
|
||||
idf_build_get_property(linker_type LINKER_TYPE)
|
||||
if("${linker_type}" STREQUAL "GNU")
|
||||
target_link_libraries("${library}" INTERFACE "-Wl,--start-group")
|
||||
endif()
|
||||
foreach(component_name IN LISTS ARG_COMPONENTS)
|
||||
idf_component_include("${component_name}")
|
||||
idf_component_get_property(component_interface "${component_name}" COMPONENT_INTERFACE)
|
||||
target_link_libraries("${library}" INTERFACE "${component_interface}")
|
||||
endforeach()
|
||||
if("${linker_type}" STREQUAL "GNU")
|
||||
target_link_libraries("${library}" INTERFACE "-Wl,--end-group")
|
||||
endif()
|
||||
|
||||
# Process optional requirements in DEFERRED mode only (no-op in IMMEDIATE or when unset).
|
||||
idf_build_get_property(opt_req_mode IDF_COMPONENT_OPTIONAL_REQUIRES_MODE)
|
||||
|
||||
+180
-2
@@ -425,6 +425,14 @@ function(__init_common_components)
|
||||
# component.
|
||||
if(explicit_requires_common)
|
||||
set(requires_common "${explicit_requires_common}")
|
||||
# Auto-append the target's arch component when the app overrides
|
||||
# common-requires without it. Lets G0-style apps (which set the property
|
||||
# before project() to a restricted list) avoid hand-rolling a
|
||||
# target -> arch map pre-project, since IDF_TARGET_ARCH isn't known
|
||||
# until after sdkconfig is included. Empty on linux -> no append.
|
||||
if(idf_target_arch AND NOT idf_target_arch IN_LIST requires_common)
|
||||
list(APPEND requires_common "${idf_target_arch}")
|
||||
endif()
|
||||
|
||||
elseif("${idf_target}" STREQUAL "linux")
|
||||
set(requires_common freertos esp_hw_support heap log soc hal esp_rom esp_common esp_system linux
|
||||
@@ -452,6 +460,89 @@ function(__init_common_components)
|
||||
idf_build_set_property(__COMMON_COMPONENTS_INITIALIZED YES)
|
||||
endfunction()
|
||||
|
||||
#[[api
|
||||
.. cmakev2:function:: idf_component_mock
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
idf_component_mock([INCLUDE_DIRS <dir>...]
|
||||
[MOCK_HEADER_FILES <file>...]
|
||||
[REQUIRES <component>...]
|
||||
[MOCK_SUBDIR <subdir>])
|
||||
|
||||
*INCLUDE_DIRS[in,opt]*
|
||||
|
||||
Include directories for the header files provided in MOCK_HEADER_FILES.
|
||||
|
||||
*MOCK_HEADER_FILES[in,opt]*
|
||||
|
||||
Header files from which CMock generates mock implementations.
|
||||
|
||||
*REQUIRES[in,opt]*
|
||||
|
||||
Additional components required by the mock component.
|
||||
|
||||
*MOCK_SUBDIR[in,opt]*
|
||||
|
||||
Subdirectory under the mocks output where generated files are placed.
|
||||
|
||||
Create a mock component using CMock and register it with the build system.
|
||||
This is a compatibility shim matching the v1 ``idf_component_mock``
|
||||
function in ``tools/cmake/component.cmake``. It generates Mock*.c and
|
||||
Mock*.h files from the given headers using Ruby + CMock, then delegates to
|
||||
``idf_component_register`` so the mock participates in normal dependency
|
||||
resolution.
|
||||
#]]
|
||||
function(idf_component_mock)
|
||||
set(options)
|
||||
set(single_value MOCK_SUBDIR)
|
||||
set(multi_value MOCK_HEADER_FILES INCLUDE_DIRS REQUIRES)
|
||||
cmake_parse_arguments(_ "${options}" "${single_value}" "${multi_value}" ${ARGN})
|
||||
|
||||
list(APPEND __REQUIRES "cmock")
|
||||
|
||||
set(MOCK_GENERATED_HEADERS "")
|
||||
set(MOCK_GENERATED_SRCS "")
|
||||
set(IDF_PATH $ENV{IDF_PATH})
|
||||
set(CMOCK_DIR "${IDF_PATH}/components/cmock/CMock")
|
||||
set(MOCK_GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
list(APPEND __INCLUDE_DIRS "${MOCK_GEN_DIR}/mocks")
|
||||
|
||||
foreach(header_file ${__MOCK_HEADER_FILES})
|
||||
get_filename_component(file_without_dir ${header_file} NAME_WE)
|
||||
if("${__MOCK_SUBDIR}" STREQUAL "")
|
||||
list(APPEND MOCK_GENERATED_HEADERS "${MOCK_GEN_DIR}/mocks/Mock${file_without_dir}.h")
|
||||
list(APPEND MOCK_GENERATED_SRCS "${MOCK_GEN_DIR}/mocks/Mock${file_without_dir}.c")
|
||||
else()
|
||||
list(APPEND MOCK_GENERATED_HEADERS "${MOCK_GEN_DIR}/mocks/${__MOCK_SUBDIR}/Mock${file_without_dir}.h")
|
||||
list(APPEND MOCK_GENERATED_SRCS "${MOCK_GEN_DIR}/mocks/${__MOCK_SUBDIR}/Mock${file_without_dir}.c")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
file(MAKE_DIRECTORY "${MOCK_GEN_DIR}/mocks")
|
||||
|
||||
idf_component_register(SRCS "${MOCK_GENERATED_SRCS}"
|
||||
INCLUDE_DIRS ${__INCLUDE_DIRS}
|
||||
REQUIRES ${__REQUIRES})
|
||||
|
||||
set(COMPONENT_LIB ${COMPONENT_LIB} PARENT_SCOPE)
|
||||
add_custom_command(
|
||||
OUTPUT ruby_found SYMBOLIC
|
||||
COMMAND "ruby" "-v"
|
||||
COMMENT "Try to find ruby. If this fails, you need to install ruby"
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${MOCK_GENERATED_SRCS} ${MOCK_GENERATED_HEADERS}
|
||||
DEPENDS ruby_found
|
||||
COMMAND ${CMAKE_COMMAND} -E env "UNITY_DIR=${IDF_PATH}/components/unity/unity"
|
||||
ruby
|
||||
${CMOCK_DIR}/lib/cmock.rb
|
||||
-o${CMAKE_CURRENT_SOURCE_DIR}/mock/mock_config.yaml
|
||||
${__MOCK_HEADER_FILES}
|
||||
)
|
||||
endfunction()
|
||||
|
||||
#[[api
|
||||
.. cmakev2:function:: idf_component_register
|
||||
|
||||
@@ -642,6 +733,47 @@ function(idf_component_register)
|
||||
target_link_libraries("${COMPONENT_TARGET}" PRIVATE "${req_interface}")
|
||||
endforeach()
|
||||
|
||||
# Special treatment for 'main' component is only applied when the project
|
||||
# was entered through the Build system v1 compatibility shim. Native
|
||||
# Build system v2 projects with no REQUIRES on main should remain the
|
||||
# author-declared dependency set rooted at main; forcing every discovered
|
||||
# component into main's link graph in that case contradicts the Build
|
||||
# system v2 contract that the dependency graph is what the author writes.
|
||||
idf_build_get_property(v1_compat_shim __V1_COMPAT_SHIM)
|
||||
if(v1_compat_shim AND COMPONENT_NAME STREQUAL "main"
|
||||
AND NOT ARG_REQUIRES AND NOT ARG_PRIV_REQUIRES)
|
||||
idf_component_get_property(component_source "${COMPONENT_NAME}" COMPONENT_SOURCE)
|
||||
if(component_source STREQUAL "project_components")
|
||||
idf_build_get_property(shim_components __SHIM_COMPONENTS)
|
||||
if(shim_components)
|
||||
# The project explicitly restricted COMPONENTS=<list>. Honor
|
||||
# the restriction literally — do not pull every discovered
|
||||
# component into main's link graph, even when the user's list
|
||||
# collapses to just "main". Apps that need additional
|
||||
# components must enumerate them in COMPONENTS or main's
|
||||
# REQUIRES.
|
||||
set(all_components ${shim_components})
|
||||
else()
|
||||
idf_build_get_property(all_components COMPONENTS_DISCOVERED)
|
||||
endif()
|
||||
list(REMOVE_ITEM all_components "main")
|
||||
# Common components are already linked via link_libraries()
|
||||
idf_build_get_property(common_components __COMPONENT_REQUIRES_COMMON)
|
||||
if(common_components)
|
||||
list(REMOVE_ITEM all_components ${common_components})
|
||||
endif()
|
||||
foreach(req IN LISTS all_components)
|
||||
idf_component_include("${req}")
|
||||
idf_component_get_property(req_interface "${req}" COMPONENT_INTERFACE)
|
||||
if(${component_type} STREQUAL LIBRARY)
|
||||
target_link_libraries("${COMPONENT_TARGET}" PUBLIC "${req_interface}")
|
||||
else()
|
||||
target_link_libraries("${COMPONENT_TARGET}" INTERFACE "${req_interface}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Signal to idf_component_include that this component was included via the
|
||||
# backward compatible idf_component_register function.
|
||||
idf_component_set_property("${COMPONENT_NAME}" COMPONENT_FORMAT CMAKEV1)
|
||||
@@ -661,8 +793,30 @@ function(idf_component_register)
|
||||
# Embedded files are managed in the idf_component_include function.
|
||||
idf_component_set_property("${COMPONENT_NAME}" EMBED_FILES "${ARG_EMBED_FILES}")
|
||||
idf_component_set_property("${COMPONENT_NAME}" EMBED_TXTFILES "${ARG_EMBED_TXTFILES}")
|
||||
idf_component_set_property("${COMPONENT_NAME}" REQUIRES "${ARG_REQUIRES}")
|
||||
idf_component_set_property("${COMPONENT_NAME}" PRIV_REQUIRES "${ARG_PRIV_REQUIRES}")
|
||||
# The component manager's dependency injection runs before this component's
|
||||
# CMakeLists.txt is evaluated (see idf_component_include() in
|
||||
# component.cmake), and writes the manifest-derived names into both the
|
||||
# MANAGED_* properties and the regular REQUIRES / PRIV_REQUIRES properties.
|
||||
# The latter must not be overwritten by the component's own register call,
|
||||
# else the manifest-derived transitive deps disappear from the build. Union
|
||||
# the two so the persisted property is what the component author wrote
|
||||
# PLUS what the manifest contributed.
|
||||
idf_component_get_property(__existing_requires "${COMPONENT_NAME}" REQUIRES)
|
||||
idf_component_get_property(__existing_priv_requires "${COMPONENT_NAME}" PRIV_REQUIRES)
|
||||
set(__merged_requires "${ARG_REQUIRES}")
|
||||
set(__merged_priv_requires "${ARG_PRIV_REQUIRES}")
|
||||
foreach(__r IN LISTS __existing_requires)
|
||||
if(__r AND NOT __r IN_LIST __merged_requires)
|
||||
list(APPEND __merged_requires "${__r}")
|
||||
endif()
|
||||
endforeach()
|
||||
foreach(__r IN LISTS __existing_priv_requires)
|
||||
if(__r AND NOT __r IN_LIST __merged_priv_requires)
|
||||
list(APPEND __merged_priv_requires "${__r}")
|
||||
endif()
|
||||
endforeach()
|
||||
idf_component_set_property("${COMPONENT_NAME}" REQUIRES "${__merged_requires}")
|
||||
idf_component_set_property("${COMPONENT_NAME}" PRIV_REQUIRES "${__merged_priv_requires}")
|
||||
idf_component_set_property("${COMPONENT_NAME}" REQUIRED_IDF_TARGETS "${ARG_REQUIRED_IDF_TARGETS}")
|
||||
idf_component_set_property("${COMPONENT_NAME}" COMPONENT_TYPE "${component_type}")
|
||||
endfunction()
|
||||
@@ -776,3 +930,27 @@ function(idf_build_component component_dir)
|
||||
PREFIX "${component_prefix}"
|
||||
SOURCE "${component_source}")
|
||||
endfunction()
|
||||
|
||||
#[[
|
||||
__import_sdkconfig_as_build_properties()
|
||||
|
||||
Mirror every CONFIG_* symbol from the generated sdkconfig.cmake onto the
|
||||
build-properties target so that the
|
||||
`idf_build_get_property(var CONFIG_FOO)` idiom keeps working under the
|
||||
compatibility shim. Called from kconfig.cmake::__generate_sdkconfig after
|
||||
each kconfgen run.
|
||||
#]]
|
||||
function(__import_sdkconfig_as_build_properties)
|
||||
idf_build_get_property(sdkconfig_cmake __SDKCONFIG_CMAKE)
|
||||
if(NOT sdkconfig_cmake OR NOT EXISTS "${sdkconfig_cmake}")
|
||||
return()
|
||||
endif()
|
||||
include("${sdkconfig_cmake}")
|
||||
if(NOT DEFINED CONFIGS_LIST)
|
||||
return()
|
||||
endif()
|
||||
idf_build_set_property(__CONFIG_VARIABLES "${CONFIGS_LIST}")
|
||||
foreach(config IN LISTS CONFIGS_LIST)
|
||||
idf_build_set_property("${config}" "${${config}}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
@@ -891,6 +891,29 @@ function(idf_component_include name)
|
||||
endif()
|
||||
|
||||
list(APPEND __DEPENDENCY_CHAIN "${component_interface}")
|
||||
|
||||
# Inject managed dependencies BEFORE add_subdirectory() evaluates the
|
||||
# component's CMakeLists.txt — otherwise any component that queries a
|
||||
# managed dependency at register time via
|
||||
# idf_component_get_property(... COMPONENT_LIB) finds nothing because the
|
||||
# target hasn't been created yet.
|
||||
idf_build_get_property(idf_component_manager IDF_COMPONENT_MANAGER)
|
||||
if(idf_component_manager EQUAL 1)
|
||||
idf_component_get_property(_comp_dir "${component_name}" COMPONENT_DIR)
|
||||
if(EXISTS "${_comp_dir}/idf_component.yml")
|
||||
__inject_requirements_for_component_from_manager("${component_name}")
|
||||
|
||||
idf_component_get_property(_managed_req "${component_name}" MANAGED_REQUIRES)
|
||||
idf_component_get_property(_managed_priv_req "${component_name}" MANAGED_PRIV_REQUIRES)
|
||||
|
||||
foreach(_dep IN LISTS _managed_req _managed_priv_req)
|
||||
if(_dep)
|
||||
idf_component_include("${_dep}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Evaluate the CMakeLists.txt file of the component.
|
||||
idf_component_get_property(component_build_dir "${component_name}" COMPONENT_BUILD_DIR)
|
||||
add_subdirectory("${component_directory}" "${component_build_dir}")
|
||||
@@ -977,25 +1000,16 @@ function(idf_component_include name)
|
||||
target_add_binary_data(${COMPONENT_TARGET} "${file}" "TEXT")
|
||||
endforeach()
|
||||
|
||||
# Inject managed dependencies if component manager is enabled
|
||||
# Link managed dependencies for cmakev1 components (backward compat).
|
||||
# The injection and inclusion already happened before add_subdirectory().
|
||||
idf_build_get_property(idf_component_manager IDF_COMPONENT_MANAGER)
|
||||
idf_component_get_property(component_format "${component_name}" COMPONENT_FORMAT)
|
||||
if(idf_component_manager EQUAL 1)
|
||||
idf_component_get_property(component_dir "${component_name}" COMPONENT_DIR)
|
||||
# Check if component has manifest for managed dependency injection
|
||||
if(EXISTS "${component_dir}/idf_component.yml")
|
||||
__inject_requirements_for_component_from_manager("${component_name}")
|
||||
|
||||
# Include any managed dependencies
|
||||
idf_component_get_property(managed_requires "${component_name}" MANAGED_REQUIRES)
|
||||
idf_component_get_property(managed_priv_requires "${component_name}" MANAGED_PRIV_REQUIRES)
|
||||
|
||||
foreach(dep IN LISTS managed_requires managed_priv_requires)
|
||||
if(dep)
|
||||
idf_component_include("${dep}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# For cmakev1 components, automatically link managed dependencies to maintain
|
||||
# backward compatibility.
|
||||
if("${component_format}" STREQUAL "CMAKEV1")
|
||||
|
||||
@@ -208,6 +208,10 @@ function(__generate_sdkconfig)
|
||||
# Generate Kconfig outputs
|
||||
__generate_kconfig_outputs()
|
||||
|
||||
# Mirror CONFIG_* values onto build properties so
|
||||
# `idf_build_get_property(var CONFIG_FOO)` keeps working.
|
||||
__import_sdkconfig_as_build_properties()
|
||||
|
||||
idf_msg("Generated sdkconfig configuration")
|
||||
endfunction()
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ function(__init_project_configuration)
|
||||
# Subprojects that handle their own compiler optimization flags can set the
|
||||
# SET_COMPILER_OPTIMIZATION build property to NO before idf_project_init().
|
||||
idf_build_get_property(set_compiler_optimization SET_COMPILER_OPTIMIZATION)
|
||||
if(NOT set_compiler_optimization)
|
||||
if(NOT DEFINED set_compiler_optimization OR set_compiler_optimization STREQUAL "")
|
||||
set(set_compiler_optimization YES)
|
||||
endif()
|
||||
if(set_compiler_optimization)
|
||||
@@ -533,7 +533,9 @@ endfunction()
|
||||
esptool_py component.
|
||||
#]]
|
||||
function(__init_project_flash_targets)
|
||||
if(CONFIG_APP_BUILD_GENERATE_BINARIES)
|
||||
# Skip if esptool_py is not in the build set; the flash-target function
|
||||
# would otherwise be undefined.
|
||||
if(CONFIG_APP_BUILD_GENERATE_BINARIES AND COMMAND esptool_py_flash_target)
|
||||
idf_component_get_property(main_args esptool_py FLASH_ARGS)
|
||||
idf_component_get_property(sub_args esptool_py FLASH_SUB_ARGS)
|
||||
esptool_py_flash_target(flash "${main_args}" "${sub_args}")
|
||||
@@ -741,10 +743,54 @@ endfunction()
|
||||
function(__project_default)
|
||||
idf_build_get_property(build_dir BUILD_DIR)
|
||||
idf_build_get_property(executable PROJECT_NAME)
|
||||
|
||||
# When the Build system v1 compatibility shim forwarded a COMPONENTS
|
||||
# list, use it instead of default main.
|
||||
idf_build_get_property(shim_components __SHIM_COMPONENTS)
|
||||
if(shim_components)
|
||||
set(root_components ${shim_components})
|
||||
else()
|
||||
set(root_components main)
|
||||
endif()
|
||||
|
||||
idf_build_executable("${executable}"
|
||||
COMPONENTS main
|
||||
COMPONENTS ${root_components}
|
||||
MAPFILE_TARGET "${executable}_mapfile")
|
||||
|
||||
# In Build system v1, the ``project_elf`` variable (set to
|
||||
# "${project_name}.elf") is used by several app CMakeLists.txt files to add
|
||||
# linker flags after project(). In Build system v2 the executable target
|
||||
# is just "${executable}" (the .elf suffix is an output property, not part
|
||||
# of the target name). Propagate it to the caller's scope so existing
|
||||
# code keeps working.
|
||||
set(project_elf "${executable}" PARENT_SCOPE)
|
||||
|
||||
# Provide Build system v1-compatible build properties so that existing
|
||||
# test apps and project CMakeLists.txt files that query EXECUTABLE or
|
||||
# BUILD_COMPONENTS continue to work when built through the shim.
|
||||
idf_build_get_property(v1_compat __V1_COMPAT_SHIM)
|
||||
if(v1_compat)
|
||||
idf_build_set_property(EXECUTABLE "${executable}")
|
||||
idf_build_set_property(EXECUTABLE_NAME "${executable}")
|
||||
|
||||
# BUILD_COMPONENTS: in Build system v1 this is the set of components
|
||||
# actually processed during the build (COMPONENTS + their transitive
|
||||
# REQUIRES within the restricted scope). Use LIBRARY_COMPONENTS_LINKED
|
||||
# from the Build system v2 library target which reflects the actual
|
||||
# list of components linked, plus the architecture component which
|
||||
# Build system v1 always includes but Build system v2 does not track
|
||||
# as a linked library.
|
||||
get_target_property(library ${executable} LIBRARY_INTERFACE)
|
||||
if(library)
|
||||
idf_library_get_property(linked_components "${library}" LIBRARY_COMPONENTS_LINKED)
|
||||
idf_build_get_property(target_arch IDF_TARGET_ARCH)
|
||||
if(target_arch AND NOT target_arch IN_LIST linked_components)
|
||||
list(APPEND linked_components ${target_arch})
|
||||
endif()
|
||||
idf_build_set_property(BUILD_COMPONENTS "${linked_components}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_APP_BUILD_GENERATE_BINARIES AND TARGET idf::esptool_py)
|
||||
# Is it possible to have a configuration where
|
||||
# CONFIG_APP_BUILD_GENERATE_BINARIES is not set?
|
||||
|
||||
Reference in New Issue
Block a user