mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
Merge branch 'feat/cmakev2_bootloader' into 'master'
feat(cmakev2): build bootloader using the cmakev2 build system Closes IDF-15433 See merge request espressif/esp-idf!46465
This commit is contained in:
@@ -122,7 +122,6 @@ idf_build_get_property(extra_cmake_args EXTRA_CMAKE_ARGS)
|
||||
|
||||
# BOOTLOADER_EXTRA_COMPONENT_DIRS may have been set by the `main` component, do not overwrite it
|
||||
idf_build_get_property(bootloader_extra_component_dirs BOOTLOADER_EXTRA_COMPONENT_DIRS)
|
||||
list(APPEND bootloader_extra_component_dirs "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
# We cannot pass lists as a parameter to the external project without modifying the ';' separator
|
||||
string(REPLACE ";" "|" BOOTLOADER_IGNORE_EXTRA_COMPONENT "${BOOTLOADER_IGNORE_EXTRA_COMPONENT}")
|
||||
@@ -139,6 +138,7 @@ externalproject_add(bootloader
|
||||
-DEXTRA_COMPONENT_DIRS=${bootloader_extra_component_dirs}
|
||||
-DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR}
|
||||
-DIGNORE_EXTRA_COMPONENT=${BOOTLOADER_IGNORE_EXTRA_COMPONENT}
|
||||
-DIDF_BUILD_V2=${IDF_BUILD_V2}
|
||||
${sign_key_arg} ${ver_key_arg}
|
||||
${extra_cmake_args}
|
||||
INSTALL_COMMAND ""
|
||||
|
||||
@@ -15,6 +15,11 @@ if(NOT IDF_TARGET)
|
||||
"in by the parent build process.")
|
||||
endif()
|
||||
|
||||
if(IDF_BUILD_V2)
|
||||
include(CMakeLists_v2.txt)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# A number of these components are implemented as config-only when built in the bootloader
|
||||
set(COMPONENTS
|
||||
bootloader
|
||||
|
||||
@@ -0,0 +1,366 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Bootloader subproject CMakeLists (cmakev2 build system)
|
||||
#
|
||||
# This file drives the build of the ESP-IDF second-stage bootloader as a
|
||||
# standalone CMake sub-project that is invoked by the top-level build when
|
||||
# the project links against the `bootloader` component.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Extra component directories
|
||||
#
|
||||
# Users may supply custom bootloader components by placing them inside a
|
||||
# `bootloader_components/` directory at the root of their application
|
||||
# project. If the directory exists it is appended to EXTRA_COMPONENT_DIRS
|
||||
# so that the IDF component discovery logic can find them.
|
||||
#
|
||||
# IGNORE_EXTRA_COMPONENT (list) – optional variable that names individual
|
||||
# sub-directories of `bootloader_components/` to *exclude* from the build.
|
||||
# Each entry is turned into an absolute path and collected in
|
||||
# EXTRA_COMPONENT_EXCLUDE_DIRS which is consumed by the component resolver.
|
||||
# ---------------------------------------------------------------------------
|
||||
set(PROJECT_EXTRA_COMPONENTS "${PROJECT_SOURCE_DIR}/bootloader_components")
|
||||
if(EXISTS ${PROJECT_EXTRA_COMPONENTS})
|
||||
list(APPEND EXTRA_COMPONENT_DIRS "${PROJECT_EXTRA_COMPONENTS}")
|
||||
endif()
|
||||
|
||||
if(IGNORE_EXTRA_COMPONENT)
|
||||
# Prefix all entries of the list with ${PROJECT_EXTRA_COMPONENTS} absolute path
|
||||
list(TRANSFORM IGNORE_EXTRA_COMPONENT
|
||||
PREPEND "${PROJECT_EXTRA_COMPONENTS}/"
|
||||
OUTPUT_VARIABLE EXTRA_COMPONENT_EXCLUDE_DIRS)
|
||||
endif()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Include the cmakev2 IDF build framework
|
||||
# ---------------------------------------------------------------------------
|
||||
include("${IDF_PATH}/tools/cmakev2/idf.cmake")
|
||||
|
||||
project(bootloader C CXX ASM)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Bootloader-specific build properties set before project initialization
|
||||
# ---------------------------------------------------------------------------
|
||||
set(BOOTLOADER_BUILD 1)
|
||||
set(NON_OS_BUILD 1)
|
||||
idf_build_set_property(BOOTLOADER_BUILD "${BOOTLOADER_BUILD}")
|
||||
idf_build_set_property(NON_OS_BUILD "${NON_OS_BUILD}")
|
||||
# The bootloader subproject has a different set of components and hence
|
||||
# different Kconfig files. Do not regenerate the main project's sdkconfig.
|
||||
idf_build_set_property(GENERATE_SDKCONFIG 0)
|
||||
# Treat the bootloader subproject's own components (main/, components/) as
|
||||
# IDF components (priority 0) instead of the default project components
|
||||
# (priority 3). The bootloader's built-in components are provided by ESP-IDF
|
||||
# and should be overridable by user-supplied components placed in the
|
||||
# application's bootloader_components/ directory, which are discovered through
|
||||
# EXTRA_COMPONENT_DIRS (priority 2). The cmakev1 build system allowed this
|
||||
# override because it used a last-one-wins strategy. In cmakev2 with strict
|
||||
# priority-based resolution, project_components would always win and prevent
|
||||
# the override, so we downgrade them to idf_components priority.
|
||||
idf_build_set_property(PROJECT_COMPONENTS_SOURCE "idf_components")
|
||||
# Allow lazy optional component requirements evaluation for
|
||||
# `idf_component_optional_requires`. The bootloader uses a single ESP-IDF
|
||||
# library, and since it includes `esp_common`, this ensures that not all
|
||||
# components listed in `esp_common` as optional requirements are pulled into
|
||||
# the build.
|
||||
idf_build_set_property(IDF_COMPONENT_OPTIONAL_REQUIRES_MODE DEFERRED)
|
||||
# The bootloader uses its own compiler optimization flags
|
||||
# (CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_*) set below, not the app-level
|
||||
# CONFIG_COMPILER_OPTIMIZATION_* defaults.
|
||||
idf_build_set_property(SET_COMPILER_OPTIMIZATION NO)
|
||||
|
||||
# Perform internal IDF project initialisation
|
||||
idf_project_init()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Common component requirements
|
||||
# ---------------------------------------------------------------------------
|
||||
idf_build_get_property(idf_target_arch IDF_TARGET_ARCH)
|
||||
set(common_req log esp_rom esp_common esp_hw_support esp_libc ${idf_target_arch})
|
||||
idf_build_set_property(__COMPONENT_REQUIRES_COMMON "${common_req}")
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Compiler options and defines specific for bootloader
|
||||
# ---------------------------------------------------------------------------
|
||||
if(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
idf_build_set_property(COMPILE_OPTIONS "-Oz" APPEND)
|
||||
else()
|
||||
idf_build_set_property(COMPILE_OPTIONS "-Os" APPEND)
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
idf_build_set_property(COMPILE_OPTIONS "-freorder-blocks" APPEND)
|
||||
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
|
||||
idf_build_set_property(COMPILE_OPTIONS "-mno-target-align" APPEND)
|
||||
endif()
|
||||
endif()
|
||||
elseif(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_DEBUG)
|
||||
idf_build_set_property(COMPILE_OPTIONS "-Og" APPEND)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU" AND NOT CONFIG_IDF_TARGET_LINUX)
|
||||
# Disable shrink-wrapping to reduce binary size
|
||||
idf_build_set_property(COMPILE_OPTIONS "-fno-shrink-wrap" APPEND)
|
||||
endif()
|
||||
elseif(CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_PERF)
|
||||
idf_build_set_property(COMPILE_OPTIONS "-O2" APPEND)
|
||||
endif()
|
||||
|
||||
idf_build_set_property(COMPILE_DEFINITIONS "BOOTLOADER_BUILD=1" APPEND)
|
||||
idf_build_set_property(COMPILE_DEFINITIONS "NON_OS_BUILD=1" APPEND)
|
||||
idf_build_set_property(COMPILE_OPTIONS "-fno-stack-protector" APPEND)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Bootloader Linker script
|
||||
# ---------------------------------------------------------------------------
|
||||
set(LD_DEFAULT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/main/ld/${IDF_TARGET}")
|
||||
if(CONFIG_ESP32P4_SELECTS_REV_LESS_V3)
|
||||
idf_build_set_property(BOOTLOADER_LINKER_SCRIPT "${LD_DEFAULT_PATH}/bootloader.rev0_2.ld.in" APPEND)
|
||||
else()
|
||||
idf_build_set_property(BOOTLOADER_LINKER_SCRIPT "${LD_DEFAULT_PATH}/bootloader.ld.in" APPEND)
|
||||
endif()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build the bootloader ELF
|
||||
# ---------------------------------------------------------------------------
|
||||
idf_build_executable(bootloader_elf
|
||||
NAME bootloader
|
||||
COMPONENTS main
|
||||
MAPFILE_TARGET bootloader_mapfile)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Binary generation and post-build messages
|
||||
#
|
||||
# Collect tool command lists from the esptool_py component so that we can
|
||||
# assemble human-readable flash / key-management commands for the developer.
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build display strings for the post-build message
|
||||
idf_component_get_property(esptool_py_cmd esptool_py ESPTOOLPY_CMD)
|
||||
idf_component_get_property(main_args esptool_py FLASH_ARGS)
|
||||
idf_component_get_property(sub_args esptool_py FLASH_SUB_ARGS)
|
||||
idf_component_get_property(espsecure_py_cmd esptool_py ESPSECUREPY_CMD)
|
||||
idf_component_get_property(espefuse_py_cmd esptool_py ESPEFUSEPY_CMD)
|
||||
|
||||
# String for printing flash command
|
||||
string(REPLACE ";" " " esptoolpy_write_flash
|
||||
"${esptool_py_cmd} --port=(PORT) --baud=(BAUD) ${main_args} write-flash ${sub_args}")
|
||||
|
||||
string(REPLACE ";" " " espsecurepy "${espsecure_py_cmd}")
|
||||
string(REPLACE ";" " " espefusepy "${espefuse_py_cmd}")
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Guard: if binary generation is disabled or esptool_py is not part of the
|
||||
# build, there is no binary to produce and no flash commands to print, so we
|
||||
# stop here.
|
||||
# ---------------------------------------------------------------------------
|
||||
if(NOT CONFIG_APP_BUILD_GENERATE_BINARIES OR NOT TARGET idf::esptool_py)
|
||||
# Binaries should not be generated; there's nothing else to do.
|
||||
return()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# No secure boot
|
||||
#
|
||||
# Convert the ELF directly to a flat binary. The size check target
|
||||
# (idf_check_bootloader_size) verifies that the binary fits within the
|
||||
# region reserved for the bootloader in the partition table / flash layout.
|
||||
# idf_build_generate_metadata emits a JSON metadata file consumed by the
|
||||
# top-level build and flash tooling.
|
||||
# ---------------------------------------------------------------------------
|
||||
elseif(NOT CONFIG_SECURE_BOOT)
|
||||
# No bootloader signing is required
|
||||
idf_build_binary(bootloader_elf
|
||||
OUTPUT_FILE "${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||
TARGET bootloader_bin
|
||||
ALL)
|
||||
idf_check_bootloader_size(bootloader_bin)
|
||||
idf_build_generate_metadata(EXECUTABLE bootloader_elf)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Secure Boot V1
|
||||
#
|
||||
# Secure Boot V1 uses a symmetric HMAC-SHA256 key burned into eFuse. Two
|
||||
# sub-modes are supported:
|
||||
#
|
||||
# ONE_TIME_FLASH – the bootloader is flashed once and can never be
|
||||
# replaced on the same device. The developer is shown the exact
|
||||
# esptool.py command to use for the initial flash.
|
||||
#
|
||||
# REFLASHABLE – a symmetric key is derived from the private signing key
|
||||
# and burned into eFuse. Later reflashes are accepted only if the
|
||||
# bootloader image is bundled with a digest computed using the same
|
||||
# derived key. This mode requires generating the derived key file
|
||||
# (secure-bootloader-key-<N>.bin) from the project signing key, and a
|
||||
# bootloader digest image (bootloader-reflash-digest.bin) that prepends
|
||||
# the bootloader binary with the matching digest.
|
||||
# ---------------------------------------------------------------------------
|
||||
elseif(CONFIG_SECURE_BOOT_V1_ENABLED)
|
||||
|
||||
idf_build_binary(bootloader_elf
|
||||
OUTPUT_FILE "${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||
TARGET bootloader_bin
|
||||
ALL)
|
||||
idf_check_bootloader_size(bootloader_bin)
|
||||
idf_build_generate_metadata(EXECUTABLE bootloader_elf)
|
||||
|
||||
if(CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH)
|
||||
|
||||
idf_target_post_build_msg(bootloader_bin
|
||||
"=============================================================================="
|
||||
"Bootloader built. Secure boot enabled, so bootloader not flashed automatically."
|
||||
"One-time flash command is:"
|
||||
"\t${esptoolpy_write_flash} ${BOOTLOADER_OFFSET} ${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||
"* IMPORTANT: After first boot, BOOTLOADER CANNOT BE RE-FLASHED on same device"
|
||||
)
|
||||
|
||||
elseif(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
||||
|
||||
# Derived key length depends on encoding: 192-bit or 256-bit (default).
|
||||
if(CONFIG_SECURE_BOOTLOADER_KEY_ENCODING_192BIT)
|
||||
set(key_digest_len 192)
|
||||
else()
|
||||
set(key_digest_len 256)
|
||||
endif()
|
||||
|
||||
set(bootloader_digest_bin "${CMAKE_BINARY_DIR}/bootloader-reflash-digest.bin")
|
||||
set(secure_bootloader_key "${CMAKE_BINARY_DIR}/secure-bootloader-key-${key_digest_len}.bin")
|
||||
|
||||
# Derive the symmetric eFuse key from the ECDSA signing key.
|
||||
# The resulting binary is burned into the SECURE_BOOT_V1 eFuse block.
|
||||
add_custom_command(OUTPUT "${secure_bootloader_key}"
|
||||
COMMAND ${espsecure_py_cmd} digest-private-key
|
||||
--keylen "${key_digest_len}"
|
||||
--keyfile "${SECURE_BOOT_SIGNING_KEY}"
|
||||
"${secure_bootloader_key}"
|
||||
DEPENDS "${SECURE_BOOT_SIGNING_KEY}"
|
||||
VERBATIM)
|
||||
|
||||
if(NOT CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES AND NOT EXISTS "${secure_bootloader_key}")
|
||||
idf_die(
|
||||
"No pre-generated key for a reflashable secure bootloader is available, "
|
||||
"due to signing configuration."
|
||||
"\nTo generate one, you can use this command:"
|
||||
"\n\t${espsecurepy} generate-flash-encryption-key ${secure_bootloader_key}"
|
||||
"\nIf a signing key is present, then instead use:"
|
||||
"\n\t${espsecurepy} digest-private-key "
|
||||
"--keylen (192/256) --keyfile KEYFILE "
|
||||
"${secure_bootloader_key}")
|
||||
endif()
|
||||
|
||||
# Produce the reflash-digest image: the bootloader binary prefixed
|
||||
# with a digest computed using the derived symmetric key.
|
||||
add_custom_command(OUTPUT "${bootloader_digest_bin}"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "DIGEST ${bootloader_digest_bin}"
|
||||
COMMAND ${espsecure_py_cmd} digest-secure-bootloader --keyfile "${secure_bootloader_key}"
|
||||
-o "${bootloader_digest_bin}" "${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||
DEPENDS "${secure_bootloader_key}" bootloader_bin
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target(bootloader_digest_bin ALL DEPENDS "${bootloader_digest_bin}")
|
||||
|
||||
idf_target_post_build_msg(bootloader_bin
|
||||
"=============================================================================="
|
||||
"Bootloader built and secure digest generated."
|
||||
"Secure boot enabled, so bootloader not flashed automatically."
|
||||
"Burn secure boot key to efuse using:"
|
||||
"\t${espefusepy} burn-key secure_boot_v1 ${secure_bootloader_key}"
|
||||
"First time flash command is:"
|
||||
"\t${esptoolpy_write_flash} ${BOOTLOADER_OFFSET} ${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||
"=============================================================================="
|
||||
"To reflash the bootloader after initial flash:"
|
||||
"\t${esptoolpy_write_flash} 0x0 ${bootloader_digest_bin}"
|
||||
"=============================================================================="
|
||||
"* After first boot, only re-flashes of this kind (with same key) will be accepted."
|
||||
"* Not recommended to reuse the same secure boot keyfile on multiple production devices."
|
||||
)
|
||||
endif()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Secure Boot V2
|
||||
#
|
||||
# Secure Boot V2 uses asymmetric signing. The bootloader ELF is first created
|
||||
# as an *unsigned* flat binary; then, depending on
|
||||
# CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES, it is either signed in-place
|
||||
# (producing bootloader.bin) or left unsigned for the developer to sign
|
||||
# externally.
|
||||
#
|
||||
# Multiple signing keys – devices with more than one eFuse key digest slot
|
||||
# (CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS > 1) may have additional keys
|
||||
# appended to the signature block after the build; instructions for doing so
|
||||
# are printed in the post-build message.
|
||||
#
|
||||
# CONFIG_SECURE_BOOT_FLASH_BOOTLOADER_DEFAULT – when set, the bootloader is
|
||||
# flashed automatically by the normal flash target and no extra instructions
|
||||
# are needed, so the post-build message block is skipped.
|
||||
# ---------------------------------------------------------------------------
|
||||
elseif(CONFIG_SECURE_BOOT_V2_ENABLED)
|
||||
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
||||
# When signing during build, produce the raw binary as
|
||||
# bootloader-unsigned.bin and then sign it into bootloader.bin.
|
||||
set(bootloader_unsigned_bin "bootloader-unsigned.bin")
|
||||
else()
|
||||
# Without build-time signing, produce the binary directly as
|
||||
# bootloader.bin (matching v1 behavior). The user is expected
|
||||
# to sign it externally before flashing.
|
||||
set(bootloader_unsigned_bin "bootloader.bin")
|
||||
endif()
|
||||
|
||||
idf_build_binary(bootloader_elf
|
||||
OUTPUT_FILE "${CMAKE_BINARY_DIR}/${bootloader_unsigned_bin}"
|
||||
TARGET bootloader_unsigned_bin
|
||||
ALL)
|
||||
idf_check_bootloader_size(bootloader_unsigned_bin)
|
||||
|
||||
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
||||
if(NOT EXISTS "${SECURE_BOOT_SIGNING_KEY}")
|
||||
idf_die(
|
||||
"Secure Boot Signing Key Not found."
|
||||
"\nGenerate the Secure Boot V2 RSA-PSS 3072 Key."
|
||||
"\nTo generate one, you can use this command:"
|
||||
"\n\t${espsecurepy} generate-signing-key --version 2 your_key.pem"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Sign the unsigned binary with the configured signing key and
|
||||
# write the signed image to bootloader.bin.
|
||||
idf_sign_binary(bootloader_unsigned_bin
|
||||
OUTPUT_FILE "${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||
TARGET bootloader_signed_bin
|
||||
KEYFILE "${SECURE_BOOT_SIGNING_KEY}"
|
||||
ALL)
|
||||
idf_check_bootloader_size(bootloader_signed_bin)
|
||||
|
||||
set(post_build_target bootloader_signed_bin)
|
||||
else()
|
||||
# Signing will be performed externally; communicate this to the user.
|
||||
set(post_build_target bootloader_unsigned_bin)
|
||||
idf_target_post_build_msg(bootloader_unsigned_bin
|
||||
"Bootloader generated but not signed"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Emit post-build flash instructions. The message varies depending on
|
||||
# whether the device has multiple eFuse key digest slots and whether the
|
||||
# bootloader is flashed by default.
|
||||
if(CONFIG_SOC_EFUSE_SECURE_BOOT_KEY_DIGESTS GREATER 1
|
||||
AND NOT CONFIG_SECURE_BOOT_FLASH_BOOTLOADER_DEFAULT)
|
||||
idf_target_post_build_msg(${post_build_target}
|
||||
"=============================================================================="
|
||||
"Bootloader built. Secure boot enabled, so bootloader not flashed automatically."
|
||||
"To sign the bootloader with additional private keys."
|
||||
"\t${espsecurepy} sign-data -k secure_boot_signing_key2.pem -v 2 \
|
||||
--append-signatures -o signed_bootloader.bin build/bootloader/bootloader.bin"
|
||||
"Secure boot enabled, so bootloader not flashed automatically."
|
||||
"\t${esptoolpy_write_flash} ${BOOTLOADER_OFFSET} ${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||
"=============================================================================="
|
||||
)
|
||||
elseif(NOT CONFIG_SECURE_BOOT_FLASH_BOOTLOADER_DEFAULT)
|
||||
idf_target_post_build_msg(${post_build_target}
|
||||
"=============================================================================="
|
||||
"Bootloader built. Secure boot enabled, so bootloader not flashed automatically."
|
||||
"\t${esptoolpy_write_flash} ${BOOTLOADER_OFFSET} ${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||
"=============================================================================="
|
||||
)
|
||||
endif()
|
||||
|
||||
idf_build_generate_metadata(EXECUTABLE bootloader_elf)
|
||||
endif()
|
||||
@@ -70,6 +70,7 @@ if(CONFIG_ESP_ROM_REV0_HAS_NO_ECDSA_INTERFACE)
|
||||
endif()
|
||||
|
||||
if(BOOTLOADER_BUILD OR CONFIG_APP_BUILD_TYPE_RAM)
|
||||
set(priv_include_dirs)
|
||||
set(include_dirs "include" "bootloader_flash/include"
|
||||
"private_include")
|
||||
# micro-ecc is only needed for secure boot sources built under BOOTLOADER_BUILD.
|
||||
|
||||
@@ -10,7 +10,6 @@ if(BOOTLOADER_BUILD)
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_INCLUDE_DIRS ${private_include_dirs}
|
||||
REQUIRES ${reqs}
|
||||
PRIV_REQUIRES ${priv_reqs})
|
||||
|
||||
@@ -22,7 +21,6 @@ elseif(esp_tee_build)
|
||||
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS "include"
|
||||
PRIV_INCLUDE_DIRS ${private_include_dirs}
|
||||
REQUIRES ${reqs}
|
||||
PRIV_REQUIRES ${priv_reqs})
|
||||
|
||||
|
||||
@@ -24,14 +24,16 @@ else()
|
||||
"patches/esp_rom_efuse.c"
|
||||
"patches/esp_rom_gpio.c")
|
||||
|
||||
if(CONFIG_HEAP_TLSF_USE_ROM_IMPL AND CONFIG_ESP_ROM_TLSF_CHECK_PATCH)
|
||||
# This file shall be included in the build if TLSF in ROM is activated
|
||||
list(APPEND sources "patches/esp_rom_tlsf.c")
|
||||
endif()
|
||||
if(NOT BOOTLOADER_BUILD)
|
||||
if(CONFIG_HEAP_TLSF_USE_ROM_IMPL AND CONFIG_ESP_ROM_TLSF_CHECK_PATCH)
|
||||
# This file shall be included in the build if TLSF in ROM is activated
|
||||
list(APPEND sources "patches/esp_rom_tlsf.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_HEAP_TLSF_USE_ROM_IMPL AND CONFIG_ESP_ROM_MULTI_HEAP_WALK_PATCH)
|
||||
# This file shall be included in the build if TLSF in ROM is activated
|
||||
list(APPEND sources "patches/esp_rom_multi_heap.c")
|
||||
if(CONFIG_HEAP_TLSF_USE_ROM_IMPL AND CONFIG_ESP_ROM_MULTI_HEAP_WALK_PATCH)
|
||||
# This file shall be included in the build if TLSF in ROM is activated
|
||||
list(APPEND sources "patches/esp_rom_multi_heap.c")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND private_required_comp soc hal esp_hal_uart)
|
||||
|
||||
@@ -913,7 +913,8 @@ endfunction()
|
||||
|
||||
idf_build_binary(<executable>
|
||||
TARGET <target>
|
||||
OUTPUT_FILE <file>)
|
||||
OUTPUT_FILE <file>
|
||||
[ALL])
|
||||
|
||||
*executable[in]*
|
||||
|
||||
@@ -928,6 +929,10 @@ endfunction()
|
||||
|
||||
Output file path for storing the binary image file.
|
||||
|
||||
*ALL[in,opt]*
|
||||
|
||||
If specified, the target will be added to the default build target.
|
||||
|
||||
Create a binary image for the specified ``executable`` target and save it
|
||||
in the file specified with the ``OUTPUT_FILE`` option. A custom target
|
||||
named ``TARGET`` will be created for the generated binary image. The path
|
||||
@@ -936,7 +941,7 @@ endfunction()
|
||||
the ``TARGET``.
|
||||
#]]
|
||||
function(idf_build_binary executable)
|
||||
set(options)
|
||||
set(options ALL)
|
||||
set(one_value OUTPUT_FILE TARGET)
|
||||
set(multi_value)
|
||||
cmake_parse_arguments(ARG "${options}" "${one_value}" "${multi_value}" ${ARGN})
|
||||
@@ -990,8 +995,13 @@ function(idf_build_binary executable)
|
||||
COMMENT "Generating binary image '${binary_name}' from executable '${executable_name}'"
|
||||
)
|
||||
|
||||
# Create a custom target to generate the binary file
|
||||
add_custom_target(${ARG_TARGET} DEPENDS "${ARG_OUTPUT_FILE}")
|
||||
# Create a custom target to generate the binary file.
|
||||
# If ALL is specified, include the target in the default build.
|
||||
set(all_arg)
|
||||
if(ARG_ALL)
|
||||
set(all_arg ALL)
|
||||
endif()
|
||||
add_custom_target(${ARG_TARGET} ${all_arg} DEPENDS "${ARG_OUTPUT_FILE}")
|
||||
|
||||
# Store the path of the binary file in the BINARY_PATH property of the
|
||||
# custom binary target, which is used by the idf_flash_binary.
|
||||
@@ -1010,7 +1020,8 @@ endfunction()
|
||||
idf_sign_binary(<binary>
|
||||
TARGET <target>
|
||||
OUTPUT_FILE <file>
|
||||
[KEYFILE <file>])
|
||||
[KEYFILE <file>]
|
||||
[ALL])
|
||||
|
||||
*binary[in]*
|
||||
|
||||
@@ -1033,6 +1044,10 @@ endfunction()
|
||||
provided, the key file specified by the
|
||||
``CONFIG_SECURE_BOOT_SIGNING_KEY`` configuration option will be used.
|
||||
|
||||
*ALL[in,opt]*
|
||||
|
||||
If specified, the target will be added to the default build target.
|
||||
|
||||
Sign binary image specified by ``binary`` target with ``KEYFILE`` and save
|
||||
it in the file specified with the `OUTPUT_FILE` option. A custom target
|
||||
named ``TARGET`` will be created for the signed binary image. The path of
|
||||
@@ -1041,7 +1056,7 @@ endfunction()
|
||||
``TARGET``.
|
||||
#]]
|
||||
function(idf_sign_binary binary)
|
||||
set(options)
|
||||
set(options ALL)
|
||||
set(one_value OUTPUT_FILE TARGET KEYFILE)
|
||||
set(multi_value)
|
||||
cmake_parse_arguments(ARG "${options}" "${one_value}" "${multi_value}" ${ARGN})
|
||||
@@ -1067,7 +1082,7 @@ function(idf_sign_binary binary)
|
||||
endif()
|
||||
|
||||
if(ARG_KEYFILE)
|
||||
set(keyfle "${ARG_KEYFILE}")
|
||||
set(keyfile "${ARG_KEYFILE}")
|
||||
else()
|
||||
idf_build_get_property(project_dir PROJECT_DIR)
|
||||
get_filename_component(keyfile "${CONFIG_SECURE_BOOT_SIGNING_KEY}" ABSOLUTE BASE_DIR "${project_dir}")
|
||||
@@ -1097,7 +1112,13 @@ function(idf_sign_binary binary)
|
||||
VERBATIM
|
||||
COMMENT "Signing '${binary_name}' with key '${key_name}' into '${signed_binary_name}'"
|
||||
)
|
||||
add_custom_target(${ARG_TARGET} DEPENDS "${ARG_OUTPUT_FILE}")
|
||||
# Create a custom target for the signed binary file.
|
||||
# If ALL is specified, include the target in the default build.
|
||||
set(all_arg)
|
||||
if(ARG_ALL)
|
||||
set(all_arg ALL)
|
||||
endif()
|
||||
add_custom_target(${ARG_TARGET} ${all_arg} DEPENDS "${ARG_OUTPUT_FILE}")
|
||||
|
||||
# Store the path of the binary file in the BINARY_PATH property of the
|
||||
# custom signed binary target, which is used by the idf_flash_binary.
|
||||
@@ -1227,6 +1248,35 @@ function(idf_check_binary_size binary)
|
||||
add_dependencies("${binary}" "${binary}_check_size")
|
||||
endfunction()
|
||||
|
||||
#[[
|
||||
.. cmakev2:function:: idf_check_bootloader_size
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
idf_check_bootloader_size(<binary>)
|
||||
|
||||
*binary[in]*
|
||||
|
||||
Binary image target to which to add a bootloader size check. The
|
||||
``binary`` target is created by the :cmakev2:ref:`idf_build_binary` or
|
||||
:cmakev2:ref:`idf_sign_binary` function.
|
||||
|
||||
Ensure that the bootloader binary image does not overlap the partition
|
||||
table. The file path of the binary image should be stored in the
|
||||
``BINARY_PATH`` property of the ``binary`` target.
|
||||
#]]
|
||||
function(idf_check_bootloader_size binary)
|
||||
get_target_property(binary_path ${binary} BINARY_PATH)
|
||||
if(NOT binary_path)
|
||||
idf_die("Binary target '${binary}' is missing 'BINARY_PATH' property.")
|
||||
endif()
|
||||
|
||||
partition_table_add_check_bootloader_size_target("${binary}_check_size"
|
||||
DEPENDS "${binary_path}"
|
||||
BOOTLOADER_BINARY_PATH "${binary_path}")
|
||||
add_dependencies("${binary}" "${binary}_check_size")
|
||||
endfunction()
|
||||
|
||||
#[[
|
||||
.. cmakev2:function:: idf_check_binary_signed
|
||||
|
||||
|
||||
@@ -419,10 +419,14 @@ function(__init_common_components)
|
||||
|
||||
idf_build_get_property(idf_target IDF_TARGET)
|
||||
idf_build_get_property(idf_target_arch IDF_TARGET_ARCH)
|
||||
idf_build_get_property(explicit_requires_common __COMPONENT_REQUIRES_COMMON)
|
||||
|
||||
# Define common components that are included as dependencies for each
|
||||
# component.
|
||||
if("${idf_target}" STREQUAL "linux")
|
||||
if(explicit_requires_common)
|
||||
set(requires_common "${explicit_requires_common}")
|
||||
|
||||
elseif("${idf_target}" STREQUAL "linux")
|
||||
set(requires_common freertos esp_hw_support heap log soc hal esp_rom esp_common esp_system linux
|
||||
esp_stdio)
|
||||
else()
|
||||
|
||||
@@ -963,13 +963,17 @@ function(idf_component_include name)
|
||||
idf_die("Unsupported target type '${component_real_target_type}' in component '${component_name}'")
|
||||
endif()
|
||||
|
||||
idf_component_get_property(component_dir "${component_name}" COMPONENT_DIR)
|
||||
|
||||
idf_component_get_property(embed_files "${component_name}" EMBED_FILES)
|
||||
foreach(file IN LISTS embed_files)
|
||||
get_filename_component(file "${file}" ABSOLUTE BASE_DIR "${component_dir}")
|
||||
target_add_binary_data(${COMPONENT_TARGET} "${file}" "BINARY")
|
||||
endforeach()
|
||||
|
||||
idf_component_get_property(embed_txtfiles "${component_name}" EMBED_TXTFILES)
|
||||
foreach(file IN LISTS embed_txtfiles)
|
||||
get_filename_component(file "${file}" ABSOLUTE BASE_DIR "${component_dir}")
|
||||
target_add_binary_data(${COMPONENT_TARGET} "${file}" "TEXT")
|
||||
endforeach()
|
||||
|
||||
|
||||
+23
-1
@@ -362,12 +362,34 @@ endfunction()
|
||||
EXTRA_COMPONENT_EXCLUDE_DIRS
|
||||
List of paths to exclude from searching the component directories.
|
||||
|
||||
The ``PROJECT_COMPONENTS_SOURCE`` build property controls how the
|
||||
project's own components are categorised -- i.e. those discovered
|
||||
under ``CMAKE_CURRENT_SOURCE_DIR/main``,
|
||||
``CMAKE_CURRENT_SOURCE_DIR/components``, or the paths listed in
|
||||
``COMPONENT_DIRS``. It defaults to ``project_components``
|
||||
(priority 3 -- highest). Setting it to ``idf_components``
|
||||
(priority 0) makes them overridable by components supplied through
|
||||
``EXTRA_COMPONENT_DIRS`` (priority 2). This is useful for
|
||||
sub-projects whose built-in components are provided by ESP-IDF and
|
||||
should be overridable by user-supplied components.
|
||||
|
||||
Each component is initialized for every component directory found.
|
||||
#]]
|
||||
function(__init_components)
|
||||
idf_build_get_property(idf_path IDF_PATH)
|
||||
idf_build_get_property(prefix PREFIX)
|
||||
|
||||
idf_build_get_property(project_components_source PROJECT_COMPONENTS_SOURCE)
|
||||
if(NOT project_components_source)
|
||||
set(project_components_source "project_components")
|
||||
endif()
|
||||
|
||||
set(valid_sources "project_components" "idf_components")
|
||||
if(NOT project_components_source IN_LIST valid_sources)
|
||||
idf_die("Invalid PROJECT_COMPONENTS_SOURCE '${project_components_source}'."
|
||||
" Must be one of: ${valid_sources}")
|
||||
endif()
|
||||
|
||||
__get_component_paths(PATHS "${idf_path}/components"
|
||||
OUTPUT idf_components)
|
||||
if(COMPONENT_DIRS)
|
||||
@@ -404,7 +426,7 @@ function(__init_components)
|
||||
foreach(path IN LISTS project_components)
|
||||
__init_component(DIRECTORY "${path}"
|
||||
PREFIX "${prefix}"
|
||||
SOURCE "project_components")
|
||||
SOURCE "${project_components_source}")
|
||||
endforeach()
|
||||
|
||||
foreach(path IN LISTS project_extra_components)
|
||||
|
||||
@@ -57,6 +57,7 @@ function(__init_kconfig)
|
||||
idf_build_set_property(SDKCONFIG "${sdkconfig}")
|
||||
idf_build_set_property(__SDKCONFIG_ORIG "${sdkconfig}")
|
||||
idf_build_set_property(SDKCONFIG_DEFAULTS "${sdkconfig_defaults_checked}")
|
||||
idf_build_set_property(GENERATE_SDKCONFIG 1)
|
||||
|
||||
# Setup ESP-IDF root Kconfig and sdkconfig.rename files.
|
||||
idf_build_set_property(__ROOT_KCONFIG "${idf_path}/Kconfig")
|
||||
@@ -643,9 +644,13 @@ function(__generate_kconfig_outputs)
|
||||
--output header "${sdkconfig_header}"
|
||||
--output cmake "${sdkconfig_cmake}"
|
||||
--output json "${sdkconfig_json}"
|
||||
--output config "${sdkconfig}"
|
||||
)
|
||||
|
||||
idf_build_get_property(generate_sdkconfig GENERATE_SDKCONFIG)
|
||||
if(generate_sdkconfig)
|
||||
list(APPEND kconfgen_outputs_cmd --output config "${sdkconfig}")
|
||||
endif()
|
||||
|
||||
idf_build_set_property(__KCONFGEN_OUTPUTS_CMD "${kconfgen_outputs_cmd}")
|
||||
|
||||
# Generate Kconfig outputs using kconfgen
|
||||
|
||||
+26
-17
@@ -84,6 +84,7 @@ function(__init_project_configuration)
|
||||
set(link_options)
|
||||
|
||||
idf_build_get_property(idf_ver IDF_VER)
|
||||
idf_build_get_property(idf_path IDF_PATH)
|
||||
idf_build_get_property(idf_target IDF_TARGET)
|
||||
idf_build_get_property(component_interfaces COMPONENT_INTERFACES)
|
||||
idf_build_get_property(build_dir BUILD_DIR)
|
||||
@@ -186,24 +187,32 @@ function(__init_project_configuration)
|
||||
list(APPEND cxx_compile_options "-std=gnu++26")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_OPTIMIZATION_SIZE)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
list(APPEND compile_options "-Oz")
|
||||
else()
|
||||
list(APPEND compile_options "-Os")
|
||||
# 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)
|
||||
set(set_compiler_optimization YES)
|
||||
endif()
|
||||
if(set_compiler_optimization)
|
||||
if(CONFIG_COMPILER_OPTIMIZATION_SIZE)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
list(APPEND compile_options "-Oz")
|
||||
else()
|
||||
list(APPEND compile_options "-Os")
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
list(APPEND compile_options "-freorder-blocks")
|
||||
endif()
|
||||
elseif(CONFIG_COMPILER_OPTIMIZATION_DEBUG)
|
||||
list(APPEND compile_options "-Og")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU" AND NOT CONFIG_IDF_TARGET_LINUX)
|
||||
list(APPEND compile_options "-fno-shrink-wrap") # Disable shrink-wrapping to reduce binary size
|
||||
endif()
|
||||
elseif(CONFIG_COMPILER_OPTIMIZATION_NONE)
|
||||
list(APPEND compile_options "-O0")
|
||||
elseif(CONFIG_COMPILER_OPTIMIZATION_PERF)
|
||||
list(APPEND compile_options "-O2")
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
|
||||
list(APPEND compile_options "-freorder-blocks")
|
||||
endif()
|
||||
elseif(CONFIG_COMPILER_OPTIMIZATION_DEBUG)
|
||||
list(APPEND compile_options "-Og")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "GNU" AND NOT CONFIG_IDF_TARGET_LINUX)
|
||||
list(APPEND compile_options "-fno-shrink-wrap") # Disable shrink-wrapping to reduce binary size
|
||||
endif()
|
||||
elseif(CONFIG_COMPILER_OPTIMIZATION_NONE)
|
||||
list(APPEND compile_options "-O0")
|
||||
elseif(CONFIG_COMPILER_OPTIMIZATION_PERF)
|
||||
list(APPEND compile_options "-O2")
|
||||
endif()
|
||||
|
||||
if(CONFIG_COMPILER_CXX_EXCEPTIONS)
|
||||
|
||||
@@ -683,6 +683,31 @@ function(add_prefix var prefix)
|
||||
set(${var} "${newlist}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
#[[
|
||||
idf_target_post_build_msg(<target> <line>...)
|
||||
|
||||
*target[in]*
|
||||
|
||||
Target to attach the post-build message to.
|
||||
|
||||
*line[in]*
|
||||
|
||||
Message lines to print after the target is built.
|
||||
|
||||
Add a post-build step to ``<target>`` that prints the given message lines.
|
||||
The lines are joined with newlines, written to a file at configure time,
|
||||
and printed at build time using a single ``cmake -E cat`` command.
|
||||
#]]
|
||||
function(idf_target_post_build_msg target)
|
||||
string(MD5 hash "${ARGN}")
|
||||
set(msg_file "${CMAKE_CURRENT_BINARY_DIR}/_post_build_msg_${target}_${hash}.txt")
|
||||
list(JOIN ARGN "\n" msg)
|
||||
file(WRITE "${msg_file}" "${msg}\n")
|
||||
add_custom_command(TARGET ${target} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E cat "${msg_file}"
|
||||
VERBATIM)
|
||||
endfunction()
|
||||
|
||||
#[[
|
||||
fail_target(<target> <line0> [<line>...])
|
||||
|
||||
@@ -812,12 +837,7 @@ function(target_add_binary_data target embed_file embed_type)
|
||||
idf_build_get_property(build_dir BUILD_DIR)
|
||||
idf_build_get_property(idf_path IDF_PATH)
|
||||
|
||||
# The target_add_binary_data function is also called within the
|
||||
# idf_component_include function, which is not executed in the component
|
||||
# directory context. Therefore, ensure that the absolute path of the
|
||||
# embedded file is resolved relative to the component directory.
|
||||
idf_component_get_property(component_directory "${target}" COMPONENT_DIR)
|
||||
get_filename_component(embed_file "${embed_file}" ABSOLUTE BASE_DIR "${component_directory}")
|
||||
get_filename_component(embed_file "${embed_file}" ABSOLUTE)
|
||||
|
||||
get_filename_component(name "${embed_file}" NAME)
|
||||
set(embed_srcfile "${build_dir}/${name}.S")
|
||||
|
||||
Reference in New Issue
Block a user