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