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
This commit is contained in:
Juan Ramos 2023-07-05 13:14:09 -06:00
parent d9a2e4641b
commit 3d23bb07e3
5 changed files with 110 additions and 199 deletions

View File

@ -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 add_library(VulkanMemoryAllocator INTERFACE)
option(VMA_BUILD_SAMPLE "Build VulkanMemoryAllocator sample application" OFF) add_library(GPUOpen::VulkanMemoryAllocator ALIAS VulkanMemoryAllocator)
option(VMA_BUILD_SAMPLE_SHADERS "Build VulkanMemoryAllocator sample application's shaders" OFF)
message(STATUS "VMA_BUILD_SAMPLE = ${VMA_BUILD_SAMPLE}") target_include_directories(VulkanMemoryAllocator INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
message(STATUS "VMA_BUILD_SAMPLE_SHADERS = ${VMA_BUILD_SAMPLE_SHADERS}")
option(VMA_STATIC_VULKAN_FUNCTIONS "Link statically with Vulkan API" ON) if (CMAKE_VERSION VERSION_LESS "3.21")
option(VMA_DYNAMIC_VULKAN_FUNCTIONS "Fetch pointers to Vulkan functions internally (no static linking)" OFF) # https://cmake.org/cmake/help/latest/variable/PROJECT_IS_TOP_LEVEL.html
option(VMA_DEBUG_ALWAYS_DEDICATED_MEMORY "Every allocation will have its own memory block" OFF) string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_TOP_LEVEL)
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)
endif() endif()
if(VMA_BUILD_SAMPLE) if (PROJECT_IS_TOP_LEVEL)
set(VMA_BUILD_SAMPLE_SHADERS ON) 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() 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)

View File

@ -99,38 +99,37 @@ With this one function call:
# How to build # 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: On Linux:
``` ```sh
mkdir build cmake -S . -B build
cd build # Since VMA has no source files, you can skip to installation immediately
cmake .. cmake --install build --prefix build/install
make
``` ```
The following targets are available ## How to use
| Target | Description | CMake option | Default setting | After calling either `find_package` or `add_subdirectory` simply link the library.
| ------------- | ------------- | ------------- | ------------- | This automatically handles configuring the include directory.
| VmaSample | VMA sample application | `VMA_BUILD_SAMPLE` | `OFF` |
| VmaBuildSampleShaders | Shaders for VmaSample | `VMA_BUILD_SAMPLE_SHADERS` | `OFF` |
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 | For more info on using CMake visit the official [CMake documentation](https://cmake.org/cmake/help/latest/index.html).
| ------------- | ------------- | ------------- |
| `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` |
## Building using vcpkg ## Building using vcpkg

View File

@ -1,107 +1,76 @@
set(CMAKE_DEBUG_POSTFIX d) if (NOT WIN32)
set(CMAKE_RELWITHDEBINFO_POSTFIX rd) message(STATUS "VmaSample application is only supported on Windows")
set(CMAKE_MINSIZEREL_POSTFIX s) return()
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)
endif() endif()
set_target_properties( option(VMA_STATIC_VULKAN_FUNCTIONS "Link statically with Vulkan API" ON)
VulkanMemoryAllocator PROPERTIES 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 message(STATUS "VMA_STATIC_VULKAN_FUNCTIONS = ${VMA_STATIC_VULKAN_FUNCTIONS}")
CXX_STANDARD 17 message(STATUS "VMA_DYNAMIC_VULKAN_FUNCTIONS = ${VMA_DYNAMIC_VULKAN_FUNCTIONS}")
CXX_STANDARD_REQUIRED ON 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)
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
) # 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 # Only link to Vulkan library if static linking is used, but always add Vulkan headers directory
if(VMA_STATIC_VULKAN_FUNCTIONS) if(VMA_STATIC_VULKAN_FUNCTIONS)
target_link_libraries(VulkanMemoryAllocator PUBLIC Vulkan::Vulkan) target_link_libraries(VmaUsage PUBLIC Vulkan::Vulkan)
else() else()
target_link_libraries(VulkanMemoryAllocator PUBLIC Vulkan::Headers) target_link_libraries(VmaUsage PUBLIC Vulkan::Headers)
endif() endif()
target_compile_definitions( target_compile_definitions(VmaUsage PUBLIC
VulkanMemoryAllocator
PUBLIC
VMA_STATIC_VULKAN_FUNCTIONS=$<BOOL:${VMA_STATIC_VULKAN_FUNCTIONS}> VMA_STATIC_VULKAN_FUNCTIONS=$<BOOL:${VMA_STATIC_VULKAN_FUNCTIONS}>
VMA_DYNAMIC_VULKAN_FUNCTIONS=$<BOOL:${VMA_DYNAMIC_VULKAN_FUNCTIONS}> VMA_DYNAMIC_VULKAN_FUNCTIONS=$<BOOL:${VMA_DYNAMIC_VULKAN_FUNCTIONS}>
VMA_DEBUG_ALWAYS_DEDICATED_MEMORY=$<BOOL:${VMA_DEBUG_ALWAYS_DEDICATED_MEMORY}> VMA_DEBUG_ALWAYS_DEDICATED_MEMORY=$<BOOL:${VMA_DEBUG_ALWAYS_DEDICATED_MEMORY}>
VMA_DEBUG_INITIALIZE_ALLOCATIONS=$<BOOL:${VMA_DEBUG_INITIALIZE_ALLOCATIONS}> VMA_DEBUG_INITIALIZE_ALLOCATIONS=$<BOOL:${VMA_DEBUG_INITIALIZE_ALLOCATIONS}>
VMA_DEBUG_GLOBAL_MUTEX=$<BOOL:${VMA_DEBUG_GLOBAL_MUTEX}> VMA_DEBUG_GLOBAL_MUTEX=$<BOOL:${VMA_DEBUG_GLOBAL_MUTEX}>
VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT=$<BOOL:${VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT}> VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT=$<BOOL:${VMA_DEBUG_DONT_EXCEED_MAX_MEMORY_ALLOCATION_COUNT}>
VMA_RECORDING_ENABLED=$<BOOL:${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) target_link_libraries(VmaSample PRIVATE VmaUsage)
if(WIN32)
set(VMA_SAMPLE_SOURCE_FILES
Common.cpp
Common.h
SparseBindingTest.cpp
SparseBindingTest.h
Tests.cpp
Tests.h
VulkanSample.cpp
)
add_executable(VmaSample ${VMA_SAMPLE_SOURCE_FILES}) add_subdirectory(Shaders)
add_dependencies(VmaSample VulkanMemoryAllocator VmaSampleShaders) add_dependencies(VmaSample 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")
# Set VmaSample as startup project # Use Unicode instead of multibyte set
set_property(DIRECTORY "${PROJECT_SOURCE_DIR}" PROPERTY VS_STARTUP_PROJECT "VmaSample") add_compile_definitions(UNICODE _UNICODE)
# Set working directory for Visual Studio debugger # Add C++ warnings and security checks
set_target_properties( add_compile_options(/permissive- /sdl /W3)
VmaSample
PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/bin"
)
endif()
set_target_properties( # Set VmaSample as startup project
VmaSample PROPERTIES set_property(DIRECTORY "${PROJECT_SOURCE_DIR}" PROPERTY VS_STARTUP_PROJECT "VmaSample")
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()

View File

@ -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@")

View File

@ -1,33 +0,0 @@
include(GNUInstallDirs)
target_include_directories(VulkanMemoryAllocator PUBLIC
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDE_DIRS}>
)
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)