• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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