Export versioned targets for CMake
authorRahul Sheth <rahul@snap.com>
Thu, 14 Nov 2019 21:45:58 +0000 (16:45 -0500)
committerMike Weiblen (LunarG) <mikew-lunarg@users.noreply.github.com>
Thu, 16 Apr 2020 22:21:54 +0000 (16:21 -0600)
Generate VulkanHeadersConfig.cmake and version file and install them.
To get the version information the header file vulkan_core.h is parsed.

In client code one can use `find_package(VulkanHeaders)` and get the
targets `Vulkan::Headers` and `Vulkan::Registry`.

The following additional files are generated and installed by CMake:
- VulkanHeadersConfig.cmake:        searched for by find_package(VulkanHeaders)
- VulkanHeadersConfigVersion.cmake: provides version numbers
- VulkanHeadersTargets.cmake:       CMake target definitions used by config file

CMakeLists.txt
cmake/Config.cmake.in [new file with mode: 0644]

index fc96c5e..7ab25eb 100644 (file)
@@ -22,6 +22,26 @@ cmake_minimum_required(VERSION 3.10.2)
 
 # NONE = this project has no language toolchain requirement.
 project(Vulkan-Headers NONE)
+file(READ "include/vulkan/vulkan_core.h" ver)
+string(REGEX MATCH "#define[ ]+VK_HEADER_VERSION_COMPLETE[ ]+VK_MAKE_VERSION\\([ ]*([0-9]+),[ ]*([0-9]+),[ ]*VK_HEADER_VERSION[ ]*\\)" _ ${ver})
+set(VK_VERSION_MAJOR "${CMAKE_MATCH_1}")
+set(VK_VERSION_MINOR "${CMAKE_MATCH_2}")
+string(REGEX MATCH "#define[ ]+VK_HEADER_VERSION[ ]+([0-9]+)" _ ${ver})
+set(VK_HEADER_VERSION "${CMAKE_MATCH_1}")
+# check if version parsing was successful
+if(VK_VERSION_MAJOR STREQUAL "")
+    message(FATAL_ERROR "Error reading major version from 'include/vulkan/vulkan_core.h'")
+endif()
+if(VK_VERSION_MINOR STREQUAL "")
+    message(FATAL_ERROR "Error reading minor version from 'include/vulkan/vulkan_core.h'")
+endif()
+if(VK_HEADER_VERSION STREQUAL "")
+    message(FATAL_ERROR "Error reading header version from 'include/vulkan/vulkan_core.h'")
+endif()
+set(VK_VERSION_STRING "${VK_VERSION_MAJOR}.${VK_VERSION_MINOR}.${VK_HEADER_VERSION}")
+message(STATUS "Found Vulkan-Headers VK_VERSION_STRING '${VK_VERSION_STRING}'")
+
+option(VULKAN_HEADERS_SKIP_INSTALL "Skip install" OFF)
 
 # User-interface declarations ----------------------------------------------------------------------------------------------------
 # This section contains variables that affect development GUIs (e.g. CMake GUI and IDEs), such as option(), folders, and variables
@@ -38,21 +58,74 @@ endif()
 
 # define exported targets for nested project builds to consume
 add_library(Vulkan-Headers INTERFACE)
-target_include_directories(Vulkan-Headers INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
+target_include_directories(Vulkan-Headers INTERFACE
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
+)
 add_library(Vulkan::Headers ALIAS Vulkan-Headers)
 
 add_library(Vulkan-Registry INTERFACE)
-target_include_directories(Vulkan-Registry INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/registry")
+target_include_directories(Vulkan-Registry INTERFACE
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/registry>
+    $<INSTALL_INTERFACE:${CMAKE_INSTALL_DATADIR}/vulkan>
+)
 add_library(Vulkan::Registry ALIAS Vulkan-Registry)
 
-install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/vulkan" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
-install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/registry" DESTINATION ${CMAKE_INSTALL_DATADIR}/vulkan)
+# Installation
+# This adds the following files to the install target
+# - Vulkan Header files
+# - Vulkan Registry files
+# - CMake config files generated by CMake
+#   - VulkanHeadersConfig.cmake:        searched for by find_package(VulkanHeaders)
+#   - VulkanHeadersConfigVersion.cmake: provides version numbers
+#   - VulkanHeadersTargets.cmake:       CMake target definitions used by config file
+if(NOT VULKAN_HEADERS_SKIP_INSTALL)
+    set(config_install_dir "${CMAKE_INSTALL_DATADIR}/cmake/VulkanHeaders")
+    set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
+    set(version_config "${generated_dir}/VulkanHeadersConfigVersion.cmake")
+    set(project_config "${generated_dir}/VulkanHeadersConfig.cmake")
+    set(TARGETS_EXPORT_NAME "VulkanHeadersTargets")
+    set(namespace "Vulkan::")
+
+    include(CMakePackageConfigHelpers)
+    write_basic_package_version_file(
+        "${version_config}"
+        VERSION ${VK_VERSION_STRING}
+        COMPATIBILITY AnyNewerVersion
+    )
+    configure_package_config_file(
+        "cmake/Config.cmake.in"
+        "${project_config}"
+        INSTALL_DESTINATION "${config_install_dir}"
+    )
+    install(
+        TARGETS Vulkan-Headers Vulkan-Registry
+        EXPORT "${TARGETS_EXPORT_NAME}"
+        LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    )
+    install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/vulkan"
+        DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+    )
+    install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/registry"
+        DESTINATION ${CMAKE_INSTALL_DATADIR}/vulkan
+    )
+    install(FILES "${project_config}" "${version_config}"
+        DESTINATION "${config_install_dir}"
+    )
+    install(
+        EXPORT "${TARGETS_EXPORT_NAME}"
+        NAMESPACE "${namespace}"
+        DESTINATION "${config_install_dir}")
 
-# uninstall target
-if(NOT TARGET uninstall)
-    configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
-                   "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
-                   IMMEDIATE
-                   @ONLY)
-    add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
+    # uninstall target
+    if(NOT TARGET uninstall)
+        configure_file(
+            "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
+            "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+            IMMEDIATE
+            @ONLY)
+        add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
+    endif()
 endif()
diff --git a/cmake/Config.cmake.in b/cmake/Config.cmake.in
new file mode 100644 (file)
index 0000000..4bf6cd5
--- /dev/null
@@ -0,0 +1,25 @@
+@PACKAGE_INIT@
+
+include("${CMAKE_CURRENT_LIST_DIR}/@TARGETS_EXPORT_NAME@.cmake")
+check_required_components("@PROJECT_NAME@")
+
+# ALIAS for imported target requires CMake >= 3.11:
+# - https://cmake.org/cmake/help/latest/release/3.11.html#other
+if(NOT CMAKE_VERSION VERSION_LESS 3.11)
+    if(NOT TARGET Vulkan::Headers)
+        set_target_properties(
+            Vulkan::Vulkan-Headers
+            PROPERTIES
+            IMPORTED_GLOBAL True
+        )
+        add_library(Vulkan::Headers ALIAS Vulkan::Vulkan-Headers)
+      endif()
+      if(NOT TARGET Vulkan::Registry)
+        set_target_properties(
+            Vulkan::Vulkan-Registry
+            PROPERTIES
+            IMPORTED_GLOBAL True
+        )
+        add_library(Vulkan::Registry ALIAS Vulkan::Vulkan-Registry)
+    endif()
+endif()