• 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.4)
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
28# User-interface declarations ----------------------------------------------------------------------------------------------------
29# This section contains variables that affect development GUIs (e.g. CMake GUI and IDEs), such as option(), folders, and variables
30# with the CACHE property.
31
32# API_NAME allows renaming builds to avoid conflicts with installed SDKs.  It is referenced by layers/vk_loader_platform.h
33set(API_NAME "Vulkan" CACHE STRING "API name to use when building")
34string(TOLOWER ${API_NAME} API_LOWERCASE)
35add_definitions(-DAPI_NAME="${API_NAME}")
36
37set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
38
39find_package(PythonInterp 3 REQUIRED)
40
41if (TARGET Vulkan::Headers)
42    message(STATUS "Using Vulkan headers from Vulkan::Headers target")
43    get_target_property(VulkanHeaders_INCLUDE_DIRS Vulkan::Headers INTERFACE_INCLUDE_DIRECTORIES)
44    get_target_property(VulkanRegistry_DIR Vulkan::Registry INTERFACE_INCLUDE_DIRECTORIES)
45else()
46    find_package(VulkanHeaders REQUIRED)
47
48    # xxxnsubtil: this should eventually be replaced by exported targets
49    add_library(Vulkan-Headers INTERFACE)
50    target_include_directories(Vulkan-Headers INTERFACE ${VulkanHeaders_INCLUDE_DIRS})
51    add_library(Vulkan::Headers ALIAS Vulkan-Headers)
52endif()
53
54option(USE_CCACHE "Use ccache" OFF)
55if(USE_CCACHE)
56    find_program(CCACHE_FOUND ccache)
57    if(CCACHE_FOUND)
58        set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
59    endif()
60endif()
61
62set(CMAKE_POSITION_INDEPENDENT_CODE ON)
63
64include(GNUInstallDirs)
65
66if(WIN32 AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
67    # Windows: if install locations not set by user, set install prefix to "<build_dir>\install".
68    set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "default install path" FORCE)
69endif()
70
71if(APPLE)
72    # CMake versions 3 or later need CMAKE_MACOSX_RPATH defined. This avoids the CMP0042 policy message.
73    set(CMAKE_MACOSX_RPATH 1)
74    # The "install" target for MacOS fixes up bundles in place.
75    set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR})
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# Generate a source file from vk.xml
295macro(GenerateFromVkXml dependency output)
296    add_custom_command(OUTPUT ${output}
297                       COMMAND ${PYTHON_EXECUTABLE} ${SCRIPTS_DIR}/lvl_genvk.py -registry ${VulkanRegistry_DIR}/vk.xml -scripts
298                               ${VulkanRegistry_DIR} ${output}
299                       DEPENDS ${VulkanRegistry_DIR}/vk.xml
300                               ${VulkanRegistry_DIR}/generator.py
301                               ${SCRIPTS_DIR}/${dependency}
302                               ${SCRIPTS_DIR}/lvl_genvk.py
303                               ${VulkanRegistry_DIR}/reg.py)
304endmacro()
305
306# Add rules to generate XML-derived source files.
307GenerateFromVkXml(layer_dispatch_table_generator.py vk_layer_dispatch_table.h)
308GenerateFromVkXml(dispatch_table_helper_generator.py vk_dispatch_table_helper.h)
309GenerateFromVkXml(helper_file_generator.py vk_safe_struct.h)
310GenerateFromVkXml(helper_file_generator.py vk_safe_struct.cpp)
311GenerateFromVkXml(helper_file_generator.py vk_enum_string_helper.h)
312GenerateFromVkXml(helper_file_generator.py vk_object_types.h)
313GenerateFromVkXml(helper_file_generator.py vk_extension_helper.h)
314GenerateFromVkXml(helper_file_generator.py vk_typemap_helper.h)
315
316# This target causes the source files to be generated.
317add_custom_target(VulkanVL_generate_helper_files
318                  DEPENDS vk_enum_string_helper.h
319                          vk_safe_struct.h
320                          vk_safe_struct.cpp
321                          vk_object_types.h
322                          vk_layer_dispatch_table.h
323                          vk_dispatch_table_helper.h
324                          vk_extension_helper.h
325                          vk_typemap_helper.h)
326set_target_properties(VulkanVL_generate_helper_files PROPERTIES FOLDER ${LAYERS_HELPER_FOLDER})
327
328# VkLayer_utils library ----------------------------------------------------------------------------------------------------------
329# For Windows, we use a static lib because the Windows loader has a fairly restrictive loader search path that can't be easily
330# modified to point it to the same directory that contains the layers. TODO: This should not be a library -- in future, include
331# files directly in layers.
332
333add_library(VkLayer_utils
334            STATIC
335            layers/vk_layer_config.cpp
336            layers/vk_layer_extension_utils.cpp
337            layers/vk_layer_utils.cpp
338            layers/vk_format_utils.cpp)
339target_link_libraries(VkLayer_utils PUBLIC Vulkan::Headers)
340if(WIN32)
341    target_compile_definitions(VkLayer_utils PUBLIC _CRT_SECURE_NO_WARNINGS)
342endif()
343install(TARGETS VkLayer_utils DESTINATION ${CMAKE_INSTALL_LIBDIR})
344set_target_properties(VkLayer_utils PROPERTIES LINKER_LANGUAGE CXX)
345add_dependencies(VkLayer_utils VulkanVL_generate_helper_files)
346target_include_directories(VkLayer_utils
347                           PUBLIC ${VulkanHeaders_INCLUDE_DIR}
348                                  ${CMAKE_CURRENT_BINARY_DIR}
349                                  ${CMAKE_CURRENT_BINARY_DIR}/layers
350                                  ${PROJECT_BINARY_DIR})
351
352# uninstall target ---------------------------------------------------------------------------------------------------------------
353if(NOT TARGET uninstall)
354    configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
355                   "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
356                   IMMEDIATE
357                   @ONLY)
358    add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
359    set_target_properties(uninstall PROPERTIES FOLDER ${LAYERS_HELPER_FOLDER})
360endif()
361
362# Fetch header version from vulkan_core.h ----------------------------------------------------------------------------------------
363file(STRINGS "${VulkanHeaders_INCLUDE_DIRS}/vulkan/vulkan_core.h" lines REGEX "^#define VK_HEADER_VERSION [0-9]+")
364list(LENGTH lines len)
365if(${len} EQUAL 1)
366    string(REGEX MATCHALL
367                 "[0-9]+"
368                 vk_header_version
369                 ${lines})
370else()
371    message(FATAL_ERROR "Unable to fetch version from vulkan_core.h")
372endif()
373
374# Add subprojects ----------------------------------------------------------------------------------------------------------------
375
376add_subdirectory(external)
377if(BUILD_TESTS)
378    add_subdirectory(tests)
379endif()
380
381if(BUILD_LAYERS OR BUILD_LAYER_SUPPORT_FILES)
382    add_subdirectory(layers)
383endif()
384