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
-7
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}")
+21 -22
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()
+1 -22
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)
+1 -22
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)
+1 -22
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)
+1 -23
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)
+1 -22
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)
+1 -23
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)
+1 -22
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)
+1 -22
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)
+1 -24
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)
+1 -24
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)
+1 -21
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)
+1 -21
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)
+85
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)
+157
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()
+54 -14
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()