Files
esp-idf/components/esp_psram/project_include.cmake
Frantisek Hrbata 534a7c0c96 feat(cmakev2): add IDF_CUSTOM_TOOLCHAIN for sub-projects with non-IDF toolchains
Sub-projects like ULP are built as external CMake projects via
externalproject_add() and may use toolchains that are completely
different from the IDF target toolchain. For example, the ULP RISC-V
co-processor on an xtensa target (ESP32-S2/S3) uses
riscv32-esp-elf-gcc while the main project uses xtensa-esp-elf-gcc.

This causes problems in cmakev2:

1. __init_toolchain() in idf.cmake validates that CMAKE_TOOLCHAIN_FILE
   matches IDF_TARGET and then overrides it. For sub-projects with
   custom toolchains (passed via -DCMAKE_TOOLCHAIN_FILE from the
   parent), this validation fails because the toolchain doesn't follow
   the IDF naming convention (toolchain-<target>.cmake).

2. Several component project_include.cmake files use functions from
   the IDF toolchain response file machinery (idf_toolchain_add_flags,
   idf_toolchain_remove_flags, idf_toolchain_rerun_abi_detection) that
   are not available in sub-projects with custom toolchains, or perform
   validation that assumes the IDF target toolchain is in use.

Introduce IDF_CUSTOM_TOOLCHAIN, a CMake variable passed via -D from
the parent build to indicate that the toolchain was provided externally
and should not be resolved or validated by the IDF build system.

When IDF_CUSTOM_TOOLCHAIN is set:
- __init_toolchain() records the pre-set CMAKE_TOOLCHAIN_FILE and
  skips IDF_TARGET-based resolution and validation.
- Component project_include.cmake files that manipulate IDF toolchain
  flags (xtensa, esp_libc, esp_psram, soc) return early, as those
  operations are not applicable to custom toolchains.

This is a generic mechanism usable by any sub-project that provides
its own toolchain (ULP, or any future sub-project with a non-IDF
toolchain).

Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
2026-07-14 16:54:57 +09:00

39 lines
2.0 KiB
CMake

if(IDF_CUSTOM_TOOLCHAIN)
return()
endif()
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()
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()