EmbedAssets.cmake 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. find_program(PYTHON_EXECUTABLE python3 REQUIRED)
  2. # Inline Python script to generate the main assets.h header
  3. set(ASSETS_HEADER_GENERATOR_SCRIPT "
  4. import sys
  5. import os
  6. def generate_assets_header(asset_names, output_file):
  7. with open(output_file, 'w') as f:
  8. f.write('#ifndef ASSETS_H\\n')
  9. f.write('#define ASSETS_H\\n\\n')
  10. f.write('// Auto-generated header that includes all asset headers\\n\\n')
  11. for asset_name in asset_names:
  12. f.write(f'#include \"./assets/{asset_name}.h\"\\n')
  13. f.write('\\n#endif // ASSETS_H\\n')
  14. if __name__ == '__main__':
  15. if len(sys.argv) < 3:
  16. print('Usage: python script.py <output_file> <asset_name1> [asset_name2] ...')
  17. sys.exit(1)
  18. output_file = sys.argv[1]
  19. asset_names = sys.argv[2:]
  20. generate_assets_header(asset_names, output_file)
  21. ")
  22. # Create the temporary Python script only once
  23. file(WRITE "${CMAKE_BINARY_DIR}/generate_assets_header.py" "${ASSETS_HEADER_GENERATOR_SCRIPT}")
  24. # Internal function to create a custom command for an asset
  25. function(_add_asset_command asset_file output_file)
  26. get_filename_component(asset_name "${asset_file}" NAME)
  27. add_custom_command(
  28. OUTPUT "${output_file}"
  29. COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/generated/include/assets"
  30. COMMAND ${PYTHON_EXECUTABLE} "${R3D_ROOT_PATH}/scripts/bin2c.py" -f "${asset_file}" -n "${asset_name}" "${output_file}"
  31. DEPENDS "${asset_file}"
  32. COMMENT "Processing asset: ${asset_file}"
  33. VERBATIM
  34. )
  35. endfunction()
  36. function(_add_assets_header_command asset_names output_file)
  37. add_custom_command(
  38. OUTPUT "${output_file}"
  39. COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_BINARY_DIR}/generated/include"
  40. COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_BINARY_DIR}/generate_assets_header.py"
  41. "${output_file}" ${asset_names}
  42. COMMENT "Generating main assets header: ${output_file}"
  43. VERBATIM
  44. )
  45. endfunction()
  46. # Public function to process an asset (used by EmbedAssets)
  47. function(ProcessAsset asset_file output_file_var)
  48. # Extract the file name without the path to use as the array name
  49. get_filename_component(asset_name "${asset_file}" NAME)
  50. # Define the output file
  51. set(output_file "${CMAKE_BINARY_DIR}/generated/include/assets/${asset_name}.h")
  52. # Return the output file via the variable
  53. set("${output_file_var}" "${output_file}" PARENT_SCOPE)
  54. # Create the custom command
  55. _add_asset_command("${asset_file}" "${output_file}")
  56. endfunction()
  57. function(EmbedAssets target_name)
  58. # Retrieve the list of asset files (all arguments except the first)
  59. set(asset_files ${ARGN})
  60. # Ensure at least one file has been provided
  61. if(NOT asset_files)
  62. message(FATAL_ERROR "EmbedAssets: No asset file specified")
  63. endif()
  64. # List to store all output files and asset names
  65. set(output_files)
  66. set(asset_names)
  67. # Count the number of assets
  68. list(LENGTH asset_files num_assets)
  69. message(STATUS "Configuring processing of ${num_assets} asset(s) for target ${target_name}...")
  70. # Process each asset file
  71. foreach(asset_file ${asset_files})
  72. # Ensure the file exists
  73. if(NOT EXISTS "${asset_file}")
  74. message(FATAL_ERROR "EmbedAssets: Asset file not found: ${asset_file}")
  75. endif()
  76. get_filename_component(asset_name "${asset_file}" NAME)
  77. list(APPEND asset_names "${asset_name}")
  78. # Process the asset and retrieve the output file
  79. ProcessAsset("${asset_file}" output_file)
  80. list(APPEND output_files "${output_file}")
  81. message(STATUS " - ${asset_file} -> assets/${asset_name}.h")
  82. endforeach()
  83. # Generate the main assets.h header
  84. set(main_assets_header "${CMAKE_BINARY_DIR}/generated/include/assets.h")
  85. _add_assets_header_command("${asset_names}" "${main_assets_header}")
  86. list(APPEND output_files "${main_assets_header}")
  87. # Create a custom target to group all assets
  88. set(assets_target "${target_name}_assets")
  89. add_custom_target(${assets_target}
  90. DEPENDS ${output_files}
  91. COMMENT "Generating asset headers for ${target_name}"
  92. )
  93. # Add dependency to the main target
  94. add_dependencies(${target_name} ${assets_target})
  95. # Add the generated include directory to the target
  96. target_include_directories(${target_name} PRIVATE "${CMAKE_BINARY_DIR}/generated/include")
  97. message(STATUS "Target ${assets_target} created with ${num_assets} asset(s)")
  98. message(STATUS "Main assets header: ${main_assets_header}")
  99. message(STATUS "Assets will be automatically recompiled if modified")
  100. endfunction()