Cleanup CMake finding of Vulkan & installation code

Adds extensive integration tests that exercise the various ways of finding
the Vulkan-Headers.

vk-bootstrap should now use the Vulkan-Headers or Vulkan::Headers targets if
they were already defined (such as is the case of FetchContent), and will
look for the VulkanHeaders package and Vulkan package as a fallback, and will
FetchContent Vulkan-Headers directly if that fails.

This should make integration seamless with the various ways vulkan-headers
is acquired.

The vk-bootstrap-vulkan-headers target was dropped in favor of directly
linking to Vulkan-Headers (creating a target by that name if none exists).
This commit is contained in:
Charles Giessen 2023-11-30 13:43:00 -07:00 committed by Charles Giessen
parent 34be5eb2c5
commit f223c8d5ae
7 changed files with 222 additions and 47 deletions

View File

@ -1,39 +1,57 @@
cmake_minimum_required(VERSION 3.15 FATAL_ERROR) cmake_minimum_required(VERSION 3.15)
include(gen/CurrentBuildVulkanVersion.cmake)
project(VulkanBootstrap project(VulkanBootstrap
LANGUAGES CXX LANGUAGES CXX
DESCRIPTION "A Vulkan utility library to ease the initialization steps in Vulkan") DESCRIPTION "A Vulkan utility library to ease the initialization steps in Vulkan"
VERSION ${VK_BOOTSTRAP_SOURCE_HEADER_VERSION})
option(VK_BOOTSTRAP_DISABLE_WARNINGS "Disable warnings during compilation" OFF) option(VK_BOOTSTRAP_DISABLE_WARNINGS "Disable warnings during compilation" OFF)
option(VK_BOOTSTRAP_WERROR "Enable warnings as errors during compilation" OFF) option(VK_BOOTSTRAP_WERROR "Enable warnings as errors during compilation" OFF)
add_library(vk-bootstrap-vulkan-headers INTERFACE) if (CMAKE_VERSION VERSION_LESS "3.21")
# By default, only build tests & install if this repo is standalone, but still allow configuration by the user
string(COMPARE EQUAL ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR} PROJECT_IS_TOP_LEVEL)
endif()
set(VK_BOOTSTRAP_VULKAN_HEADER_DIR "" CACHE STRING "Specify the location of the Vulkan-Headers include directory.") option(VK_BOOTSTRAP_TEST "Test Vk-Bootstrap using Catch2 as well as build examples" ${PROJECT_IS_TOP_LEVEL})
option(VK_BOOTSTRAP_INSTALL "Enable warnings as errors during compilation" ${PROJECT_IS_TOP_LEVEL})
set(VK_BOOTSTRAP_VULKAN_HEADER_DIR "" CACHE FILEPATH "Specify the location of the Vulkan-Headers include directory.")
mark_as_advanced(VK_BOOTSTRAP_VULKAN_HEADER_DIR) mark_as_advanced(VK_BOOTSTRAP_VULKAN_HEADER_DIR)
include(gen/CurrentBuildVulkanVersion.cmake) # Check if the user has set this variable explicitly
if(IS_DIRECTORY ${VK_BOOTSTRAP_VULKAN_HEADER_DIR})
add_library(Vulkan-Headers INTERFACE)
add_library(Vulkan::Headers ALIAS Vulkan-Headers)
target_include_directories(Vulkan-Headers INTERFACE $<BUILD_INTERFACE:${VK_BOOTSTRAP_VULKAN_HEADER_DIR}>)
if(NOT "${VK_BOOTSTRAP_VULKAN_HEADER_DIR}" STREQUAL "") # Check if the target is already defined
target_include_directories(vk-bootstrap-vulkan-headers INTERFACE $<BUILD_INTERFACE:${VK_BOOTSTRAP_VULKAN_HEADER_DIR}>) elseif(NOT TARGET Vulkan::Headers)
else () # Try looking for the VulkanHeaders package directly
find_package(VulkanHeaders CONFIG QUIET)
if (NOT VulkanHeaders_FOUND)
# Try looking using the CMake built in Vulkan support
find_package(Vulkan QUIET) find_package(Vulkan QUIET)
if(NOT Vulkan_FOUND)
if(${Vulkan_INCLUDE_DIR} STREQUAL "Vulkan_INCLUDE_DIR-NOTFOUND") # Lastly just grab Vulkan-Headers directly using FetchContent
include(FetchContent) include(FetchContent)
FetchContent_Declare( FetchContent_Declare(
VulkanHeaders Vulkan-Headers-for-vk-bootstrap
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Headers GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Headers
GIT_TAG ${VK_BOOTSTRAP_SOURCE_HEADER_VERSION_GIT_TAG} GIT_TAG ${VK_BOOTSTRAP_SOURCE_HEADER_VERSION_GIT_TAG}
) )
FetchContent_MakeAvailable(VulkanHeaders) FetchContent_MakeAvailable(Vulkan-Headers-for-vk-bootstrap)
target_link_libraries(vk-bootstrap-vulkan-headers INTERFACE Vulkan::Headers) # If we had to use FetchContent to get the headers, disable installing
else() set(VK_BOOTSTRAP_INSTALL OFF)
set_target_properties(vk-bootstrap-vulkan-headers PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${Vulkan_INCLUDE_DIR}) endif()
endif() endif()
endif() endif()
add_library(vk-bootstrap STATIC src/VkBootstrap.h src/VkBootstrap.cpp src/VkBootstrapDispatch.h) if(NOT TARGET Vulkan::Headers)
add_library(vk-bootstrap::vk-bootstrap ALIAS vk-bootstrap) message(FATAL_ERROR "Unable to locate required dependency Vulkan::Headers!")
endif()
add_library(vk-bootstrap-compiler-warnings INTERFACE) add_library(vk-bootstrap-compiler-warnings INTERFACE)
@ -68,36 +86,73 @@ if(NOT VK_BOOTSTRAP_DISABLE_WARNINGS)
endif() endif()
endif() endif()
add_library(vk-bootstrap STATIC src/VkBootstrap.h src/VkBootstrap.cpp src/VkBootstrapDispatch.h)
add_library(vk-bootstrap::vk-bootstrap ALIAS vk-bootstrap)
target_include_directories(vk-bootstrap PUBLIC target_include_directories(vk-bootstrap PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:include>) $<INSTALL_INTERFACE:include>)
target_link_libraries(vk-bootstrap target_link_libraries(vk-bootstrap
PUBLIC
Vulkan::Headers
PRIVATE PRIVATE
vk-bootstrap-compiler-warnings vk-bootstrap-compiler-warnings
vk-bootstrap-vulkan-headers
${CMAKE_DL_LIBS}) ${CMAKE_DL_LIBS})
target_compile_features(vk-bootstrap PUBLIC cxx_std_17) target_compile_features(vk-bootstrap PUBLIC cxx_std_17)
include(GNUInstallDirs)
install(FILES src/VkBootstrap.h src/VkBootstrapDispatch.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(TARGETS
vk-bootstrap
vk-bootstrap-compiler-warnings
vk-bootstrap-vulkan-headers
EXPORT
vk-bootstrap-targets)
# By default, we want to only build tests if this repo is built standalone, but still should be configurable by the user
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
set(VK_BOOTSTRAP_TEST_DEFAULT_VALUE ON)
else()
set(VK_BOOTSTRAP_TEST_DEFAULT_VALUE OFF)
endif()
option(VK_BOOTSTRAP_TEST "Test Vk-Bootstrap with glfw and Catch2" ${VK_BOOTSTRAP_TEST_DEFAULT_VALUE})
if(VK_BOOTSTRAP_TEST) if(VK_BOOTSTRAP_TEST)
enable_testing() enable_testing()
add_subdirectory(ext) add_subdirectory(ext)
add_subdirectory(tests) add_subdirectory(tests)
add_subdirectory(example) add_subdirectory(example)
endif () endif ()
if (VK_BOOTSTRAP_INSTALL)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
install(FILES src/VkBootstrap.h src/VkBootstrapDispatch.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(
TARGETS vk-bootstrap vk-bootstrap-compiler-warnings
EXPORT vk-bootstrap-targets
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
EXPORT vk-bootstrap-targets
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/vk-bootstrap
NAMESPACE vk-bootstrap::
)
# Create vk-bootstrap-config.cmake
set(VK_BOOTSTRAP_EXPORT_TARGETS ${CMAKE_INSTALL_LIBDIR}/cmake/vk-bootstrap/vk-bootstrap-targets.cmake)
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/vk-bootstrap-config.cmake.in" [=[
@PACKAGE_INIT@
# Try to find Vulkan-Headers using find_package. Assume the package is available through either Vulkan-Headers or the older Vulkan
# Package managers should have Vulkan-Headers be a dependency of this repo.
find_package(VulkanHeaders CONFIG)
if (NOT VulkanHeaders_FOUND)
find_package(Vulkan)
if (NOT Vulkan_FOUND)
message(FATAL_ERROR "Unable to locate required dependency Vulkan::Headers!")
endif()
endif()
include(@PACKAGE_VK_BOOTSTRAP_EXPORT_TARGETS@)
]=])
configure_package_config_file(
${CMAKE_CURRENT_BINARY_DIR}/vk-bootstrap-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/vk-bootstrap-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/vk-bootstrap
PATH_VARS VK_BOOTSTRAP_EXPORT_TARGETS
NO_SET_AND_CHECK_MACRO
NO_CHECK_REQUIRED_COMPONENTS_MACRO
)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/vk-bootstrap-config.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/vk-bootstrap
)
endif()

View File

@ -4,7 +4,7 @@ target_link_libraries(vk-bootstrap-triangle
glfw glfw
vk-bootstrap vk-bootstrap
vk-bootstrap-compiler-warnings vk-bootstrap-compiler-warnings
vk-bootstrap-vulkan-headers) Vulkan::Headers)
target_include_directories(vk-bootstrap-triangle PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) # path to build directory for shaders target_include_directories(vk-bootstrap-triangle PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) # path to build directory for shaders
add_custom_command( add_custom_command(

View File

@ -7,7 +7,7 @@ option(CATCH_BUILD_TESTING "" OFF)
option(CATCH_ENABLE_WERROR "" OFF) option(CATCH_ENABLE_WERROR "" OFF)
option(CATCH_INSTALL_DOCS "" OFF) option(CATCH_INSTALL_DOCS "" OFF)
option(CATCH_INSTALL_HELPERS "" OFF) option(CATCH_INSTALL_HELPERS "" OFF)
option(CATCH_INSTALL_EXTRAS "" ON) option(CATCH_INSTALL_EXTRAS "" OFF)
include(FetchContent) include(FetchContent)
FetchContent_Declare( FetchContent_Declare(

View File

@ -7,11 +7,12 @@ else()
endif() endif()
target_link_libraries(VulkanMock target_link_libraries(VulkanMock
PUBLIC PUBLIC
vk-bootstrap-vulkan-headers Vulkan::Headers
PRIVATE PRIVATE
vk-bootstrap-compiler-warnings vk-bootstrap-compiler-warnings
) )
target_compile_features(VulkanMock PUBLIC cxx_std_17) target_compile_features(VulkanMock PUBLIC cxx_std_17)
target_compile_definitions(VulkanMock PUBLIC VK_NO_PROTOTYPES)
add_executable(vk-bootstrap-test add_executable(vk-bootstrap-test
vulkan_library_loader.hpp vulkan_library_loader.hpp
@ -24,7 +25,7 @@ add_executable(vk-bootstrap-test
target_link_libraries(vk-bootstrap-test target_link_libraries(vk-bootstrap-test
PRIVATE PRIVATE
vk-bootstrap vk-bootstrap
vk-bootstrap-vulkan-headers Vulkan::Headers
vk-bootstrap-compiler-warnings vk-bootstrap-compiler-warnings
VulkanMock VulkanMock
Catch2::Catch2WithMain Catch2::Catch2WithMain
@ -37,6 +38,79 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
endif() endif()
list(APPEND CMAKE_MODULE_PATH ${Catch2_SOURCE_DIR}/extras) list(APPEND CMAKE_MODULE_PATH ${Catch2_SOURCE_DIR}/extras)
include(CTest)
include(Catch) include(Catch)
catch_discover_tests(vk-bootstrap-test) catch_discover_tests(vk-bootstrap-test)
# Test add_subdirectory suppport using fetch content vulkan headers
add_test(NAME integration.add_subdirectory.fetch_content_vulkan_headers
COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test ${CMAKE_CURRENT_LIST_DIR}/integration
${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory/fetch_content_vulkan_headers
--build-generator ${CMAKE_GENERATOR}
--build-options -DADD_SUBDIRECTORY_TESTING=ON -DVULKAN_HEADER_VERSION_GIT_TAG=${VK_BOOTSTRAP_SOURCE_HEADER_VERSION_GIT_TAG}
)
get_target_property(vulkan_headers_include_dir Vulkan::Headers INTERFACE_INCLUDE_DIRECTORIES)
# Test add_subdirectory suppport by setting VK_BOOTSTRAP_VULKAN_HEADER_DIR to the include directory of the Vulkan::Headers
add_test(NAME integration.add_subdirectory.vulkan_header_dir
COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test ${CMAKE_CURRENT_LIST_DIR}/integration
${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory/vulkan_header_dir
--build-generator ${CMAKE_GENERATOR}
--build-options -DADD_SUBDIRECTORY_TESTING=ON -DVK_BOOTSTRAP_VULKAN_HEADER_DIR=${vulkan_headers_include_dir}
)
set(test_install_dir "${CMAKE_CURRENT_BINARY_DIR}/install")
add_test(NAME integration.install
COMMAND ${CMAKE_COMMAND} --install ${CMAKE_BINARY_DIR} --prefix ${test_install_dir} --config $<CONFIG>
)
find_package(VulkanHeaders CONFIG)
if (VulkanHeaders_FOUND)
set(vulkan_headers_package_location ${VulkanHeaders_DIR})
# Test add_subdirectory suppport using find_package(VulkanHeaders)
add_test(NAME integration.add_subdirectory.find_package_vulkan_headers
COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test ${CMAKE_CURRENT_LIST_DIR}/integration
${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory/find_package_vulkan_headers
--build-generator ${CMAKE_GENERATOR}
--build-options -DADD_SUBDIRECTORY_TESTING=ON -DCMAKE_PREFIX_PATH=${vulkan_headers_install_dir}
)
# Test find_package suppport using find_package(VulkanHeaders)
add_test(NAME integration.find_package.find_package_vulkan_headers
COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test ${CMAKE_CURRENT_LIST_DIR}/integration
${CMAKE_CURRENT_BINARY_DIR}/find_package/find_package_vulkan_headers
--build-generator ${CMAKE_GENERATOR}
--build-options -DFIND_PACKAGE_TESTING=ON "-DCMAKE_PREFIX_PATH=${vulkan_headers_install_dir};${test_install_dir}"
)
set_tests_properties(integration.find_package.find_package_vulkan_headers PROPERTIES DEPENDS integration.install)
endif()
find_package(Vulkan)
if (Vulkan_FOUND)
# Test add_subdirectory suppport using find_package(Vulkan)
add_test(NAME integration.add_subdirectory.find_package_vulkan
COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test ${CMAKE_CURRENT_LIST_DIR}/integration
${CMAKE_CURRENT_BINARY_DIR}/add_subdirectory/find_package_vulkan
--build-generator ${CMAKE_GENERATOR}
--build-options -DADD_SUBDIRECTORY_TESTING=ON -DFIND_PACKAGE_VULKAN=ON
)
# Test find_package suppport using find_package(Vulkan)
add_test(NAME integration.find_package.find_package_vulkan
COMMAND ${CMAKE_CTEST_COMMAND}
--build-and-test ${CMAKE_CURRENT_LIST_DIR}/integration
${CMAKE_CURRENT_BINARY_DIR}/find_package/find_package_vulkan
--build-generator ${CMAKE_GENERATOR}
--build-options -DFIND_PACKAGE_TESTING=ON -DCMAKE_PREFIX_PATH=${test_install_dir} -DFIND_PACKAGE_VULKAN=ON
)
set_tests_properties(integration.find_package.find_package_vulkan PROPERTIES DEPENDS integration.install)
endif()

View File

@ -0,0 +1,41 @@
cmake_minimum_required(VERSION 3.14.2)
project(IntegrationTests LANGUAGES CXX)
if (VULKAN_HEADER_VERSION_GIT_TAG)
include(FetchContent)
FetchContent_Declare(
VulkanHeadersIntegrationTest
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Headers
GIT_TAG ${VULKAN_HEADER_VERSION_GIT_TAG}
)
FetchContent_MakeAvailable(VulkanHeadersIntegrationTest)
if (NOT TARGET Vulkan::Headers)
message(FATAL_ERROR "Vulkan::Headers target not defined")
endif()
endif()
if (FIND_PACKAGE_VULKAN_HEADERS)
find_package(VulkanHeaders REQUIRED)
endif()
if (FIND_PACKAGE_VULKAN)
find_package(Vulkan REQUIRED)
endif()
if (ADD_SUBDIRECTORY_TESTING)
add_subdirectory(../.. ${CMAKE_CURRENT_BINARY_DIR}/vk-bootstrap)
endif()
if (FIND_PACKAGE_TESTING)
find_package(vk-bootstrap CONFIG REQUIRED)
endif()
if (NOT TARGET vk-bootstrap::vk-bootstrap)
message(FATAL_ERROR "vk-bootstrap::vk-bootstrap target not defined")
endif()
add_executable(integration_test integration_test.cpp)
target_link_libraries(integration_test vk-bootstrap::vk-bootstrap)

View File

@ -0,0 +1,6 @@
#include "VkBootstrap.h"
int main() {
[[maybe_unused]] vkb::InstanceBuilder builder{};
return 0;
}

View File

@ -8,7 +8,6 @@
#include <string> #include <string>
#include <vector> #include <vector>
#define VK_NO_PROTOTYPES
#include <vulkan/vulkan.h> #include <vulkan/vulkan.h>
// Helper function to get the size of a struct given a VkStructureType // Helper function to get the size of a struct given a VkStructureType