From c59a56eeea63c3e7c5d6ab4c1fd97fa0f0a254ab Mon Sep 17 00:00:00 2001 From: Euclid Skyline Date: Fri, 30 Jan 2026 01:49:39 +0300 Subject: [PATCH 1/5] Add root CMakeLists.txt to facilitate project structure and subdirectory access --- CMakeLists.txt | 8 ++++++++ attachments/CMakeLists.txt | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..02c16a09 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required (VERSION 3.29) + +project (VulkanTutorialRoot) +# This is to allow the CMakeLists.txt files in attachments/ to be accessed from root level +# Use command: cmake -S . -B build to configure from root level +add_subdirectory(attachments) + +# Any other subdirectories can be added here \ No newline at end of file diff --git a/attachments/CMakeLists.txt b/attachments/CMakeLists.txt index 1261ca30..aafaea3c 100644 --- a/attachments/CMakeLists.txt +++ b/attachments/CMakeLists.txt @@ -95,7 +95,7 @@ function (add_shaders_target TARGET) COMMAND glslang::validator ARGS --target-env vulkan1.0 ${SHADER_SOURCES} --quiet WORKING_DIRECTORY ${SHADERS_DIR} - DEPENDS ${SHADERS_DIR} ${SHADER_SOURCES} + DEPENDS ${SHADER_SOURCES} COMMENT "Compiling Shaders" VERBATIM ) @@ -118,7 +118,7 @@ function (add_slang_shader_target TARGET) OUTPUT ${SHADERS_DIR}/slang.spv COMMAND ${SLANGC_EXECUTABLE} ${SHADER_SOURCES} -target spirv -profile spirv_1_4+spvRayQueryKHR -emit-spirv-directly -fvk-use-entrypoint-name ${ENTRY_POINTS} -o slang.spv WORKING_DIRECTORY ${SHADERS_DIR} - DEPENDS ${SHADERS_DIR} ${SHADER_SOURCES} + DEPENDS ${SHADER_SOURCES} COMMENT "Compiling Slang Shaders" VERBATIM ) @@ -165,11 +165,11 @@ function (add_chapter CHAPTER_NAME) target_link_libraries (${CHAPTER_NAME} ${CHAPTER_LIBS}) endif () if (DEFINED CHAPTER_MODELS) - list(TRANSFORM CHAPTER_MODELS PREPEND "${CMAKE_SOURCE_DIR}/assets/") + list(TRANSFORM CHAPTER_MODELS PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/assets/") file (COPY ${CHAPTER_MODELS} DESTINATION ${CMAKE_BINARY_DIR}/${CHAPTER_NAME}/models) endif () if (DEFINED CHAPTER_TEXTURES) - list(TRANSFORM CHAPTER_TEXTURES PREPEND "${CMAKE_SOURCE_DIR}/assets/") + list(TRANSFORM CHAPTER_TEXTURES PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/assets/") file (COPY ${CHAPTER_TEXTURES} DESTINATION ${CMAKE_BINARY_DIR}/${CHAPTER_NAME}/textures) endif () endfunction () From 6fd788329a2fb78f0ab37966aac3cc85f3193ebf Mon Sep 17 00:00:00 2001 From: Euclid Skyline Date: Fri, 30 Jan 2026 04:14:23 +0300 Subject: [PATCH 2/5] Update .gitignore and CMakeLists.txt for improved build management and shader compilation --- .gitignore | 2 ++ attachments/CMakeLists.txt | 34 +++++++++++++++++----------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index c6d15111..daaecff3 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ ebook/*.epub convert.py +**/[B,b]uild/* + attachments/build/** attachments/android/.gradle/** attachments/android/.idea diff --git a/attachments/CMakeLists.txt b/attachments/CMakeLists.txt index aafaea3c..bea193e2 100644 --- a/attachments/CMakeLists.txt +++ b/attachments/CMakeLists.txt @@ -51,12 +51,12 @@ if(ENABLE_CPP20_MODULE) endif() target_sources(VulkanCppModule - PUBLIC - FILE_SET cxx_modules TYPE CXX_MODULES - BASE_DIRS - "${Vulkan_INCLUDE_DIR}" - FILES - "${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm" + PUBLIC + FILE_SET cxx_modules TYPE CXX_MODULES + BASE_DIRS + "${Vulkan_INCLUDE_DIR}" + FILES + "${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm" ) @@ -85,7 +85,7 @@ find_program(SLANGC_EXECUTABLE slangc HINTS $ENV{VULKAN_SDK}/bin REQUIRED) function (add_shaders_target TARGET) cmake_parse_arguments ("SHADER" "" "CHAPTER_NAME" "SOURCES" ${ARGN}) - set (SHADERS_DIR ${SHADER_CHAPTER_NAME}/shaders) + set (SHADERS_DIR ${CMAKE_BINARY_DIR}/${SHADER_CHAPTER_NAME}/shaders) add_custom_command ( OUTPUT ${SHADERS_DIR} COMMAND ${CMAKE_COMMAND} -E make_directory ${SHADERS_DIR} @@ -96,7 +96,7 @@ function (add_shaders_target TARGET) ARGS --target-env vulkan1.0 ${SHADER_SOURCES} --quiet WORKING_DIRECTORY ${SHADERS_DIR} DEPENDS ${SHADER_SOURCES} - COMMENT "Compiling Shaders" + COMMENT "Compiling Shaders for ${TARGET}" VERBATIM ) add_custom_target (${TARGET} DEPENDS ${SHADERS_DIR}/frag.spv ${SHADERS_DIR}/vert.spv) @@ -104,23 +104,23 @@ endfunction () function (add_slang_shader_target TARGET) cmake_parse_arguments ("SHADER" "" "CHAPTER_NAME" "SOURCES" ${ARGN}) - set (SHADERS_DIR ${SHADER_CHAPTER_NAME}/shaders) + set (SHADERS_DIR ${CMAKE_BINARY_DIR}/${SHADER_CHAPTER_NAME}/shaders) file(GLOB HAS_COMPUTE ${CHAPTER_SHADER}.comp) set (ENTRY_POINTS -entry vertMain -entry fragMain) if(HAS_COMPUTE) list(APPEND ENTRY_POINTS -entry compMain) endif() add_custom_command ( - OUTPUT ${SHADERS_DIR} - COMMAND ${CMAKE_COMMAND} -E make_directory ${SHADERS_DIR} + OUTPUT ${SHADERS_DIR} + COMMAND ${CMAKE_COMMAND} -E make_directory ${SHADERS_DIR} ) add_custom_command ( - OUTPUT ${SHADERS_DIR}/slang.spv - COMMAND ${SLANGC_EXECUTABLE} ${SHADER_SOURCES} -target spirv -profile spirv_1_4+spvRayQueryKHR -emit-spirv-directly -fvk-use-entrypoint-name ${ENTRY_POINTS} -o slang.spv - WORKING_DIRECTORY ${SHADERS_DIR} - DEPENDS ${SHADER_SOURCES} - COMMENT "Compiling Slang Shaders" - VERBATIM + OUTPUT ${SHADERS_DIR}/slang.spv + COMMAND ${SLANGC_EXECUTABLE} ${SHADER_SOURCES} -target spirv -profile spirv_1_4+spvRayQueryKHR -emit-spirv-directly -fvk-use-entrypoint-name ${ENTRY_POINTS} -o slang.spv + WORKING_DIRECTORY ${SHADERS_DIR} + DEPENDS ${SHADER_SOURCES} + COMMENT "Compiling Slang Shaders for ${TARGET}" + VERBATIM ) add_custom_target (${TARGET} DEPENDS ${SHADERS_DIR}/slang.spv) endfunction() From d8640f418783fccb2986ae77f2286b078203f3fb Mon Sep 17 00:00:00 2001 From: Euclid Skyline Date: Fri, 30 Jan 2026 11:51:49 +0300 Subject: [PATCH 3/5] Add sync_directory function and post-build asset synchronization for chapters in Visual Studio generator and Ninja Multi-Config generator --- attachments/CMakeLists.txt | 58 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/attachments/CMakeLists.txt b/attachments/CMakeLists.txt index bea193e2..ad7e2c4d 100644 --- a/attachments/CMakeLists.txt +++ b/attachments/CMakeLists.txt @@ -125,6 +125,24 @@ function (add_slang_shader_target TARGET) add_custom_target (${TARGET} DEPENDS ${SHADERS_DIR}/slang.spv) endfunction() +function(sync_directory SRC_DIR DST_DIR TARGET_NAME LABEL) + file(GLOB_RECURSE FILES "${SRC_DIR}/*") + + foreach(FILE IN LISTS FILES) + file(RELATIVE_PATH REL_PATH "${SRC_DIR}" "${FILE}") + set(DST_FILE "${DST_DIR}/${REL_PATH}") + get_filename_component(DST_DIR_PATH "${DST_FILE}" DIRECTORY) + + add_custom_command( + TARGET ${TARGET_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "${DST_DIR_PATH}" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${FILE}" "${DST_FILE}" + COMMENT "${LABEL}: Syncing ${REL_PATH}" + ) + endforeach() +endfunction() + function (add_chapter CHAPTER_NAME) cmake_parse_arguments (CHAPTER "" "SHADER" "LIBS;TEXTURES;MODELS" ${ARGN}) add_executable (${CHAPTER_NAME} ${CHAPTER_NAME}.cpp) @@ -172,6 +190,46 @@ function (add_chapter CHAPTER_NAME) list(TRANSFORM CHAPTER_TEXTURES PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/assets/") file (COPY ${CHAPTER_TEXTURES} DESTINATION ${CMAKE_BINARY_DIR}/${CHAPTER_NAME}/textures) endif () + + # Post-build step to copy assets to executable directory + if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*" OR + ${CMAKE_GENERATOR} MATCHES "Ninja Multi-Config") + + set(EXECUTABLE_DIR $) + + add_custom_target(${CHAPTER_NAME}_postbuild ALL + COMMENT "${CHAPTER_NAME}: Post-build asset sync" + ) + + add_dependencies(${CHAPTER_NAME}_postbuild ${CHAPTER_NAME}) + + if(DEFINED CHAPTER_SHADER) + sync_directory( + "${CMAKE_BINARY_DIR}/${CHAPTER_NAME}/shaders" + "${EXECUTABLE_DIR}/shaders" + ${CHAPTER_NAME} + "${CHAPTER_NAME}: Shaders" + ) + endif() + + if(DEFINED CHAPTER_MODELS) + sync_directory( + "${CMAKE_BINARY_DIR}/${CHAPTER_NAME}/models" + "${EXECUTABLE_DIR}/models" + ${CHAPTER_NAME} + "${CHAPTER_NAME}: Models" + ) + endif() + + if(DEFINED CHAPTER_TEXTURES) + sync_directory( + "${CMAKE_BINARY_DIR}/${CHAPTER_NAME}/textures" + "${EXECUTABLE_DIR}/textures" + ${CHAPTER_NAME} + "${CHAPTER_NAME}: Textures" + ) + endif() + endif() endfunction () add_chapter (00_base_code) From 19a620bd598dd370417409ab083906d304c348cb Mon Sep 17 00:00:00 2001 From: Euclid Skyline Date: Fri, 30 Jan 2026 12:19:11 +0300 Subject: [PATCH 4/5] Enhance root CMakeLists.txt with additional build instructions and comments for clarity --- CMakeLists.txt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 02c16a09..cbd76ba7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,16 @@ cmake_minimum_required (VERSION 3.29) project (VulkanTutorialRoot) # This is to allow the CMakeLists.txt files in attachments/ to be accessed from root level # Use command: cmake -S . -B build to configure from root level +# Then use command: cmake --build build to build from root level +# This will generate the build files in the build/ directory +# The build files will reference the source files in the attachments/ directory +# No need to change or delete any lines in attachments/ CMakeLists.txt files +# You can still build from attachments/ directory if needed +# Just navigate to attachments/ and run cmake and build commands as usual add_subdirectory(attachments) -# Any other subdirectories can be added here \ No newline at end of file +# Any other subdirectories can be added here +# Need to be carefull using CMAKE_SOURCE_DIR is points to the root level CMakeLists.txt +# Use CMAKE_CURRENT_SOURCE_DIR to point to the current directory instead +# For Simple Vulkan Engine project please uncomment the following line +# add_subdirectory(attachments/simple_engine) \ No newline at end of file From aa83dc8de1e63a0c07dd2dec0e72da42694ca10d Mon Sep 17 00:00:00 2001 From: Euclid Skyline Date: Fri, 30 Jan 2026 17:14:13 +0300 Subject: [PATCH 5/5] Refactor sync_directory function and update post-build asset synchronization by removing dependency on any previous tasks (executable build task or shaders targets). The post-build task will garntee only the copy-if-different of shader/texture/modele files to proper location in case of Visual Studio or Ninja Multi-Config. --- attachments/CMakeLists.txt | 43 ++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 25 deletions(-) diff --git a/attachments/CMakeLists.txt b/attachments/CMakeLists.txt index ad7e2c4d..8fed8649 100644 --- a/attachments/CMakeLists.txt +++ b/attachments/CMakeLists.txt @@ -125,24 +125,6 @@ function (add_slang_shader_target TARGET) add_custom_target (${TARGET} DEPENDS ${SHADERS_DIR}/slang.spv) endfunction() -function(sync_directory SRC_DIR DST_DIR TARGET_NAME LABEL) - file(GLOB_RECURSE FILES "${SRC_DIR}/*") - - foreach(FILE IN LISTS FILES) - file(RELATIVE_PATH REL_PATH "${SRC_DIR}" "${FILE}") - set(DST_FILE "${DST_DIR}/${REL_PATH}") - get_filename_component(DST_DIR_PATH "${DST_FILE}" DIRECTORY) - - add_custom_command( - TARGET ${TARGET_NAME} - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E make_directory "${DST_DIR_PATH}" - COMMAND ${CMAKE_COMMAND} -E copy_if_different "${FILE}" "${DST_FILE}" - COMMENT "${LABEL}: Syncing ${REL_PATH}" - ) - endforeach() -endfunction() - function (add_chapter CHAPTER_NAME) cmake_parse_arguments (CHAPTER "" "SHADER" "LIBS;TEXTURES;MODELS" ${ARGN}) add_executable (${CHAPTER_NAME} ${CHAPTER_NAME}.cpp) @@ -196,13 +178,6 @@ function (add_chapter CHAPTER_NAME) ${CMAKE_GENERATOR} MATCHES "Ninja Multi-Config") set(EXECUTABLE_DIR $) - - add_custom_target(${CHAPTER_NAME}_postbuild ALL - COMMENT "${CHAPTER_NAME}: Post-build asset sync" - ) - - add_dependencies(${CHAPTER_NAME}_postbuild ${CHAPTER_NAME}) - if(DEFINED CHAPTER_SHADER) sync_directory( "${CMAKE_BINARY_DIR}/${CHAPTER_NAME}/shaders" @@ -232,6 +207,24 @@ function (add_chapter CHAPTER_NAME) endif() endfunction () +function(sync_directory SRC_DIR DST_DIR TARGET_NAME LABEL) + file(GLOB_RECURSE FILES "${SRC_DIR}/*") + + foreach(FILE IN LISTS FILES) + file(RELATIVE_PATH REL_PATH "${SRC_DIR}" "${FILE}") + set(DST_FILE "${DST_DIR}/${REL_PATH}") + get_filename_component(DST_DIR_PATH "${DST_FILE}" DIRECTORY) + + add_custom_command( + TARGET ${TARGET_NAME} + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory "${DST_DIR_PATH}" + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${FILE}" "${DST_FILE}" + COMMENT "${LABEL}: Syncing ${REL_PATH}" + ) + endforeach() +endfunction() + add_chapter (00_base_code) add_chapter (01_instance_creation)