From 3d23bb07e375ecabad0ad2e53599861be77310e3 Mon Sep 17 00:00:00 2001 From: Juan Ramos Date: Wed, 5 Jul 2023 13:14:09 -0600 Subject: [PATCH] Make VulkanMemoryAllocator a header only library Dramatically simplify the CMake code for end users. The intent is to make the CMake for this library very easy to maintain. While also making it easier for end users to consume. This makes the CMake code very similar to: - KhronosGroup/Vulkan-Headers - KhronosGroup/SPIRV-Headers Which is good for consistency/expectations. The VmaUsage library still highlights the expected usage of the "stb-style" single header file in a project. closes #346 --- CMakeLists.txt | 82 +++++++++----------- README.md | 45 ++++++----- src/CMakeLists.txt | 135 +++++++++++++-------------------- src/cmake/Config.cmake.in | 14 ---- src/cmake/install_target.cmake | 33 -------- 5 files changed, 110 insertions(+), 199 deletions(-) delete mode 100644 src/cmake/Config.cmake.in delete mode 100644 src/cmake/install_target.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 553822f..cfc31a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,53 +1,43 @@ -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.15...3.26) -project(VulkanMemoryAllocator LANGUAGES CXX) +project(VMA LANGUAGES CXX) -# VulkanMemoryAllocator contains an sample application which is not built by default -option(VMA_BUILD_SAMPLE "Build VulkanMemoryAllocator sample application" OFF) -option(VMA_BUILD_SAMPLE_SHADERS "Build VulkanMemoryAllocator sample application's shaders" OFF) +add_library(VulkanMemoryAllocator INTERFACE) +add_library(GPUOpen::VulkanMemoryAllocator ALIAS VulkanMemoryAllocator) -message(STATUS "VMA_BUILD_SAMPLE = ${VMA_BUILD_SAMPLE}") -message(STATUS "VMA_BUILD_SAMPLE_SHADERS = ${VMA_BUILD_SAMPLE_SHADERS}") +target_include_directories(VulkanMemoryAllocator INTERFACE $) -option(VMA_STATIC_VULKAN_FUNCTIONS "Link statically with Vulkan API" ON) -option(VMA_DYNAMIC_VULKAN_FUNCTIONS "Fetch pointers to Vulkan functions internally (no static linking)" OFF) -option(VMA_DEBUG_ALWAYS_DEDICATED_MEMORY "Every allocation will have its own memory block" OFF) -option(VMA_DEBUG_INITIALIZE_ALLOCATIONS "Automatically fill new allocations and destroyed allocations with some bit pattern" OFF) -option(VMA_DEBUG_GLOBAL_MUTEX "Enable single mutex protecting all entry calls to the library" OFF) -option(VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT "Never exceed VkPhysicalDeviceLimits::maxMemoryAllocationCount and return error" OFF) - -message(STATUS "VMA_STATIC_VULKAN_FUNCTIONS = ${VMA_STATIC_VULKAN_FUNCTIONS}") -message(STATUS "VMA_DYNAMIC_VULKAN_FUNCTIONS = ${VMA_DYNAMIC_VULKAN_FUNCTIONS}") -message(STATUS "VMA_DEBUG_ALWAYS_DEDICATED_MEMORY = ${VMA_DEBUG_ALWAYS_DEDICATED_MEMORY}") -message(STATUS "VMA_DEBUG_INITIALIZE_ALLOCATIONS = ${VMA_DEBUG_INITIALIZE_ALLOCATIONS}") -message(STATUS "VMA_DEBUG_GLOBAL_MUTEX = ${VMA_DEBUG_GLOBAL_MUTEX}") -message(STATUS "VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT = ${VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT}") - -if(VMA_STATIC_VULKAN_FUNCTIONS OR VMA_BUILD_SAMPLE) - find_package(Vulkan REQUIRED) -else() - find_package(VulkanHeaders REQUIRED) +if (CMAKE_VERSION VERSION_LESS "3.21") + # https://cmake.org/cmake/help/latest/variable/PROJECT_IS_TOP_LEVEL.html + string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_TOP_LEVEL) endif() -if(VMA_BUILD_SAMPLE) - set(VMA_BUILD_SAMPLE_SHADERS ON) +if (PROJECT_IS_TOP_LEVEL) + include(GNUInstallDirs) + + install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + install(TARGETS VulkanMemoryAllocator EXPORT VulkanMemoryAllocatorConfig INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + install(EXPORT VulkanMemoryAllocatorConfig NAMESPACE "GPUOpen::" DESTINATION "${CMAKE_INSTALL_DATADIR}/cmake/VulkanMemoryAllocator") + + option(VMA_BUILD_DOCUMENTATION "Create and install the HTML based API documentation") + if(VMA_BUILD_DOCUMENTATION) + find_package(Doxygen REQUIRED) + # set input and output files + set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile) + set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) + # request to configure the file + configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY) + # note the option ALL which allows to build the docs together with the application + add_custom_target(doc_doxygen ALL + COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating API documentation with Doxygen" + VERBATIM + ) + endif() + + option(VMA_BUILD_SAMPLES "Build samples") + if (VMA_BUILD_SAMPLES) + add_subdirectory(src) + endif() endif() - -option(BUILD_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" OFF) - -if(BUILD_DOCUMENTATION) - find_package(Doxygen REQUIRED) - # set input and output files - set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile) - set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) - # request to configure the file - configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY) - # note the option ALL which allows to build the docs together with the application - add_custom_target( doc_doxygen ALL - COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Generating API documentation with Doxygen" - VERBATIM ) -endif() - -add_subdirectory(src) diff --git a/README.md b/README.md index 621bc41..d9a4296 100644 --- a/README.md +++ b/README.md @@ -99,38 +99,37 @@ With this one function call: # How to build -On Windows it is recommended to use [CMake UI](https://cmake.org/runningcmake/). Alternatively you can generate a Visual Studio project map using CMake in command line: `cmake -B./build/ -DCMAKE_BUILD_TYPE=Debug -G "Visual Studio 16 2019" -A x64 ./` +On Windows it is recommended to use [CMake GUI](https://cmake.org/runningcmake/). + +Alternatively you can generate/open a Visual Studio from the command line: + +```sh +# By default CMake picks the newest version of Visual Studio it can use +cmake -S . -B build -D VMA_BUILD_SAMPLES=ON +cmake --open build +``` On Linux: -``` -mkdir build -cd build -cmake .. -make +```sh +cmake -S . -B build +# Since VMA has no source files, you can skip to installation immediately +cmake --install build --prefix build/install ``` -The following targets are available +## How to use -| Target | Description | CMake option | Default setting | -| ------------- | ------------- | ------------- | ------------- | -| VmaSample | VMA sample application | `VMA_BUILD_SAMPLE` | `OFF` | -| VmaBuildSampleShaders | Shaders for VmaSample | `VMA_BUILD_SAMPLE_SHADERS` | `OFF` | +After calling either `find_package` or `add_subdirectory` simply link the library. +This automatically handles configuring the include directory. -Please note that while VulkanMemoryAllocator library is supported on other platforms besides Windows, VmaSample is not. +EX: -These CMake options are available +```cmake +find_package(VulkanMemoryAllocator CONFIG REQUIRED) +target_link_libraries(YourGameEngine PRIVATE GPUOpen::VulkanMemoryAllocator) +``` -| CMake option | Description | Default setting | -| ------------- | ------------- | ------------- | -| `VMA_RECORDING_ENABLED` | Enable VMA memory recording for debugging | `OFF` | -| `VMA_USE_STL_CONTAINERS` | Use C++ STL containers instead of VMA's containers | `OFF` | -| `VMA_STATIC_VULKAN_FUNCTIONS` | Link statically with Vulkan API | `OFF` | -| `VMA_DYNAMIC_VULKAN_FUNCTIONS` | Fetch pointers to Vulkan functions internally (no static linking) | `ON` | -| `VMA_DEBUG_ALWAYS_DEDICATED_MEMORY` | Every allocation will have its own memory block | `OFF` | -| `VMA_DEBUG_INITIALIZE_ALLOCATIONS` | Automatically fill new allocations and destroyed allocations with some bit pattern | `OFF` | -| `VMA_DEBUG_GLOBAL_MUTEX` | Enable single mutex protecting all entry calls to the library | `OFF` | -| `VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT` | Never exceed [VkPhysicalDeviceLimits::maxMemoryAllocationCount](https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#limits-maxMemoryAllocationCount) and return error | `OFF` | +For more info on using CMake visit the official [CMake documentation](https://cmake.org/cmake/help/latest/index.html). ## Building using vcpkg diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 51d7a6e..7f8ea55 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,107 +1,76 @@ -set(CMAKE_DEBUG_POSTFIX d) -set(CMAKE_RELWITHDEBINFO_POSTFIX rd) -set(CMAKE_MINSIZEREL_POSTFIX s) - -add_library(VulkanMemoryAllocator - VmaUsage.cpp - VmaUsage.h - ${PROJECT_SOURCE_DIR}/include/vk_mem_alloc.h -) - -if (MSVC) - # Provides MSVC users nicer debugging support - target_sources(VulkanMemoryAllocator PRIVATE ${CMAKE_CURRENT_LIST_DIR}/vk_mem_alloc.natvis) +if (NOT WIN32) + message(STATUS "VmaSample application is only supported on Windows") + return() endif() -set_target_properties( - VulkanMemoryAllocator PROPERTIES +option(VMA_STATIC_VULKAN_FUNCTIONS "Link statically with Vulkan API" ON) +option(VMA_DYNAMIC_VULKAN_FUNCTIONS "Fetch pointers to Vulkan functions internally (no static linking)" OFF) +option(VMA_DEBUG_ALWAYS_DEDICATED_MEMORY "Every allocation will have its own memory block" OFF) +option(VMA_DEBUG_INITIALIZE_ALLOCATIONS "Automatically fill new allocations and destroyed allocations with some bit pattern" OFF) +option(VMA_DEBUG_GLOBAL_MUTEX "Enable single mutex protecting all entry calls to the library" OFF) +option(VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT "Never exceed VkPhysicalDeviceLimits::maxMemoryAllocationCount and return error" OFF) - CXX_EXTENSIONS OFF - CXX_STANDARD 17 - CXX_STANDARD_REQUIRED ON +message(STATUS "VMA_STATIC_VULKAN_FUNCTIONS = ${VMA_STATIC_VULKAN_FUNCTIONS}") +message(STATUS "VMA_DYNAMIC_VULKAN_FUNCTIONS = ${VMA_DYNAMIC_VULKAN_FUNCTIONS}") +message(STATUS "VMA_DEBUG_ALWAYS_DEDICATED_MEMORY = ${VMA_DEBUG_ALWAYS_DEDICATED_MEMORY}") +message(STATUS "VMA_DEBUG_INITIALIZE_ALLOCATIONS = ${VMA_DEBUG_INITIALIZE_ALLOCATIONS}") +message(STATUS "VMA_DEBUG_GLOBAL_MUTEX = ${VMA_DEBUG_GLOBAL_MUTEX}") +message(STATUS "VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT = ${VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT}") + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +add_library(VmaUsage STATIC) +target_sources(VmaUsage PRIVATE + VmaUsage.cpp + VmaUsage.h ) -target_include_directories(VulkanMemoryAllocator PUBLIC - $ -) +target_link_libraries(VmaUsage PUBLIC GPUOpen::VulkanMemoryAllocator) + +# Provides MSVC users nicer debugging support +target_sources(VmaUsage PRIVATE vk_mem_alloc.natvis) + +find_package(Vulkan REQUIRED) # Only link to Vulkan library if static linking is used, but always add Vulkan headers directory if(VMA_STATIC_VULKAN_FUNCTIONS) - target_link_libraries(VulkanMemoryAllocator PUBLIC Vulkan::Vulkan) + target_link_libraries(VmaUsage PUBLIC Vulkan::Vulkan) else() - target_link_libraries(VulkanMemoryAllocator PUBLIC Vulkan::Headers) + target_link_libraries(VmaUsage PUBLIC Vulkan::Headers) endif() -target_compile_definitions( - VulkanMemoryAllocator - - PUBLIC +target_compile_definitions(VmaUsage PUBLIC VMA_STATIC_VULKAN_FUNCTIONS=$ VMA_DYNAMIC_VULKAN_FUNCTIONS=$ VMA_DEBUG_ALWAYS_DEDICATED_MEMORY=$ VMA_DEBUG_INITIALIZE_ALLOCATIONS=$ VMA_DEBUG_GLOBAL_MUTEX=$ VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT=$ - VMA_RECORDING_ENABLED=$ ) -include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/install_target.cmake) +add_executable(VmaSample) +target_sources(VmaSample PRIVATE + Common.cpp + Common.h + SparseBindingTest.cpp + SparseBindingTest.h + Tests.cpp + Tests.h + VulkanSample.cpp +) -if(VMA_BUILD_SAMPLE) - if(WIN32) - set(VMA_SAMPLE_SOURCE_FILES - Common.cpp - Common.h - SparseBindingTest.cpp - SparseBindingTest.h - Tests.cpp - Tests.h - VulkanSample.cpp - ) +target_link_libraries(VmaSample PRIVATE VmaUsage) - add_executable(VmaSample ${VMA_SAMPLE_SOURCE_FILES}) - add_dependencies(VmaSample VulkanMemoryAllocator VmaSampleShaders) - - if(MSVC) - # Use Unicode instead of multibyte set - add_compile_definitions(UNICODE _UNICODE) - - # Add C++ warnings and security checks - add_compile_options(/permissive- /sdl /W3) - - # Enable multithreaded compiling - target_compile_options(VmaSample PRIVATE "/MP") +add_subdirectory(Shaders) +add_dependencies(VmaSample VmaSampleShaders) - # Set VmaSample as startup project - set_property(DIRECTORY "${PROJECT_SOURCE_DIR}" PROPERTY VS_STARTUP_PROJECT "VmaSample") +# Use Unicode instead of multibyte set +add_compile_definitions(UNICODE _UNICODE) - # Set working directory for Visual Studio debugger - set_target_properties( - VmaSample - PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/bin" - ) - endif() +# Add C++ warnings and security checks +add_compile_options(/permissive- /sdl /W3) - set_target_properties( - VmaSample PROPERTIES - - CXX_EXTENSIONS OFF - CXX_STANDARD 17 - CXX_STANDARD_REQUIRED ON - ) - - target_link_libraries( - VmaSample - PRIVATE - - VulkanMemoryAllocator - Vulkan::Vulkan - ) - else() - message(STATUS "VmaSample application is not supported to Linux") - endif() -endif() - -if(VMA_BUILD_SAMPLE_SHADERS) - add_subdirectory(Shaders) -endif() +# Set VmaSample as startup project +set_property(DIRECTORY "${PROJECT_SOURCE_DIR}" PROPERTY VS_STARTUP_PROJECT "VmaSample") diff --git a/src/cmake/Config.cmake.in b/src/cmake/Config.cmake.in deleted file mode 100644 index 106befe..0000000 --- a/src/cmake/Config.cmake.in +++ /dev/null @@ -1,14 +0,0 @@ -@PACKAGE_INIT@ - -include(CMakeFindDependencyMacro) - -if(@VMA_STATIC_VULKAN_FUNCTIONS@) - find_dependency(Vulkan) -else() - find_dependency(VulkanHeaders) -endif() - -include("${CMAKE_CURRENT_LIST_DIR}/VulkanMemoryAllocatorTargets.cmake") -check_required_components("@PROJECT_NAME@") - - diff --git a/src/cmake/install_target.cmake b/src/cmake/install_target.cmake deleted file mode 100644 index 22415c8..0000000 --- a/src/cmake/install_target.cmake +++ /dev/null @@ -1,33 +0,0 @@ -include(GNUInstallDirs) -target_include_directories(VulkanMemoryAllocator PUBLIC - $ -) -install(TARGETS VulkanMemoryAllocator - EXPORT VulkanMemoryAllocatorTargets - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} -) -# install(FILES "${PROJECT_SOURCE_DIR}/include/vk_mem_alloc.h" DESTINATION "include") -install(FILES "${PROJECT_SOURCE_DIR}/include/vk_mem_alloc.h" - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} -) -install(EXPORT VulkanMemoryAllocatorTargets - FILE VulkanMemoryAllocatorTargets.cmake - NAMESPACE VulkanMemoryAllocator:: - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VulkanMemoryAllocator -) -include(CMakePackageConfigHelpers) -configure_package_config_file(${CMAKE_CURRENT_LIST_DIR}/Config.cmake.in - "${CMAKE_CURRENT_BINARY_DIR}/VulkanMemoryAllocatorConfig.cmake" - INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VulkanMemoryAllocator -) -install(FILES - "${CMAKE_CURRENT_BINARY_DIR}/VulkanMemoryAllocatorConfig.cmake" - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VulkanMemoryAllocator -) -add_library(VulkanMemoryAllocator::VulkanMemoryAllocator ALIAS VulkanMemoryAllocator) - - -