Skip to content

Commit

Permalink
Cleanup CMake finding of Vulkan & installation code
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
charles-lunarg committed Nov 30, 2023
1 parent 83826b9 commit b85733b
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 41 deletions.
136 changes: 98 additions & 38 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,39 +1,51 @@
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)

include(gen/CurrentBuildVulkanVersion.cmake)

project(VulkanBootstrap
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_WERROR "Enable warnings as errors during compilation" OFF)

add_library(vk-bootstrap-vulkan-headers INTERFACE)

set(VK_BOOTSTRAP_VULKAN_HEADER_DIR "" CACHE STRING "Specify the location of the Vulkan-Headers include directory.")
mark_as_advanced(VK_BOOTSTRAP_VULKAN_HEADER_DIR)

include(gen/CurrentBuildVulkanVersion.cmake)

# Check if the user has set this variable explicitly
if(NOT "${VK_BOOTSTRAP_VULKAN_HEADER_DIR}" STREQUAL "")
target_include_directories(vk-bootstrap-vulkan-headers INTERFACE $<BUILD_INTERFACE:${VK_BOOTSTRAP_VULKAN_HEADER_DIR}>)
else ()
find_package(Vulkan QUIET)

if(${Vulkan_INCLUDE_DIR} STREQUAL "Vulkan_INCLUDE_DIR-NOTFOUND")
include(FetchContent)
FetchContent_Declare(
VulkanHeaders
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Headers
GIT_TAG ${VK_BOOTSTRAP_SOURCE_HEADER_VERSION_GIT_TAG}
)
FetchContent_MakeAvailable(VulkanHeaders)
target_link_libraries(vk-bootstrap-vulkan-headers INTERFACE Vulkan::Headers)
else()
set_target_properties(vk-bootstrap-vulkan-headers PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${Vulkan_INCLUDE_DIR})
add_library(Vulkan-Headers INTERFACE)
target_include_directories(Vulkan-Headers INTERFACE $<BUILD_INTERFACE:${VK_BOOTSTRAP_VULKAN_HEADER_DIR}>)

# Check if the target is already defined
elseif(NOT (TARGET Vulkan-Headers OR TARGET Vulkan::Headers))
# Try looking for the Vulkan-Headers package directly
find_package(VulkanHeaders CONFIG)
if (NOT VulkanHeaders_FOUND)
# Try looking using the CMake built in Vulkan support
find_package(Vulkan QUIET)
if(NOT Vulkan_FOUND)
# Lastly just grab Vulkan-Headers directly using FetchContent
include(FetchContent)
FetchContent_Declare(
Vulkan-Headers-for-vk-bootstrap
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Headers
GIT_TAG ${VK_BOOTSTRAP_SOURCE_HEADER_VERSION_GIT_TAG}
)
FetchContent_MakeAvailable(Vulkan-Headers-for-vk-bootstrap)
endif()
endif()
endif()
# find_package(Vulkan) only defines Vulkan::Headers, create Vulkan-Headers in this case
if(TARGET Vulkan::Headers AND NOT TARGET Vulkan-Headers)
add_library(Vulkan-Headers INTERFACE)
target_link_libraries(Vulkan-Headers INTERFACE Vulkan::Headers)
endif()

add_library(vk-bootstrap STATIC src/VkBootstrap.h src/VkBootstrap.cpp src/VkBootstrapDispatch.h)
add_library(vk-bootstrap::vk-bootstrap ALIAS vk-bootstrap)
if(NOT TARGET Vulkan-Headers)
message(FATAL_ERROR "Unable to locate required dependency Vulkan-Headers!")
endif()

add_library(vk-bootstrap-compiler-warnings INTERFACE)

Expand Down Expand Up @@ -68,36 +80,84 @@ if(NOT VK_BOOTSTRAP_DISABLE_WARNINGS)
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
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<INSTALL_INTERFACE:include>)
target_link_libraries(vk-bootstrap
PUBLIC
Vulkan-Headers
PRIVATE
vk-bootstrap-compiler-warnings
vk-bootstrap-vulkan-headers
${CMAKE_DL_LIBS})
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)
if (CMAKE_VERSION VERSION_LESS "3.21")
# 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(PROJECT_IS_TOP_LEVEL ON)
else()
set(PROJECT_IS_TOP_LEVEL OFF)
endif()
endif()
option(VK_BOOTSTRAP_TEST "Test Vk-Bootstrap with glfw and Catch2" ${VK_BOOTSTRAP_TEST_DEFAULT_VALUE})

option(VK_BOOTSTRAP_TEST "Test Vk-Bootstrap using Catch2 as well as build examples" ${PROJECT_IS_TOP_LEVEL})

if(VK_BOOTSTRAP_TEST)
enable_testing()
add_subdirectory(ext)
add_subdirectory(tests)
add_subdirectory(example)
endif ()

if (PROJECT_IS_TOP_LEVEL)

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

install(FILES src/VkBootstrap.h src/VkBootstrapDispatch.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})

install(
TARGETS vk-bootstrap vk-bootstrap-compiler-warnings Vulkan-Headers
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 "Missing dependency on vulkan!")
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()
2 changes: 1 addition & 1 deletion example/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ target_link_libraries(vk-bootstrap-triangle
glfw
vk-bootstrap
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

add_custom_command(
Expand Down
65 changes: 63 additions & 2 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ else()
endif()
target_link_libraries(VulkanMock
PUBLIC
vk-bootstrap-vulkan-headers
Vulkan-Headers
PRIVATE
vk-bootstrap-compiler-warnings
)
Expand All @@ -24,7 +24,7 @@ add_executable(vk-bootstrap-test
target_link_libraries(vk-bootstrap-test
PRIVATE
vk-bootstrap
vk-bootstrap-vulkan-headers
Vulkan-Headers
vk-bootstrap-compiler-warnings
VulkanMock
Catch2::Catch2WithMain
Expand All @@ -40,3 +40,64 @@ list(APPEND CMAKE_MODULE_PATH ${Catch2_SOURCE_DIR}/extras)
include(CTest)
include(Catch)
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}
)

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}
)

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

# 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
)
endif()
41 changes: 41 additions & 0 deletions tests/integration/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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(Vulkan-Headers 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)

6 changes: 6 additions & 0 deletions tests/integration/integration_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "VkBootstrap.h"

int main() {
[[maybe_unused]] vkb::InstanceBuilder builder{};
return 0;
}

0 comments on commit b85733b

Please sign in to comment.