From d9389ba0828640a8a7fe058b6feee80169ba74ce Mon Sep 17 00:00:00 2001 From: Alexey Lapshin Date: Thu, 18 Sep 2025 12:48:50 +0700 Subject: [PATCH] change(bootloader): rename bootloader.ld -> bootloader.ld.in This change passes file through compiler preprocessor which unlocks future code refactoring. --- .../bootloader/subproject/CMakeLists.txt | 4 +- .../esp32/{bootloader.ld => bootloader.ld.in} | 3 + .../{bootloader.ld => bootloader.ld.in} | 3 + .../{bootloader.ld => bootloader.ld.in} | 3 + .../{bootloader.ld => bootloader.ld.in} | 3 + .../{bootloader.ld => bootloader.ld.in} | 3 + .../{bootloader.ld => bootloader.ld.in} | 3 + .../{bootloader.ld => bootloader.ld.in} | 3 + .../{bootloader.ld => bootloader.ld.in} | 3 + .../{bootloader.ld => bootloader.ld.in} | 3 + .../{bootloader.ld => bootloader.ld.in} | 3 + ...otloader.rev3.ld => bootloader.rev3.ld.in} | 3 + .../{bootloader.ld => bootloader.ld.in} | 3 + .../{bootloader.ld => bootloader.ld.in} | 3 + .../private_include/bootloader_init.h | 2 +- components/esp_system/CMakeLists.txt | 10 +- components/esp_system/ld/esp32s3/memory.ld.in | 2 +- components/esp_system/ld/ld.cmake | 57 ---------- tools/cmake/linker_script_preprocessor.cmake | 15 +++ tools/cmake/utilities.cmake | 104 +++++++++++++++++- tools/idf_py_actions/hints.yml | 3 + 21 files changed, 169 insertions(+), 67 deletions(-) rename components/bootloader/subproject/main/ld/esp32/{bootloader.ld => bootloader.ld.in} (99%) rename components/bootloader/subproject/main/ld/esp32c2/{bootloader.ld => bootloader.ld.in} (99%) rename components/bootloader/subproject/main/ld/esp32c3/{bootloader.ld => bootloader.ld.in} (99%) rename components/bootloader/subproject/main/ld/esp32c5/{bootloader.ld => bootloader.ld.in} (99%) rename components/bootloader/subproject/main/ld/esp32c6/{bootloader.ld => bootloader.ld.in} (99%) rename components/bootloader/subproject/main/ld/esp32c61/{bootloader.ld => bootloader.ld.in} (99%) rename components/bootloader/subproject/main/ld/esp32h2/{bootloader.ld => bootloader.ld.in} (99%) rename components/bootloader/subproject/main/ld/esp32h21/{bootloader.ld => bootloader.ld.in} (99%) rename components/bootloader/subproject/main/ld/esp32h4/{bootloader.ld => bootloader.ld.in} (99%) rename components/bootloader/subproject/main/ld/esp32p4/{bootloader.ld => bootloader.ld.in} (99%) rename components/bootloader/subproject/main/ld/esp32p4/{bootloader.rev3.ld => bootloader.rev3.ld.in} (99%) rename components/bootloader/subproject/main/ld/esp32s2/{bootloader.ld => bootloader.ld.in} (99%) rename components/bootloader/subproject/main/ld/esp32s3/{bootloader.ld => bootloader.ld.in} (99%) create mode 100644 tools/cmake/linker_script_preprocessor.cmake diff --git a/components/bootloader/subproject/CMakeLists.txt b/components/bootloader/subproject/CMakeLists.txt index e67ad30fb4..9909718b88 100644 --- a/components/bootloader/subproject/CMakeLists.txt +++ b/components/bootloader/subproject/CMakeLists.txt @@ -69,9 +69,9 @@ set(LD_DEFAULT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/main/ld/${IDF_TARGET}") idf_build_set_property(BOOTLOADER_LINKER_SCRIPT "${LD_DEFAULT_PATH}/bootloader.rom.ld" APPEND) project(bootloader) if(CONFIG_ESP32P4_REV_MIN_300) - target_linker_script("__idf_main" INTERFACE "${LD_DEFAULT_PATH}/bootloader.rev3.ld") + target_linker_script("__idf_main" INTERFACE "${LD_DEFAULT_PATH}/bootloader.rev3.ld.in") else() - target_linker_script("__idf_main" INTERFACE "${LD_DEFAULT_PATH}/bootloader.ld") + target_linker_script("__idf_main" INTERFACE "${LD_DEFAULT_PATH}/bootloader.ld.in") endif() idf_build_set_property(COMPILE_DEFINITIONS "BOOTLOADER_BUILD=1" APPEND) diff --git a/components/bootloader/subproject/main/ld/esp32/bootloader.ld b/components/bootloader/subproject/main/ld/esp32/bootloader.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32/bootloader.ld rename to components/bootloader/subproject/main/ld/esp32/bootloader.ld.in index facbf63f55..b08be78c8e 100644 --- a/components/bootloader/subproject/main/ld/esp32/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32/bootloader.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /* Linker file used to link the bootloader. */ diff --git a/components/bootloader/subproject/main/ld/esp32c2/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c2/bootloader.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32c2/bootloader.ld rename to components/bootloader/subproject/main/ld/esp32c2/bootloader.ld.in index 01be5ff6a1..6426ebe7c0 100644 --- a/components/bootloader/subproject/main/ld/esp32c2/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c2/bootloader.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. * diff --git a/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32c3/bootloader.ld rename to components/bootloader/subproject/main/ld/esp32c3/bootloader.ld.in index b7c8685ef1..641ba1ee59 100644 --- a/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. * diff --git a/components/bootloader/subproject/main/ld/esp32c5/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c5/bootloader.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32c5/bootloader.ld rename to components/bootloader/subproject/main/ld/esp32c5/bootloader.ld.in index 9738e41bda..a3cffd8790 100644 --- a/components/bootloader/subproject/main/ld/esp32c5/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c5/bootloader.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. * diff --git a/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32c6/bootloader.ld rename to components/bootloader/subproject/main/ld/esp32c6/bootloader.ld.in index 2b4daa233f..6daed3ff7d 100644 --- a/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. * diff --git a/components/bootloader/subproject/main/ld/esp32c61/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c61/bootloader.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32c61/bootloader.ld rename to components/bootloader/subproject/main/ld/esp32c61/bootloader.ld.in index cadd0fad16..b9a15e7008 100644 --- a/components/bootloader/subproject/main/ld/esp32c61/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c61/bootloader.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. * diff --git a/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld b/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32h2/bootloader.ld rename to components/bootloader/subproject/main/ld/esp32h2/bootloader.ld.in index c2acf37df6..a6205d9307 100644 --- a/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32h2/bootloader.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. * diff --git a/components/bootloader/subproject/main/ld/esp32h21/bootloader.ld b/components/bootloader/subproject/main/ld/esp32h21/bootloader.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32h21/bootloader.ld rename to components/bootloader/subproject/main/ld/esp32h21/bootloader.ld.in index 9774dbfac4..be42e5194d 100644 --- a/components/bootloader/subproject/main/ld/esp32h21/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32h21/bootloader.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. * diff --git a/components/bootloader/subproject/main/ld/esp32h4/bootloader.ld b/components/bootloader/subproject/main/ld/esp32h4/bootloader.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32h4/bootloader.ld rename to components/bootloader/subproject/main/ld/esp32h4/bootloader.ld.in index 093a7a8b78..385083fd51 100644 --- a/components/bootloader/subproject/main/ld/esp32h4/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32h4/bootloader.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. * diff --git a/components/bootloader/subproject/main/ld/esp32p4/bootloader.ld b/components/bootloader/subproject/main/ld/esp32p4/bootloader.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32p4/bootloader.ld rename to components/bootloader/subproject/main/ld/esp32p4/bootloader.ld.in index d3941b7e44..0610d48c9f 100644 --- a/components/bootloader/subproject/main/ld/esp32p4/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32p4/bootloader.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /** * Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. diff --git a/components/bootloader/subproject/main/ld/esp32p4/bootloader.rev3.ld b/components/bootloader/subproject/main/ld/esp32p4/bootloader.rev3.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32p4/bootloader.rev3.ld rename to components/bootloader/subproject/main/ld/esp32p4/bootloader.rev3.ld.in index b61b725c2c..2b85817068 100644 --- a/components/bootloader/subproject/main/ld/esp32p4/bootloader.rev3.ld +++ b/components/bootloader/subproject/main/ld/esp32p4/bootloader.rev3.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /** * Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. diff --git a/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld b/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32s2/bootloader.ld rename to components/bootloader/subproject/main/ld/esp32s2/bootloader.ld.in index 9bde08ceed..7f45e6fcb3 100644 --- a/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32s2/bootloader.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /* Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. */ diff --git a/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld b/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld.in similarity index 99% rename from components/bootloader/subproject/main/ld/esp32s3/bootloader.ld rename to components/bootloader/subproject/main/ld/esp32s3/bootloader.ld.in index 90514a6a7a..ea92b8e239 100644 --- a/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32s3/bootloader.ld.in @@ -3,6 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ + +#include "sdkconfig.h" + /** Simplified memory map for the bootloader. * Make sure the bootloader can load into main memory without overwriting itself. * diff --git a/components/bootloader_support/private_include/bootloader_init.h b/components/bootloader_support/private_include/bootloader_init.h index 22765a3f8d..54f5eb4851 100644 --- a/components/bootloader_support/private_include/bootloader_init.h +++ b/components/bootloader_support/private_include/bootloader_init.h @@ -14,7 +14,7 @@ extern "C" { /**@{*/ /** - * @brief labels from bootloader linker script: bootloader.ld + * @brief labels from bootloader linker script: bootloader.ld.in * */ extern int _bss_start; diff --git a/components/esp_system/CMakeLists.txt b/components/esp_system/CMakeLists.txt index 6ce27760f9..557f6ddc95 100644 --- a/components/esp_system/CMakeLists.txt +++ b/components/esp_system/CMakeLists.txt @@ -99,7 +99,15 @@ else() PROPERTIES COMPILE_FLAGS -fno-stack-protector) - include(${CMAKE_CURRENT_LIST_DIR}/ld/ld.cmake) + target_linker_script(${COMPONENT_LIB} INTERFACE "ld/${target}/memory.ld.in") + + # Generate sections.ld.in and pass it through linker script generator + set(sections_name "ld/${target}/sections.ld.in") + if(CONFIG_ESP32P4_REV_MIN_300) + set(sections_name "ld/${target}/sections.rev3.ld.in") + endif() + target_linker_script(${COMPONENT_LIB} INTERFACE "${sections_name}" + PROCESS "${CMAKE_CURRENT_BINARY_DIR}/ld/sections.ld") endif() if(CONFIG_IDF_ENV_FPGA OR CONFIG_ESP_BRINGUP_BYPASS_CPU_CLK_SETTING) diff --git a/components/esp_system/ld/esp32s3/memory.ld.in b/components/esp_system/ld/esp32s3/memory.ld.in index ba229c649b..5055aaf7f7 100644 --- a/components/esp_system/ld/esp32s3/memory.ld.in +++ b/components/esp_system/ld/esp32s3/memory.ld.in @@ -28,7 +28,7 @@ #define SRAM_IRAM_START 0x40370000 #define SRAM_DIRAM_I_START 0x40378000 -#define SRAM_IRAM_END 0x403CB700 /* Please refer to ESP32-S3 bootloader.ld for more information on this */ +#define SRAM_IRAM_END 0x403CB700 /* Please refer to ESP32-S3 bootloader linker script for more information on this */ #define I_D_SRAM_OFFSET (SRAM_DIRAM_I_START - SRAM_DRAM_START) #define SRAM_DRAM_START 0x3FC88000 diff --git a/components/esp_system/ld/ld.cmake b/components/esp_system/ld/ld.cmake index 7ddc776c9a..e69de29bb2 100644 --- a/components/esp_system/ld/ld.cmake +++ b/components/esp_system/ld/ld.cmake @@ -1,57 +0,0 @@ -idf_build_get_property(target IDF_TARGET) -idf_build_get_property(sdkconfig_header SDKCONFIG_HEADER) -idf_build_get_property(config_dir CONFIG_DIR) - -file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/ld") - -# Cmake script that generates linker script from "*.ld.in" scripts using compiler preprocessor -set(linker_script_generator "${CMAKE_CURRENT_BINARY_DIR}/ld/linker_script_generator.cmake") -file(WRITE ${linker_script_generator} -[=[ -execute_process(COMMAND "${CC}" "-C" "-P" "-x" "c" "-E" "-I" "${CONFIG_DIR}" "-I" "${LD_DIR}" "${SOURCE}" - RESULT_VARIABLE RET_CODE - OUTPUT_VARIABLE PREPROCESSED_LINKER_SCRIPT - ERROR_VARIABLE ERROR_VAR) -if(RET_CODE AND NOT RET_CODE EQUAL 0) - message(FATAL_ERROR "Can't generate ${TARGET}\nRET_CODE: ${RET_CODE}\nERROR_MESSAGE: ${ERROR_VAR}") -endif() -string(REPLACE "\\n" "\n" TEXT "${PREPROCESSED_LINKER_SCRIPT}") -file(WRITE "${TARGET}" "${TEXT}") -]=]) - -set(target_folder "${target}") - -function(preprocess_linker_file name_in name_out out_path) - set(script_in "${CMAKE_CURRENT_LIST_DIR}/${target_folder}/${name_in}") - set(script_out "${CMAKE_CURRENT_BINARY_DIR}/ld/${name_out}") - set(${out_path} ${script_out} PARENT_SCOPE) - - add_custom_command( - OUTPUT ${script_out} - COMMAND ${CMAKE_COMMAND} - "-DCC=${CMAKE_C_COMPILER}" - "-DSOURCE=${script_in}" - "-DTARGET=${script_out}" - "-DCONFIG_DIR=${config_dir}" - "-DLD_DIR=${CMAKE_CURRENT_LIST_DIR}" - -P "${linker_script_generator}" - MAIN_DEPENDENCY ${script_in} - DEPENDS ${sdkconfig_header} - COMMENT "Generating ${script_out} linker script..." - VERBATIM) - add_custom_target("${name_out}" DEPENDS "${script_out}") - add_dependencies(${COMPONENT_LIB} "${name_out}") -endfunction() - -# Generate memory.ld -preprocess_linker_file("memory.ld.in" "memory.ld" ld_out_path) -target_linker_script(${COMPONENT_LIB} INTERFACE "${ld_out_path}") - -# Generate sections.ld.in and pass it through linker script generator -if(CONFIG_ESP32P4_REV_MIN_300) - preprocess_linker_file("sections.rev3.ld.in" "sections.ld.in" ld_out_path) -else() - preprocess_linker_file("sections.ld.in" "sections.ld.in" ld_out_path) -endif() -target_linker_script(${COMPONENT_LIB} INTERFACE "${ld_out_path}" - PROCESS "${CMAKE_CURRENT_BINARY_DIR}/ld/sections.ld") diff --git a/tools/cmake/linker_script_preprocessor.cmake b/tools/cmake/linker_script_preprocessor.cmake new file mode 100644 index 0000000000..df06494a70 --- /dev/null +++ b/tools/cmake/linker_script_preprocessor.cmake @@ -0,0 +1,15 @@ +# Split CFLAGS string into list for proper argument passing +# Uses UNIX_COMMAND method because NATIVE_COMMAND has issues on Windows +# where the first argument is parsed specially, causing problems with quoted paths +# Note: Paths are expected to be quoted in the CFLAGS variable +separate_arguments(CFLAGS_LIST UNIX_COMMAND "${CFLAGS}") + +execute_process(COMMAND "${CC}" "-C" "-P" "-x" "c" "-E" ${CFLAGS_LIST} "${SOURCE}" + RESULT_VARIABLE RET_CODE + OUTPUT_VARIABLE PREPROCESSED_LINKER_SCRIPT + ERROR_VARIABLE ERROR_VAR) +if(RET_CODE AND NOT RET_CODE EQUAL 0) + message(FATAL_ERROR "Can't generate ${TARGET}\nRET_CODE: ${RET_CODE}\nERROR_MESSAGE: ${ERROR_VAR}") +endif() +string(REPLACE "\\n" "\n" TEXT "${PREPROCESSED_LINKER_SCRIPT}") +file(WRITE "${TARGET}" "${TEXT}") diff --git a/tools/cmake/utilities.cmake b/tools/cmake/utilities.cmake index 053ee1e7e8..dd244171ec 100644 --- a/tools/cmake/utilities.cmake +++ b/tools/cmake/utilities.cmake @@ -132,18 +132,112 @@ function(file_append_line file line) file(APPEND "${file}" "${line}${line_ending}") endfunction() -# Add one or more linker scripts to the target, including a link-time dependency +# Preprocess linker script using C preprocessor # -# Automatically adds a -L search path for the containing directory (if found), -# and then adds -T with the filename only. This allows INCLUDE directives to be -# used to include other linker scripts in the same directory. +# Processes .in linker script files through the C preprocessor to handle: +# - #include directives for modular linker scripts +# - #define macros and conditional compilation +# - Config-dependent linker script generation +# +# This function creates a custom command to preprocess the input script, +# determines the appropriate output path, and generates a CMake target for dependency tracking. +# +# Parameters: +# cmake_target - CMake target to add dependencies to +# script_in - Input .in file path (absolute) +# output_var - Variable name to store the resulting output path +# preserve_suffix - Whether to keep .in suffix in output filename (optional) +function(preprocess_linker_file cmake_target script_in output_var preserve_suffix) + set(output_dir "${CMAKE_CURRENT_BINARY_DIR}/ld") + # Ensure output directory exists + file(MAKE_DIRECTORY "${output_dir}") + + # Determine output filename with conditional .in suffix removal + get_filename_component(script_name "${script_in}" NAME) + set(script_out "${output_dir}/${script_name}") + + # Remove .in suffix if not preserving it + if(NOT preserve_suffix) + string(REGEX REPLACE "\\.in$" "" script_out "${script_out}") + endif() + + # Return the output path to caller + set(${output_var} "${script_out}" PARENT_SCOPE) + + # Get build properties + idf_build_get_property(sdkconfig_header SDKCONFIG_HEADER) + idf_build_get_property(config_dir CONFIG_DIR) + idf_build_get_property(idf_path IDF_PATH) + idf_build_get_property(idf_target IDF_TARGET) + + # Reference the linker script generator + set(linker_script_generator "${idf_path}/tools/cmake/linker_script_preprocessor.cmake") + + # check if the script_in parent directory is the name of the idf_target + get_filename_component(script_parent_dir "${script_in}" DIRECTORY) + get_filename_component(script_parent_name "${script_parent_dir}" NAME) + + # Initialize extra_cflags to avoid undefined variable + set(extra_cflags "") + + if(script_parent_name STREQUAL idf_target) + # Add "../.." directory to include path (e.g. for esp_system component) + get_filename_component(dir_to_include "${script_parent_dir}" DIRECTORY) + set(extra_cflags "-I\"${dir_to_include}\"") + endif() + + add_custom_command( + OUTPUT ${script_out} + COMMAND ${CMAKE_COMMAND} + "-DCC=${CMAKE_C_COMPILER}" + "-DSOURCE=${script_in}" + "-DTARGET=${script_out}" + "-DCFLAGS=-I\"${config_dir}\" ${extra_cflags}" + -P "${linker_script_generator}" + MAIN_DEPENDENCY ${script_in} + DEPENDS ${sdkconfig_header} + COMMENT "Preprocessing linker script ${script_in} -> ${script_out}" + VERBATIM) + + # Create target name based on script filename + string(MAKE_C_IDENTIFIER "${script_name}_preprocess" target_name) + add_custom_target("${target_name}" DEPENDS "${script_out}") + + add_dependencies(${cmake_target} "${target_name}") +endfunction() + +# Add one or more linker scripts to the target, including a link-time dependency. +# +# Core Features: +# - Adds -L search path for the containing directory (enables INCLUDE directives) +# - Adds -T with the filename only for linker command +# - Automatically preprocesses .in files using C preprocessor +# - Supports explicit PROCESS parameter to enable ldgen processing +# +# Parameters: +# target - Target to add linker scripts to +# deptype - Dependency type (PUBLIC, PRIVATE, INTERFACE) +# scriptfiles - List of linker script files (.ld, .ld.in, etc.) +# PROCESS - Optional: enable ldgen processing function(target_linker_script target deptype scriptfiles) cmake_parse_arguments(_ "" "PROCESS" "" ${ARGN}) foreach(scriptfile ${scriptfiles}) get_filename_component(abs_script "${scriptfile}" ABSOLUTE) message(STATUS "Adding linker script ${abs_script}") + # === SCRIPT PROCESSING PIPELINE === + # Stage 1: Auto-preprocess .in files (C preprocessor) + # Stage 2: Apply explicit template processing (ldgen templates) + + # Stage 1: Handle .in files with C preprocessor + if(abs_script MATCHES "\\.in$") + message(STATUS " -> Preprocessing .in script: ${abs_script}") + preprocess_linker_file("${target}" "${abs_script}" abs_script "${__PROCESS}") + endif() + + # Stage 2: Apply explicit ldgen template processing (if requested) if(__PROCESS) + message(STATUS " -> Applying ldgen processing: ${abs_script}") get_filename_component(output "${__PROCESS}" ABSOLUTE) __ldgen_process_template(${abs_script} ${output}) set(abs_script ${output}) @@ -165,7 +259,7 @@ function(target_linker_script target deptype scriptfiles) # For the time being, record all linker scripts in __LINK_DEPENDS and attach manually to # the executable target once it is known. if(NOT __PROCESS) - idf_build_set_property(__LINK_DEPENDS ${abs_script} APPEND) + idf_build_set_property(__LINK_DEPENDS "${abs_script}" APPEND) endif() endforeach() endfunction() diff --git a/tools/idf_py_actions/hints.yml b/tools/idf_py_actions/hints.yml index 4ea5775630..83f722edde 100644 --- a/tools/idf_py_actions/hints.yml +++ b/tools/idf_py_actions/hints.yml @@ -575,3 +575,6 @@ - re: "error: implicit declaration of function 'vPortCleanUpTCB'" hint: "The legacy FreeRTOS hook vPortCleanUpTCB() has been removed from ESP-IDF. Use CONFIG_FREERTOS_TASK_PRE_DELETION_HOOK with vTaskPreDeletionHook( void * pxTCB ) instead." + + re: "cannot open linker script file bootloader.ld" + hint: "The file 'bootloader.ld' was renamed to 'bootloader.ld.in' in ESP-IDF v6.0. Please use update your build scripts."