From db9a7cdd6833e56748409a7eabafc00ad24a9002 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 02:09:49 +0200 Subject: [PATCH 01/15] cmake: rename DaemonBuildInfo as DaemonSourceGenerator --- CMakeLists.txt | 2 +- cmake/DaemonGame.cmake | 2 +- cmake/{DaemonBuildInfo.cmake => DaemonSourceGenerator.cmake} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename cmake/{DaemonBuildInfo.cmake => DaemonSourceGenerator.cmake} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24b09edacf..3c7254cf51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,7 @@ if (Daemon_OUT) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Daemon_OUT}) endif() -include(DaemonBuildInfo) +include(DaemonSourceGenerator) include(DaemonPlatform) ################################################################################ diff --git a/cmake/DaemonGame.cmake b/cmake/DaemonGame.cmake index 331980efaf..9cf9ee95cc 100644 --- a/cmake/DaemonGame.cmake +++ b/cmake/DaemonGame.cmake @@ -39,7 +39,7 @@ option(BUILD_GAME_NATIVE_DLL "Build the shared library files, mostly useful for option(BUILD_GAME_NATIVE_EXE "Build native executable, which might be used for better performances by server owners" OFF) include(ExternalProject) -include(DaemonBuildInfo) +include(DaemonSourceGenerator) include(DaemonPlatform) # Do not report unused native compiler if native vms are not built. diff --git a/cmake/DaemonBuildInfo.cmake b/cmake/DaemonSourceGenerator.cmake similarity index 100% rename from cmake/DaemonBuildInfo.cmake rename to cmake/DaemonSourceGenerator.cmake From 530c3bab3c494d5c82f03e770b4baf0af6d721f9 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 02:13:14 +0200 Subject: [PATCH 02/15] DaemonSourceGenerator: rework it a bit --- cmake/DaemonSourceGenerator.cmake | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 95f08084e5..ebd5fe3ba7 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -1,23 +1,27 @@ -set(DAEMON_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/GeneratedSource") +set(DAEMON_GENERATED_SUBDIR "GeneratedSource") +set(DAEMON_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/${DAEMON_GENERATED_SUBDIR}") -set(DAEMON_BUILDINFO_DIR "DaemonBuildInfo") -set(DAEMON_BUILDINFO_HEADER "// Automatically generated, do not modify!\n") -set(DAEMON_BUILDINFO_CPP_EXT ".cpp") -set(DAEMON_BUILDINFO_H_EXT ".h") -set(BUILDINFOLIST) +set(DAEMON_BUILDINFO_SUBDIR "DaemonBuildInfo") +set(DAEMON_BUILDINFO_DIR "${DAEMON_GENERATED_DIR}/${DAEMON_BUILDINFO_SUBDIR}") file(MAKE_DIRECTORY "${DAEMON_GENERATED_DIR}") include_directories("${DAEMON_GENERATED_DIR}") -file(MAKE_DIRECTORY "${DAEMON_GENERATED_DIR}/${DAEMON_BUILDINFO_DIR}") +file(MAKE_DIRECTORY "${DAEMON_BUILDINFO_DIR}") + +set(DAEMON_GENERATED_HEADER "// Automatically generated, do not modify!\n") +set(DAEMON_GENERATED_CPP_EXT ".cpp") +set(DAEMON_GENERATED_H_EXT ".h") + +set(BUILDINFOLIST) foreach(kind CPP H) - set(DAEMON_BUILDINFO_${kind} "${DAEMON_BUILDINFO_HEADER}") + set(DAEMON_BUILDINFO_${kind}_TEXT "${DAEMON_GENERATED_HEADER}") endforeach() macro(daemon_add_buildinfo TYPE NAME VALUE) - set(DAEMON_BUILDINFO_CPP "${DAEMON_BUILDINFO_CPP}const ${TYPE} ${NAME}=${VALUE};\n") - set(DAEMON_BUILDINFO_H "${DAEMON_BUILDINFO_H}extern const ${TYPE} ${NAME};\n") + string(APPEND DAEMON_BUILDINFO_CPP_TEXT "const ${TYPE} ${NAME}=${VALUE};\n") + string(APPEND DAEMON_BUILDINFO_H_TEXT "extern const ${TYPE} ${NAME};\n") endmacro() macro(daemon_write_generated GENERATED_PATH GENERATED_CONTENT) @@ -35,10 +39,10 @@ endmacro() macro(daemon_write_buildinfo NAME) foreach(kind CPP H) - set(DAEMON_BUILDINFO_${kind}_NAME "${NAME}${DAEMON_BUILDINFO_${kind}_EXT}") - set(DAEMON_BUILDINFO_${kind}_PATH "${DAEMON_BUILDINFO_DIR}/${DAEMON_BUILDINFO_${kind}_NAME}") + set(DAEMON_BUILDINFO_${kind}_NAME "${NAME}${DAEMON_GENERATED_${kind}_EXT}") + set(DAEMON_BUILDINFO_${kind}_PATH "${DAEMON_BUILDINFO_SUBDIR}/${DAEMON_BUILDINFO_${kind}_NAME}") - daemon_write_generated("${DAEMON_BUILDINFO_${kind}_PATH}" "${DAEMON_BUILDINFO_${kind}}") + daemon_write_generated("${DAEMON_BUILDINFO_${kind}_PATH}" "${DAEMON_BUILDINFO_${kind}_TEXT}") list(APPEND BUILDINFOLIST "${DAEMON_GENERATED_FILE}") endforeach() endmacro() From 275f03b0a8fb2490ab2d81b28a3728d39ea7b235 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Sat, 4 Oct 2025 01:07:17 +0200 Subject: [PATCH 03/15] DaemonSourceGenerator: make the embedded file generator reusable --- CMakeLists.txt | 35 +--------- cmake/DaemonSourceGenerator.cmake | 68 +++++++++++++++++++ src.cmake | 104 +++++++++++++++--------------- src/engine/renderer/gl_shader.cpp | 6 +- src/engine/renderer/src.cmake | 3 +- 5 files changed, 127 insertions(+), 89 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c7254cf51..7fad63177c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -927,39 +927,8 @@ if (BUILD_CLIENT) Tests ${CLIENTTESTLIST} ) - # generate glsl include files - set(GLSL_SOURCE_DIR ${ENGINE_DIR}/renderer/glsl_source) - set(EMBED_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/embed_data) - file(MAKE_DIRECTORY ${EMBED_INCLUDE_DIR}) - - set(SHADERS_CPP_TEXT "// This file is auto-generated by CMakeLists.txt.\n") - string(APPEND SHADERS_CPP_TEXT "#include \"common/Common.h\"\n\n") - set(SHADERMAP_TEXT "") - - foreach(res ${GLSLSOURCELIST}) - get_filename_component(filename_no_ext ${res} NAME_WE) - set(outpath ${EMBED_INCLUDE_DIR}/${filename_no_ext}.glsl.h) - - add_custom_command( - OUTPUT ${outpath} - COMMAND ${CMAKE_COMMAND} "-DINPUT_FILE=${res}" "-DOUTPUT_FILE=${outpath}" - "-DVARIABLE_NAME=${filename_no_ext}_glsl" -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake - MAIN_DEPENDENCY ${res} - ) - - set_property(TARGET client-objects APPEND PROPERTY SOURCES ${outpath}) - - string(APPEND SHADERS_CPP_TEXT "#include \"../embed_data/${filename_no_ext}.glsl.h\"\n") - string(APPEND SHADERMAP_TEXT "\t{ \"${filename_no_ext}.glsl\", ") - string(APPEND SHADERMAP_TEXT "std::string(reinterpret_cast( ${filename_no_ext}_glsl ), ") - string(APPEND SHADERMAP_TEXT "sizeof( ${filename_no_ext}_glsl )) },\n") - endforeach() - - string(APPEND SHADERS_CPP_TEXT "\nextern const std::unordered_map shadermap\n{\n") - string(APPEND SHADERS_CPP_TEXT "${SHADERMAP_TEXT}") - string(APPEND SHADERS_CPP_TEXT "};\n") - - daemon_write_generated("shaders.cpp" "${SHADERS_CPP_TEXT}") + # Generate GLSL include files. + daemon_embed_files("EngineShaders" "GLSL" "client-objects") endif() if (BUILD_SERVER) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index ebd5fe3ba7..fc2cdbb58c 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -2,12 +2,16 @@ set(DAEMON_GENERATED_SUBDIR "GeneratedSource") set(DAEMON_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/${DAEMON_GENERATED_SUBDIR}") set(DAEMON_BUILDINFO_SUBDIR "DaemonBuildInfo") +set(DAEMON_EMBEDDED_SUBDIR "DaemonEmbeddedFiles") + set(DAEMON_BUILDINFO_DIR "${DAEMON_GENERATED_DIR}/${DAEMON_BUILDINFO_SUBDIR}") +set(DAEMON_EMBEDDED_DIR "${DAEMON_GENERATED_DIR}/${DAEMON_EMBEDDED_SUBDIR}") file(MAKE_DIRECTORY "${DAEMON_GENERATED_DIR}") include_directories("${DAEMON_GENERATED_DIR}") file(MAKE_DIRECTORY "${DAEMON_BUILDINFO_DIR}") +file(MAKE_DIRECTORY "${DAEMON_EMBEDDED_DIR}") set(DAEMON_GENERATED_HEADER "// Automatically generated, do not modify!\n") set(DAEMON_GENERATED_CPP_EXT ".cpp") @@ -46,3 +50,67 @@ macro(daemon_write_buildinfo NAME) list(APPEND BUILDINFOLIST "${DAEMON_GENERATED_FILE}") endforeach() endmacro() + +macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) + set(EMBED_SOURCE_DIR "${SLUG}_EMBED_DIR") + set(EMBED_SOURCE_LIST "${SLUG}_EMBED_LIST") + + set(EMBED_SUBDIR "${DAEMON_EMBEDDED_SUBDIR}/${BASENAME}") + set(EMBED_DIR "${DAEMON_GENERATED_DIR}/${EMBED_SUBDIR}") + + foreach(kind CPP H) + set(EMBED_${kind}_FILE "${DAEMON_EMBEDDED_SUBDIR}/${BASENAME}${DAEMON_GENERATED_${kind}_EXT}") + set(EMBED_${kind}_TEXT "${DAEMON_GENERATED_HEADER}") + endforeach() + + string(APPEND EMBED_CPP_TEXT "#include \"${EMBED_H_FILE}\"\n\n") + + set(EMBED_MAP_TEXT "") + + foreach(filename ${${EMBED_SOURCE_LIST}}) + string(REGEX REPLACE "[^A-Za-z0-9]" "_" filename_symbol "${filename}") + + set(inpath "${${EMBED_SOURCE_DIR}}/${filename}") + set(outpath "${EMBED_DIR}/${filename_symbol}${DAEMON_GENERATED_H_EXT}") + + add_custom_command( + OUTPUT "${outpath}" + COMMAND ${CMAKE_COMMAND} + "-DINPUT_FILE=${inpath}" + "-DOUTPUT_FILE=${outpath}" + "-DVARIABLE_NAME=${filename_symbol}" + -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake" + MAIN_DEPENDENCY ${inpath} + ) + + set_property(TARGET "${TARGETNAME}" APPEND PROPERTY SOURCES "${outpath}") + + string(APPEND EMBED_CPP_TEXT + "#include \"${BASENAME}/${filename_symbol}.h\"\n") + string(APPEND EMBED_MAP_TEXT + "\t{ \"${filename}\", " + "std::string(reinterpret_cast( ${filename_symbol} ), " + "sizeof( ${filename_symbol} )) },\n") + endforeach() + + string(APPEND EMBED_CPP_TEXT + "\n" + "namespace ${BASENAME} {\n" + "const std::unordered_map FileMap\n{\n" + "${EMBED_MAP_TEXT}" + "};\n" + "}" + ) + + string(APPEND EMBED_H_TEXT + "#include \"common/Common.h\"\n" + "\n" + "namespace ${BASENAME} {\n" + "extern const std::unordered_map FileMap;\n" + "};\n" + ) + + foreach(kind CPP H) + daemon_write_generated("${EMBED_${kind}_FILE}" "${EMBED_${kind}_TEXT}") + endforeach() +endmacro() diff --git a/src.cmake b/src.cmake index 20305a0ebb..7430a577b9 100644 --- a/src.cmake +++ b/src.cmake @@ -86,68 +86,68 @@ else() include (${ENGINE_DIR}/renderer/src.cmake) endif() -set(GLSLSOURCELIST +set(GLSL_EMBED_DIR "${ENGINE_DIR}/renderer/glsl_source") +set(GLSL_EMBED_LIST # Common shader libraries - ${ENGINE_DIR}/renderer/glsl_source/common.glsl - ${ENGINE_DIR}/renderer/glsl_source/common_cp.glsl - ${ENGINE_DIR}/renderer/glsl_source/fogEquation_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/shaderProfiler_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/shaderProfiler_fp.glsl - + common.glsl + common_cp.glsl + fogEquation_fp.glsl + shaderProfiler_vp.glsl + shaderProfiler_fp.glsl # Material system shaders - ${ENGINE_DIR}/renderer/glsl_source/material_cp.glsl - ${ENGINE_DIR}/renderer/glsl_source/material_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/material_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/clearSurfaces_cp.glsl - ${ENGINE_DIR}/renderer/glsl_source/cull_cp.glsl - ${ENGINE_DIR}/renderer/glsl_source/depthReduction_cp.glsl - ${ENGINE_DIR}/renderer/glsl_source/processSurfaces_cp.glsl + material_cp.glsl + material_vp.glsl + material_fp.glsl + clearSurfaces_cp.glsl + cull_cp.glsl + depthReduction_cp.glsl + processSurfaces_cp.glsl # Screen-space shaders - ${ENGINE_DIR}/renderer/glsl_source/screenSpace_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/blur_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/cameraEffects_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/contrast_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/fogGlobal_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/fxaa_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/fxaa3_11_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/motionblur_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/ssao_fp.glsl + screenSpace_vp.glsl + blur_fp.glsl + cameraEffects_fp.glsl + contrast_fp.glsl + fogGlobal_fp.glsl + fxaa_fp.glsl + fxaa3_11_fp.glsl + motionblur_fp.glsl + ssao_fp.glsl # Lighting shaders - ${ENGINE_DIR}/renderer/glsl_source/depthtile1_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/depthtile1_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/depthtile2_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/lighttile_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/lighttile_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/computeLight_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/reliefMapping_fp.glsl + depthtile1_vp.glsl + depthtile1_fp.glsl + depthtile2_fp.glsl + lighttile_vp.glsl + lighttile_fp.glsl + computeLight_fp.glsl + reliefMapping_fp.glsl # Common vertex shader libraries - ${ENGINE_DIR}/renderer/glsl_source/deformVertexes_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/vertexAnimation_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/vertexSimple_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/vertexSkinning_vp.glsl + deformVertexes_vp.glsl + vertexAnimation_vp.glsl + vertexSimple_vp.glsl + vertexSkinning_vp.glsl # Regular shaders - ${ENGINE_DIR}/renderer/glsl_source/fogQuake3_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/fogQuake3_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/generic_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/generic_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/heatHaze_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/heatHaze_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/lightMapping_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/lightMapping_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/liquid_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/liquid_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/portal_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/portal_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/reflection_CB_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/reflection_CB_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/screen_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/screen_fp.glsl - ${ENGINE_DIR}/renderer/glsl_source/skybox_vp.glsl - ${ENGINE_DIR}/renderer/glsl_source/skybox_fp.glsl + fogQuake3_vp.glsl + fogQuake3_fp.glsl + generic_vp.glsl + generic_fp.glsl + heatHaze_vp.glsl + heatHaze_fp.glsl + lightMapping_vp.glsl + lightMapping_fp.glsl + liquid_vp.glsl + liquid_fp.glsl + portal_vp.glsl + portal_fp.glsl + reflection_CB_vp.glsl + reflection_CB_fp.glsl + screen_vp.glsl + screen_fp.glsl + skybox_vp.glsl + skybox_fp.glsl ) set(SERVERLIST diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index cc6bc46432..4552a34131 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include "gl_shader.h" #include "Material.h" +#include "DaemonEmbeddedFiles/EngineShaders.h" // We currently write GLBinaryHeader to a file and memcpy all over it. // Make sure it's a pod, so we don't put a std::string in it or something @@ -41,7 +42,6 @@ static Cvar::Cvar r_logUnmarkedGLSLBuilds( "r_logUnmarkedGLSLBuilds", "Log building information for GLSL shaders that are built after the map is loaded", Cvar::NONE, true ); -extern const std::unordered_map shadermap; // shaderKind's value will be determined later based on command line setting or absence of. ShaderKind shaderKind = ShaderKind::Unknown; @@ -92,8 +92,8 @@ namespace // Implementation details const char* GetInternalShader(Str::StringRef filename) { - auto it = shadermap.find(filename); - if (it != shadermap.end()) + auto it = EngineShaders::FileMap.find(filename); + if (it != EngineShaders::FileMap.end()) return it->second.c_str(); return nullptr; } diff --git a/src/engine/renderer/src.cmake b/src/engine/renderer/src.cmake index ff85e9872a..59c7156011 100644 --- a/src/engine/renderer/src.cmake +++ b/src/engine/renderer/src.cmake @@ -1,6 +1,7 @@ set(RENDERERLIST - ${DAEMON_GENERATED_DIR}/shaders.cpp + ${DAEMON_EMBEDDED_DIR}/EngineShaders.cpp + ${DAEMON_EMBEDDED_DIR}/EngineShaders.h ${ENGINE_DIR}/renderer/BufferBind.h ${ENGINE_DIR}/renderer/DetectGLVendors.cpp ${ENGINE_DIR}/renderer/DetectGLVendors.h From 3f9e92f5116e949970bc9b6c1f95f3a27a00969b Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 02:17:12 +0200 Subject: [PATCH 04/15] EmbedText make possible to chose between TEXT and BINARY formats when embedding files --- CMakeLists.txt | 2 +- cmake/DaemonSourceGenerator.cmake | 1 + cmake/EmbedText.cmake | 18 +++++++++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7fad63177c..17d2739a87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -928,7 +928,7 @@ if (BUILD_CLIENT) ) # Generate GLSL include files. - daemon_embed_files("EngineShaders" "GLSL" "client-objects") + daemon_embed_files("EngineShaders" "GLSL" "TEXT" "client-objects") endif() if (BUILD_SERVER) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index fc2cdbb58c..1c6da48be5 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -78,6 +78,7 @@ macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) COMMAND ${CMAKE_COMMAND} "-DINPUT_FILE=${inpath}" "-DOUTPUT_FILE=${outpath}" + "-DFILE_FORMAT=${FORMAT}" "-DVARIABLE_NAME=${filename_symbol}" -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake" MAIN_DEPENDENCY ${inpath} diff --git a/cmake/EmbedText.cmake b/cmake/EmbedText.cmake index 43b9ffab4b..dc88b23f2d 100644 --- a/cmake/EmbedText.cmake +++ b/cmake/EmbedText.cmake @@ -1,8 +1,20 @@ # Converts a text file into a C-language char array definition. # For use in CMake script mode (cmake -P). -# Required definitions on command line: INPUT_FILE, OUTPUT_FILE, VARIABLE_NAME +# Required definitions on command line: +# INPUT_FILE, OUTPUT_FILE, FILE_FORMAT, VARIABLE_NAME + +# Inspired by: +# https://stackoverflow.com/questions/11813271/embed-resources-eg-shader-code-images-into-executable-library-with-cmake/27206982#27206982 -# Inspired by https://stackoverflow.com/questions/11813271/embed-resources-eg-shader-code-images-into-executable-library-with-cmake/27206982#27206982 file(READ ${INPUT_FILE} contents HEX) -string(REGEX REPLACE "(0d)?(..)" "0x\\2," contents ${contents}) # Strip \r for consistency + +if ("${FILE_FORMAT}" STREQUAL "TEXT") + # Strip \r for consistency. + string(REGEX REPLACE "(0d)?(..)" "0x\\2," contents "${contents}") +elseif("${FILE_FORMAT}" STREQUAL "BINARY") + string(REGEX REPLACE "(..)" "0x\\1," contents "${contents}") +else() + message(FATAL_ERROR "Unknown file format: ${FILE_FORMAT}") +endif() + file(WRITE ${OUTPUT_FILE} "const unsigned char ${VARIABLE_NAME}[] = {${contents}};\n") From 5e0ce3f110d880aa29c2103e8d3363b98b2ff7d8 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 02:33:45 +0200 Subject: [PATCH 05/15] DaemonSourceGenerator: provide embedded files as part as the namespace --- cmake/DaemonSourceGenerator.cmake | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 1c6da48be5..47d74b7b49 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -63,7 +63,17 @@ macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) set(EMBED_${kind}_TEXT "${DAEMON_GENERATED_HEADER}") endforeach() - string(APPEND EMBED_CPP_TEXT "#include \"${EMBED_H_FILE}\"\n\n") + string(APPEND EMBED_CPP_TEXT + "#include \"${EMBED_H_FILE}\"\n" + "\n" + "namespace ${BASENAME} {\n" + ) + + string(APPEND EMBED_H_TEXT + "#include \"common/Common.h\"\n" + "\n" + "namespace ${BASENAME} {\n" + ) set(EMBED_MAP_TEXT "") @@ -87,16 +97,22 @@ macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) set_property(TARGET "${TARGETNAME}" APPEND PROPERTY SOURCES "${outpath}") string(APPEND EMBED_CPP_TEXT - "#include \"${BASENAME}/${filename_symbol}.h\"\n") + "#include \"${BASENAME}/${filename_symbol}.h\"\n" + ) + + string(APPEND EMBED_H_TEXT + "extern const unsigned char ${filename_symbol}[];\n" + ) + string(APPEND EMBED_MAP_TEXT "\t{ \"${filename}\", " "std::string(reinterpret_cast( ${filename_symbol} ), " - "sizeof( ${filename_symbol} )) },\n") + "sizeof( ${filename_symbol} )) },\n" + ) endforeach() string(APPEND EMBED_CPP_TEXT "\n" - "namespace ${BASENAME} {\n" "const std::unordered_map FileMap\n{\n" "${EMBED_MAP_TEXT}" "};\n" @@ -104,9 +120,6 @@ macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) ) string(APPEND EMBED_H_TEXT - "#include \"common/Common.h\"\n" - "\n" - "namespace ${BASENAME} {\n" "extern const std::unordered_map FileMap;\n" "};\n" ) From 291613ebab8f96e65cdd4ab6ab9b016baa80c71e Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 03:08:19 +0200 Subject: [PATCH 06/15] EmbedText: split embedded source lines just in case if an editor or debugger opens it --- cmake/EmbedText.cmake | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/cmake/EmbedText.cmake b/cmake/EmbedText.cmake index dc88b23f2d..447f30f069 100644 --- a/cmake/EmbedText.cmake +++ b/cmake/EmbedText.cmake @@ -8,6 +8,7 @@ file(READ ${INPUT_FILE} contents HEX) +# Translate the file content. if ("${FILE_FORMAT}" STREQUAL "TEXT") # Strip \r for consistency. string(REGEX REPLACE "(0d)?(..)" "0x\\2," contents "${contents}") @@ -17,4 +18,18 @@ else() message(FATAL_ERROR "Unknown file format: ${FILE_FORMAT}") endif() -file(WRITE ${OUTPUT_FILE} "const unsigned char ${VARIABLE_NAME}[] = {${contents}};\n") +# Split long lines. +string(REGEX REPLACE + "(0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,)" "\\1\n" + contents "${contents}" +) + +# A bit more of beautification. +string(REGEX REPLACE ",$" ",\n" contents "${contents}") + +file(WRITE ${OUTPUT_FILE} + "const unsigned char ${VARIABLE_NAME}[] =\n" + "{\n" + "${contents}" + "};\n" +) From 16236aff900c3b5d40a49bfd7f7c95bf38c459bf Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 03:56:30 +0200 Subject: [PATCH 07/15] DaemonSourceGenerator: also add the generated source entry-point to the target --- cmake/DaemonSourceGenerator.cmake | 5 ++++- src/engine/renderer/src.cmake | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 47d74b7b49..2bf09fcc06 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -59,8 +59,11 @@ macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) set(EMBED_DIR "${DAEMON_GENERATED_DIR}/${EMBED_SUBDIR}") foreach(kind CPP H) - set(EMBED_${kind}_FILE "${DAEMON_EMBEDDED_SUBDIR}/${BASENAME}${DAEMON_GENERATED_${kind}_EXT}") + set(EMBED_${kind}_BASENAME "${BASENAME}${DAEMON_GENERATED_${kind}_EXT}") + set(EMBED_${kind}_SRC_FILE "${DAEMON_EMBEDDED_DIR}/${EMBED_${kind}_BASENAME}") + set(EMBED_${kind}_FILE "${DAEMON_EMBEDDED_SUBDIR}/${EMBED_${kind}_BASENAME}") set(EMBED_${kind}_TEXT "${DAEMON_GENERATED_HEADER}") + set_property(TARGET "${TARGETNAME}" APPEND PROPERTY SOURCES "${EMBED_${kind}_SRC_FILE}") endforeach() string(APPEND EMBED_CPP_TEXT diff --git a/src/engine/renderer/src.cmake b/src/engine/renderer/src.cmake index 59c7156011..98ef800b31 100644 --- a/src/engine/renderer/src.cmake +++ b/src/engine/renderer/src.cmake @@ -1,7 +1,5 @@ set(RENDERERLIST - ${DAEMON_EMBEDDED_DIR}/EngineShaders.cpp - ${DAEMON_EMBEDDED_DIR}/EngineShaders.h ${ENGINE_DIR}/renderer/BufferBind.h ${ENGINE_DIR}/renderer/DetectGLVendors.cpp ${ENGINE_DIR}/renderer/DetectGLVendors.h From cef003ac83392c4b2f478e0f81e241d9e4ee4e75 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Mon, 6 Oct 2025 04:16:25 +0200 Subject: [PATCH 08/15] DaemonSourceGenerator: lowercase local variables (even if the leak outside) --- cmake/DaemonSourceGenerator.cmake | 84 +++++++++++++++---------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 2bf09fcc06..c3e542263c 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -23,111 +23,111 @@ foreach(kind CPP H) set(DAEMON_BUILDINFO_${kind}_TEXT "${DAEMON_GENERATED_HEADER}") endforeach() -macro(daemon_add_buildinfo TYPE NAME VALUE) - string(APPEND DAEMON_BUILDINFO_CPP_TEXT "const ${TYPE} ${NAME}=${VALUE};\n") - string(APPEND DAEMON_BUILDINFO_H_TEXT "extern const ${TYPE} ${NAME};\n") +macro(daemon_add_buildinfo type name value) + string(APPEND DAEMON_BUILDINFO_CPP_TEXT "const ${type} ${name}=${value};\n") + string(APPEND DAEMON_BUILDINFO_H_TEXT "extern const ${type} ${name};\n") endmacro() -macro(daemon_write_generated GENERATED_PATH GENERATED_CONTENT) - set(DAEMON_GENERATED_FILE ${DAEMON_GENERATED_DIR}/${GENERATED_PATH}) +macro(daemon_write_generated generated_path generated_content) + set(DAEMON_GENERATED_FILE ${DAEMON_GENERATED_DIR}/${generated_path}) if (EXISTS "${DAEMON_GENERATED_FILE}") - file(READ "${DAEMON_GENERATED_FILE}" GENERATED_CONTENT_READ) + file(READ "${DAEMON_GENERATED_FILE}" generated_content_read) endif() - if (NOT "${GENERATED_CONTENT}" STREQUAL "${GENERATED_CONTENT_READ}") - message(STATUS "Generating ${GENERATED_PATH}") - file(WRITE "${DAEMON_GENERATED_FILE}" "${GENERATED_CONTENT}") + if (NOT "${generated_content}" STREQUAL "${generated_content_read}") + message(STATUS "Generating ${generated_path}") + file(WRITE "${DAEMON_GENERATED_FILE}" "${generated_content}") endif() endmacro() -macro(daemon_write_buildinfo NAME) +macro(daemon_write_buildinfo name) foreach(kind CPP H) - set(DAEMON_BUILDINFO_${kind}_NAME "${NAME}${DAEMON_GENERATED_${kind}_EXT}") - set(DAEMON_BUILDINFO_${kind}_PATH "${DAEMON_BUILDINFO_SUBDIR}/${DAEMON_BUILDINFO_${kind}_NAME}") + set(daemon_buildinfo_${kind}_name "${name}${DAEMON_GENERATED_${kind}_EXT}") + set(daemon_buildinfo_${kind}_path "${DAEMON_BUILDINFO_SUBDIR}/${daemon_buildinfo_${kind}_name}") - daemon_write_generated("${DAEMON_BUILDINFO_${kind}_PATH}" "${DAEMON_BUILDINFO_${kind}_TEXT}") + daemon_write_generated("${daemon_buildinfo_${kind}_path}" "${DAEMON_BUILDINFO_${kind}_TEXT}") list(APPEND BUILDINFOLIST "${DAEMON_GENERATED_FILE}") endforeach() endmacro() -macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME) - set(EMBED_SOURCE_DIR "${SLUG}_EMBED_DIR") - set(EMBED_SOURCE_LIST "${SLUG}_EMBED_LIST") +macro(daemon_embed_files basename slug format targetname) + set(embed_source_dir "${slug}_EMBED_DIR") + set(embed_source_list "${slug}_EMBED_LIST") - set(EMBED_SUBDIR "${DAEMON_EMBEDDED_SUBDIR}/${BASENAME}") - set(EMBED_DIR "${DAEMON_GENERATED_DIR}/${EMBED_SUBDIR}") + set(embed_subdir "${DAEMON_EMBEDDED_SUBDIR}/${basename}") + set(embed_dir "${DAEMON_GENERATED_DIR}/${embed_subdir}") foreach(kind CPP H) - set(EMBED_${kind}_BASENAME "${BASENAME}${DAEMON_GENERATED_${kind}_EXT}") - set(EMBED_${kind}_SRC_FILE "${DAEMON_EMBEDDED_DIR}/${EMBED_${kind}_BASENAME}") - set(EMBED_${kind}_FILE "${DAEMON_EMBEDDED_SUBDIR}/${EMBED_${kind}_BASENAME}") - set(EMBED_${kind}_TEXT "${DAEMON_GENERATED_HEADER}") - set_property(TARGET "${TARGETNAME}" APPEND PROPERTY SOURCES "${EMBED_${kind}_SRC_FILE}") + set(embed_${kind}_basename "${basename}${DAEMON_GENERATED_${kind}_EXT}") + set(embed_${kind}_src_file "${DAEMON_EMBEDDED_DIR}/${embed_${kind}_basename}") + set(embed_${kind}_file "${DAEMON_EMBEDDED_SUBDIR}/${embed_${kind}_basename}") + set(embed_${kind}_text "${DAEMON_GENERATED_HEADER}") + set_property(TARGET "${targetname}" APPEND PROPERTY SOURCES "${embed_${kind}_src_file}") endforeach() - string(APPEND EMBED_CPP_TEXT - "#include \"${EMBED_H_FILE}\"\n" + string(APPEND embed_CPP_text + "#include \"${embed_H_file}\"\n" "\n" - "namespace ${BASENAME} {\n" + "namespace ${basename} {\n" ) - string(APPEND EMBED_H_TEXT + string(APPEND embed_H_text "#include \"common/Common.h\"\n" "\n" - "namespace ${BASENAME} {\n" + "namespace ${basename} {\n" ) - set(EMBED_MAP_TEXT "") + set(embed_map_text "") - foreach(filename ${${EMBED_SOURCE_LIST}}) + foreach(filename ${${embed_source_list}}) string(REGEX REPLACE "[^A-Za-z0-9]" "_" filename_symbol "${filename}") - set(inpath "${${EMBED_SOURCE_DIR}}/${filename}") - set(outpath "${EMBED_DIR}/${filename_symbol}${DAEMON_GENERATED_H_EXT}") + set(inpath "${${embed_source_dir}}/${filename}") + set(outpath "${embed_dir}/${filename_symbol}${DAEMON_GENERATED_H_EXT}") add_custom_command( OUTPUT "${outpath}" COMMAND ${CMAKE_COMMAND} "-DINPUT_FILE=${inpath}" "-DOUTPUT_FILE=${outpath}" - "-DFILE_FORMAT=${FORMAT}" + "-DFILE_FORMAT=${format}" "-DVARIABLE_NAME=${filename_symbol}" -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake" MAIN_DEPENDENCY ${inpath} ) - set_property(TARGET "${TARGETNAME}" APPEND PROPERTY SOURCES "${outpath}") + set_property(TARGET "${targetname}" APPEND PROPERTY SOURCES "${outpath}") - string(APPEND EMBED_CPP_TEXT - "#include \"${BASENAME}/${filename_symbol}.h\"\n" + string(APPEND embed_CPP_text + "#include \"${basename}/${filename_symbol}.h\"\n" ) - string(APPEND EMBED_H_TEXT + string(APPEND embed_H_text "extern const unsigned char ${filename_symbol}[];\n" ) - string(APPEND EMBED_MAP_TEXT + string(APPEND embed_map_text "\t{ \"${filename}\", " "std::string(reinterpret_cast( ${filename_symbol} ), " "sizeof( ${filename_symbol} )) },\n" ) endforeach() - string(APPEND EMBED_CPP_TEXT + string(APPEND embed_CPP_text "\n" "const std::unordered_map FileMap\n{\n" - "${EMBED_MAP_TEXT}" + "${embed_map_text}" "};\n" "}" ) - string(APPEND EMBED_H_TEXT + string(APPEND embed_H_text "extern const std::unordered_map FileMap;\n" "};\n" ) foreach(kind CPP H) - daemon_write_generated("${EMBED_${kind}_FILE}" "${EMBED_${kind}_TEXT}") + daemon_write_generated("${embed_${kind}_file}" "${embed_${kind}_text}") endforeach() endmacro() From 39ce4924e6e1be775221226195407f12ccc5f756 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Tue, 7 Oct 2025 02:18:45 +0200 Subject: [PATCH 09/15] DaemonSourceGenerator: explicit mkdir --- cmake/DaemonSourceGenerator.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index c3e542263c..4aab0699bb 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -58,6 +58,8 @@ macro(daemon_embed_files basename slug format targetname) set(embed_subdir "${DAEMON_EMBEDDED_SUBDIR}/${basename}") set(embed_dir "${DAEMON_GENERATED_DIR}/${embed_subdir}") + file(MAKE_DIRECTORY "${embed_dir}") + foreach(kind CPP H) set(embed_${kind}_basename "${basename}${DAEMON_GENERATED_${kind}_EXT}") set(embed_${kind}_src_file "${DAEMON_EMBEDDED_DIR}/${embed_${kind}_basename}") From 6ae471b60db1f90b74aee896d33beea9d6900a94 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Tue, 7 Oct 2025 01:24:56 +0200 Subject: [PATCH 10/15] DaemonSourceGenerator: do not copy the embedded files in the map --- cmake/DaemonSourceGenerator.cmake | 8 +++----- cmake/EmbedText.cmake | 7 +++++-- src/common/Common.h | 1 + src/common/EmbeddedFile.h | 7 +++++++ src/engine/renderer/gl_shader.cpp | 2 +- 5 files changed, 17 insertions(+), 8 deletions(-) create mode 100644 src/common/EmbeddedFile.h diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 4aab0699bb..f0f68ab208 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -110,22 +110,20 @@ macro(daemon_embed_files basename slug format targetname) ) string(APPEND embed_map_text - "\t{ \"${filename}\", " - "std::string(reinterpret_cast( ${filename_symbol} ), " - "sizeof( ${filename_symbol} )) },\n" + "\t{ \"${filename}\", { ${filename_symbol}, sizeof( ${filename_symbol}) - 1 } },\n" ) endforeach() string(APPEND embed_CPP_text "\n" - "const std::unordered_map FileMap\n{\n" + "const embeddedFileMap_t FileMap\n{\n" "${embed_map_text}" "};\n" "}" ) string(APPEND embed_H_text - "extern const std::unordered_map FileMap;\n" + "extern const embeddedFileMap_t FileMap;\n" "};\n" ) diff --git a/cmake/EmbedText.cmake b/cmake/EmbedText.cmake index 447f30f069..43512dbf54 100644 --- a/cmake/EmbedText.cmake +++ b/cmake/EmbedText.cmake @@ -11,13 +11,16 @@ file(READ ${INPUT_FILE} contents HEX) # Translate the file content. if ("${FILE_FORMAT}" STREQUAL "TEXT") # Strip \r for consistency. - string(REGEX REPLACE "(0d)?(..)" "0x\\2," contents "${contents}") + string(REGEX REPLACE "(0d)?(..)" "0x\\2," contents "${contents}") elseif("${FILE_FORMAT}" STREQUAL "BINARY") string(REGEX REPLACE "(..)" "0x\\1," contents "${contents}") else() message(FATAL_ERROR "Unknown file format: ${FILE_FORMAT}") endif() +# Add null terminator. +set(contents "${contents}0x00,") + # Split long lines. string(REGEX REPLACE "(0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,0x..,)" "\\1\n" @@ -28,7 +31,7 @@ string(REGEX REPLACE string(REGEX REPLACE ",$" ",\n" contents "${contents}") file(WRITE ${OUTPUT_FILE} - "const unsigned char ${VARIABLE_NAME}[] =\n" + "constexpr unsigned char ${VARIABLE_NAME}[] =\n" "{\n" "${contents}" "};\n" diff --git a/src/common/Common.h b/src/common/Common.h index 4fedbd6844..bc7d7de12a 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -48,6 +48,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "Color.h" #include "Serialize.h" #include "DisjointSets.h" +#include "EmbeddedFile.h" using Math::Vec2; using Math::Vec3; diff --git a/src/common/EmbeddedFile.h b/src/common/EmbeddedFile.h new file mode 100644 index 0000000000..142995c941 --- /dev/null +++ b/src/common/EmbeddedFile.h @@ -0,0 +1,7 @@ +struct embeddedFileMapEntry_t +{ + const unsigned char* data; + size_t size; +}; + +using embeddedFileMap_t = std::unordered_map; diff --git a/src/engine/renderer/gl_shader.cpp b/src/engine/renderer/gl_shader.cpp index 4552a34131..ef4d07b448 100644 --- a/src/engine/renderer/gl_shader.cpp +++ b/src/engine/renderer/gl_shader.cpp @@ -94,7 +94,7 @@ namespace // Implementation details { auto it = EngineShaders::FileMap.find(filename); if (it != EngineShaders::FileMap.end()) - return it->second.c_str(); + return (const char*) it->second.data; return nullptr; } From 3ec028c9bcab642e2df8ca382f41f7a94ce1dd29 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Tue, 7 Oct 2025 01:44:22 +0200 Subject: [PATCH 11/15] DaemonSourceGenerator: also make generated source depend on generators to regenerate the target --- cmake/DaemonSourceGenerator.cmake | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index f0f68ab208..4f092e9e3e 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -1,3 +1,7 @@ +set(DAEMON_SOURCE_GENERATOR "${CMAKE_CURRENT_LIST_FILE}") +get_filename_component(current_list_dir "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) +set(DAEMON_TEXT_EMBEDDER "${current_list_dir}/cmake/EmbedText.cmake") + set(DAEMON_GENERATED_SUBDIR "GeneratedSource") set(DAEMON_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/${DAEMON_GENERATED_SUBDIR}") @@ -65,6 +69,7 @@ macro(daemon_embed_files basename slug format targetname) set(embed_${kind}_src_file "${DAEMON_EMBEDDED_DIR}/${embed_${kind}_basename}") set(embed_${kind}_file "${DAEMON_EMBEDDED_SUBDIR}/${embed_${kind}_basename}") set(embed_${kind}_text "${DAEMON_GENERATED_HEADER}") + set_property(SOURCE "${embed_${kind}_src_file}" APPEND PROPERTY OBJECT_DEPENDS "${DAEMON_SOURCE_GENERATOR}") set_property(TARGET "${targetname}" APPEND PROPERTY SOURCES "${embed_${kind}_src_file}") endforeach() @@ -95,8 +100,11 @@ macro(daemon_embed_files basename slug format targetname) "-DOUTPUT_FILE=${outpath}" "-DFILE_FORMAT=${format}" "-DVARIABLE_NAME=${filename_symbol}" - -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake" + -P "${DAEMON_TEXT_EMBEDDER}" MAIN_DEPENDENCY ${inpath} + DEPENDS + "${DAEMON_FILE_EMBEDDER}" + "${DAEMON_SOURCE_GENERATOR}" ) set_property(TARGET "${targetname}" APPEND PROPERTY SOURCES "${outpath}") From c548e8e6c2d10ca6ad26d17ebebcfe6f2ad49cd6 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 9 Oct 2025 01:26:31 +0200 Subject: [PATCH 12/15] cmake: rename EmbedText as DaemonFileEmbedder --- cmake/{EmbedText.cmake => DaemonFileEmbedder.cmake} | 0 cmake/DaemonSourceGenerator.cmake | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename cmake/{EmbedText.cmake => DaemonFileEmbedder.cmake} (100%) diff --git a/cmake/EmbedText.cmake b/cmake/DaemonFileEmbedder.cmake similarity index 100% rename from cmake/EmbedText.cmake rename to cmake/DaemonFileEmbedder.cmake diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 4f092e9e3e..5dc59ccc0f 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -1,6 +1,6 @@ set(DAEMON_SOURCE_GENERATOR "${CMAKE_CURRENT_LIST_FILE}") get_filename_component(current_list_dir "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) -set(DAEMON_TEXT_EMBEDDER "${current_list_dir}/cmake/EmbedText.cmake") +set(DAEMON_FILE_EMBEDDER "${current_list_dir}/DaemonFileEmbedder.cmake") set(DAEMON_GENERATED_SUBDIR "GeneratedSource") set(DAEMON_GENERATED_DIR "${CMAKE_CURRENT_BINARY_DIR}/${DAEMON_GENERATED_SUBDIR}") @@ -100,7 +100,7 @@ macro(daemon_embed_files basename slug format targetname) "-DOUTPUT_FILE=${outpath}" "-DFILE_FORMAT=${format}" "-DVARIABLE_NAME=${filename_symbol}" - -P "${DAEMON_TEXT_EMBEDDER}" + -P "${DAEMON_FILE_EMBEDDER}" MAIN_DEPENDENCY ${inpath} DEPENDS "${DAEMON_FILE_EMBEDDER}" From 2f790846ef60ffda5b34f5920cc80396ace5bd0c Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 9 Oct 2025 04:16:39 +0200 Subject: [PATCH 13/15] DaemonSourceGenerator: add license --- cmake/DaemonSourceGenerator.cmake | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index 5dc59ccc0f..d3d3fcc546 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -1,3 +1,29 @@ +# Daemon BSD Source Code +# Copyright (c) 2025, Daemon Developers +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of the nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + set(DAEMON_SOURCE_GENERATOR "${CMAKE_CURRENT_LIST_FILE}") get_filename_component(current_list_dir "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) set(DAEMON_FILE_EMBEDDER "${current_list_dir}/DaemonFileEmbedder.cmake") From 350f28a12690c66360ea537c8e00ff9245af63cb Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 16 Oct 2025 17:11:09 +0200 Subject: [PATCH 14/15] =?UTF-8?q?DaemonSourceGenerator:=20use=20file(GENER?= =?UTF-8?q?ATE=20=E2=80=A6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmake/DaemonSourceGenerator.cmake | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index d3d3fcc546..a0c5b8b2ef 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -58,26 +58,12 @@ macro(daemon_add_buildinfo type name value) string(APPEND DAEMON_BUILDINFO_H_TEXT "extern const ${type} ${name};\n") endmacro() -macro(daemon_write_generated generated_path generated_content) - set(DAEMON_GENERATED_FILE ${DAEMON_GENERATED_DIR}/${generated_path}) - - if (EXISTS "${DAEMON_GENERATED_FILE}") - file(READ "${DAEMON_GENERATED_FILE}" generated_content_read) - endif() - - if (NOT "${generated_content}" STREQUAL "${generated_content_read}") - message(STATUS "Generating ${generated_path}") - file(WRITE "${DAEMON_GENERATED_FILE}" "${generated_content}") - endif() -endmacro() - macro(daemon_write_buildinfo name) foreach(kind CPP H) - set(daemon_buildinfo_${kind}_name "${name}${DAEMON_GENERATED_${kind}_EXT}") - set(daemon_buildinfo_${kind}_path "${DAEMON_BUILDINFO_SUBDIR}/${daemon_buildinfo_${kind}_name}") + set(buildinfo_file_path "${DAEMON_BUILDINFO_DIR}/${name}${DAEMON_GENERATED_${kind}_EXT}") - daemon_write_generated("${daemon_buildinfo_${kind}_path}" "${DAEMON_BUILDINFO_${kind}_TEXT}") - list(APPEND BUILDINFOLIST "${DAEMON_GENERATED_FILE}") + file(GENERATE OUTPUT "${buildinfo_file_path}" CONTENT "${DAEMON_BUILDINFO_${kind}_TEXT}") + list(APPEND BUILDINFOLIST "${buildinfo_file_path}") endforeach() endmacro() @@ -162,6 +148,7 @@ macro(daemon_embed_files basename slug format targetname) ) foreach(kind CPP H) - daemon_write_generated("${embed_${kind}_file}" "${embed_${kind}_text}") + set(embed_file "${DAEMON_GENERATED_DIR}/${embed_${kind}_file}") + file(GENERATE OUTPUT "${embed_file}" CONTENT "${embed_${kind}_text}") endforeach() endmacro() From b3d0517e2dff4b7b810e50788d7ed6f0dd7c58f6 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 16 Oct 2025 17:29:11 +0200 Subject: [PATCH 15/15] DaemonSourceGenerator: use explicit variable names --- CMakeLists.txt | 2 +- cmake/DaemonSourceGenerator.cmake | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17d2739a87..028bbd3188 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -928,7 +928,7 @@ if (BUILD_CLIENT) ) # Generate GLSL include files. - daemon_embed_files("EngineShaders" "GLSL" "TEXT" "client-objects") + daemon_embed_files("EngineShaders" "${GLSL_EMBED_DIR}" "${GLSL_EMBED_LIST}" "TEXT" "client-objects") endif() if (BUILD_SERVER) diff --git a/cmake/DaemonSourceGenerator.cmake b/cmake/DaemonSourceGenerator.cmake index a0c5b8b2ef..cd1559838e 100644 --- a/cmake/DaemonSourceGenerator.cmake +++ b/cmake/DaemonSourceGenerator.cmake @@ -67,10 +67,7 @@ macro(daemon_write_buildinfo name) endforeach() endmacro() -macro(daemon_embed_files basename slug format targetname) - set(embed_source_dir "${slug}_EMBED_DIR") - set(embed_source_list "${slug}_EMBED_LIST") - +macro(daemon_embed_files basename dir list format targetname) set(embed_subdir "${DAEMON_EMBEDDED_SUBDIR}/${basename}") set(embed_dir "${DAEMON_GENERATED_DIR}/${embed_subdir}") @@ -99,10 +96,10 @@ macro(daemon_embed_files basename slug format targetname) set(embed_map_text "") - foreach(filename ${${embed_source_list}}) + foreach(filename ${list}) string(REGEX REPLACE "[^A-Za-z0-9]" "_" filename_symbol "${filename}") - set(inpath "${${embed_source_dir}}/${filename}") + set(inpath "${dir}/${filename}") set(outpath "${embed_dir}/${filename_symbol}${DAEMON_GENERATED_H_EXT}") add_custom_command(