data_file_embed_asm.cmake 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #
  2. # Convert a file (text or binary) into an assembler source file suitable
  3. # for gcc. Designed to replicate 'objcopy' with more predictable
  4. # naming, and supports appending a null byte for embedding text as
  5. # a string.
  6. #
  7. # Designed to be run as a script with "cmake -P"
  8. #
  9. # Set variables DATA_FILE, SOURCE_FILE, FILE_TYPE when running this.
  10. #
  11. # If FILE_TYPE is set to TEXT, a null byte is appended to DATA_FILE's contents
  12. # before SOURCE_FILE is created.
  13. #
  14. # If FILE_TYPE is unset (or any other value), DATA_FILE is copied
  15. # verbatim into SOURCE_FILE.
  16. #
  17. #
  18. if(NOT DATA_FILE)
  19. message(FATAL_ERROR "DATA_FILE for converting must be specified")
  20. endif()
  21. if(NOT SOURCE_FILE)
  22. message(FATAL_ERROR "SOURCE_FILE destination must be specified")
  23. endif()
  24. file(READ "${DATA_FILE}" data HEX)
  25. string(LENGTH "${data}" data_len)
  26. math(EXPR data_len "${data_len} / 2") # 2 hex bytes per byte
  27. if(FILE_TYPE STREQUAL "TEXT")
  28. set(data "${data}00") # null-byte termination
  29. endif()
  30. ## Convert string of raw hex bytes to lines of hex bytes as gcc .byte expressions
  31. string(REGEX REPLACE "................................" ".byte \\0\n" data "${data}") # 16 bytes per line
  32. string(REGEX REPLACE "[^\n]+$" ".byte \\0\n" data "${data}") # last line
  33. string(REGEX REPLACE "[0-9a-f][0-9a-f]" "0x\\0, " data "${data}") # hex formatted C bytes
  34. string(REGEX REPLACE ", \n" "\n" data "${data}") # trim the last comma
  35. # Use source file name as variable name unless VARIABLE_BASENAME is set
  36. if(NOT VARIABLE_BASENAME)
  37. get_filename_component(varname "${DATA_FILE}" NAME)
  38. else()
  39. set(varname "${VARIABLE_BASENAME}")
  40. endif()
  41. function(append str)
  42. file(APPEND "${SOURCE_FILE}" "${str}")
  43. endfunction()
  44. function(append_line str)
  45. append("${str}\n")
  46. endfunction()
  47. function(make_and_append_identifier str)
  48. string(MAKE_C_IDENTIFIER "${str}" symbol)
  49. append_line("\n.global ${symbol}")
  50. append("${symbol}:")
  51. if(${ARGC} GREATER 1) # optional comment
  52. append(" /* ${ARGV1} */")
  53. endif()
  54. append("\n")
  55. endfunction()
  56. file(WRITE "${SOURCE_FILE}" "/*")
  57. append_line(" * Data converted from ${DATA_FILE}")
  58. if(FILE_TYPE STREQUAL "TEXT")
  59. append_line(" * (null byte appended)")
  60. endif()
  61. append_line(" */")
  62. append_line(".data")
  63. append_line(".section .rodata.embedded")
  64. make_and_append_identifier("${varname}")
  65. make_and_append_identifier("_binary_${varname}_start" "for objcopy compatibility")
  66. append("${data}")
  67. make_and_append_identifier("_binary_${varname}_end" "for objcopy compatibility")
  68. append_line("")
  69. if(FILE_TYPE STREQUAL "TEXT")
  70. make_and_append_identifier("${varname}_length" "not including null byte")
  71. else()
  72. make_and_append_identifier("${varname}_length")
  73. endif()
  74. append_line(".word ${data_len}")