if(PLATFORM_WIN32 OR PLATFORM_UNIVERSAL_WINDOWS) function(copy_required_dlls TARGET_NAME) if(D3D11_SUPPORTED) list(APPEND ENGINE_DLLS Diligent-GraphicsEngineD3D11-shared) endif() if(D3D12_SUPPORTED) list(APPEND ENGINE_DLLS Diligent-GraphicsEngineD3D12-shared) endif() if(GL_SUPPORTED) list(APPEND ENGINE_DLLS Diligent-GraphicsEngineOpenGL-shared) endif() if(VULKAN_SUPPORTED) list(APPEND ENGINE_DLLS Diligent-GraphicsEngineVk-shared) endif() if(METAL_SUPPORTED) list(APPEND ENGINE_DLLS Diligent-GraphicsEngineMetal-shared) endif() foreach(DLL ${ENGINE_DLLS}) add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different "\"$\"" "\"$\"") endforeach(DLL) # Copy D3Dcompiler_47.dll, dxcompiler.dll, and dxil.dll if(MSVC) if ((D3D11_SUPPORTED OR D3D12_SUPPORTED) AND VS_D3D_COMPILER_PATH) # Note that VS_D3D_COMPILER_PATH can only be used in a Visual Studio command # and is not a valid path during CMake configuration list(APPEND SHADER_COMPILER_DLLS ${VS_D3D_COMPILER_PATH}) endif() if(D3D12_SUPPORTED AND VS_DXC_COMPILER_PATH AND VS_DXIL_SIGNER_PATH) # For the compiler to sign the bytecode, you have to have a copy of dxil.dll in # the same folder as the dxcompiler.dll at runtime. # Note that VS_DXC_COMPILER_PATH and VS_DXIL_SIGNER_PATH can only be used in a Visual Studio command # and are not valid paths during CMake configuration list(APPEND SHADER_COMPILER_DLLS ${VS_DXC_COMPILER_PATH}) list(APPEND SHADER_COMPILER_DLLS ${VS_DXIL_SIGNER_PATH}) endif() foreach(DLL ${SHADER_COMPILER_DLLS}) add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DLL} "\"$\"") endforeach(DLL) if(VULKAN_SUPPORTED) if(NOT DEFINED DILIGENT_DXCOMPILER_FOR_SPIRV_PATH) message(FATAL_ERROR "DILIGENT_DXCOMPILER_FOR_SPIRV_PATH is undefined, check order of cmake includes") endif() if(EXISTS ${DILIGENT_DXCOMPILER_FOR_SPIRV_PATH}) add_custom_command(TARGET ${TARGET_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DILIGENT_DXCOMPILER_FOR_SPIRV_PATH} "\"$/spv_dxcompiler.dll\"") endif() endif() endif() endfunction() function(package_required_dlls TARGET_NAME) if(D3D12_SUPPORTED AND VS_DXC_COMPILER_PATH AND VS_DXIL_SIGNER_PATH) # Copy the dlls to the project's CMake binary dir # Note that VS_DXC_COMPILER_PATH and VS_DXIL_SIGNER_PATH can only be used in a Visual Studio command # and are not valid paths during CMake configuration add_custom_command(TARGET ${TARGET_NAME} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${VS_DXC_COMPILER_PATH} "\"${CMAKE_CURRENT_BINARY_DIR}/dxcompiler.dll\"" COMMAND ${CMAKE_COMMAND} -E copy_if_different ${VS_DXIL_SIGNER_PATH} "\"${CMAKE_CURRENT_BINARY_DIR}/dxil.dll\"") set(DLLS "${CMAKE_CURRENT_BINARY_DIR}/dxcompiler.dll" "${CMAKE_CURRENT_BINARY_DIR}/dxil.dll") # Add the dlls to the target project as source files target_sources(${TARGET_NAME} PRIVATE ${DLLS}) # Label them as content set_source_files_properties(${DLLS} PROPERTIES GENERATED TRUE VS_DEPLOYMENT_CONTENT 1 VS_DEPLOYMENT_LOCATION ".") endif() endfunction() # Set dll output name by adding _{32|64}{r|d} suffix function(set_dll_output_name TARGET_NAME OUTPUT_NAME_WITHOUT_SUFFIX) foreach(DBG_CONFIG ${DEBUG_CONFIGURATIONS}) set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME_${DBG_CONFIG} ${OUTPUT_NAME_WITHOUT_SUFFIX}${DLL_DBG_SUFFIX} ) endforeach() foreach(REL_CONFIG ${RELEASE_CONFIGURATIONS}) set_target_properties(${TARGET_NAME} PROPERTIES OUTPUT_NAME_${REL_CONFIG} ${OUTPUT_NAME_WITHOUT_SUFFIX}${DLL_REL_SUFFIX} ) endforeach() endfunction() endif(PLATFORM_WIN32 OR PLATFORM_UNIVERSAL_WINDOWS) function(set_common_target_properties TARGET) if(COMMAND custom_pre_configure_target) custom_pre_configure_target(${TARGET}) if(TARGET_CONFIGURATION_COMPLETE) return() endif() endif() get_target_property(TARGET_TYPE ${TARGET} TYPE) if(MSVC) # For msvc, enable link-time code generation for release builds (I was not able to # find any way to set these settings through interface library BuildSettings) if(TARGET_TYPE STREQUAL STATIC_LIBRARY) foreach(REL_CONFIG ${RELEASE_CONFIGURATIONS}) set_target_properties(${TARGET} PROPERTIES STATIC_LIBRARY_FLAGS_${REL_CONFIG} /LTCG ) endforeach() else() foreach(REL_CONFIG ${RELEASE_CONFIGURATIONS}) set_target_properties(${TARGET} PROPERTIES LINK_FLAGS_${REL_CONFIG} "/LTCG /OPT:REF /INCREMENTAL:NO" ) endforeach() if(PLATFORM_UNIVERSAL_WINDOWS) # On UWP, disable incremental link to avoid linker warnings foreach(DBG_CONFIG ${DEBUG_CONFIGURATIONS}) set_target_properties(${TARGET} PROPERTIES LINK_FLAGS_${DBG_CONFIG} "/INCREMENTAL:NO" ) endforeach() endif() endif() else() set_target_properties(${TARGET} PROPERTIES CXX_VISIBILITY_PRESET hidden # -fvisibility=hidden C_VISIBILITY_PRESET hidden # -fvisibility=hidden VISIBILITY_INLINES_HIDDEN TRUE # Without -fPIC option GCC fails to link static libraries into dynamic library: # -fPIC # If supported for the target machine, emit position-independent code, suitable for # dynamic linking and avoiding any limit on the size of the global offset table. POSITION_INDEPENDENT_CODE ON # It is crucial to set CXX_STANDARD flag to only affect c++ files and avoid failures compiling c-files: # error: invalid argument '-std=c++11' not allowed with 'C/ObjC' CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON C_STANDARD 11 ) if(NOT MINGW_BUILD) # Do not disable extensions when building with MinGW! set_target_properties(${TARGET} PROPERTIES CXX_EXTENSIONS OFF ) endif() endif() if(COMMAND custom_post_configure_target) custom_post_configure_target(${TARGET}) endif() endfunction() function(find_targets_in_directory _RESULT _DIR) get_property(_subdirs DIRECTORY "${_DIR}" PROPERTY SUBDIRECTORIES) foreach(_subdir IN LISTS _subdirs) find_targets_in_directory(${_RESULT} "${_subdir}") endforeach() get_property(_SUB_TARGETS DIRECTORY "${_DIR}" PROPERTY BUILDSYSTEM_TARGETS) set(${_RESULT} ${${_RESULT}} ${_SUB_TARGETS} PARENT_SCOPE) endfunction() function(set_directory_root_folder _DIRECTORY _ROOT_FOLDER) find_targets_in_directory(_TARGETS ${_DIRECTORY}) foreach(_TARGET IN LISTS _TARGETS) get_target_property(_FOLDER ${_TARGET} FOLDER) if(_FOLDER) set_target_properties(${_TARGET} PROPERTIES FOLDER "${_ROOT_FOLDER}/${_FOLDER}") else() set_target_properties(${_TARGET} PROPERTIES FOLDER "${_ROOT_FOLDER}") endif() endforeach() endfunction() # Returns default backend library type (static/dynamic) for the current platform function(get_backend_libraries_type _LIB_TYPE) if(PLATFORM_WIN32 OR PLATFORM_LINUX OR PLATFORM_ANDROID OR PLATFORM_UNIVERSAL_WINDOWS OR PLATFORM_MACOS) set(LIB_TYPE "shared") elseif(PLATFORM_IOS) # Statically link with the engine on iOS. # It is also possible to link dynamically by # putting the library into the framework. set(LIB_TYPE "static") else() message(FATAL_ERROR "Undefined platform") endif() set(${_LIB_TYPE} ${LIB_TYPE} PARENT_SCOPE) endfunction() # Adds the list of supported backend targets to variable ${_TARGETS} in parent scope. # Second argument to the function may override the target type (static/dynamic). If It # is not given, default target type for the platform is used. function(get_supported_backends _TARGETS) if(${ARGC} GREATER 1) set(LIB_TYPE ${ARGV1}) else() get_backend_libraries_type(LIB_TYPE) endif() if(D3D11_SUPPORTED) list(APPEND BACKENDS Diligent-GraphicsEngineD3D11-${LIB_TYPE}) endif() if(D3D12_SUPPORTED) list(APPEND BACKENDS Diligent-GraphicsEngineD3D12-${LIB_TYPE}) endif() if(GL_SUPPORTED OR GLES_SUPPORTED) list(APPEND BACKENDS Diligent-GraphicsEngineOpenGL-${LIB_TYPE}) endif() if(VULKAN_SUPPORTED) list(APPEND BACKENDS Diligent-GraphicsEngineVk-${LIB_TYPE}) endif() if(METAL_SUPPORTED) list(APPEND BACKENDS Diligent-GraphicsEngineMetal-${LIB_TYPE}) endif() # ${_TARGETS} == ENGINE_LIBRARIES # ${${_TARGETS}} == ${ENGINE_LIBRARIES} set(${_TARGETS} ${${_TARGETS}} ${BACKENDS} PARENT_SCOPE) endfunction() # Returns path to the target relative to CMake root function(get_target_relative_dir _TARGET _DIR) get_target_property(TARGET_SOURCE_DIR ${_TARGET} SOURCE_DIR) file(RELATIVE_PATH TARGET_RELATIVE_PATH "${CMAKE_SOURCE_DIR}" "${TARGET_SOURCE_DIR}") set(${_DIR} ${TARGET_RELATIVE_PATH} PARENT_SCOPE) endfunction() # Performs installation steps for the core library function(install_core_lib _TARGET) get_target_relative_dir(${_TARGET} TARGET_RELATIVE_PATH) get_target_property(TARGET_TYPE ${_TARGET} TYPE) if(TARGET_TYPE STREQUAL STATIC_LIBRARY) list(APPEND DILIGENT_CORE_INSTALL_LIBS_LIST ${_TARGET}) set(DILIGENT_CORE_INSTALL_LIBS_LIST ${DILIGENT_CORE_INSTALL_LIBS_LIST} CACHE INTERNAL "Core libraries installation list") elseif(TARGET_TYPE STREQUAL SHARED_LIBRARY) install(TARGETS ${_TARGET} ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}/${DILIGENT_CORE_DIR}/$" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}/${DILIGENT_CORE_DIR}/$" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}/${DILIGENT_CORE_DIR}/$" ) if (DILIGENT_INSTALL_PDB) install(FILES $ DESTINATION "${CMAKE_INSTALL_BINDIR}/${DILIGENT_CORE_DIR}/$" OPTIONAL) endif() endif() if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/interface") install(DIRECTORY interface DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${TARGET_RELATIVE_PATH}/" ) endif() endfunction() function(install_combined_static_lib COMBINED_LIB_NAME LIBS_LIST CUSTOM_TARGET_NAME CUSTOM_TARGET_FOLDER INSTALL_DESTINATION) foreach(LIB ${LIBS_LIST}) list(APPEND COMBINED_LIB_TARGET_FILES $) endforeach(LIB) if(MSVC) add_custom_command( OUTPUT ${COMBINED_LIB_NAME} COMMAND lib.exe /OUT:${COMBINED_LIB_NAME} ${COMBINED_LIB_TARGET_FILES} DEPENDS ${LIBS_LIST} COMMENT "Combining libraries..." ) add_custom_target(${CUSTOM_TARGET_NAME} ALL DEPENDS ${COMBINED_LIB_NAME}) else() if(PLATFORM_WIN32) # do NOT use stock ar on MinGW find_program(AR NAMES x86_64-w64-mingw32-gcc-ar) else() set(AR ${CMAKE_AR}) endif() if(AR) add_custom_command( OUTPUT ${COMBINED_LIB_NAME} # Delete all object files from current directory COMMAND ${CMAKE_COMMAND} -E remove "*${CMAKE_C_OUTPUT_EXTENSION}" DEPENDS ${LIBS_LIST} COMMENT "Combining libraries..." ) # Unpack all object files from all targets to current directory foreach(LIB_TARGET ${COMBINED_LIB_TARGET_FILES}) add_custom_command( OUTPUT ${COMBINED_LIB_NAME} COMMAND ${AR} -x ${LIB_TARGET} APPEND ) endforeach() # Pack object files to a combined library and delete them add_custom_command( OUTPUT ${COMBINED_LIB_NAME} COMMAND ${AR} -crs ${COMBINED_LIB_NAME} "*${CMAKE_C_OUTPUT_EXTENSION}" COMMAND ${CMAKE_COMMAND} -E remove "*${CMAKE_C_OUTPUT_EXTENSION}" APPEND ) add_custom_target(${CUSTOM_TARGET_NAME} ALL DEPENDS ${COMBINED_LIB_NAME}) else() message("ar command is not found") endif() endif() if(TARGET ${CUSTOM_TARGET_NAME}) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${COMBINED_LIB_NAME}" DESTINATION ${INSTALL_DESTINATION} ) set_target_properties(${CUSTOM_TARGET_NAME} PROPERTIES FOLDER ${CUSTOM_TARGET_FOLDER} ) else() message("Unable to find librarian tool. Combined ${COMBINED_LIB_NAME} static library will not be produced.") endif() endfunction() function(add_format_validation_target MODULE_NAME MODULE_ROOT_PATH IDE_FOLDER) if(${DILIGENT_NO_FORMAT_VALIDATION}) return() endif() # Start by copying .clang-format file to the module's root folder add_custom_target(${MODULE_NAME}-ValidateFormatting ALL COMMAND ${CMAKE_COMMAND} -E copy_if_different "${DILIGENT_CORE_SOURCE_DIR}/.clang-format" "${MODULE_ROOT_PATH}/.clang-format" ) if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") set(RUN_VALIDATION_SCRIPT validate_format_win.bat) elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux") set(RUN_VALIDATION_SCRIPT ./validate_format_linux.sh) elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") set(RUN_VALIDATION_SCRIPT ./validate_format_mac.sh) else() mesage(FATAL_ERROR "Unexpected host system") endif() # Run the format validation script add_custom_command(TARGET ${MODULE_NAME}-ValidateFormatting COMMAND ${RUN_VALIDATION_SCRIPT} WORKING_DIRECTORY "${MODULE_ROOT_PATH}/BuildTools/FormatValidation" COMMENT "Validating ${MODULE_NAME} module's source code formatting..." VERBATIM ) if(TARGET ${MODULE_NAME}-ValidateFormatting) set_target_properties(${MODULE_NAME}-ValidateFormatting PROPERTIES FOLDER ${IDE_FOLDER}) endif() endfunction()