1# ~~~ 2# Copyright (c) 2014-2023 Valve Corporation 3# Copyright (c) 2014-2023 LunarG, Inc. 4# Copyright (c) 2021-2022 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 5# Copyright (c) 2023-2023 RasterGrid Kft. 6# 7# Licensed under the Apache License, Version 2.0 (the "License"); 8# you may not use this file except in compliance with the License. 9# You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, software 14# distributed under the License is distributed on an "AS IS" BASIS, 15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16# See the License for the specific language governing permissions and 17# limitations under the License. 18# ~~~ 19cmake_minimum_required(VERSION 3.22.1) 20 21project(VULKAN_LOADER VERSION 1.4.309 LANGUAGES C) 22 23option(CODE_COVERAGE "Enable Code Coverage" OFF) 24if (CODE_COVERAGE) 25 include(scripts/CodeCoverage.cmake) 26 add_code_coverage_all_targets() 27endif() 28 29 30# This variable enables downstream users to customize the target API 31# variant (e.g. Vulkan SC) 32set(API_TYPE "vulkan") 33 34add_subdirectory(scripts) 35 36set(CMAKE_C_STANDARD 99) 37set(CMAKE_C_STANDARD_REQUIRED ON) 38set(CMAKE_C_EXTENSIONS OFF) 39set(CMAKE_C_VISIBILITY_PRESET "hidden") 40set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") 41 42# By default, loader & tests are built without sanitizers 43# Use these options to force a specific sanitizer on the loader and test executables 44if (UNIX) 45 option(LOADER_ENABLE_ADDRESS_SANITIZER "Linux & macOS only: Advanced memory checking" OFF) 46 option(LOADER_ENABLE_THREAD_SANITIZER "Linux & macOS only: Advanced thread checking" OFF) 47endif() 48 49if(WIN32) 50 # Optional: Allow specify the exact version used in the loader dll 51 # Format is major.minor.patch.build 52 set(BUILD_DLL_VERSIONINFO "" CACHE STRING "Set the version to be used in the loader.rc file. Default value is the currently generated header version") 53endif() 54 55find_package(VulkanHeaders CONFIG QUIET) 56 57include(GNUInstallDirs) 58 59set(GIT_BRANCH_NAME "--unknown--") 60set(GIT_TAG_INFO "--unknown--") 61find_package (Git) 62if (GIT_FOUND AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/.git/HEAD") 63 execute_process( 64 COMMAND ${GIT_EXECUTABLE} describe --tags --always 65 WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} 66 OUTPUT_VARIABLE GIT_TAG_INFO) 67 string(REGEX REPLACE "\n$" "" GIT_TAG_INFO "${GIT_TAG_INFO}") 68 69 file(READ "${CMAKE_CURRENT_LIST_DIR}/.git/HEAD" GIT_HEAD_REF_INFO) 70 if (GIT_HEAD_REF_INFO) 71 string(REGEX MATCH "ref: refs/heads/(.*)" _ ${GIT_HEAD_REF_INFO}) 72 if (CMAKE_MATCH_1) 73 set(GIT_BRANCH_NAME ${CMAKE_MATCH_1}) 74 else() 75 set(GIT_BRANCH_NAME ${GIT_HEAD_REF_INFO}) 76 endif() 77 string(REGEX REPLACE "\n$" "" GIT_BRANCH_NAME "${GIT_BRANCH_NAME}") 78 endif() 79endif() 80 81# Enable IDE GUI folders. "Helper targets" that don't have interesting source code should set their FOLDER property to this 82set_property(GLOBAL PROPERTY USE_FOLDERS ON) 83set(LOADER_HELPER_FOLDER "Helper Targets") 84 85if(UNIX) 86 set(FALLBACK_CONFIG_DIRS "/etc/xdg" CACHE STRING 87 "Search path to use when XDG_CONFIG_DIRS is unset or empty or the current process is SUID/SGID. Default is freedesktop compliant.") 88 set(FALLBACK_DATA_DIRS "/usr/local/share:/usr/share" CACHE STRING 89 "Search path to use when XDG_DATA_DIRS is unset or empty or the current process is SUID/SGID. Default is freedesktop compliant.") 90 set(SYSCONFDIR "" CACHE STRING 91 "System-wide search directory. If not set or empty, CMAKE_INSTALL_FULL_SYSCONFDIR and /etc are used.") 92endif() 93 94if(WIN32) 95 option(ENABLE_WIN10_ONECORE "Link the loader with OneCore umbrella libraries" OFF) 96endif() 97 98add_library(platform_wsi INTERFACE) 99if(WIN32) 100 target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_WIN32_KHR) 101elseif(ANDROID) 102 message(FATAL_ERROR "Android build not supported!") 103elseif(APPLE) 104 target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_METAL_EXT) 105 if (IOS) 106 target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_IOS_MVK) 107 endif() 108 if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") 109 target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_MACOS_MVK) 110 endif() 111elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|DragonFly|GNU") 112 option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON) 113 option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON) 114 option(BUILD_WSI_XLIB_XRANDR_SUPPORT "Build X11 Xrandr WSI support" ON) 115 option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON) 116 option(BUILD_WSI_DIRECTFB_SUPPORT "Build DirectFB WSI support" OFF) 117 118 find_package(PkgConfig REQUIRED QUIET) # Use PkgConfig to find Linux system libraries 119 120 if(BUILD_WSI_XCB_SUPPORT) 121 pkg_check_modules(XCB REQUIRED QUIET IMPORTED_TARGET xcb) 122 pkg_get_variable(XCB_INCLUDE_DIRS xcb includedir) 123 target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_XCB_KHR) 124 target_include_directories(platform_wsi INTERFACE ${XCB_INCLUDE_DIRS}) 125 endif() 126 if(BUILD_WSI_XLIB_SUPPORT) 127 pkg_check_modules(X11 REQUIRED QUIET IMPORTED_TARGET x11) 128 pkg_get_variable(XLIB_INCLUDE_DIRS x11 includedir) 129 target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_XLIB_KHR) 130 target_include_directories(platform_wsi INTERFACE ${XLIB_INCLUDE_DIRS}) 131 if(BUILD_WSI_XLIB_XRANDR_SUPPORT) 132 pkg_check_modules(XRANDR REQUIRED QUIET IMPORTED_TARGET xrandr) 133 pkg_get_variable(XLIB_XRANDR_INCLUDE_DIRS xrandr includedir) 134 target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_XLIB_XRANDR_EXT) 135 target_include_directories(platform_wsi INTERFACE ${XLIB_XRANDR_INCLUDE_DIRS}) 136 endif() 137 endif() 138 if(BUILD_WSI_WAYLAND_SUPPORT) 139 target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_WAYLAND_KHR) 140 endif() 141 if(BUILD_WSI_DIRECTFB_SUPPORT) 142 pkg_check_modules(DirectFB QUIET REQUIRED IMPORTED_TARGET directfb) 143 pkg_get_variable(DIRECTFB_INCLUDE_DIRS directfb includedir) 144 target_compile_definitions(platform_wsi INTERFACE VK_USE_PLATFORM_DIRECTFB_EXT) 145 # vulkan_core.h includes <directfb.h> but the header is installed to directfb/directfb.h 146 target_include_directories(platform_wsi INTERFACE ${DIRECTFB_INCLUDE_DIRS} ${DIRECTFB_INCLUDE_DIRS}/directfb) 147 endif() 148elseif(CMAKE_SYSTEM_NAME MATCHES "QNX") 149 message(FATAL_ERROR "See BUILD.md for QNX build") 150elseif(CMAKE_SYSTEM_NAME MATCHES "Fuchsia") 151 message(FATAL_ERROR "Fuchsia uses Chromium build. See BUILD.gn") 152else() 153 message(FATAL_ERROR "Unsupported Platform!") 154endif() 155 156add_library(loader_common_options INTERFACE) 157target_link_libraries(loader_common_options INTERFACE platform_wsi) 158 159# Enable beta Vulkan extensions 160target_compile_definitions(loader_common_options INTERFACE VK_ENABLE_BETA_EXTENSIONS) 161 162string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" SYSTEM_PROCESSOR) 163 164option(BUILD_WERROR "Enable warnings as errors") 165 166# Set warnings as errors and the main diagnostic flags 167# Must be set first so the warning silencing later on works properly 168# Note that clang-cl.exe should use MSVC flavor flags, not GNU 169if (CMAKE_C_COMPILER_ID STREQUAL "MSVC" OR (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) 170 if (BUILD_WERROR) 171 target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:/WX>) 172 endif() 173 target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:/W4>) 174elseif(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") 175 # using GCC or Clang with the regular front end 176 if (BUILD_WERROR) 177 target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:-Werror>) 178 endif() 179 target_compile_options(loader_common_options INTERFACE 180 $<$<COMPILE_LANGUAGE::CXX,C>:-Wall> 181 $<$<COMPILE_LANGUAGE::CXX,C>:-Wextra> 182 ) 183endif() 184 185if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") 186 target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:-Wno-missing-field-initializers>) 187 188 # need to prepend /clang: to compiler arguments when using clang-cl 189 if (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND "${CMAKE_C_COMPILER_FRONTEND_VARIANT}" MATCHES "MSVC") 190 target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:/clang:-fno-strict-aliasing>) 191 else() 192 target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:-fno-strict-aliasing>) 193 endif() 194 195 if(CMAKE_C_COMPILER_ID STREQUAL "GNU") 196 target_compile_options(loader_common_options INTERFACE 197 $<$<COMPILE_LANGUAGE::CXX,C>:-Wno-stringop-truncation> 198 $<$<COMPILE_LANGUAGE::CXX,C>:-Wno-stringop-overflow> 199 ) 200 if (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 7.1) 201 target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:-Wshadow=local>) #only added in GCC 7 202 endif() 203 endif() 204 205 target_compile_options(loader_common_options INTERFACE $<$<COMPILE_LANGUAGE::CXX,C>:-Wpointer-arith>) 206 207 # Force GLIBC to use the 64 bit interface for file operations instead of 32 bit - More info in issue #1551 208 if("${CMAKE_SIZEOF_VOID_P}" EQUAL "4") 209 target_compile_definitions(loader_common_options INTERFACE _FILE_OFFSET_BITS=64) 210 endif() 211endif() 212 213if(CMAKE_C_COMPILER_ID MATCHES "MSVC" OR (CMAKE_C_COMPILER_ID STREQUAL "Clang" AND CMAKE_C_COMPILER_FRONTEND_VARIANT MATCHES "MSVC")) 214 # /sdl: Enable additional security checks 215 # /GR-: Disable RTTI 216 # /guard:cf: Enable control flow guard 217 # /wd4152: Disable warning on conversion of a function pointer to a data pointer 218 # /wd4201: Disable warning on anonymous struct/unions 219 target_compile_options(loader_common_options INTERFACE 220 $<$<COMPILE_LANGUAGE::CXX,C>:/sdl> 221 $<$<COMPILE_LANGUAGE::CXX,C>:/GR-> 222 $<$<COMPILE_LANGUAGE::CXX,C>:/guard:cf> 223 $<$<COMPILE_LANGUAGE::CXX,C>:/wd4152> 224 $<$<COMPILE_LANGUAGE::CXX,C>:/wd4201> 225 ) 226 227 # Enable control flow guard 228 target_link_options(loader_common_options INTERFACE "LINKER:/guard:cf") 229 230 # Prevent <windows.h> from polluting the code. guards against things like MIN and MAX 231 target_compile_definitions(loader_common_options INTERFACE WIN32_LEAN_AND_MEAN) 232 233 # For some reason Advapi32.lib needs to be explicitely linked to when building for Arm (32 bit) on Windows, but isn't required on any other architecture 234 if (SYSTEM_PROCESSOR MATCHES "arm" AND CMAKE_SIZEOF_VOID_P EQUAL 4) 235 target_link_libraries(loader_common_options INTERFACE Advapi32) 236 endif() 237endif() 238 239# DEBUG enables runtime loader ICD verification 240# Add git branch and tag info in debug mode 241target_compile_definitions(loader_common_options INTERFACE $<$<CONFIG:DEBUG>:DEBUG;GIT_BRANCH_NAME="${GIT_BRANCH_NAME}";GIT_TAG_INFO="${GIT_TAG_INFO}">) 242 243if (NOT (WIN32 OR APPLE)) 244 # Check for the existance of the secure_getenv or __secure_getenv commands 245 include(CheckFunctionExists) 246 247 check_function_exists(secure_getenv HAVE_SECURE_GETENV) 248 check_function_exists(__secure_getenv HAVE___SECURE_GETENV) 249 250 if (HAVE_SECURE_GETENV) 251 target_compile_definitions(loader_common_options INTERFACE HAVE_SECURE_GETENV) 252 endif() 253 if (HAVE___SECURE_GETENV) 254 target_compile_definitions(loader_common_options INTERFACE HAVE___SECURE_GETENV) 255 endif() 256 if (NOT (HAVE_SECURE_GETENV OR HAVE___SECURE_GETENV)) 257 message(WARNING "Using non-secure environmental lookups. This loader will not properly disable environent variables when run with elevated permissions.") 258 endif() 259endif() 260 261option(LOADER_CODEGEN "Enable vulkan loader code generation") 262if(LOADER_CODEGEN) 263 find_package(Python3 REQUIRED) 264 add_custom_target(loader_codegen 265 COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/scripts/generate_source.py 266 "${VULKAN_HEADERS_INSTALL_DIR}/${CMAKE_INSTALL_DATADIR}/vulkan/registry" 267 --generated-version ${VulkanHeaders_VERSION} --incremental --api ${API_TYPE} 268 ) 269endif() 270 271if(UNIX) 272 target_compile_definitions(loader_common_options INTERFACE FALLBACK_CONFIG_DIRS="${FALLBACK_CONFIG_DIRS}" FALLBACK_DATA_DIRS="${FALLBACK_DATA_DIRS}") 273 274 if(NOT (SYSCONFDIR STREQUAL "")) 275 # SYSCONFDIR is specified, use it and do not force /etc. 276 target_compile_definitions(loader_common_options INTERFACE SYSCONFDIR="${SYSCONFDIR}") 277 else() 278 target_compile_definitions(loader_common_options INTERFACE SYSCONFDIR="${CMAKE_INSTALL_FULL_SYSCONFDIR}") 279 280 # Make sure /etc is searched by the loader 281 if(NOT (CMAKE_INSTALL_FULL_SYSCONFDIR STREQUAL "/etc")) 282 target_compile_definitions(loader_common_options INTERFACE EXTRASYSCONFDIR="/etc") 283 endif() 284 endif() 285endif() 286 287add_subdirectory(loader) 288 289option(BUILD_TESTS "Build Tests") 290if (BUILD_TESTS) 291 enable_testing() 292 add_subdirectory(tests) 293endif() 294