From 2816cf1d67b4f3bd4df50dfbacda33ec54d4958e Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Thu, 1 Mar 2018 18:41:15 +1100 Subject: [PATCH] cmake: Change data_file_to_c to data_file_embed_asm for objcopy compatibility Now generates _binary_filename_start / _binary_filename_end as well as more useful naming. --- tools/cmake/scripts/data_file_embed_asm.cmake | 82 +++++++++++++++++++ tools/cmake/scripts/data_file_to_c.cmake | 56 ------------- tools/cmake/utilities.cmake | 5 +- 3 files changed, 85 insertions(+), 58 deletions(-) create mode 100644 tools/cmake/scripts/data_file_embed_asm.cmake delete mode 100644 tools/cmake/scripts/data_file_to_c.cmake diff --git a/tools/cmake/scripts/data_file_embed_asm.cmake b/tools/cmake/scripts/data_file_embed_asm.cmake new file mode 100644 index 000000000..76a1fe298 --- /dev/null +++ b/tools/cmake/scripts/data_file_embed_asm.cmake @@ -0,0 +1,82 @@ +# +# Convert a file (text or binary) into an assembler source file suitable +# for gcc. Designed to replicate 'objcopy' with more predictable +# naming, and supports appending a null byte for embedding text as +# a string. +# +# Designed to be run as a script with "cmake -P" +# +# Set variables DATA_FILE, SOURCE_FILE, FILE_TYPE when running this. +# +# If FILE_TYPE is set to STRING, a null byte is appended to DATA_FILE's contents +# before SOURCE_FILE is created. +# +# If FILE_TYPE is unset (or any other value), DATA_FILE is copied +# verbatim into SOURCE_FILE. +# +# +if(NOT DATA_FILE) + message(FATAL_ERROR "DATA_FILE for converting must be specified") +endif() + +if(NOT SOURCE_FILE) + message(FATAL_ERROR "SOURCE_FILE destination must be specified") +endif() + +file(READ "${DATA_FILE}" data HEX) + +string(LENGTH "${data}" data_len) +math(EXPR data_len "${data_len} / 2") # 2 hex bytes per byte + +if(FILE_TYPE STREQUAL "TEXT") + set(data "${data}00") # null-byte termination +endif() + +## Convert string of raw hex bytes to lines of hex bytes as gcc .byte expressions +string(REGEX REPLACE "................................" ".byte \\0\n" data "${data}") # 16 bytes per line +string(REGEX REPLACE "[^\n]+$" ".byte \\0\n" data "${data}") # last line +string(REGEX REPLACE "[0-9a-f][0-9a-f]" "0x\\0, " data "${data}") # hex formatted C bytes +string(REGEX REPLACE ", \n" "\n" data "${data}") # trim the last comma + +## Come up with C-friendly symbol name based on source file +get_filename_component(source_filename "${DATA_FILE}" NAME) +string(MAKE_C_IDENTIFIER "${source_filename}" varname) + +function(append str) + file(APPEND "${SOURCE_FILE}" "${str}") +endfunction() + +function(append_line str) + append("${str}\n") +endfunction() + +function(append_identifier symbol) +append_line("\n.global ${symbol}") +append("${symbol}:") +if(${ARGC} GREATER 1) # optional comment + append(" /* ${ARGV1} */") +endif() +append("\n") +endfunction() + +file(WRITE "${SOURCE_FILE}" "/*") +append_line(" * Data converted from ${DATA_FILE}") +if(FILE_TYPE STREQUAL "TEXT") + append_line(" * (null byte appended)") +endif() +append_line(" */") + +append_line(".data") +append_identifier("${varname}") +append_identifier("_binary_${varname}_start" "for objcopy compatibility") +append("${data}") + +append_identifier("_binary_${varname}_end" "for objcopy compatibility") + +append_line("") +if(FILE_TYPE STREQUAL "TEXT") + append_identifier("${varname}_length" "not including null byte") +else() + append_identifier("${varname}_length") +endif() +append_line(".word ${data_len}") diff --git a/tools/cmake/scripts/data_file_to_c.cmake b/tools/cmake/scripts/data_file_to_c.cmake deleted file mode 100644 index fb93bfddc..000000000 --- a/tools/cmake/scripts/data_file_to_c.cmake +++ /dev/null @@ -1,56 +0,0 @@ -# -# Convert a file (text or binary) into a C source file suitable -# for gcc. Designed to replicate 'objcopy' with more predictable -# naming, and supports appending a null byte for embedding text as -# a string. -# -# Designed to be run as a script with "cmake -P" -# -# Set variables DATA_FILE, SOURCE_FILE, FILE_TYPE when running this. -# -# If FILE_TYPE is set to STRING, a null byte is appended to DATA_FILE's contents -# before it is embedded. -# -# If FILE_TYPE is unset (or any other value), DATA_FILE is embedded -# verbatim. -# -# -if(NOT DATA_FILE) - message(FATAL_ERROR "DATA_FILE for converting must be specified") -endif() - -if(NOT SOURCE_FILE) - message(FATAL_ERROR "SOURCE_FILE destination must be specified") -endif() - -file(READ "${DATA_FILE}" data HEX) - -if(FILE_TYPE STREQUAL "TEXT") - set(data "${data}00") # null-byte terimnation -endif() - -## Convert string of raw hex bytes to lines of hex bytes in C array format -string(REGEX REPLACE "................................" "\\0\n " data "${data}") # 16 bytes per line -string(REGEX REPLACE "[0-9a-f][0-9a-f]" "0x\\0, " data "${data}") # hex formatted C bytes -string(REGEX REPLACE ", $" "" data "${data}") # trim the last comma (cosmetic) - -## Come up with C-friendly name for file -get_filename_component(source_filename "${DATA_FILE}" NAME) -string(MAKE_C_IDENTIFIER "${source_filename}" varname) - -file(WRITE "${SOURCE_FILE}" "/*\n") -file(APPEND "${SOURCE_FILE}" " * Data converted from ${DATA_FILE}\n") -if(FILE_TYPE STREQUAL "TEXT") - file(APPEND "${SOURCE_FILE}" " * (null byte appended)\n") -endif() -file(APPEND "${SOURCE_FILE}" " */\n") -file(APPEND "${SOURCE_FILE}" "#include \n") -file(APPEND "${SOURCE_FILE}" "#include \n\n") - -file(APPEND "${SOURCE_FILE}" "const char ${varname}[] = {\n ${data}\n };\n") -file(APPEND "${SOURCE_FILE}" "const size_t ${varname}_length = sizeof(${varname});\n\n") - -# Backwards compatibility, matches objcopy binary symbol names -file(APPEND "${SOURCE_FILE}" "/* Backwards compatible names, match objcopy -I binary naming */\n") -file(APPEND "${SOURCE_FILE}" "const char *_binary_${varname}_start = ${varname};\n") -file(APPEND "${SOURCE_FILE}" "const char *_binary_${varname}_end = ${varname} + sizeof(${varname});\n") diff --git a/tools/cmake/utilities.cmake b/tools/cmake/utilities.cmake index ec6323d90..f3c0c1981 100644 --- a/tools/cmake/utilities.cmake +++ b/tools/cmake/utilities.cmake @@ -106,15 +106,16 @@ function(target_add_binary_data target embed_file embed_type) get_filename_component(embed_file "${embed_file}" ABSOLUTE) get_filename_component(name "${embed_file}" NAME) - set(embed_srcfile "${CMAKE_BINARY_DIR}/${name}.c") + set(embed_srcfile "${CMAKE_BINARY_DIR}/${name}.S") add_custom_command(OUTPUT "${embed_srcfile}" COMMAND "${CMAKE_COMMAND}" -D "DATA_FILE=${embed_file}" -D "SOURCE_FILE=${embed_srcfile}" -D "FILE_TYPE=${embed_type}" - -P "${IDF_PATH}/tools/cmake/scripts/data_file_to_c.cmake" + -P "${IDF_PATH}/tools/cmake/scripts/data_file_embed_asm.cmake" MAIN_DEPENDENCY "${embed_file}" + DEPENDENCIES "${IDF_PATH}/tools/cmake/scripts/data_file_embed_asm.cmake" WORKING_DIRECTORY "${CMAKE_BINARY_DIR}") set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${embed_srcfile}")