From 3e162786cb1dfb0c042c7108d64a7efa5ab3e10a Mon Sep 17 00:00:00 2001 From: morris Date: Mon, 20 Jul 2026 12:44:18 +0800 Subject: [PATCH] feat(build): support aligned embedded binary data Allow callers to align embedded binary start symbols for DMA-capable assets. --- docs/en/api-guides/build-system.rst | 4 ++++ docs/zh_CN/api-guides/build-system.rst | 4 ++++ .../cmakev2/get-started/hello_world/README.md | 2 +- tools/cmake/scripts/data_file_embed_asm.cmake | 3 +++ tools/cmake/utilities.cmake | 18 +++++++++++++-- tools/cmakev2/utilities.cmake | 23 +++++++++++++++++-- 6 files changed, 49 insertions(+), 5 deletions(-) diff --git a/docs/en/api-guides/build-system.rst b/docs/en/api-guides/build-system.rst index ac57d66a3e9..3f10f099fc2 100644 --- a/docs/en/api-guides/build-system.rst +++ b/docs/en/api-guides/build-system.rst @@ -996,6 +996,10 @@ To embed a file into a project, rather than a component, you can call the functi Place this line after the ``project()`` line in your project CMakeLists.txt file. Replace ``myproject.elf`` with your project name. The final argument can be ``TEXT`` to embed a null-terminated string, or ``BINARY`` to embed the content as-is. +Use the optional ``ALIGN`` argument to align the embedded data's start symbol to a positive power of two. For example, to align binary data to 16 bytes:: + + target_add_binary_data(myproject.elf "main/data.bin" BINARY ALIGN 16) + For an example of using this technique, see the "main" component of the file_serving example :example_file:`protocols/http_server/file_serving/main/CMakeLists.txt` - two files are loaded at build time and linked into the firmware. .. highlight:: cmake diff --git a/docs/zh_CN/api-guides/build-system.rst b/docs/zh_CN/api-guides/build-system.rst index b3f72737849..9e4c577ca67 100644 --- a/docs/zh_CN/api-guides/build-system.rst +++ b/docs/zh_CN/api-guides/build-system.rst @@ -996,6 +996,10 @@ CMake 文件可以使用 ``IDF_TARGET`` 变量来获取当前的硬件目标。 并将这行代码放在项目 CMakeLists.txt 的 ``project()`` 命令之后,修改 ``myproject.elf`` 为你自己的项目名。如果最后一个参数是 ``TEXT``,那么构建系统会嵌入以 null 结尾的字符串,如果最后一个参数被设置为 ``BINARY``,则将文件内容按照原样嵌入。 +可选的 ``ALIGN`` 参数用于将嵌入数据的起始符号对齐到指定的正整数 2 的幂。例如,将二进制数据按 16 字节对齐:: + + target_add_binary_data(myproject.elf "main/data.bin" BINARY ALIGN 16) + 有关使用此技术的示例,请查看 file_serving 示例 :example_file:`protocols/http_server/file_serving/main/CMakeLists.txt` 中的 main 组件,两个文件会在编译时加载并链接到固件中。 .. highlight:: cmake diff --git a/examples/build_system/cmakev2/get-started/hello_world/README.md b/examples/build_system/cmakev2/get-started/hello_world/README.md index 63693a0cbf2..16366d1fb98 100644 --- a/examples/build_system/cmakev2/get-started/hello_world/README.md +++ b/examples/build_system/cmakev2/get-started/hello_world/README.md @@ -34,7 +34,7 @@ Below is short explanation of remaining files in the project folder. └── README.md This is the file you are currently reading ``` -For more information on structure and contents of ESP-IDF projects, please refer to Section [Build System v2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system-v2.html) of the ESP-IDF Programming Guide. +For more information on structure and contents of ESP-IDF projects, please refer to Section [Build System v2](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/build-system-v2/index.html) of the ESP-IDF Programming Guide. ## Troubleshooting diff --git a/tools/cmake/scripts/data_file_embed_asm.cmake b/tools/cmake/scripts/data_file_embed_asm.cmake index 5d19e7a1ba9..b8612976894 100644 --- a/tools/cmake/scripts/data_file_embed_asm.cmake +++ b/tools/cmake/scripts/data_file_embed_asm.cmake @@ -74,6 +74,9 @@ append_line(".data") append_line("#if !defined (__APPLE__) && !defined (__linux__)") append_line(".section .rodata.embedded") append_line("#endif") +if(DEFINED DATA_ALIGNMENT) + append_line(".balign ${DATA_ALIGNMENT}") +endif() make_and_append_identifier("${varname}") make_and_append_identifier("_binary_${varname}_start" "for objcopy compatibility") append("${data}") diff --git a/tools/cmake/utilities.cmake b/tools/cmake/utilities.cmake index 4580c30e2a9..4b78dff163f 100644 --- a/tools/cmake/utilities.cmake +++ b/tools/cmake/utilities.cmake @@ -103,9 +103,10 @@ endfunction() # target_add_binary_data adds binary data into the built target, # by converting it to a generated source file which is then compiled -# to a binary object as part of the build +# to a binary object as part of the build. ALIGN optionally sets the +# alignment of the embedded data's start symbol. function(target_add_binary_data target embed_file embed_type) - cmake_parse_arguments(_ "" "RENAME_TO" "DEPENDS" ${ARGN}) + cmake_parse_arguments(_ "" "RENAME_TO;ALIGN" "DEPENDS" ${ARGN}) idf_build_get_property(build_dir BUILD_DIR) idf_build_get_property(idf_path IDF_PATH) @@ -119,11 +120,24 @@ function(target_add_binary_data target embed_file embed_type) set(rename_to_arg -D "VARIABLE_BASENAME=${__RENAME_TO}") endif() + set(align_arg) + if(DEFINED __ALIGN) + if(NOT __ALIGN MATCHES "^[1-9][0-9]*$") + message(FATAL_ERROR "ALIGN must be a positive integer") + endif() + math(EXPR alignment_mask "${__ALIGN} & (${__ALIGN} - 1)") + if(NOT alignment_mask EQUAL 0) + message(FATAL_ERROR "ALIGN must be a power of two") + endif() + set(align_arg -D "DATA_ALIGNMENT=${__ALIGN}") + endif() + add_custom_command(OUTPUT "${embed_srcfile}" COMMAND "${CMAKE_COMMAND}" -D "DATA_FILE=${embed_file}" -D "SOURCE_FILE=${embed_srcfile}" ${rename_to_arg} + ${align_arg} -D "FILE_TYPE=${embed_type}" -P "${idf_path}/tools/cmake/scripts/data_file_embed_asm.cmake" MAIN_DEPENDENCY "${embed_file}" diff --git a/tools/cmakev2/utilities.cmake b/tools/cmakev2/utilities.cmake index 4e2a7c5fabf..5fb245466dc 100644 --- a/tools/cmakev2/utilities.cmake +++ b/tools/cmakev2/utilities.cmake @@ -829,7 +829,8 @@ endfunction() #[[ target_add_binary_data( - [RENAME_TO ]) + [RENAME_TO ] + [ALIGN ] [DEPENDS ...]) *target[in]* @@ -849,6 +850,11 @@ endfunction() Use the given symbol name for the embedded data. If no symbol name is provided, the embed_file file name will be used instead. + *ALIGN[in,opt]* + + Align the embedded data's start symbol to the given positive power + of two. + *DEPENDS[in,opt]* List of additional dependencies for the generated file containing @@ -859,7 +865,7 @@ endfunction() build process. #]] function(target_add_binary_data target embed_file embed_type) - cmake_parse_arguments(_ "" "RENAME_TO" "DEPENDS" ${ARGN}) + cmake_parse_arguments(_ "" "RENAME_TO;ALIGN" "DEPENDS" ${ARGN}) idf_build_get_property(build_dir BUILD_DIR) # In cmakev1, the executable target was named "${project}.elf". @@ -884,11 +890,24 @@ function(target_add_binary_data target embed_file embed_type) set(rename_to_arg -D "VARIABLE_BASENAME=${__RENAME_TO}") endif() + set(align_arg) + if(DEFINED __ALIGN) + if(NOT __ALIGN MATCHES "^[1-9][0-9]*$") + message(FATAL_ERROR "ALIGN must be a positive integer") + endif() + math(EXPR alignment_mask "${__ALIGN} & (${__ALIGN} - 1)") + if(NOT alignment_mask EQUAL 0) + message(FATAL_ERROR "ALIGN must be a power of two") + endif() + set(align_arg -D "DATA_ALIGNMENT=${__ALIGN}") + endif() + add_custom_command(OUTPUT "${embed_srcfile}" COMMAND "${CMAKE_COMMAND}" -D "DATA_FILE=${embed_file}" -D "SOURCE_FILE=${embed_srcfile}" ${rename_to_arg} + ${align_arg} -D "FILE_TYPE=${embed_type}" -P "${idf_path}/tools/cmake/scripts/data_file_embed_asm.cmake" MAIN_DEPENDENCY "${embed_file}"