1# ~~~ 2# Copyright (c) 2014-2019 Valve Corporation 3# Copyright (c) 2014-2019 LunarG, Inc. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# ~~~ 17 18# CMake project initialization --------------------------------------------------------------------------------------------------- 19# This section contains pre-project() initialization, and ends with the project() command. 20 21cmake_minimum_required(VERSION 3.10.2) 22 23# Apple: Must be set before enable_language() or project() as it may influence configuration of the toolchain and flags. 24set(CMAKE_OSX_DEPLOYMENT_TARGET "10.12" CACHE STRING "Minimum OS X deployment version") 25 26project(Vulkan-ValidationLayers) 27 28enable_testing() 29 30# User-interface declarations ---------------------------------------------------------------------------------------------------- 31# This section contains variables that affect development GUIs (e.g. CMake GUI and IDEs), such as option(), folders, and variables 32# with the CACHE property. 33 34# API_NAME allows renaming builds to avoid conflicts with installed SDKs. It is referenced by layers/vk_loader_platform.h 35set(API_NAME "Vulkan" CACHE STRING "API name to use when building") 36string(TOLOWER ${API_NAME} API_LOWERCASE) 37add_definitions(-DAPI_NAME="${API_NAME}") 38 39set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 40 41find_package(PythonInterp 3 QUIET) 42 43if (TARGET Vulkan::Headers) 44 message(STATUS "Using Vulkan headers from Vulkan::Headers target") 45 get_target_property(VulkanHeaders_INCLUDE_DIRS Vulkan::Headers INTERFACE_INCLUDE_DIRECTORIES) 46 get_target_property(VulkanRegistry_DIR Vulkan::Registry INTERFACE_INCLUDE_DIRECTORIES) 47else() 48 find_package(VulkanHeaders REQUIRED) 49 50 # xxxnsubtil: this should eventually be replaced by exported targets 51 add_library(Vulkan-Headers INTERFACE) 52 target_include_directories(Vulkan-Headers INTERFACE ${VulkanHeaders_INCLUDE_DIRS}) 53 add_library(Vulkan::Headers ALIAS Vulkan-Headers) 54endif() 55 56option(USE_CCACHE "Use ccache" OFF) 57if(USE_CCACHE) 58 find_program(CCACHE_FOUND ccache) 59 if(CCACHE_FOUND) 60 set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) 61 endif() 62endif() 63 64set(CMAKE_POSITION_INDEPENDENT_CODE ON) 65 66include(GNUInstallDirs) 67 68if(WIN32 AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 69 # Windows: if install locations not set by user, set install prefix to "<build_dir>\install". 70 set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "default install path" FORCE) 71endif() 72 73if(APPLE) 74 # CMake versions 3 or later need CMAKE_MACOSX_RPATH defined. This avoids the CMP0042 policy message. 75 set(CMAKE_MACOSX_RPATH 1) 76endif() 77 78# Enable IDE GUI folders 79set_property(GLOBAL PROPERTY USE_FOLDERS ON) 80# "Helper" targets that don't have interesting source code should set their FOLDER property to this 81set(LAYERS_HELPER_FOLDER "Helper Targets") 82 83# Options for Linux only 84if(UNIX AND NOT APPLE) # i.e. Linux 85 include(FindPkgConfig) 86 option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON) 87 option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON) 88 option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON) 89 set(DEMOS_WSI_SELECTION "XCB" CACHE STRING "Select WSI target for demos (XCB, XLIB, WAYLAND, DISPLAY)") 90 91 if(BUILD_WSI_XCB_SUPPORT) 92 find_package(XCB REQUIRED) 93 endif() 94 95 if(BUILD_WSI_XLIB_SUPPORT) 96 find_package(X11 REQUIRED) 97 endif() 98 99 if(BUILD_WSI_WAYLAND_SUPPORT) 100 find_package(Wayland REQUIRED) 101 include_directories(${WAYLAND_CLIENT_INCLUDE_DIR}) 102 endif() 103endif() 104 105# Platform-specific compiler switches 106if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang") 107 add_compile_options(-Wall 108 -Wextra 109 -Wno-unused-parameter 110 -Wno-missing-field-initializers 111 -fno-strict-aliasing 112 -fno-builtin-memcmp 113 -fvisibility=hidden) 114 115 # Treat warnings as errors for versions of GCC and Clang that are shipped on Ubuntu 18.04 or older. 116 if((CMAKE_COMPILER_IS_GNUCXX AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.3.0)) OR 117 (("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 3.8.0))) 118 add_compile_options(-Werror) 119 endif() 120 121 set(CMAKE_C_STANDARD 99) 122 set(CMAKE_CXX_STANDARD 11) 123 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") 124 125 # For GCC version 7.1 or greater, we need to disable the implicit fallthrough warning since there's no consistent way to satisfy 126 # all compilers until they all accept the C++17 standard. 127 if(CMAKE_COMPILER_IS_GNUCC AND NOT (CMAKE_CXX_COMPILER_VERSION LESS 7.1)) 128 add_compile_options(-Wimplicit-fallthrough=0) 129 endif() 130elseif(MSVC) 131 # Treat warnings as errors 132 add_compile_options("/WX") 133 # Disable RTTI 134 add_compile_options("/GR-") 135 # Warn about nested declarations 136 add_compile_options("/w34456") 137 # Warn about potentially uninitialized variables 138 add_compile_options("/w34701") 139 add_compile_options("/w34703") 140 # Warn about different indirection types. 141 add_compile_options("/w34057") 142 # Warn about signed/unsigned mismatch. 143 add_compile_options("/w34245") 144endif() 145 146if(TARGET gtest OR IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/external/googletest) 147 option(BUILD_TESTS "Build tests" ON) 148else() 149 option(BUILD_TESTS "Build tests" OFF) 150endif() 151 152option(INSTALL_TESTS "Install tests" OFF) 153option(BUILD_LAYERS "Build layers" ON) 154option(BUILD_LAYER_SUPPORT_FILES "Generate layer files" OFF) # For generating files when not building layers 155 156if(BUILD_TESTS OR BUILD_LAYERS) 157 158 set(GLSLANG_INSTALL_DIR "GLSLANG-NOTFOUND" CACHE PATH "Absolute path to a glslang install directory") 159 if(NOT GLSLANG_INSTALL_DIR AND NOT DEFINED ENV{GLSLANG_INSTALL_DIR} AND NOT TARGET glslang) 160 message(FATAL_ERROR "Must define location of glslang binaries -- see BUILD.md") 161 endif() 162 163 # GLSLANG_INSTALL_DIR is used as the path to all dependent projects' install dirs 164 # CMake command line option overrides environment variable 165 if(NOT GLSLANG_INSTALL_DIR) 166 set(GLSLANG_INSTALL_DIR $ENV{GLSLANG_INSTALL_DIR}) 167 endif() 168 169 if (NOT TARGET glslang) 170 message(STATUS "Using glslang install located at ${GLSLANG_INSTALL_DIR}") 171 set(GLSLANG_SEARCH_PATH "${GLSLANG_INSTALL_DIR}/lib") 172 set(GLSLANG_DEBUG_SEARCH_PATH "${GLSLANG_INSTALL_DIR}/lib") 173 set(GLSLANG_SPIRV_INCLUDE_DIR "${GLSLANG_INSTALL_DIR}/include" CACHE PATH "Path to glslang spirv headers") 174 175 find_library(GLSLANG_LIB NAMES glslang HINTS ${GLSLANG_SEARCH_PATH}) 176 find_library(OGLCompiler_LIB NAMES OGLCompiler HINTS ${GLSLANG_SEARCH_PATH}) 177 find_library(OSDependent_LIB NAMES OSDependent HINTS ${GLSLANG_SEARCH_PATH}) 178 find_library(HLSL_LIB NAMES HLSL HINTS ${GLSLANG_SEARCH_PATH}) 179 find_library(SPIRV_LIB NAMES SPIRV HINTS ${GLSLANG_SEARCH_PATH}) 180 find_library(SPIRV_REMAPPER_LIB NAMES SPVRemapper HINTS ${GLSLANG_SEARCH_PATH}) 181 182 if(WIN32) 183 add_library(glslang STATIC IMPORTED) 184 add_library(OGLCompiler STATIC IMPORTED) 185 add_library(OSDependent STATIC IMPORTED) 186 add_library(HLSL STATIC IMPORTED) 187 add_library(SPIRV STATIC IMPORTED) 188 add_library(SPVRemapper STATIC IMPORTED) 189 add_library(Loader STATIC IMPORTED) 190 191 find_library(GLSLANG_DLIB NAMES glslangd HINTS ${GLSLANG_DEBUG_SEARCH_PATH}) 192 find_library(OGLCompiler_DLIB NAMES OGLCompilerd HINTS ${GLSLANG_DEBUG_SEARCH_PATH}) 193 find_library(OSDependent_DLIB NAMES OSDependentd HINTS ${GLSLANG_DEBUG_SEARCH_PATH}) 194 find_library(HLSL_DLIB NAMES HLSLd HINTS ${GLSLANG_DEBUG_SEARCH_PATH}) 195 find_library(SPIRV_DLIB NAMES SPIRVd HINTS ${GLSLANG_DEBUG_SEARCH_PATH}) 196 find_library(SPIRV_REMAPPER_DLIB NAMES SPVRemapperd HINTS ${GLSLANG_DEBUG_SEARCH_PATH}) 197 198 set_target_properties(glslang 199 PROPERTIES IMPORTED_LOCATION 200 "${GLSLANG_LIB}" 201 IMPORTED_LOCATION_DEBUG 202 "${GLSLANG_DLIB}") 203 set_target_properties(OGLCompiler 204 PROPERTIES IMPORTED_LOCATION 205 "${OGLCompiler_LIB}" 206 IMPORTED_LOCATION_DEBUG 207 "${OGLCompiler_DLIB}") 208 set_target_properties(OSDependent 209 PROPERTIES IMPORTED_LOCATION 210 "${OSDependent_LIB}" 211 IMPORTED_LOCATION_DEBUG 212 "${OSDependent_DLIB}") 213 set_target_properties(HLSL 214 PROPERTIES IMPORTED_LOCATION 215 "${HLSL_LIB}" 216 IMPORTED_LOCATION_DEBUG 217 "${HLSL_DLIB}") 218 set_target_properties(SPIRV 219 PROPERTIES IMPORTED_LOCATION 220 "${SPIRV_LIB}" 221 IMPORTED_LOCATION_DEBUG 222 "${SPIRV_DLIB}") 223 set_target_properties(SPVRemapper 224 PROPERTIES IMPORTED_LOCATION 225 "${SPIRV_REMAPPER_LIB}" 226 IMPORTED_LOCATION_DEBUG 227 "${SPIRV_REMAPPER_DLIB}") 228 229 set(GLSLANG_LIBRARIES glslang OGLCompiler OSDependent HLSL SPIRV SPVRemapper ${SPIRV_TOOLS_LIBRARIES}) 230 else() 231 set(GLSLANG_LIBRARIES 232 ${GLSLANG_LIB} 233 ${OGLCompiler_LIB} 234 ${OSDependent_LIB} 235 ${HLSL_LIB} 236 ${SPIRV_LIB} 237 ${SPIRV_REMAPPER_LIB} 238 ${SPIRV_TOOLS_LIBRARIES}) 239 endif() 240 else() 241 set(GLSLANG_SPIRV_INCLUDE_DIR "${glslang_SOURCE_DIR}" CACHE PATH "Path to glslang spirv headers") 242 set(GLSLANG_LIBRARIES glslang SPIRV SPVRemapper) 243 endif() 244 245 # spirv-tools 246 if (NOT TARGET SPIRV-Tools) 247 set(SPIRV_TOOLS_BINARY_ROOT "${GLSLANG_INSTALL_DIR}/lib" 248 CACHE PATH "User defined path to the SPIRV-Tools binaries for this project") 249 set(SPIRV_TOOLS_OPT_BINARY_ROOT "${GLSLANG_INSTALL_DIR}/lib" 250 CACHE PATH "User defined path to the SPIRV-Tools-opt binaries for this project") 251 set(SPIRV_TOOLS_INCLUDE_DIR "${GLSLANG_INSTALL_DIR}/include" CACHE PATH "Path to spirv tools headers") 252 set(SPIRV_TOOLS_SEARCH_PATH "${GLSLANG_INSTALL_DIR}/lib") 253 set(SPIRV_TOOLS_DEBUG_SEARCH_PATH "${GLSLANG_INSTALL_DIR}/lib") 254 set(SPIRV_TOOLS_OPT_SEARCH_PATH "${GLSLANG_INSTALL_DIR}/lib") 255 set(SPIRV_TOOLS_OPT_DEBUG_SEARCH_PATH "${GLSLANG_INSTALL_DIR}/lib") 256 257 find_library(SPIRV_TOOLS_LIB NAMES SPIRV-Tools HINTS ${SPIRV_TOOLS_SEARCH_PATH}) 258 find_library(SPIRV_TOOLS_OPT_LIB NAMES SPIRV-Tools-opt HINTS ${SPIRV_TOOLS_OPT_SEARCH_PATH}) 259 260 if(WIN32) 261 add_library(SPIRV-Tools-opt STATIC IMPORTED) 262 add_library(SPIRV-Tools STATIC IMPORTED) 263 264 find_library(SPIRV_TOOLS_DLIB NAMES SPIRV-Toolsd HINTS ${SPIRV_TOOLS_DEBUG_SEARCH_PATH}) 265 find_library(SPIRV_TOOLS_OPT_DLIB NAMES SPIRV-Tools-optd HINTS ${SPIRV_TOOLS_OPT_DEBUG_SEARCH_PATH}) 266 267 set_target_properties(SPIRV-Tools 268 PROPERTIES IMPORTED_LOCATION 269 "${SPIRV_TOOLS_LIB}" 270 IMPORTED_LOCATION_DEBUG 271 "${SPIRV_TOOLS_DLIB}") 272 set_target_properties(SPIRV-Tools-opt 273 PROPERTIES IMPORTED_LOCATION 274 "${SPIRV_TOOLS_OPT_LIB}" 275 IMPORTED_LOCATION_DEBUG 276 "${SPIRV_TOOLS_OPT_DLIB}") 277 278 set(SPIRV_TOOLS_LIBRARIES SPIRV-Tools-opt SPIRV-Tools) 279 else() 280 set(SPIRV_TOOLS_LIBRARIES ${SPIRV_TOOLS_OPT_LIB} ${SPIRV_TOOLS_LIB}) 281 endif() 282 else() 283 set(SPIRV_TOOLS_LIBRARIES SPIRV-Tools SPIRV-Tools-opt) 284 set(SPIRV_TOOLS_INCLUDE_DIR "${spirv-tools_SOURCE_DIR}/include" CACHE PATH "Path to spirv tools headers") 285 endif() 286 287 set(GLSLANG_LIBRARIES ${GLSLANG_LIBRARIES} ${SPIRV_TOOLS_LIBRARIES}) 288endif() 289 290# Generate dependent helper files ------------------------------------------------------------------------------------------------ 291 292set(SCRIPTS_DIR "${PROJECT_SOURCE_DIR}/scripts") 293 294# VkLayer_utils library ---------------------------------------------------------------------------------------------------------- 295# For Windows, we use a static lib because the Windows loader has a fairly restrictive loader search path that can't be easily 296# modified to point it to the same directory that contains the layers. TODO: This should not be a library -- in future, include 297# files directly in layers. 298 299add_library(VkLayer_utils 300 STATIC 301 layers/vk_layer_config.cpp 302 layers/vk_layer_extension_utils.cpp 303 layers/vk_layer_utils.cpp 304 layers/vk_format_utils.cpp) 305target_link_libraries(VkLayer_utils PUBLIC Vulkan::Headers) 306if(WIN32) 307 target_compile_definitions(VkLayer_utils PUBLIC _CRT_SECURE_NO_WARNINGS) 308endif() 309install(TARGETS VkLayer_utils DESTINATION ${CMAKE_INSTALL_LIBDIR}) 310set_target_properties(VkLayer_utils PROPERTIES LINKER_LANGUAGE CXX) 311target_include_directories(VkLayer_utils 312 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/layers 313 ${CMAKE_CURRENT_SOURCE_DIR}/layers/generated 314 ${CMAKE_CURRENT_BINARY_DIR} 315 ${CMAKE_CURRENT_BINARY_DIR}/layers 316 ${PROJECT_BINARY_DIR} 317 ${VulkanHeaders_INCLUDE_DIR}) 318 319# uninstall target --------------------------------------------------------------------------------------------------------------- 320if(NOT TARGET uninstall) 321 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" 322 "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" 323 IMMEDIATE 324 @ONLY) 325 add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) 326 set_target_properties(uninstall PROPERTIES FOLDER ${LAYERS_HELPER_FOLDER}) 327endif() 328 329# Fetch header version from vulkan_core.h ---------------------------------------------------------------------------------------- 330file(STRINGS "${VulkanHeaders_INCLUDE_DIRS}/vulkan/vulkan_core.h" lines REGEX "^#define VK_HEADER_VERSION [0-9]+") 331list(LENGTH lines len) 332if(${len} EQUAL 1) 333 string(REGEX MATCHALL 334 "[0-9]+" 335 vk_header_version 336 ${lines}) 337else() 338 message(FATAL_ERROR "Unable to fetch version from vulkan_core.h") 339endif() 340 341# Optional codegen target -------------------------------------------------------------------------------------------------------- 342if(PYTHONINTERP_FOUND) 343 add_custom_target(VulkanVL_generated_source 344 COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/generate_source.py 345 ${VulkanRegistry_DIR} --incremental 346 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/layers/generated 347 ) 348else() 349 message("WARNING: VulkanVL_generated_source target requires python 3") 350endif() 351 352# Add subprojects ---------------------------------------------------------------------------------------------------------------- 353 354add_subdirectory(external) 355if(BUILD_TESTS) 356 add_subdirectory(tests) 357endif() 358 359if(BUILD_LAYERS OR BUILD_LAYER_SUPPORT_FILES) 360 add_subdirectory(layers) 361endif() 362