Merge branch 'feature/dynamic_flags_in_toolchain_cmake_v6.0' into 'release/v6.0'

feat(build): propagate compiler flags from files to toolchain.cmake (v6.0)

See merge request espressif/esp-idf!43499
This commit is contained in:
Alexey Gerenkov
2025-11-21 16:19:34 +08:00
37 changed files with 576 additions and 357 deletions

21
Kconfig
View File

@@ -370,6 +370,27 @@ mainmenu "Espressif IoT Development Framework Configuration"
endchoice
config COMPILER_ENABLE_RISCV_ZCMP
bool "Enable RISCV ZCMP extension"
depends on SOC_CPU_ZCMP_WORKAROUND
default n
help
Enable the RISC-V ZCMP (Compressed Macro) extension to reduce binary size
by optimizing function prologue and epilogue sequences.
Note: Due to a hardware issue on some ESP32 chips (e.g., ESP32C5, ESP32C61,
ESP32H4), executing "cm.push" may re-enable interrupts even when global
interrupts are disabled (mstatus.mie = 0). This can cause unexpected interrupts
during CPU retention or within critical sections.
Workarounds are implemented in the IDF codebase. However, if user code
directly disables interrupts, additional actions may be required. Refer
to code examples under the SOC_CPU_ZCMP_WORKAROUND macro, or disable
the ZCMP extension for source files that contain functions which may
execute while mstatus.mie = 0.
Even with these workarounds, the issue may still affect dual-core variants.
choice COMPILER_OPTIMIZATION_ASSERTION_LEVEL
prompt "Assertion level"
default COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE

View File

@@ -205,17 +205,8 @@ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/include/soc/${target}")
)
endif()
if(CONFIG_ESP32P4_SELECTS_REV_LESS_V3)
if(CMAKE_C_COMPILER_ID MATCHES "GNU")
# 1. Set xespv2p1 explicitly to override the default xespv2p2.
# 2. Remove zc* extensions:
# The ESP32-P4 has always supported the zc* extensions,
# but revisions earlier than v3.0 are affected by hardware issue DIG-661
# and lack the mintthresh_csr register needed for the workaround.
idf_build_set_property(COMPILE_OPTIONS "-march=rv32imafc_zicsr_zifencei_zaamo_zalrsc_xesploop_xespv2p1" APPEND)
endif()
elseif(CONFIG_IDF_TARGET_ESP32P4)
if(CMAKE_C_COMPILER_ID MATCHES "Clang") # TODO: LLVM-478
if(NOT CONFIG_ESP32P4_SELECTS_REV_LESS_V3 AND CONFIG_IDF_TARGET_ESP32P4)
if(CMAKE_C_COMPILER_ID MATCHES "Clang") # TODO: LLVM-478 IDF-14338
message(FATAL_ERROR "ESP32-P4 rev. 3.0 or higher is not supported in Clang-based toolchain")
endif()
endif()

View File

@@ -136,8 +136,6 @@ if(CONFIG_LIBC_NEWLIB_NANO_FORMAT)
)
get_filename_component(libc_dir ${libc_dir} DIRECTORY)
target_link_directories(${COMPONENT_LIB} INTERFACE "${libc_dir}/nano")
else()
target_link_libraries(${COMPONENT_LIB} INTERFACE "--specs=nano.specs")
endif()
endif()

View File

@@ -1,3 +1,23 @@
if(CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND)
idf_build_set_property(COMPILE_OPTIONS "-mdisable-hardware-atomics" APPEND)
if(CONFIG_IDF_TOOLCHAIN_GCC)
if(CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND)
idf_toolchain_add_flags(COMPILE_OPTIONS "-mdisable-hardware-atomics")
else()
idf_toolchain_remove_flags(COMPILE_OPTIONS "-mdisable-hardware-atomics")
endif()
if(CONFIG_LIBC_PICOLIBC)
idf_toolchain_add_flags(COMPILE_OPTIONS "-specs=picolibc.specs")
else()
idf_toolchain_remove_flags(COMPILE_OPTIONS "-specs=picolibc.specs")
endif()
if(CONFIG_LIBC_NEWLIB_NANO_FORMAT)
idf_toolchain_add_flags(LINK_OPTIONS "--specs=nano.specs")
else()
idf_toolchain_remove_flags(LINK_OPTIONS "--specs=nano.specs")
endif()
else() # TODO IDF-14338
if(CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND)
idf_build_set_property(COMPILE_OPTIONS "-mdisable-hardware-atomics" APPEND)
endif()
endif()

View File

@@ -50,7 +50,8 @@ if(CONFIG_SPIRAM)
endif()
if(CONFIG_IDF_TARGET_ESP32 AND CONFIG_SPIRAM_CACHE_WORKAROUND AND NOT BOOTLOADER_BUILD)
# TODO IDF-14338
if(CONFIG_IDF_TOOLCHAIN_CLANG AND CONFIG_IDF_TARGET_ESP32 AND CONFIG_SPIRAM_CACHE_WORKAROUND AND NOT BOOTLOADER_BUILD)
# Note: Adding as a PUBLIC compile option here causes this option to propagate to all
# components that depend on esp_psram.
#

View File

@@ -1,17 +1,34 @@
if(CONFIG_IDF_TARGET_ESP32 AND CONFIG_SPIRAM_CACHE_WORKAROUND AND NOT BOOTLOADER_BUILD)
# We do this here as well as in CMakeLists.txt, because targets that
# are not part of the ESP-IDF build system (for cases where a generic
# non-IDF CMakeLists.txt file is imported into a component) don't depend
# on the esp32 component so don't get the extra flag. This handles that case.
idf_build_set_property(COMPILE_OPTIONS "-mfix-esp32-psram-cache-issue" APPEND)
# note that we don't need to set link options as the library linked is independent of this
if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST)
idf_build_set_property(COMPILE_OPTIONS "-mfix-esp32-psram-cache-strategy=dupldst" APPEND)
if(CONFIG_IDF_TOOLCHAIN_GCC)
# Remove all "-mfix-esp32-psram-cache*" from toolchain flags
# that may have appeared during configuration changes.
idf_toolchain_remove_flags(COMPILE_OPTIONS "-mfix-esp32-psram-cache")
if(CONFIG_IDF_TARGET_ESP32 AND CONFIG_SPIRAM_CACHE_WORKAROUND AND NOT BOOTLOADER_BUILD)
idf_toolchain_add_flags(COMPILE_OPTIONS "-mfix-esp32-psram-cache-issue")
if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST)
idf_toolchain_add_flags(COMPILE_OPTIONS "-mfix-esp32-psram-cache-strategy=dupldst")
endif()
if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_MEMW)
idf_toolchain_add_flags(COMPILE_OPTIONS "-mfix-esp32-psram-cache-strategy=memw")
endif()
if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_NOPS)
idf_toolchain_add_flags(COMPILE_OPTIONS "-mfix-esp32-psram-cache-strategy=nops")
endif()
endif()
if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_MEMW)
idf_build_set_property(COMPILE_OPTIONS "-mfix-esp32-psram-cache-strategy=memw" APPEND)
endif()
if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_NOPS)
idf_build_set_property(COMPILE_OPTIONS "-mfix-esp32-psram-cache-strategy=nops" APPEND)
else()
if(CONFIG_IDF_TARGET_ESP32 AND CONFIG_SPIRAM_CACHE_WORKAROUND AND NOT BOOTLOADER_BUILD)
# We do this here as well as in CMakeLists.txt, because targets that
# are not part of the ESP-IDF build system (for cases where a generic
# non-IDF CMakeLists.txt file is imported into a component) don't depend
# on the esp32 component so don't get the extra flag. This handles that case.
idf_build_set_property(COMPILE_OPTIONS "-mfix-esp32-psram-cache-issue" APPEND)
if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST)
idf_build_set_property(COMPILE_OPTIONS "-mfix-esp32-psram-cache-strategy=dupldst" APPEND)
endif()
if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_MEMW)
idf_build_set_property(COMPILE_OPTIONS "-mfix-esp32-psram-cache-strategy=memw" APPEND)
endif()
if(CONFIG_SPIRAM_CACHE_WORKAROUND_STRATEGY_NOPS)
idf_build_set_property(COMPILE_OPTIONS "-mfix-esp32-psram-cache-strategy=nops" APPEND)
endif()
endif()
endif()

View File

@@ -1,5 +0,0 @@
# avoid esp-clang "unused-command-line-argument" warning
if(NOT (CMAKE_C_COMPILER_ID MATCHES "Clang") )
set(compile_options "-nostartfiles")
idf_build_set_property(COMPILE_OPTIONS "${compile_options}" APPEND)
endif()

View File

@@ -487,6 +487,14 @@ config SOC_CPU_ZCMP_WORKAROUND
bool
default y
config SOC_CPU_ZCMP_PUSH_REVERSED
bool
default y
config SOC_CPU_ZCMP_POPRET_ISSUE
bool
default y
config SOC_DS_SIGNATURE_MAX_BIT_LEN
int
default 3072

View File

@@ -183,6 +183,8 @@
#define SOC_CPU_HAS_LOCKUP_RESET 1
#define SOC_CPU_ZCMP_WORKAROUND 1
#define SOC_CPU_ZCMP_PUSH_REVERSED 1
#define SOC_CPU_ZCMP_POPRET_ISSUE 1
/*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/
/** The maximum length of a Digital Signature in bits. */

View File

@@ -375,6 +375,14 @@ config SOC_CPU_ZCMP_WORKAROUND
bool
default y
config SOC_CPU_ZCMP_PUSH_REVERSED
bool
default y
config SOC_CPU_ZCMP_POPRET_ISSUE
bool
default y
config SOC_DMA_CAN_ACCESS_FLASH
bool
default y

View File

@@ -150,6 +150,8 @@
#define SOC_CPU_HAS_LOCKUP_RESET 1
#define SOC_CPU_ZCMP_WORKAROUND 1
#define SOC_CPU_ZCMP_PUSH_REVERSED 1
#define SOC_CPU_ZCMP_POPRET_ISSUE 1
/*-------------------------- DMA Common CAPS ----------------------------------------*/
#define SOC_DMA_CAN_ACCESS_FLASH 1 /*!< DMA can access Flash memory */

View File

@@ -247,10 +247,26 @@ config SOC_CPU_HAS_LOCKUP_RESET
bool
default y
config SOC_CPU_HAS_ZC_EXTENSIONS
bool
default y
config SOC_CPU_HAS_ZB_EXTENSIONS
bool
default y
config SOC_CPU_ZCMP_WORKAROUND
bool
default y
config SOC_CPU_ZCMP_PUSH_REVERSED
bool
default y
config SOC_CPU_ZCMP_POPRET_ISSUE
bool
default y
config SOC_DMA_CAN_ACCESS_FLASH
bool
default y

View File

@@ -175,7 +175,12 @@
#define SOC_HP_CPU_HAS_MULTIPLE_CORES 1 // Convenience boolean macro used to determine if a target has multiple cores.
#define SOC_CPU_HAS_LOCKUP_RESET 1
#define SOC_CPU_HAS_ZC_EXTENSIONS 1
#define SOC_CPU_HAS_ZB_EXTENSIONS 1
#define SOC_CPU_ZCMP_WORKAROUND 1
#define SOC_CPU_ZCMP_PUSH_REVERSED 1
#define SOC_CPU_ZCMP_POPRET_ISSUE 1
/*-------------------------- DMA Common CAPS ----------------------------------------*/
#define SOC_DMA_CAN_ACCESS_FLASH 1 /*!< DMA can access Flash memory */

View File

@@ -591,6 +591,18 @@ config SOC_CPU_HAS_LOCKUP_RESET
bool
default y
config SOC_CPU_HAS_ZC_EXTENSIONS
bool
default y
config SOC_CPU_ZCMP_PUSH_REVERSED
bool
default y
config SOC_CPU_ZCMP_POPRET_ISSUE
bool
default y
config SOC_SIMD_PREFERRED_DATA_ALIGNMENT
int
default 16

View File

@@ -209,6 +209,11 @@
#define SOC_CPU_HAS_LOCKUP_RESET 1
#define SOC_CPU_HAS_ZC_EXTENSIONS 1
#define SOC_CPU_ZCMP_PUSH_REVERSED 1
#define SOC_CPU_ZCMP_POPRET_ISSUE 1
#define SOC_SIMD_PREFERRED_DATA_ALIGNMENT 16 // The preferred data alignment accepted by the SIMD instructions, in bytes
/*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/

View File

@@ -0,0 +1,109 @@
if(CONFIG_IDF_TOOLCHAIN_GCC)
# Common flags
idf_toolchain_add_flags(LINK_OPTIONS "-nostartfiles")
# Target-specific flags
if(CONFIG_IDF_TARGET_ESP32)
idf_toolchain_add_flags(COMPILE_OPTIONS "-Wno-frame-address")
elseif(CONFIG_IDF_TARGET_ESP32C2 OR
CONFIG_IDF_TARGET_ESP32C3)
set(_march "rv32imc_zicsr_zifencei")
elseif(CONFIG_IDF_TARGET_ESP32C5 OR
CONFIG_IDF_TARGET_ESP32C6 OR
CONFIG_IDF_TARGET_ESP32C61 OR
CONFIG_IDF_TARGET_ESP32H2 OR
CONFIG_IDF_TARGET_ESP32H21)
set(_march "rv32imac_zicsr_zifencei_zaamo_zalrsc")
elseif(CONFIG_IDF_TARGET_ESP32H4)
set(_march "rv32imafcb_zicsr_zifencei_zaamo_zalrsc")
elseif(CONFIG_IDF_TARGET_ESP32P4)
set(_march "rv32imafc_zicsr_zifencei_zaamo_zalrsc")
elseif(NOT(CONFIG_IDF_TARGET_ESP32S2 OR CONFIG_IDF_TARGET_ESP32S3))
message(FATAL_ERROR "Unknown Espressif target: ${CONFIG_IDF_TARGET}")
endif()
# Architecture-specific flags
if(CONFIG_IDF_TARGET_ARCH_XTENSA)
idf_toolchain_add_flags(COMPILE_OPTIONS "-mlongcalls"
"-fno-builtin-memcpy"
"-fno-builtin-memset"
"-fno-builtin-bzero")
elseif(CONFIG_IDF_TARGET_ARCH_RISCV)
if(NOT DEFINED _march)
message(FATAL_ERROR "-march option is not defined for target ${CONFIG_IDF_TARGET}!")
endif()
# Clean compile options that were added by previous configurations and may be outdated
idf_toolchain_remove_flags(COMPILE_OPTIONS "-march="
"-mno-cm-push-reverse"
"-mno-cm-popret")
if(CONFIG_SOC_CPU_HAS_ZB_EXTENSIONS)
set(_march "${_march}_zba_zbb_zbs")
endif()
if((CONFIG_SOC_CPU_HAS_ZC_EXTENSIONS AND NOT CONFIG_SOC_CPU_ZCMP_WORKAROUND) OR
CONFIG_COMPILER_ENABLE_RISCV_ZCMP)
if(NOT CONFIG_ESP32P4_SELECTS_REV_LESS_V3)
set(_march "${_march}_zcb_zcmp_zcmt")
if(CONFIG_SOC_CPU_ZCMP_PUSH_REVERSED)
idf_toolchain_add_flags(COMPILE_OPTIONS "-mno-cm-push-reverse")
endif()
if(CONFIG_SOC_CPU_ZCMP_POPRET_ISSUE)
idf_toolchain_add_flags(COMPILE_OPTIONS "-mno-cm-popret")
endif()
endif()
endif()
if(CONFIG_SOC_CPU_HAS_HWLOOP)
set(_march "${_march}_xesploop")
endif()
if(CONFIG_SOC_CPU_HAS_PIE)
set(_march "${_march}_xespv")
if(CONFIG_ESP32P4_SELECTS_REV_LESS_V3)
set(_march "${_march}2p1")
endif()
endif()
if(CONFIG_SOC_CPU_HAS_DSP)
set(_march "${_march}_xespdsp")
endif()
# Set ABI and ARCH options
if(CONFIG_SOC_CPU_HAS_FPU)
idf_toolchain_add_flags(COMPILE_OPTIONS "-mabi=ilp32f")
endif()
idf_toolchain_add_flags(COMPILE_OPTIONS "-march=${_march}")
if(NOT CONFIG_SOC_CPU_MISALIGNED_ACCESS_ON_PMP_MISMATCH_ISSUE)
idf_toolchain_add_flags(COMPILE_OPTIONS "-mtune=esp-base")
endif()
else()
message(FATAL_ERROR "Unknown Espressif architecture: ${CONFIG_IDF_TARGET_ARCH}")
endif()
# Workaround: Re-run CMake compiler ABI detection after ABI flags are set.
#
# Problem: CMake performs compiler checks at an early stage during
# toolchain.cmake processing. At this early stage, response files are not yet
# ready, which causes CMake paths (e.g., CMAKE_<lang>_IMPLICIT_LINK_DIRECTORIES)
# to be incorrectly determined.
#
# Solution: Re-run the ABI detection after ABI flags are present to correctly
# determine these paths.
#
# Note: If the CMake API changes, this solution may need to be revised.
set(lang_ext_pairs "C|c" "CXX|cpp")
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
foreach(lang_ext ${lang_ext_pairs})
string(REPLACE "|" ";" lang_ext_parts ${lang_ext})
list(GET lang_ext_parts 0 lang)
list(GET lang_ext_parts 1 ext)
if(DEFINED CMAKE_${lang}_ABI_COMPILED)
unset(CMAKE_${lang}_ABI_COMPILED)
cmake_determine_compiler_abi(${lang} ${CMAKE_ROOT}/Modules/CMake${lang}CompilerABI.${ext})
endif()
endforeach()
endif()

View File

@@ -1054,10 +1054,6 @@ Obviously, there are cases where all these recipes are insufficient for a certai
- The second set of commands adds a library target, which points to the "imported" library file built by the external system. Some properties need to be set in order to add include directories and tell CMake where this file is.
- Finally, the generated library is added to `ADDITIONAL_CLEAN_FILES`_. This means ``make clean`` will delete this library. (Note that the other object files from the build won't be deleted.)
.. only:: esp32
.. note:: When using an external build process with PSRAM, remember to add ``-mfix-esp32-psram-cache-issue`` to the C compiler arguments. See :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND` for details of this flag.
.. _ADDITIONAL_CLEAN_FILES_note:

View File

@@ -91,6 +91,7 @@ The following configuration options reduces the final binary size of almost any
- Setting :ref:`CONFIG_ESP_SYSTEM_PANIC` to ``Silent reboot`` saves a small amount of binary size, however this is **only** recommended if no one will use UART output to debug the device.
:CONFIG_IDF_TARGET_ARCH_RISCV: - Setting :ref:`CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS` reduces binary size by replacing inlined prologues/epilogues with library calls.
- If the application binary uses only one of the security versions of the protocomm component, then the support for others can be disabled to save some code size. The support can be disabled through :ref:`CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_0`, :ref:`CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_1` or :ref:`CONFIG_ESP_PROTOCOMM_SUPPORT_SECURITY_VERSION_2` respectively.
:CONFIG_SOC_CPU_ZCMP_WORKAROUND: - Enable :ref:`CONFIG_COMPILER_ENABLE_RISCV_ZCMP` to reduce binary size by using compressed function prologues/epilogues. Read the :ref:`CONFIG_COMPILER_ENABLE_RISCV_ZCMP` notes carefully before enabling this option!
.. note::

View File

@@ -1054,10 +1054,6 @@ ESP-IDF 还支持自动生成链接脚本,它允许组件通过链接片段文
- 第二组命令添加了一个目标库,指向外部构建系统生成的库文件。为了添加 include 目录,并告知 CMake 该文件的位置,需要再设置一些属性。
- 最后,生成的库被添加到 `ADDITIONAL_MAKE_CLEAN_FILES`_ 中。即执行 ``make clean`` 后会删除该库。请注意,构建系统中的其他目标文件不会被删除。
.. only:: esp32
.. note:: 当外部构建系统使用 PSRAM 时,请记得将 ``-mfix-esp32-psram-cache-issue`` 添加到 C 编译器的参数中。关于该标志的更多详细信息,请参考 :ref:`CONFIG_SPIRAM_CACHE_WORKAROUND`
.. _ADDITIONAL_MAKE_CLEAN_FILES_note:

View File

@@ -7,7 +7,6 @@
#include "esp_log.h"
#include "esp_vfs_fat.h"
#include "tinyxml2.h"
#include "sdkconfig.h" // TODO IDF-11323: remove
static const char *TAG = "example";
@@ -30,12 +29,11 @@ extern "C" void app_main(void)
tinyxml2::XMLDocument data;
data.LoadFile("/spiflash/sample.xml");
#if !CONFIG_LIBC_PICOLIBC // TODO IDF-11323: subproject builds with default toolchain-esp*.cmake. No additional -specs=picolibc.specs applied
tinyxml2::XMLPrinter printer;
data.Print(&printer);
ESP_LOGI(TAG, "Read XML data:\n%s", printer.CStr());
#endif
const char* to_data = data.FirstChildElement("note")->FirstChildElement("to")->GetText();
const char* from_data = data.FirstChildElement("note")->FirstChildElement("from")->GetText();
const char* heading_data = data.FirstChildElement("note")->FirstChildElement("heading")->GetText();

View File

@@ -885,13 +885,6 @@ macro(project project_name)
unset(idf_target)
endif()
if(CONFIG_LIBC_PICOLIBC)
idf_build_set_property(C_COMPILE_OPTIONS "-specs=picolibc.specs" APPEND)
idf_build_set_property(CXX_COMPILE_OPTIONS "-specs=picolibcpp.specs" APPEND)
idf_build_set_property(LINK_OPTIONS "-specs=picolibc.specs" APPEND)
endif()
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY
ADDITIONAL_CLEAN_FILES
"${mapfile}" "${project_elf_src}")

View File

@@ -1,3 +1,4 @@
include(${CMAKE_CURRENT_LIST_DIR}/toolchain_flags.cmake)
#
# Get target from single sdkconfig file
#
@@ -71,7 +72,7 @@ endfunction()
# Set the target used for the standard project build.
#
macro(__target_init config_file)
# Input is IDF_TARGET environement variable
# Input is IDF_TARGET environment variable
set(env_idf_target $ENV{IDF_TARGET})
if(NOT env_idf_target)
@@ -129,30 +130,30 @@ macro(__target_set_toolchain)
set(env_idf_toolchain $ENV{IDF_TOOLCHAIN})
if(NOT env_idf_toolchain)
# IDF_TOOLCHAIN not set in environment, see if it is set in cache
if(IDF_TOOLCHAIN)
set(env_idf_toolchain ${IDF_TOOLCHAIN})
else()
set(env_idf_toolchain gcc)
endif()
elseif(DEFINED CACHE{IDF_TOOLCHAIN})
# IDF_TOOLCHAIN set both in environment and in cache, must be the same
if(NOT $CACHE{IDF_TOOLCHAIN} STREQUAL ${env_idf_toolchain})
message(FATAL_ERROR " IDF_TOOLCHAIN '$CACHE{IDF_TOOLCHAIN}' in CMake cache does not match"
" currently selected IDF_TOOLCHAIN '${env_idf_toolchain}'. To change the toolchain, clear"
" the build directory and sdkconfig file, and build the project again.")
set(env_idf_toolchain ${IDF_TOOLCHAIN})
if(NOT env_idf_toolchain)
set(env_idf_toolchain "gcc")
endif()
endif()
# Finally, set IDF_TOOLCHAIN in cache
set(IDF_TOOLCHAIN ${env_idf_toolchain} CACHE STRING "IDF Build Toolchain Type")
if(DEFINED CACHE{IDF_TOOLCHAIN} AND NOT "$CACHE{IDF_TOOLCHAIN}" STREQUAL "${env_idf_toolchain}")
# IDF_TOOLCHAIN set both in environment and in cache, must be the same
message(FATAL_ERROR " IDF_TOOLCHAIN '$CACHE{IDF_TOOLCHAIN}' in CMake cache does not match"
" currently selected IDF_TOOLCHAIN '${env_idf_toolchain}'. To change the toolchain, clear"
" the build directory and sdkconfig file, and build the project again.")
endif()
if(${env_idf_toolchain} STREQUAL "clang")
set(toolchain_type "clang-")
# TODO IDF-14338: remove the line below since it will be set in toolchain.cmake
set(IDF_TOOLCHAIN ${env_idf_toolchain} CACHE STRING "IDF Build Toolchain Type")
set(toolchain_filename "toolchain-clang-${IDF_TARGET}.cmake")
else()
set(toolchain_filename "toolchain-${IDF_TARGET}.cmake")
endif()
# Check if selected target is consistent with toolchain file in CMake cache
if(DEFINED CMAKE_TOOLCHAIN_FILE)
string(FIND "${CMAKE_TOOLCHAIN_FILE}" "-${toolchain_type}${IDF_TARGET}.cmake" found)
string(FIND "${CMAKE_TOOLCHAIN_FILE}" "${toolchain_filename}" found)
if(${found} EQUAL -1)
get_filename_component(toolchain "${CMAKE_TOOLCHAIN_FILE}" NAME_WE)
message(FATAL_ERROR " CMAKE_TOOLCHAIN_FILE '${toolchain}'"
@@ -162,11 +163,9 @@ macro(__target_set_toolchain)
endif()
endif()
# First try to load the toolchain file from the tools/cmake/directory of IDF
set(toolchain_file_global ${idf_path}/tools/cmake/toolchain-${toolchain_type}${IDF_TARGET}.cmake)
if(EXISTS ${toolchain_file_global})
set(CMAKE_TOOLCHAIN_FILE ${toolchain_file_global})
else()
message(FATAL_ERROR "Toolchain file ${toolchain_file_global} not found")
# Check if generated toolchain filepath is correct
set(CMAKE_TOOLCHAIN_FILE "${idf_path}/tools/cmake/${toolchain_filename}")
if(NOT EXISTS ${CMAKE_TOOLCHAIN_FILE})
message(FATAL_ERROR "Toolchain file ${CMAKE_TOOLCHAIN_FILE} not found")
endif()
endmacro()

View File

@@ -1,23 +1,2 @@
include($ENV{IDF_PATH}/tools/cmake/deduplicate_flags.cmake)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER xtensa-esp32-elf-gcc)
set(CMAKE_CXX_COMPILER xtensa-esp32-elf-g++)
set(CMAKE_ASM_COMPILER xtensa-esp32-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX xtensa-esp32-elf-)
set(_CMAKE_TOOLCHAIN_COMMON_FLAGS
"-mlongcalls -Wno-frame-address -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero")
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "ASM Compiler Base Flags" FORCE)
remove_duplicated_flags("-nostartfiles ${CMAKE_EXE_LINKER_FLAGS}" UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE)
include($ENV{IDF_PATH}/tools/cmake/toolchain.cmake)

View File

@@ -1,23 +1,2 @@
include($ENV{IDF_PATH}/tools/cmake/deduplicate_flags.cmake)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-)
set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imc_zicsr_zifencei")
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "Asm Compiler Base Flags" FORCE)
remove_duplicated_flags("-nostartfiles ${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}"
UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE)
include($ENV{IDF_PATH}/tools/cmake/toolchain.cmake)

View File

@@ -1,23 +1,2 @@
include($ENV{IDF_PATH}/tools/cmake/deduplicate_flags.cmake)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-)
set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imc_zicsr_zifencei")
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "Asm Compiler Base Flags" FORCE)
remove_duplicated_flags("-nostartfiles ${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}"
UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE)
include($ENV{IDF_PATH}/tools/cmake/toolchain.cmake)

View File

@@ -1,24 +1,2 @@
include($ENV{IDF_PATH}/tools/cmake/deduplicate_flags.cmake)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-)
set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imac_zicsr_zifencei_zaamo_zalrsc_zcb_zcmp_zcmt \
-mno-cm-popret -mno-cm-push-reverse")
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "Asm Compiler Base Flags" FORCE)
remove_duplicated_flags("-nostartfiles ${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}"
UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE)
include($ENV{IDF_PATH}/tools/cmake/toolchain.cmake)

View File

@@ -1,23 +1,2 @@
include($ENV{IDF_PATH}/tools/cmake/deduplicate_flags.cmake)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-)
set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imac_zicsr_zifencei_zaamo_zalrsc")
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "Asm Compiler Base Flags" FORCE)
remove_duplicated_flags("-nostartfiles ${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}"
UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE)
include($ENV{IDF_PATH}/tools/cmake/toolchain.cmake)

View File

@@ -1,24 +1,2 @@
include($ENV{IDF_PATH}/tools/cmake/deduplicate_flags.cmake)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-)
set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imac_zicsr_zifencei_zaamo_zalrsc_zcb_zcmp_zcmt \
-mno-cm-popret -mno-cm-push-reverse")
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "Asm Compiler Base Flags" FORCE)
remove_duplicated_flags("-nostartfiles ${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}"
UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE)
include($ENV{IDF_PATH}/tools/cmake/toolchain.cmake)

View File

@@ -1,23 +1,2 @@
include($ENV{IDF_PATH}/tools/cmake/deduplicate_flags.cmake)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-)
set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imac_zicsr_zifencei_zaamo_zalrsc")
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "Asm Compiler Base Flags" FORCE)
remove_duplicated_flags("-nostartfiles ${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}"
UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE)
include($ENV{IDF_PATH}/tools/cmake/toolchain.cmake)

View File

@@ -1,23 +1,2 @@
include($ENV{IDF_PATH}/tools/cmake/deduplicate_flags.cmake)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-)
set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imac_zicsr_zifencei_zaamo_zalrsc")
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "Asm Compiler Base Flags" FORCE)
remove_duplicated_flags("-nostartfiles ${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}"
UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE)
include($ENV{IDF_PATH}/tools/cmake/toolchain.cmake)

View File

@@ -1,25 +1,2 @@
include($ENV{IDF_PATH}/tools/cmake/deduplicate_flags.cmake)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-)
set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imafcb_zicsr_zifencei_zaamo_zalrsc_zcb_zcmp_zcmt_zba_zbb_zbs_xespdsp \
-mabi=ilp32f \
-mno-cm-popret -mno-cm-push-reverse")
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "Asm Compiler Base Flags" FORCE)
remove_duplicated_flags("-nostartfiles ${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}"
UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE)
include($ENV{IDF_PATH}/tools/cmake/toolchain.cmake)

View File

@@ -1,25 +1,2 @@
include($ENV{IDF_PATH}/tools/cmake/deduplicate_flags.cmake)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER riscv32-esp-elf-gcc)
set(CMAKE_CXX_COMPILER riscv32-esp-elf-g++)
set(CMAKE_ASM_COMPILER riscv32-esp-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX riscv32-esp-elf-)
set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-march=rv32imafc_zicsr_zifencei_zaamo_zalrsc_zcb_zcmp_zcmt_xesploop_xespv \
-mabi=ilp32f \
-mno-cm-popret -mno-cm-push-reverse")
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} -mtune=esp-base ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "Asm Compiler Base Flags" FORCE)
remove_duplicated_flags("-nostartfiles ${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}"
UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE)
include($ENV{IDF_PATH}/tools/cmake/toolchain.cmake)

View File

@@ -1,22 +1,2 @@
include($ENV{IDF_PATH}/tools/cmake/deduplicate_flags.cmake)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER xtensa-esp32s2-elf-gcc)
set(CMAKE_CXX_COMPILER xtensa-esp32s2-elf-g++)
set(CMAKE_ASM_COMPILER xtensa-esp32s2-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX xtensa-esp32s2-elf-)
set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-mlongcalls -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero")
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "ASM Compiler Base Flags" FORCE)
remove_duplicated_flags("-nostartfiles ${CMAKE_EXE_LINKER_FLAGS}" UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE)
include($ENV{IDF_PATH}/tools/cmake/toolchain.cmake)

View File

@@ -1,22 +1,2 @@
include($ENV{IDF_PATH}/tools/cmake/deduplicate_flags.cmake)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_C_COMPILER xtensa-esp32s3-elf-gcc)
set(CMAKE_CXX_COMPILER xtensa-esp32s3-elf-g++)
set(CMAKE_ASM_COMPILER xtensa-esp32s3-elf-gcc)
set(_CMAKE_TOOLCHAIN_PREFIX xtensa-esp32s3-elf-)
set(_CMAKE_TOOLCHAIN_COMMON_FLAGS "-mlongcalls -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero")
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_C_FLAGS}" UNIQ_CMAKE_C_FLAGS)
set(CMAKE_C_FLAGS "${UNIQ_CMAKE_C_FLAGS}" CACHE STRING "C Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_CXX_FLAGS}" UNIQ_CMAKE_CXX_FLAGS)
set(CMAKE_CXX_FLAGS "${UNIQ_CMAKE_CXX_FLAGS}" CACHE STRING "C++ Compiler Base Flags" FORCE)
remove_duplicated_flags("${_CMAKE_TOOLCHAIN_COMMON_FLAGS} ${CMAKE_ASM_FLAGS}" UNIQ_CMAKE_ASM_FLAGS)
set(CMAKE_ASM_FLAGS "${UNIQ_CMAKE_ASM_FLAGS}" CACHE STRING "ASM Compiler Base Flags" FORCE)
remove_duplicated_flags("-nostartfiles ${CMAKE_EXE_LINKER_FLAGS}" UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${UNIQ_CMAKE_SAFE_EXE_LINKER_FLAGS}" CACHE STRING "Linker Base Flags" FORCE)
include($ENV{IDF_PATH}/tools/cmake/toolchain.cmake)

View File

@@ -0,0 +1,85 @@
include(${CMAKE_CURRENT_LIST_DIR}/toolchain_flags.cmake)
if(NOT CMAKE_PARENT_LIST_FILE)
message(FATAL_ERROR "toolchain.cmake cannot be used standalone (use chip-specific toolchain file instead)")
endif()
# Paths normalization
get_filename_component(_idf_toolchain_dir "$ENV{IDF_PATH}/tools/cmake" REALPATH)
file(TO_CMAKE_PATH "${_idf_toolchain_dir}" _idf_toolchain_dir)
get_filename_component(_toolchain_filename "${CMAKE_TOOLCHAIN_FILE}" NAME)
get_filename_component(_current_toolchain_dir "${CMAKE_TOOLCHAIN_FILE}" DIRECTORY REALPATH)
file(TO_CMAKE_PATH "${_current_toolchain_dir}" _current_toolchain_dir)
set(CMAKE_SYSTEM_NAME Generic)
# Set compiler tools according to the toolchain type
string(FIND "${_toolchain_filename}" "clang" found_clang)
if(NOT found_clang EQUAL -1)
set(IDF_TOOLCHAIN "clang" CACHE STRING "IDF Build Toolchain Type" FORCE)
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_ASM_COMPILER clang)
set(CMAKE_LINKER ${_CMAKE_TOOLCHAIN_PREFIX}ld)
set(CMAKE_AR llvm-ar)
set(CMAKE_RANLIB llvm-ranlib)
set(CMAKE_OBJDUMP ${_CMAKE_TOOLCHAIN_PREFIX}objdump)
else()
set(IDF_TOOLCHAIN "gcc" CACHE STRING "IDF Build Toolchain Type" FORCE)
set(CMAKE_C_COMPILER ${_CMAKE_TOOLCHAIN_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${_CMAKE_TOOLCHAIN_PREFIX}g++)
set(CMAKE_ASM_COMPILER ${_CMAKE_TOOLCHAIN_PREFIX}gcc)
endif()
# Handle different execution contexts for the toolchain file.
# CMake may execute this toolchain file in different contexts:
#
# 1. First execution (IDF project build):
# When CMAKE_TOOLCHAIN_FILE points to IDF sources, the toolchain file is
# executed for the main project. In this case, we create the response files
# directory in the build directory, copy the toolchain file there, initialize
# the response files, and update CMAKE_TOOLCHAIN_FILE to point to the copy.
#
# 2. Subsequent executions (External project builds):
# When CMAKE_TOOLCHAIN_FILE points to a copied toolchain file (from a
# previous root project build), the response files already exist in the same
# directory as the toolchain file. We simply set IDF_TOOLCHAIN_BUILD_DIR to
# point to that existing directory.
if(_idf_toolchain_dir STREQUAL _current_toolchain_dir)
set(IDF_TOOLCHAIN_BUILD_DIR "${CMAKE_BINARY_DIR}/toolchain"
CACHE PATH "Path to toolchain build directory containing response files and toolchain file copy" FORCE)
# Copy toolchain file into the build directory and update CMAKE_TOOLCHAIN_FILE
# to point to the copy. This approach allows us to avoid worrying about different
# CMAKE_BINARY_DIR values between base IDF-project builds and external projects.
# For external project builds, compiler response files are located in the same
# directory as CMAKE_TOOLCHAIN_FILE, making them easy to find.
file(MAKE_DIRECTORY "${IDF_TOOLCHAIN_BUILD_DIR}")
file(COPY "${CMAKE_TOOLCHAIN_FILE}" DESTINATION "${IDF_TOOLCHAIN_BUILD_DIR}")
set(CMAKE_TOOLCHAIN_FILE "${IDF_TOOLCHAIN_BUILD_DIR}/${_toolchain_filename}")
# Create response files before CMake performs compiler checks.
# These files are required for the compiler detection process to succeed.
# The files are created even when the flag variables are empty, ensuring
# they exist when referenced by CMAKE_*_FLAGS variables below.
idf_toolchain_add_flags(C_COMPILE_OPTIONS "${CMAKE_C_FLAGS}"
CXX_COMPILE_OPTIONS "${CMAKE_CXX_FLAGS}"
ASM_COMPILE_OPTIONS "${CMAKE_ASM_FLAGS}"
LINK_OPTIONS "${CMAKE_EXE_LINKER_FLAGS}")
else()
set(IDF_TOOLCHAIN_BUILD_DIR "${_current_toolchain_dir}"
CACHE PATH "Path to toolchain build directory containing response files and toolchain file copy" FORCE)
endif()
# Configure CMake to use response files for compiler and linker flags.
# Some compilation options enabled by IDF configuration options are not yet
# defined at this very early CMake stage (toolchain.cmake execution). Response
# files allow these flags to be dynamically updated during the CMake configuration
# phase, after the options become available.
set(CMAKE_C_FLAGS "@\"${IDF_TOOLCHAIN_BUILD_DIR}/cflags\"" CACHE STRING "C Compiler Base Flags" FORCE)
set(CMAKE_CXX_FLAGS "@\"${IDF_TOOLCHAIN_BUILD_DIR}/cxxflags\"" CACHE STRING "C++ Compiler Base Flags" FORCE)
set(CMAKE_ASM_FLAGS "@\"${IDF_TOOLCHAIN_BUILD_DIR}/asmflags\"" CACHE STRING "Asm Compiler Base Flags" FORCE)
set(CMAKE_EXE_LINKER_FLAGS "@\"${IDF_TOOLCHAIN_BUILD_DIR}/ldflags\"" CACHE STRING "Linker Base Flags" FORCE)

View File

@@ -0,0 +1,157 @@
# Map option variable names to their corresponding file lists
set(_IDF_TOOLCHAIN_OPTION_MAPPINGS
"COMPILE_OPTIONS|cflags:cxxflags:asmflags"
"C_COMPILE_OPTIONS|cflags"
"CXX_COMPILE_OPTIONS|cxxflags"
"ASM_COMPILE_OPTIONS|asmflags"
"LINK_OPTIONS|ldflags"
)
# Extract keywords from mappings (drop substring after "|")
set(_IDF_TOOLCHAIN_MULTI_VALUE_KEYWORDS "")
foreach(mapping ${_IDF_TOOLCHAIN_OPTION_MAPPINGS})
string(REGEX REPLACE "\\|.*" "" keyword "${mapping}")
list(APPEND _IDF_TOOLCHAIN_MULTI_VALUE_KEYWORDS "${keyword}")
endforeach()
# Helper macro to process toolchain flag options based on mappings
# Uses macro instead of function to access parent scope variables directly
# operation: "add" or "remove"
macro(_process_toolchain_flag_options)
cmake_parse_arguments(PARSE_ARGV 0 "" "" "" "${_IDF_TOOLCHAIN_MULTI_VALUE_KEYWORDS}")
if(NOT EXISTS "${IDF_TOOLCHAIN_BUILD_DIR}")
message(FATAL_ERROR "Toolchain directory does not exist: ${IDF_TOOLCHAIN_BUILD_DIR}")
endif()
foreach(mapping ${_IDF_TOOLCHAIN_OPTION_MAPPINGS})
string(REPLACE "|" ";" mapping_list ${mapping})
# Extract option variable name and add underscore prefix
list(GET mapping_list 0 option_var)
set(option_var "_${option_var}")
# Extract file list for this option variable
list(GET mapping_list 1 files)
string(REPLACE ":" ";" files ${files})
# Process flags based on calling function: add or remove
if("${CMAKE_CURRENT_FUNCTION}" MATCHES "add_flags" AND DEFINED ${option_var})
_add_flags_to_files("${files}" "${${option_var}}")
endif()
if("${CMAKE_CURRENT_FUNCTION}" MATCHES "remove_flags" AND ${option_var})
_remove_flags_from_files("${files}" "${${option_var}}")
endif()
endforeach()
endmacro()
# Helper function to remove flags matching patterns from specific files
function(_remove_flags_from_files files patterns)
foreach(file ${files})
set(file_path "${IDF_TOOLCHAIN_BUILD_DIR}/${file}")
if(EXISTS "${file_path}")
file(STRINGS "${file_path}" existing_lines)
else()
set(existing_lines "")
endif()
file(WRITE "${file_path}" "")
foreach(line ${existing_lines})
set(should_keep TRUE)
foreach(pattern ${patterns})
if("${line}" MATCHES "${pattern}")
set(should_keep FALSE)
break()
endif()
endforeach()
if(should_keep)
file(APPEND "${file_path}" "${line}\n")
endif()
endforeach()
endforeach()
endfunction()
# Helper function to add flags to specific files
function(_add_flags_to_files files flags)
foreach(file ${files})
set(file_path "${IDF_TOOLCHAIN_BUILD_DIR}/${file}")
if(EXISTS "${file_path}")
file(STRINGS "${file_path}" existing_lines)
else()
set(existing_lines "")
endif()
# Split flags string using regex to respect quotes.
# Matches: double-quoted strings, single-quoted strings, or unquoted space-delimited tokens.
#
# TODO IDF-14467:
# Currently, paired linker flags are not properly handled when filtering.
# The regex-based splitting treats each flag independently, which breaks
# flag pairs that must be kept together. Future enhancement should support
# the following paired flag constructs:
# - --start-group ... --end-group
# - --push-state ... --pop-state
# - --whole-archive ... --no-whole-archive
# - --as-needed ... --no-as-needed
# - --push-section ... --pop-section
string(REGEX MATCHALL "([^\\s\"']*(\"[^\"]*\"|'[^']*')|\"[^\"]*\"|'[^']*'|[^ \"']+)" flags "${flags}")
file(WRITE "${file_path}" "")
foreach(line ${existing_lines})
set(should_keep TRUE)
foreach(flag ${flags})
if("${line}" STREQUAL "${flag}")
set(should_keep FALSE)
break()
endif()
endforeach()
if(should_keep)
file(APPEND "${file_path}" "${line}\n")
endif()
endforeach()
foreach(flag ${flags})
# Skip flags that contain IDF_TOOLCHAIN_BUILD_DIR substring
# to avoid recursion
string(FIND "${flag}" "${IDF_TOOLCHAIN_BUILD_DIR}" found_pos)
if(found_pos EQUAL -1)
file(APPEND "${file_path}" "${flag}\n")
endif()
endforeach()
endforeach()
endfunction()
# idf_toolchain_add_flags
#
# @brief Add compiler or linker flags to the toolchain configuration files.
#
# This function adds flags to the appropriate toolchain response files (cflags, cxxflags,
# asmflags, or ldflags) in the IDF_TOOLCHAIN_BUILD_DIR directory. Duplicate flags
# are automatically removed before adding new ones.
#
# @param[in, optional] COMPILE_OPTIONS (multivalue) flags to add to C, C++, and ASM
# compilation. Applied to cflags, cxxflags, and asmflags files.
# @param[in, optional] C_COMPILE_OPTIONS (multivalue) flags to add to C compilation only.
# Applied to cflags file.
# @param[in, optional] CXX_COMPILE_OPTIONS (multivalue) flags to add to C++ compilation only.
# Applied to cxxflags file.
# @param[in, optional] ASM_COMPILE_OPTIONS (multivalue) flags to add to ASM compilation only.
# Applied to asmflags file.
# @param[in, optional] LINK_OPTIONS (multivalue) flags to add to linking.
# Applied to ldflags file.
#
# @note Multiple keyword arguments can be specified in a single call.
# @note Flags are deduplicated - if a flag already exists in the file, it will be
# removed before adding the new one to ensure no duplicates.
#
# Example:
# idf_toolchain_add_flags(COMPILE_OPTIONS "-Wall" "-Wextra")
# idf_toolchain_add_flags(C_COMPILE_OPTIONS "-std=c99" LINK_OPTIONS "-Wl,--gc-sections")
function(idf_toolchain_add_flags)
_process_toolchain_flag_options()
endfunction()
function(idf_toolchain_remove_flags)
_process_toolchain_flag_options()
endfunction()

View File

@@ -51,6 +51,58 @@ def test_build_custom_cmake_project_host() -> None:
run_cmake_and_build(str(idf_path / 'examples' / 'build_system' / 'cmake' / 'idf_as_lib'), '-G', 'Ninja')
@pytest.mark.buildv2_skip('import_lib example uses cmakev1, not yet updated for buildv2 (IDF-14185)')
def test_build_cmake_library_with_toolchain_flags(test_app_copy: Path) -> None:
logging.info('Building a project with CMake library imported with modified toolchain flags')
idf_path = Path(os.environ['IDF_PATH'])
# Enable Picolibc to verify that all flags are passed correctly to the external project.
# In case something is missing, the build will fail on linking stage.
# Note: To enable Picolibc, IDF_EXPERIMENTAL_FEATURES must also be set for now.
(test_app_copy / 'sdkconfig.defaults').write_text(
'\n'.join(['CONFIG_IDF_EXPERIMENTAL_FEATURES=y', 'CONFIG_LIBC_PICOLIBC=y'])
)
import_lib_path = idf_path / 'examples' / 'build_system' / 'cmake' / 'import_lib'
run_cmake_and_build(
str(import_lib_path),
'-G',
'Ninja',
f'-DSDKCONFIG_DEFAULTS={import_lib_path / "sdkconfig.defaults"};{test_app_copy / "sdkconfig.defaults"}',
)
def check_flag_in_compile_commands(build_dir: Path, flag_to_find: str) -> None:
with open(build_dir / 'build' / 'compile_commands.json', encoding='utf-8') as f:
compile_commands = json.load(f)
# check if compile_commands is an array
if not isinstance(compile_commands, list):
assert False, f'compile_commands is not a list: {compile_commands}'
assert len(compile_commands) != 0, 'compile_commands is empty'
for entry in compile_commands:
command = entry['command']
assert isinstance(command, str), f'command is not a string: {command}'
flag_is_found = flag_to_find in command
if flag_is_found:
continue # Flag found in command, no need to check response files
# check if command contains response file paths starts with @
response_file_paths = re.findall(r'@([^\s]+)', command)
for response_file_path in response_file_paths:
# check if the flag file contains flag_to_find
try:
# Strip surrounding quotes and normalize the path
response_file_path = response_file_path.strip('"\'\\')
response_file_path = Path(response_file_path).resolve()
with open(response_file_path, encoding='utf-8') as f:
flags = f.read()
if flag_to_find in flags:
flag_is_found = True
break
except FileNotFoundError:
assert False, f'{response_file_path} does not exist'
if not flag_is_found:
assert False, f'{flag_to_find} not found in {command}'
@pytest.mark.buildv2_skip('import_lib example uses cmakev1, not yet updated for buildv2 (IDF-14185)')
def test_build_cmake_library_psram_workaround(test_app_copy: Path) -> None:
logging.info(
@@ -67,13 +119,7 @@ def test_build_cmake_library_psram_workaround(test_app_copy: Path) -> None:
'-DSDKCONFIG_DEFAULTS={}'.format(test_app_copy / 'sdkconfig.defaults'),
str(idf_path / 'examples' / 'build_system' / 'cmake' / 'import_lib'),
)
with open((test_app_copy / 'build' / 'compile_commands.json'), encoding='utf-8') as f:
data = f.read()
res = re.findall(r'.*\"command\".*', data)
for r in res:
assert 'mfix-esp32-psram-cache-issue' in r, (
'All commands in compile_commands.json should use PSRAM cache workaround'
)
check_flag_in_compile_commands(test_app_copy, '-mfix-esp32-psram-cache-issue')
def test_build_cmake_library_psram_strategies(idf_py: IdfPyFunc, test_app_copy: Path) -> None:
@@ -97,13 +143,7 @@ def test_build_cmake_library_psram_strategies(idf_py: IdfPyFunc, test_app_copy:
)
)
idf_py('reconfigure')
with open((test_app_copy / 'build' / 'compile_commands.json'), encoding='utf-8') as f:
data = f.read()
res = re.findall(r'.*\"command\".*', data)
for r in res:
assert f'mfix-esp32-psram-cache-strategy={strategy.lower()}' in r, (
'All commands in compile_commands.json should use PSRAM cache workaround strategy'
)
check_flag_in_compile_commands(test_app_copy, f'-mfix-esp32-psram-cache-strategy={strategy.lower()}')
(test_app_copy / 'sdkconfig').unlink()