refactor(esptool_py): Move flash target creation to project level and add utility functions

This commit refactors the esptool_py component to provide utility
functions for flash target management instead of creating the targets
directly. Flash target creation is now moved to the project level in
build.cmake file when idf_build_executable() runs.

The following changes were done in this commit:
- Added __esptool_py_setup_tools(), __esptool_py_setup_estool_py_args()
  and __ensure_esptool_py_setup() functions to centralize esptool_py
  setup.
- Added __esptool_py_setup_main_flash_target() which is called by
  idf_build_executable() to create the flash targets.
- Updated esptool_py_flash_target(), esptool_py_custom_target() to
  accept an optional FILENAME_PREFIX argument to enable creation of
  build artifacts based on custom names.
- Create placeholder flash targets early in the build process when
  idf_build_process() is called for components to add dependencies on
  these targets.
- Moved app-flash target creation from esptool_py/CMakeLists.txt to
  build.cmake.
- Added function description to esptool_py functions.
This commit is contained in:
Sudeep Mohanty
2025-07-01 14:48:34 +02:00
parent 30083e07be
commit ef4d6462e2
6 changed files with 371 additions and 42 deletions

View File

@@ -29,7 +29,9 @@ if(NOT BOOTLOADER_BUILD)
add_custom_target(blank_ota_data ALL DEPENDS ${blank_otadata_file})
add_dependencies(flash blank_ota_data)
add_dependencies(encrypted-flash blank_ota_data)
if(CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT)
add_dependencies(encrypted-flash blank_ota_data)
endif()
set(otatool_py "${python}" "${COMPONENT_DIR}/otatool.py")

View File

@@ -50,7 +50,9 @@ else()
add_custom_target(blank_tee_ota_data ALL DEPENDS ${blank_tee_otadata_file})
add_dependencies(flash blank_tee_ota_data)
add_dependencies(encrypted-flash blank_tee_ota_data)
if(CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT)
add_dependencies(encrypted-flash blank_tee_ota_data)
endif()
partition_table_get_partition_info(tee_otadata_part
"--partition-type data --partition-subtype tee_ota" "name")

View File

@@ -15,13 +15,7 @@ idf_component_register(REQUIRES bootloader PRIV_REQUIRES partition_table)
if(NOT BOOTLOADER_BUILD)
idf_build_get_property(build_dir BUILD_DIR)
if(CONFIG_APP_BUILD_GENERATE_BINARIES)
partition_table_get_partition_info(app_partition_offset "--partition-boot-default" "offset")
esptool_py_custom_target(app-flash app "app")
esptool_py_flash_target_image(app-flash app "${app_partition_offset}" "${build_dir}/${PROJECT_BIN}")
esptool_py_flash_target_image(flash app "${app_partition_offset}" "${build_dir}/${PROJECT_BIN}")
endif()
# If anti-rollback option is set then factory partition should not be in Partition Table.
# In this case, should be used the partition table with two ota app without the factory.

View File

@@ -274,6 +274,16 @@ idf_component_set_property(esptool_py FLASH_ARGS "${esptool_flash_main_args}")
idf_component_set_property(esptool_py FLASH_SUB_ARGS "--flash_mode ${ESPFLASHMODE} --flash_freq ${ESPFLASHFREQ} \
--flash_size ${ESPFLASHSIZE}")
# esptool_py_partition_needs_encryption
#
# @brief Determine if a partition needs to be encrypted when flash encryption is enabled.
#
# When flash encryption is enabled in development mode, this function checks
# the type and subtype of a partition to determine if its contents should be
# encrypted before flashing.
#
# @param[out] retencrypted Variable to store the result (TRUE if encryption needed, FALSE otherwise)
# @param[in] partition_name Name of the partition to check
function(esptool_py_partition_needs_encryption retencrypted partition_name)
# Check if encryption is enabled
if(CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT)
@@ -311,6 +321,17 @@ function(esptool_py_partition_needs_encryption retencrypted partition_name)
endfunction()
# esptool_py_flash_to_partition
#
# @brief Add a binary image to be flashed to a specific partition.
#
# This function is a convenience wrapper that automatically determines the partition
# offset and encryption requirements, then calls esptool_py_flash_target_image() with
# the appropriate parameters. It simplifies flashing to named partitions.
#
# @param[in] target_name Name of the flash target to add the image to
# @param[in] partition_name Name of the partition where the image should be flashed
# @param[in] binary_path Path to the binary file to flash
function(esptool_py_flash_to_partition target_name partition_name binary_path)
# Retrieve the offset for the partition to flash the image on
partition_table_get_partition_info(offset "--partition-name ${partition_name}" "offset")
@@ -333,12 +354,21 @@ function(esptool_py_flash_to_partition target_name partition_name binary_path)
${binary_path} ${option})
endfunction()
# This function takes a fifth optional named parameter: "ALWAYS_PLAINTEXT". As
# its name states, it marks whether the image should be flashed as plain text or
# not. If build macro CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT is set and
# this parameter is provided, then the image will be flashed as plain text
# (not encrypted) on the target. This parameter will be ignored if build macro
# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT is not set.
# esptool_py_flash_target_image
#
# @brief Add a binary image to a flash target at a specific offset.
#
# This function adds a binary image to the specified flash target, which will be
# included when the target is executed. It handles both plain and encrypted flash
# scenarios, automatically setting up the appropriate target properties.
#
# @param[in] target_name Name of the flash target to add the image to
# @param[in] image_name Logical name for the image (used in flasher_args.json)
# @param[in] offset Flash offset where the image should be written (in hex format like 0x1000)
# @param[in] image Path to the binary file to flash
# @param[in, optional] ALWAYS_PLAINTEXT (option) Force the image to be flashed as plain text
# even when flash encryption is enabled. Ignored if flash encryption
# is not configured.
function(esptool_py_flash_target_image target_name image_name offset image)
set(options ALWAYS_PLAINTEXT)
idf_build_get_property(build_dir BUILD_DIR)
@@ -391,21 +421,56 @@ function(esptool_py_flash_target_image target_name image_name offset image)
endfunction()
# esptool_py_flash_target
#
# @brief Create a flash target that can flash multiple images using esptool.py.
#
# This function is the core of the flashing mechanism. It creates a custom target
# and attaches the actual esptool.py command to it as a POST_BUILD step. This
# ensures that the flash command only runs after all of the target's dependencies
# (like binary generation) have been successfully built.
#
# It works by generating an argument file (`<prefix>_args`) that contains all the
# necessary parameters for esptool.py. This file's content is constructed using
# CMake generator expressions, which are resolved at build time. This allows the
# final list of binaries to be flashed to be collected from properties on the
# target.
#
# If flash encryption is enabled, it also creates a corresponding `encrypted-`
# target, which handles the logic for encrypting all or a subset of the binaries.
#
# @param[in] target_name Name of the flash target to create
# @param[in] main_args Main esptool.py arguments (before write_flash command)
# @param[in] sub_args Sub-arguments for write_flash command (flash mode, frequency, size)
# @param[in, optional] FILENAME_PREFIX (single value) Prefix for generated argument files.
# If not specified, uses target_name as prefix.
# @param[in, optional] ALWAYS_PLAINTEXT (option) Force all images to be flashed as plain text.
function(esptool_py_flash_target target_name main_args sub_args)
set(single_value OFFSET IMAGE) # template file to use to be able to
# flash the image individually using esptool
set(single_value OFFSET IMAGE FILENAME_PREFIX) # template file to use to be able to
# flash the image individually using esptool
set(options ALWAYS_PLAINTEXT)
cmake_parse_arguments(_ "${options}" "${single_value}" "" "${ARGN}")
if(__FILENAME_PREFIX)
set(filename_prefix ${__FILENAME_PREFIX})
else()
set(filename_prefix ${target_name})
endif()
idf_build_get_property(idf_path IDF_PATH)
idf_build_get_property(build_dir BUILD_DIR)
idf_component_get_property(esptool_py_dir esptool_py COMPONENT_DIR)
idf_component_get_property(esptool_py_cmd esptool_py ESPTOOLPY_CMD)
add_custom_target(${target_name}
if(NOT TARGET ${target_name})
add_custom_target(${target_name})
endif()
add_custom_command(TARGET ${target_name} POST_BUILD
COMMAND ${CMAKE_COMMAND}
-D "IDF_PATH=${idf_path}"
-D "SERIAL_TOOL=${ESPTOOLPY}"
-D "SERIAL_TOOL_ARGS=${main_args};write_flash;@${target_name}_args"
-D "SERIAL_TOOL=${esptool_py_cmd}"
-D "SERIAL_TOOL_ARGS=${main_args};write_flash;@${filename_prefix}_args"
-D "WORKING_DIRECTORY=${build_dir}"
-P ${esptool_py_dir}/run_serial_tool.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
@@ -421,13 +486,13 @@ function(esptool_py_flash_target target_name main_args sub_args)
$<JOIN:$<TARGET_PROPERTY:${target_name},IMAGES>,\n>")
# Write the previous expression to the target_name_args.in file
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${target_name}_args.in"
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${filename_prefix}_args.in"
CONTENT "${flash_args_content}")
# Generate the actual expression value from the content of the file
# we just wrote
file(GENERATE OUTPUT "${build_dir}/${target_name}_args"
INPUT "${CMAKE_CURRENT_BINARY_DIR}/${target_name}_args.in")
file(GENERATE OUTPUT "${build_dir}/${filename_prefix}_args"
INPUT "${CMAKE_CURRENT_BINARY_DIR}/${filename_prefix}_args.in")
# Check if the target has to be plain text or not, depending on the macro
# CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT and the parameter
@@ -443,11 +508,15 @@ $<JOIN:$<TARGET_PROPERTY:${target_name},IMAGES>,\n>")
# For example, if 'target_name' is app-flash and 'encrypted' is TRUE,
# 'build' directory will contain a file name 'encrypted_app-flash_args'
if(${encrypted})
add_custom_target(encrypted-${target_name}
if(NOT TARGET encrypted-${target_name})
add_custom_target(encrypted-${target_name})
endif()
add_custom_command(TARGET encrypted-${target_name} POST_BUILD
COMMAND ${CMAKE_COMMAND}
-D "IDF_PATH=${idf_path}"
-D "SERIAL_TOOL=${ESPTOOLPY}"
-D "SERIAL_TOOL_ARGS=${main_args};write_flash;@encrypted_${target_name}_args"
-D "SERIAL_TOOL=${esptool_py_cmd}"
-D "SERIAL_TOOL_ARGS=${main_args};write_flash;@encrypted_${filename_prefix}_args"
-D "WORKING_DIRECTORY=${build_dir}"
-P ${esptool_py_dir}/run_serial_tool.cmake
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
@@ -493,12 +562,12 @@ ${encrypted_files}")
# The expression is ready to be generated, write it to the file which
# extension is .in
file_generate("${CMAKE_CURRENT_BINARY_DIR}/encrypted_${target_name}_args.in"
file_generate("${CMAKE_CURRENT_BINARY_DIR}/encrypted_${filename_prefix}_args.in"
CONTENT "${flash_args_content}")
# Generate the actual string from the content of the file we just wrote
file_generate("${build_dir}/encrypted_${target_name}_args"
INPUT "${CMAKE_CURRENT_BINARY_DIR}/encrypted_${target_name}_args.in")
file_generate("${build_dir}/encrypted_${filename_prefix}_args"
INPUT "${CMAKE_CURRENT_BINARY_DIR}/encrypted_${filename_prefix}_args.in")
else()
fail_target(encrypted-${target_name} "Error: The target encrypted-${target_name} requires"
"CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT to be enabled.")
@@ -507,46 +576,250 @@ ${encrypted_files}")
endfunction()
# esptool_py_custom_target
#
# @brief Create a custom flash target with dependencies.
#
# This function creates a flash target that depends on other build targets.
#
# @param[in] target_name Name of the flash target to create
# @param[in] flasher_filename Base name for generated flasher argument files
# @param[in] dependencies List of CMake targets that this flash target depends on
# @param[in, optional] FILENAME_PREFIX (single value) Custom prefix for argument files.
# If not specified, uses target_name as prefix.
function(esptool_py_custom_target target_name flasher_filename dependencies)
__ensure_esptool_py_setup()
idf_component_get_property(main_args esptool_py FLASH_ARGS)
idf_component_get_property(sub_args esptool_py FLASH_SUB_ARGS)
idf_build_get_property(build_dir BUILD_DIR)
esptool_py_flash_target(${target_name} "${main_args}" "${sub_args}")
# Parse optional arguments like FILENAME_PREFIX.
set(one_value_args FILENAME_PREFIX)
cmake_parse_arguments(arg "" "${one_value_args}" "" ${ARGN})
# Call the underlying flash target function, explicitly passing the prefix if it exists.
if(arg_FILENAME_PREFIX)
esptool_py_flash_target(${target_name} "${main_args}" "${sub_args}" FILENAME_PREFIX "${arg_FILENAME_PREFIX}")
set(filename_prefix ${arg_FILENAME_PREFIX})
else()
esptool_py_flash_target(${target_name} "${main_args}" "${sub_args}")
set(filename_prefix ${target_name})
endif()
# Copy the file to flash_xxx_args for compatibility for select target
file_generate("${build_dir}/flash_${flasher_filename}_args"
INPUT "${build_dir}/${target_name}_args")
INPUT "${build_dir}/${filename_prefix}_args")
add_dependencies(${target_name} ${dependencies})
if(CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT)
file_generate("${build_dir}/flash_encrypted_${flasher_filename}_args"
INPUT "${build_dir}/encrypted_${target_name}_args")
INPUT "${build_dir}/encrypted_${filename_prefix}_args")
add_dependencies(encrypted-${target_name} ${dependencies})
endif()
endfunction()
if(NOT non_os_build)
set(flash_deps "")
# __esptool_py_setup_tools
#
# @brief Sets up esptool.py, espsecure.py, and espefuse.py tool commands.
#
# This function retrieves the necessary paths and Python interpreter, then
# constructs the full command-line strings for `esptool.py`, `espsecure.py`,
# and `espefuse.py`. It stores these commands as properties of the `esptool_py`
# component for later use by other functions or components.
function(__esptool_py_setup_tools)
idf_build_get_property(target IDF_TARGET)
idf_build_get_property(python PYTHON)
idf_component_get_property(esptool_py_dir esptool_py COMPONENT_DIR)
if(CONFIG_APP_BUILD_TYPE_APP_2NDBOOT)
list(APPEND flash_deps "partition_table_bin")
set(esptool_py_cmd ${python} "$ENV{ESPTOOL_WRAPPER}" "${esptool_py_dir}/esptool/esptool.py" --chip ${target})
idf_component_set_property(esptool_py ESPTOOLPY_CMD "${esptool_py_cmd}")
set(espsecure_py_cmd ${python} "${esptool_py_dir}/esptool/espsecure.py")
idf_component_set_property(esptool_py ESPSECUREPY_CMD "${espsecure_py_cmd}")
set(espefuse_py_cmd ${python} "${esptool_py_dir}/esptool/espefuse.py")
idf_component_set_property(esptool_py ESPEFUSEPY_CMD "${espefuse_py_cmd}")
endfunction()
# __esptool_py_setup_esptool_py_args
#
# @brief Sets up esptool.py arguments for elf2image and flash targets.
#
# This function determines the appropriate flash mode, frequency, and size based
# on the project configuration (Kconfig values). It assembles argument lists
# for both the `elf2image` operation (converting ELF to BIN), for general
# flashing commands and for creating the flasher_args.json file.
# These argument lists are then stored as properties of the `esptool_py`
# component for consistent use across the build system.
function(__esptool_py_setup_esptool_py_args)
if(NOT CONFIG_APP_BUILD_TYPE_RAM AND CONFIG_APP_BUILD_GENERATE_BINARIES)
if(CONFIG_BOOTLOADER_FLASH_DC_AWARE)
# When set flash frequency to 120M, must keep 1st bootloader work under ``DOUT`` mode
# because on some flash chips, 120M will modify the status register,
# which will make ROM won't work.
# This change intends to be for esptool only and the bootloader should keep use
# ``DOUT`` mode.
set(ESPFLASHMODE "dout")
message("Note: HPM is enabled for the flash, force the ROM bootloader into DOUT mode for stable boot on")
else()
set(ESPFLASHMODE ${CONFIG_ESPTOOLPY_FLASHMODE})
endif()
set(ESPFLASHFREQ ${CONFIG_ESPTOOLPY_FLASHFREQ})
set(ESPFLASHSIZE ${CONFIG_ESPTOOLPY_FLASHSIZE})
set(esptool_elf2image_args
--flash_mode ${ESPFLASHMODE}
--flash_freq ${ESPFLASHFREQ}
--flash_size ${ESPFLASHSIZE}
)
if(BOOTLOADER_BUILD AND CONFIG_SECURE_BOOT_V2_ENABLED)
# The bootloader binary needs to be 4KB aligned in order to append a secure boot V2 signature block.
# If CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES is NOT set, the bootloader
# image generated is not 4KB aligned for external HSM to sign it readily.
# Following esptool option --pad-to-size 4KB generates a 4K aligned bootloader image.
# In case of signing during build, espsecure.py "sign_data" operation handles the 4K alignment of the image.
if(NOT CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
list(APPEND esptool_elf2image_args --pad-to-size 4KB)
endif()
endif()
set(MMU_PAGE_SIZE ${CONFIG_MMU_PAGE_MODE})
if(NOT BOOTLOADER_BUILD)
list(APPEND esptool_elf2image_args --elf-sha256-offset 0xb0)
# For chips that support configurable MMU page size feature
# If page size is configured to values other than the default "64KB" in menuconfig,
# then we need to pass the actual size to flash-mmu-page-size arg
if(NOT MMU_PAGE_SIZE STREQUAL "64KB")
list(APPEND esptool_elf2image_args --flash-mmu-page-size ${MMU_PAGE_SIZE})
endif()
endif()
if(NOT CONFIG_SECURE_BOOT_ALLOW_SHORT_APP_PARTITION AND NOT BOOTLOADER_BUILD)
if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME)
list(APPEND esptool_elf2image_args --secure-pad)
elseif(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME)
list(APPEND esptool_elf2image_args --secure-pad-v2)
endif()
endif()
endif()
if(CONFIG_APP_BUILD_GENERATE_BINARIES)
list(APPEND flash_deps "app")
if(CONFIG_ESPTOOLPY_HEADER_FLASHSIZE_UPDATE)
# Set ESPFLASHSIZE to 'detect' *after* esptool_elf2image_args are generated,
# as elf2image can't have 'detect' as an option...
set(ESPFLASHSIZE detect)
endif()
if(CONFIG_APP_BUILD_BOOTLOADER)
list(APPEND flash_deps "bootloader")
if(CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME)
set(ESPFLASHSIZE keep)
endif()
esptool_py_custom_target(flash project "${flash_deps}")
endif()
# We still set "--min-rev" to keep the app compatible with older bootloaders where this field is controlled.
if(CONFIG_IDF_TARGET_ESP32)
# for this chip min_rev is major revision
math(EXPR min_rev "${CONFIG_ESP_REV_MIN_FULL} / 100")
endif()
if(CONFIG_IDF_TARGET_ESP32C3)
# for this chip min_rev is minor revision
math(EXPR min_rev "${CONFIG_ESP_REV_MIN_FULL} % 100")
endif()
if(min_rev)
list(APPEND esptool_elf2image_args --min-rev ${min_rev})
endif()
list(APPEND esptool_elf2image_args --min-rev-full ${CONFIG_ESP_REV_MIN_FULL})
list(APPEND esptool_elf2image_args --max-rev-full ${CONFIG_ESP_REV_MAX_FULL})
# Save esptool_elf2image_args to component property
idf_component_set_property(esptool_py ESPTOOL_PY_ELF2IMAGE_ARGS "${esptool_elf2image_args}")
set(esptool_flash_main_args "--before=${CONFIG_ESPTOOLPY_BEFORE}")
if(CONFIG_SECURE_BOOT OR CONFIG_SECURE_FLASH_ENC_ENABLED)
# If security enabled then override post flash option
list(APPEND esptool_flash_main_args "--after=no_reset")
else()
list(APPEND esptool_flash_main_args "--after=${CONFIG_ESPTOOLPY_AFTER}")
endif()
if(CONFIG_ESPTOOLPY_NO_STUB)
list(APPEND esptool_flash_main_args "--no-stub")
endif()
# Save flash arguments to component property
idf_component_set_property(esptool_py FLASH_ARGS "${esptool_flash_main_args}")
idf_component_set_property(esptool_py FLASH_SUB_ARGS
"--flash_mode ${ESPFLASHMODE} --flash_freq ${ESPFLASHFREQ} --flash_size ${ESPFLASHSIZE}")
# Save arguments for flasher_args.json
idf_component_set_property(esptool_py ESPFLASHMODE "${ESPFLASHMODE}")
idf_component_set_property(esptool_py ESPFLASHFREQ "${ESPFLASHFREQ}")
idf_component_set_property(esptool_py ESPFLASHSIZE "${ESPFLASHSIZE}")
endfunction()
# __ensure_esptool_py_setup
#
# @brief Ensures that the esptool.py setup functions have been called once.
#
# This function acts as an initializer. It checks if the esptool_py
# setup has already been performed by checking a component property. If not, it
# calls __esptool_py_setup_tools() and __esptool_py_setup_esptool_py_args()
# to configure the component.
function(__ensure_esptool_py_setup)
idf_component_get_property(esptool_py_setup_done esptool_py _ESPTOOL_PY_SETUP_DONE)
if(NOT esptool_py_setup_done)
__esptool_py_setup_tools()
__esptool_py_setup_esptool_py_args()
idf_component_set_property(esptool_py _ESPTOOL_PY_SETUP_DONE TRUE)
endif()
endfunction()
# __esptool_py_setup_main_flash_target
#
# @brief Sets up the main `flash` target and its dependencies.
#
# This function creates the main `flash` target, which is used to flash multiple
# images to the target device. It determines the dependencies for a full
# project flash (bootloader, partition table, the main app) and then calls
#
function(__esptool_py_setup_main_flash_target)
__ensure_esptool_py_setup()
idf_build_get_property(non_os_build NON_OS_BUILD)
if(NOT non_os_build)
set(flash_deps "")
if(CONFIG_APP_BUILD_TYPE_APP_2NDBOOT)
list(APPEND flash_deps "partition_table_bin")
endif()
if(CONFIG_APP_BUILD_GENERATE_BINARIES)
list(APPEND flash_deps "app")
endif()
if(CONFIG_APP_BUILD_BOOTLOADER)
list(APPEND flash_deps "bootloader")
endif()
# Create the flash target. If encryption is enabled, it will also create
# an encrypted-flash target.
esptool_py_custom_target(flash project "${flash_deps}" FILENAME_PREFIX "flash")
endif()
endfunction()
# Adds espefuse functions for global use
idf_component_get_property(esptool_py_dir esptool_py COMPONENT_DIR)
include(${esptool_py_dir}/espefuse.cmake)
# Initialize the esptool_py component.
# This ensures that all its properties are set before any other components that
# depend on it try to access them.
__ensure_esptool_py_setup()

View File

@@ -53,7 +53,9 @@ function(nvs_create_partition_image partition csv)
if(arg_FLASH_IN_PROJECT)
esptool_py_flash_to_partition(flash "${partition}" "${image_file}")
add_dependencies(flash nvs_${partition}_bin)
add_dependencies(encrypted-flash nvs_${partition}_bin)
if(CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT)
add_dependencies(encrypted-flash nvs_${partition}_bin)
endif()
endif()
else()
set(message

View File

@@ -469,6 +469,22 @@ macro(__build_process_project_includes)
endforeach()
endmacro()
#
# Add placeholder flash targets to the build.
# This is used by components to declare dependencies on the flash target.
#
macro(__build_create_flash_targets)
if(NOT TARGET flash)
add_custom_target(flash)
endif()
# When flash encryption is enabled, a corresponding 'encrypted-flash' target will be created.
idf_build_get_config(encrypted_flash_enabled CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT)
if(encrypted_flash_enabled AND NOT TARGET encrypted-flash)
add_custom_target(encrypted-flash)
endif()
endmacro()
#
# Utility macro for setting default property value if argument is not specified
# for idf_build_process().
@@ -713,6 +729,13 @@ macro(idf_build_process target)
set(ESP_PLATFORM 1)
idf_build_set_property(COMPILE_DEFINITIONS "ESP_PLATFORM" APPEND)
# Create flash targets early so components can attach images to them.
# These targets will be appended with actual esptool.py command later
# in the build process when __idf_build_setup_flash_targets() is called.
if(NOT BOOTLOADER_BUILD AND NOT ESP_TEE_BUILD AND NOT "${target}" STREQUAL "linux")
__build_create_flash_targets()
endif()
# Perform component processing (inclusion of project_include.cmake, adding component
# subdirectories, creating library targets, linking libraries, etc.)
__build_process_project_includes()
@@ -752,6 +775,39 @@ function(idf_build_executable elf)
# Add dependency of the build target to the executable
add_dependencies(${elf} __idf_build_target)
# Set up esptool_py flash targets
# This must be done after the executable properties are set but before the function exits
# so that all components have had a chance to add their images to the phony flash targets
idf_build_get_property(bootloader_build BOOTLOADER_BUILD)
idf_build_get_property(esp_tee_build ESP_TEE_BUILD)
idf_build_get_property(target IDF_TARGET)
if(NOT bootloader_build AND NOT esp_tee_build AND NOT "${target}" STREQUAL "linux")
# Check if esptool_py component is available before calling its functions
if(TARGET idf::esptool_py)
# The following block is placed here to ensure that the application binary is added to the 'flash'
# target's properties *before* __esptool_py_setup_main_flash_target is called.
# This is because __esptool_py_setup_main_flash_target copies properties from the 'flash'
# target to an internal '_flash_impl' target, from which the final 'flash_args' file is generated.
# If the app target is not added to the 'flash' target *before* the properties are copied,
# the app binary will be missing from the final 'flash_args' file.
#
# Set up app-flash and flash targets. The app-flash target is specifically for flashing
# just the application, while the flash target is for flashing the entire system.
if(CONFIG_APP_BUILD_GENERATE_BINARIES)
idf_build_get_property(build_dir BUILD_DIR)
idf_build_get_property(project_bin PROJECT_BIN)
partition_table_get_partition_info(app_partition_offset "--partition-boot-default" "offset")
esptool_py_custom_target(app-flash app "app")
esptool_py_flash_target_image(app-flash app "${app_partition_offset}" "${build_dir}/${project_bin}")
esptool_py_flash_target_image(flash app "${app_partition_offset}" "${build_dir}/${project_bin}")
endif()
__esptool_py_setup_main_flash_target()
endif()
endif()
endfunction()
# idf_build_get_config