cmake_minimum_required (VERSION 3.29) project(VulkanEngine) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake") include(BuildInfo) include(FetchContent) #LTO include(CheckIPOSupported) check_ipo_supported(RESULT LTO_SUPPORTED OUTPUT LTO_ERROR) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") find_program(GCC_AR NAMES gcc-ar REQUIRED) find_program(GCC_RANLIB NAMES gcc-ranlib REQUIRED) set(CMAKE_AR "${GCC_AR}") set(CMAKE_RANLIB "${GCC_RANLIB}") endif() # Find all package dependencies find_package( glfw3 REQUIRED ) find_package( glm REQUIRED ) find_package( VulkanMemoryAllocator CONFIG REQUIRED ) find_package( fmt REQUIRED ) # Shader compilers # Todo add_executable (glslang::validator IMPORTED) find_program (GLSLANG_VALIDATOR "glslangValidator" HINTS $ENV{VULKAN_SDK}/bin REQUIRED) set_property (TARGET glslang::validator PROPERTY IMPORTED_LOCATION "${GLSLANG_VALIDATOR}") find_program(SLANGC_EXECUTABLE slangc HINTS $ENV{VULKAN_SDK}/bin REQUIRED) # fastgltf because it's not in nixpkgs FetchContent_Declare( fastgltf GIT_REPOSITORY https://github.com/spnda/fastgltf.git GIT_TAG v0.8.0 ) FetchContent_MakeAvailable(fastgltf) # vk-bootstrap because CMAKE can't find it on NixOS FetchContent_Declare( vk-bootstrap GIT_REPOSITORY https://github.com/charles-lunarg/vk-bootstrap.git GIT_TAG v1.3.295 ) FetchContent_MakeAvailable(vk-bootstrap) # Helper functions to build shaders function(addGlslShader SOURCE OUTPUT_DIR) get_filename_component(SHADER_NAME ${SOURCE} NAME_WE) set(SPV_FILE "${OUTPUT_DIR}/${SHADER_NAME}.spv") add_custom_command( OUTPUT ${SPV_FILE} COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTPUT_DIR} COMMAND glslang::validator -V --target-env vulkan1.3 # Change if needed -o ${SPV_FILE} ${SOURCE} DEPENDS ${SOURCE} COMMENT "Compiling GLSL shader: ${SOURCE} -> ${SPV_FILE}" VERBATIM ) set(SPV_FILE ${SPV_FILE} PARENT_SCOPE) endfunction() function(addSlangShader SOURCES ENTRY_POINTS OUTPUT_DIR) set(SPV_FILE "${OUTPUT_DIR}/slang.spv") add_custom_command( OUTPUT ${SPV_FILE} COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTPUT_DIR} COMMAND ${SLANGC_EXECUTABLE} ${SOURCES} -target spirv -profile spirv_1_4+spvRayQueryKHR # Change if needed -emit-spirv-directly -fvk-use-entrypoint-name ${ENTRY_POINTS} -o ${SPV_FILE} DEPENDS ${SOURCES} COMMENT "Compiling Slang shaders -> ${SPV_FILE}" VERBATIM ) set(SPV_FILE ${SPV_FILE} PARENT_SCOPE) endfunction() # A function to automate executables aditions function ( addBinary BINARY_NAME ) cmake_parse_arguments ( BINARY "" "SOURCE" "SHADERS;SLANG_SHADERS;LIBS;TEXTURES;MODELS" ${ARGN} ) if (DEFINED BINARY_SOURCE) add_executable ( ${BINARY_NAME} src/${BINARY_SOURCE}.cpp ) endif() target_include_directories( ${BINARY_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src ) # Sets the output dir to have clear separation between binaries set_target_properties ( ${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${BINARY_NAME} ) set_target_properties ( ${BINARY_NAME} PROPERTIES CXX_STANDARD 20 ) # Uses C++20 # Sets per binary LTO if(LTO_SUPPORTED AND CMAKE_BUILD_TYPE STREQUAL "Release") set_target_properties(${BINARY_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE) message("Enabled LTO") endif() set_target_properties(${BINARY_NAME} PROPERTIES CXX_SCAN_FOR_MODULES OFF) # Define VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS to treat VK_ERROR_OUT_OF_DATE_KHR as a success code target_compile_definitions ( ${BINARY_NAME} PRIVATE "VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS" $<$:DEBUG> # So CMAKE expose a #define DEBUG for debug builds # Exposes versions BUILD_ID="${ENGINE_VERSION}" ) if(DEFINED BINARY_SHADERS) set(SHADER_OUTPUT_DIR ${CMAKE_BINARY_DIR}/${BINARY_NAME}/shaders) set(ALL_SPV_FILES "") foreach(SHADER_SRC ${BINARY_SHADERS}) if(NOT IS_ABSOLUTE ${SHADER_SRC}) set(SHADER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER_SRC}) endif() addGlslShader(${SHADER_SRC} ${SHADER_OUTPUT_DIR}) list(APPEND ALL_SPV_FILES ${SPV_FILE}) endforeach() add_custom_target(shaders_${BINARY_NAME} DEPENDS ${ALL_SPV_FILES}) add_dependencies(${BINARY_NAME} shaders_${BINARY_NAME}) endif() if(DEFINED BINARY_SLANG_SHADERS) set(SLANG_OUTPUT_DIR ${CMAKE_BINARY_DIR}/${BINARY_NAME}/shaders) if(NOT DEFINED BINARY_SLANG_ENTRIES) message(FATAL_ERROR "addBinary: SLANG_SHADERS nécessite SLANG_ENTRIES") endif() addSlangShader("${BINARY_SLANG_SHADERS}" "${BINARY_SLANG_ENTRIES}" ${SLANG_OUTPUT_DIR}) add_custom_target(slang_shaders_${BINARY_NAME} DEPENDS ${SPV_FILE}) add_dependencies(${BINARY_NAME} slang_shaders_${BINARY_NAME}) endif() if (DEFINED BINARY_LIBS) target_link_libraries ( ${BINARY_NAME} ${BINARY_LIBS} ) endif() if (DEFINED BINARY_MODELS) # Adds the 3D models in the binary folder set(RESOLVED_MODELS "") foreach(MODEL_PATTERN ${BINARY_MODELS}) file(GLOB MATCHED_MODELS CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/assets/models/${MODEL_PATTERN}" ) list(APPEND RESOLVED_MODELS ${MATCHED_MODELS}) endforeach() if (RESOLVED_MODELS) file(COPY ${RESOLVED_MODELS} DESTINATION ${CMAKE_BINARY_DIR}/${BINARY_NAME}/models) endif() endif() if (DEFINED BINARY_TEXTURES) # Adds the textures in the binary folder set(RESOLVED_TEXTURES "") foreach(TEX_PATTERN ${BINARY_TEXTURES}) file(GLOB MATCHED_TEXTURES CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/assets/textures/${TEX_PATTERN}" ) list(APPEND RESOLVED_TEXTURES ${MATCHED_TEXTURES}) endforeach() if (RESOLVED_TEXTURES) file(COPY ${RESOLVED_TEXTURES} DESTINATION ${CMAKE_BINARY_DIR}/${BINARY_NAME}/textures) endif() endif () endfunction() # Adds the main binary addBinary ( engine SOURCE Engine/main SHADERS shaders/gradient.comp LIBS glfw fmt vk-bootstrap vulkan ) addBinary ( server SOURCE Server/main )