1# ~~~ 2# Copyright 2018-2023 The Khronos Group Inc. 3# Copyright 2018-2023 Valve Corporation 4# Copyright 2018-2023 LunarG, Inc. 5# 6# SPDX-License-Identifier: Apache-2.0 7# ~~~ 8cmake_minimum_required(VERSION 3.22.1) 9 10# NOTE: Parsing the version like this is suboptimal but neccessary due to our release process: 11# https://github.com/KhronosGroup/Vulkan-Headers/pull/346 12# 13# As shown a more robust approach would be just to add basic test code to check the project version. 14function(vlk_get_header_version) 15 set(vulkan_core_header_file "${CMAKE_CURRENT_SOURCE_DIR}/include/vulkan/vulkan_core.h") 16 if (NOT EXISTS ${vulkan_core_header_file}) 17 message(FATAL_ERROR "Couldn't find vulkan_core.h!") 18 endif() 19 20 file(READ ${vulkan_core_header_file} ver) 21 22 if (ver MATCHES "#define[ ]+VK_HEADER_VERSION_COMPLETE[ ]+VK_MAKE_API_VERSION\\([ ]*[0-9]+,[ ]*([0-9]+),[ ]*([0-9]+),[ ]*VK_HEADER_VERSION[ ]*\\)") 23 set(MAJOR_VERSION "${CMAKE_MATCH_1}") 24 set(MINOR_VERSION "${CMAKE_MATCH_2}") 25 else() 26 message(FATAL_ERROR "Couldn't get major/minor version") 27 endif() 28 29 if (ver MATCHES "#define[ ]+VK_HEADER_VERSION[ ]+([0-9]+)") 30 set(PATCH_VERSION "${CMAKE_MATCH_1}") 31 else() 32 message(FATAL_ERROR "Couldn't get the patch version") 33 endif() 34 35 set(VK_VERSION_STRING "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}" PARENT_SCOPE) 36endfunction() 37vlk_get_header_version() 38 39project(VULKAN_HEADERS LANGUAGES C CXX VERSION ${VK_VERSION_STRING}) 40 41# options for Vulkan-Headers and the Vulkan-Hpp C++20 module 42option(VULKAN_HEADERS_ENABLE_TESTS "Test Vulkan-Headers" ${PROJECT_IS_TOP_LEVEL}) 43option(VULKAN_HEADERS_ENABLE_INSTALL "Install Vulkan-Headers" ${PROJECT_IS_TOP_LEVEL}) 44option(VULKAN_HEADERS_ENABLE_MODULE "Enables building of the Vulkan C++20 module; requires minimum CMake version 3.28" OFF) 45option(VULKAN_HEADERS_ENABLE_MODULE_STD "Enables building of the Vulkan C++20 module with import std; requires minimum CMake version 3.30" OFF) 46 47# set up Vulkan-Headers 48add_library(Vulkan-Headers INTERFACE) 49add_library(Vulkan::Headers ALIAS Vulkan-Headers) 50target_include_directories(Vulkan-Headers INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>) 51 52if (VULKAN_HEADERS_ENABLE_MODULE) 53 # check for compiler support 54 if ((CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND (MSVC_VERSION GREATER_EQUAL "1941")) OR 55 # clang-cl doesn't currently support modules 56 (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" 57 AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "16.0" 58 AND (NOT CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "MSVC") 59 AND (NOT CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS STREQUAL CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS-NOTFOUND)) OR 60 (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "14.0") 61 ) 62 # check for CMake support 63 if(VULKAN_HEADERS_ENABLE_MODULE_STD AND CMAKE_VERSION VERSION_LESS "3.30") 64 message(FATAL_ERROR "Vulkan-Hpp: C++20 module with import std requires CMake 3.30 or later") 65 elseif (CMAKE_VERSION VERSION_LESS "3.28") 66 message(FATAL_ERROR "Vulkan-Hpp: C++20 module requires CMake 3.28 or later") 67 endif() 68 69 # set up Vulkan-HppModule 70 add_library(Vulkan-HppModule) 71 add_library(Vulkan::HppModule ALIAS Vulkan-HppModule) 72 target_sources(Vulkan-HppModule 73 PUBLIC 74 FILE_SET module 75 TYPE CXX_MODULES 76 FILES "${CMAKE_CURRENT_SOURCE_DIR}/include/vulkan/vulkan.cppm") 77 if (VULKAN_HEADERS_ENABLE_MODULE_STD) 78 target_compile_features(Vulkan-HppModule 79 PRIVATE cxx_std_23 80 INTERFACE cxx_std_20) # only C++20 is required to consume this module 81 set_target_properties(Vulkan-HppModule PROPERTIES CXX_MODULE_STD ON) 82 else() 83 target_compile_features(Vulkan-HppModule PUBLIC cxx_std_20) 84 endif() 85 target_link_libraries(Vulkan-HppModule PUBLIC Vulkan::Headers) 86 87 # Clang 16's module support can be broken with extensions enabled 88 if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_EQUAL "16.0") 89 set_target_properties(Vulkan-HppModule PROPERTIES CXX_EXTENSIONS OFF) 90 endif() 91 92 # set up fallback targets to notify about name deprecation 93 add_library(Vulkan-Module INTERFACE) 94 add_library(Vulkan::Module ALIAS Vulkan-Module) 95 target_link_libraries(Vulkan-Module INTERFACE Vulkan::HppModule) 96 set_target_properties(Vulkan-Module PROPERTIES 97 DEPRECATION "The Vulkan-Module and Vulkan::Module targets have been deprecated by the Vulkan-HppModule and Vulkan::HppModule targets respectively and will be removed at a future date.") 98 else() 99 message(FATAL_ERROR "Vulkan-Hpp: C++20 module support is requested but was disabled due to lacking compiler support on this platform") 100 endif() 101endif() 102 103if (VULKAN_HEADERS_ENABLE_TESTS) 104 enable_testing() # This is only effective in the top level CMakeLists.txt file. 105 add_subdirectory(tests) 106endif() 107 108if (VULKAN_HEADERS_ENABLE_INSTALL) 109 include(GNUInstallDirs) 110 include(CMakePackageConfigHelpers) 111 112 install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/vk_video" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 113 install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/vulkan" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 114 # Preserve source permissions https://github.com/KhronosGroup/Vulkan-Headers/issues/336 115 install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/registry" DESTINATION "${CMAKE_INSTALL_DATADIR}/vulkan" USE_SOURCE_PERMISSIONS) 116 117 set_target_properties(Vulkan-Headers PROPERTIES EXPORT_NAME "Headers") 118 install(TARGETS Vulkan-Headers EXPORT VulkanHeadersConfig INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 119 120 install(EXPORT VulkanHeadersConfig NAMESPACE "Vulkan::" DESTINATION "share/cmake/VulkanHeaders") 121 122 set(version_config "${CMAKE_CURRENT_BINARY_DIR}/generated/VulkanHeadersConfigVersion.cmake") 123 write_basic_package_version_file("${version_config}" COMPATIBILITY SameMajorVersion ARCH_INDEPENDENT) 124 install(FILES "${version_config}" DESTINATION "share/cmake/VulkanHeaders") 125endif() 126