• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# ~~~
2# Copyright (c) 2014-2022 Valve Corporation
3# Copyright (c) 2014-2022 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
18cmake_minimum_required(VERSION 3.10.2)
19
20# Apple: Must be set before enable_language() or project() as it may influence configuration of the toolchain and flags.
21set(CMAKE_OSX_DEPLOYMENT_TARGET "10.12" CACHE STRING "Minimum OS X deployment version")
22
23# If we are building in Visual Studio 2015 and with a CMake version 3.19 or greater, we need to set this variable
24# so that CMake will choose a Windows SDK version higher than 10.0.14393.0, as dxgi1_6.h is only found in Windows SDK
25# 10.0.17763 and higher.
26set(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION_MAXIMUM OFF)
27
28project(Vulkan-Loader)
29
30if (UPDATE_DEPS)
31    find_package(PythonInterp 3 REQUIRED)
32
33    if (CMAKE_GENERATOR_PLATFORM)
34        set(_target_arch ${CMAKE_GENERATOR_PLATFORM})
35    else()
36        if (MSVC_IDE)
37            message(WARNING "CMAKE_GENERATOR_PLATFORM not set. Using x64 as target architecture.")
38        endif()
39        set(_target_arch x64)
40    endif()
41
42    if (NOT CMAKE_BUILD_TYPE)
43        message(WARNING "CMAKE_BUILD_TYPE not set. Using Debug for dependency build type")
44        set(_build_type Debug)
45    else()
46        set(_build_type ${CMAKE_BUILD_TYPE})
47    endif()
48
49    set(_build_tests_arg "")
50    if (NOT BUILD_TESTS)
51        set(_build_tests_arg "--optional=tests")
52    endif()
53
54    message("********************************************************************************")
55    message("* NOTE: Adding target vl_update_deps to run as needed for updating            *")
56    message("*       dependencies.                                                          *")
57    message("********************************************************************************")
58
59    # Add a target so that update_deps.py will run when necessary
60    # NOTE: This is triggered off of the timestamps of known_good.json and helper.cmake
61    add_custom_command(OUTPUT ${CMAKE_CURRENT_LIST_DIR}/external/helper.cmake
62                       COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/scripts/update_deps.py --dir ${CMAKE_CURRENT_LIST_DIR}/external --arch ${_target_arch} --config ${_build_type} --generator "${CMAKE_GENERATOR}" ${_build_tests_arg}
63                       DEPENDS ${CMAKE_CURRENT_LIST_DIR}/scripts/known_good.json)
64
65    add_custom_target(vl_update_deps DEPENDS ${CMAKE_CURRENT_LIST_DIR}/external/helper.cmake)
66
67    # Check if update_deps.py needs to be run on first cmake run
68    if (${CMAKE_CURRENT_LIST_DIR}/scripts/known_good.json IS_NEWER_THAN ${CMAKE_CURRENT_LIST_DIR}/external/helper.cmake)
69        execute_process(
70            COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/scripts/update_deps.py --dir ${CMAKE_CURRENT_LIST_DIR}/external --arch ${_target_arch} --config ${_build_type} --generator "${CMAKE_GENERATOR}" ${_build_tests_arg}
71            WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
72            RESULT_VARIABLE _update_deps_result
73        )
74        if (NOT (${_update_deps_result} EQUAL 0))
75            message(FATAL_ERROR "Could not run update_deps.py which is necessary to download dependencies.")
76        endif()
77    endif()
78    include(${CMAKE_CURRENT_LIST_DIR}/external/helper.cmake)
79else()
80    message("********************************************************************************")
81    message("* NOTE: Not adding target to run update_deps.py automatically.                 *")
82    message("********************************************************************************")
83    find_package(PythonInterp 3 QUIET)
84endif()
85
86set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
87find_package(PythonInterp 3 QUIET)
88
89set(THREADS_PREFER_PTHREAD_FLAG ON)
90find_package(Threads REQUIRED)
91
92option(BUILD_TESTS "Build Tests" OFF)
93
94if(BUILD_TESTS)
95    enable_testing()
96endif()
97
98if(APPLE)
99    option(BUILD_STATIC_LOADER "Build a loader that can be statically linked" OFF)
100endif()
101
102if(WIN32)
103    # Optional: Allow specify the exact version used in the loader dll
104    # Format is major.minor.patch.build
105    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")
106endif()
107
108if(BUILD_STATIC_LOADER)
109    message(WARNING "The BUILD_STATIC_LOADER option has been set. Note that this will only work on MacOS and is not supported "
110        "or tested as part of the loader. Use it at your own risk.")
111endif()
112
113if (TARGET Vulkan::Headers)
114    message(STATUS "Using Vulkan headers from Vulkan::Headers target")
115    get_target_property(VulkanHeaders_INCLUDE_DIRS Vulkan::Headers INTERFACE_INCLUDE_DIRECTORIES)
116    get_target_property(VulkanRegistry_DIR Vulkan::Registry INTERFACE_INCLUDE_DIRECTORIES)
117else()
118    find_package(VulkanHeaders)
119    if(NOT ${VulkanHeaders_FOUND})
120        message(FATAL_ERROR "Could not find Vulkan headers path. This can be fixed by setting VULKAN_HEADERS_INSTALL_DIR to an "
121                            "installation of the Vulkan-Headers repository.")
122    endif()
123    if(NOT ${VulkanRegistry_FOUND})
124        message(FATAL_ERROR "Could not find Vulkan registry path. This can be fixed by setting VULKAN_HEADERS_INSTALL_DIR to an "
125                            "installation of the Vulkan-Headers repository.")
126    endif()
127
128    # set up the Vulkan::Headers target for consistency
129    add_library(vulkan-headers INTERFACE)
130    target_include_directories(vulkan-headers SYSTEM INTERFACE "${VulkanHeaders_INCLUDE_DIRS}")
131    add_library(Vulkan::Headers ALIAS vulkan-headers)
132endif()
133
134option(USE_CCACHE "Use ccache" OFF)
135if(USE_CCACHE)
136    find_program(CCACHE_FOUND ccache)
137    if(CCACHE_FOUND)
138        set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
139    endif()
140endif()
141
142include(GNUInstallDirs)
143
144if(UNIX AND NOT APPLE) # i.e.: Linux
145    include(FindPkgConfig)
146endif()
147
148if(APPLE)
149    # CMake versions 3 or later need CMAKE_MACOSX_RPATH defined. This avoids the CMP0042 policy message.
150    set(CMAKE_MACOSX_RPATH 1)
151endif()
152
153set(GIT_BRANCH_NAME "--unknown--")
154set(GIT_TAG_INFO "--unknown--")
155find_package (Git)
156if (GIT_FOUND AND EXISTS "${CMAKE_CURRENT_LIST_DIR}/.git/HEAD")
157    execute_process(
158        COMMAND ${GIT_EXECUTABLE} describe --tags --always
159        WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
160        OUTPUT_VARIABLE GIT_TAG_INFO)
161    string(REGEX REPLACE "\n$" "" GIT_TAG_INFO "${GIT_TAG_INFO}")
162
163    file(READ "${CMAKE_CURRENT_LIST_DIR}/.git/HEAD" GIT_HEAD_REF_INFO)
164    if (GIT_HEAD_REF_INFO)
165        string(REGEX MATCH "ref: refs/heads/(.*)" _ ${GIT_HEAD_REF_INFO})
166        if (CMAKE_MATCH_1)
167            set(GIT_BRANCH_NAME ${CMAKE_MATCH_1})
168        else()
169            set(GIT_BRANCH_NAME ${GIT_HEAD_REF_INFO})
170        endif()
171        string(REGEX REPLACE "\n$" "" GIT_BRANCH_NAME "${GIT_BRANCH_NAME}")
172    endif()
173endif()
174
175if(WIN32 AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
176    # Windows: if install locations not set by user, set install prefix to "<build_dir>\install".
177    set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE PATH "default install path" FORCE)
178endif()
179
180# Enable IDE GUI folders.  "Helper targets" that don't have interesting source code should set their FOLDER property to this
181set_property(GLOBAL PROPERTY USE_FOLDERS ON)
182set(LOADER_HELPER_FOLDER "Helper Targets")
183
184if(UNIX)
185    set(FALLBACK_CONFIG_DIRS "/etc/xdg" CACHE STRING
186            "Search path to use when XDG_CONFIG_DIRS is unset or empty or the current process is SUID/SGID. Default is freedesktop compliant.")
187    set(FALLBACK_DATA_DIRS "/usr/local/share:/usr/share" CACHE STRING
188            "Search path to use when XDG_DATA_DIRS is unset or empty or the current process is SUID/SGID. Default is freedesktop compliant.")
189    set(SYSCONFDIR "" CACHE STRING
190            "System-wide search directory. If not set or empty, CMAKE_INSTALL_FULL_SYSCONFDIR and /etc are used.")
191endif()
192
193# Because we use CMake 3.10.2, we can't use the policy which would disable adding /W3 by default. In the interim, replace the flags
194# When this project is updated to 3.15 and above, use the following line.
195#     cmake_policy(SET CMP0092 NEW)
196string(REGEX REPLACE "/W3" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
197string(REGEX REPLACE "/W3" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
198
199# For MSVC/Windows, replace /GR with an empty string, this prevents warnings of /GR being overriden by /GR-
200# Newer CMake versions (3.20) have better solutions for this through policy - using the old
201# way while waiting for when updating can occur
202string(REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
203
204if(UNIX AND NOT APPLE) # i.e.: Linux
205    option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON)
206    option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON)
207    option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON)
208    option(BUILD_WSI_DIRECTFB_SUPPORT "Build DirectFB WSI support" OFF)
209    option(BUILD_WSI_SCREEN_QNX_SUPPORT "Build QNX Screen WSI support" OFF)
210
211    if(BUILD_WSI_XCB_SUPPORT)
212        find_package(XCB REQUIRED)
213        include_directories(SYSTEM ${XCB_INCLUDE_DIR})
214    endif()
215
216    if(BUILD_WSI_XLIB_SUPPORT)
217        find_package(X11 REQUIRED)
218    endif()
219
220    if(BUILD_WSI_DIRECTFB_SUPPORT)
221        find_package(DirectFB REQUIRED)
222        include_directories(SYSTEM ${DIRECTFB_INCLUDE_DIR})
223    endif()
224
225    if(BUILD_WSI_SCREEN_QNX_SUPPORT)
226        # Part of OS, no additional include directories are required
227    endif()
228endif()
229
230if(WIN32)
231    option(ENABLE_WIN10_ONECORE "Link the loader with OneCore umbrella libraries" OFF)
232endif()
233
234add_library(platform_wsi_defines INTERFACE)
235if(WIN32)
236    target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_WIN32_KHR)
237elseif(ANDROID)
238    target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_ANDROID_KHR)
239elseif(APPLE)
240    target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_MACOS_MVK VK_USE_PLATFORM_METAL_EXT)
241elseif(UNIX AND NOT APPLE) # i.e.: Linux
242    if(BUILD_WSI_XCB_SUPPORT)
243        target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_XCB_KHR)
244    endif()
245    if(BUILD_WSI_XLIB_SUPPORT)
246        target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_XLIB_KHR VK_USE_PLATFORM_XLIB_XRANDR_EXT)
247    endif()
248    if(BUILD_WSI_WAYLAND_SUPPORT)
249        target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_WAYLAND_KHR)
250    endif()
251    if(BUILD_WSI_DIRECTFB_SUPPORT)
252        target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_DIRECTFB_EXT)
253    endif()
254    if(BUILD_WSI_SCREEN_QNX_SUPPORT)
255        target_compile_definitions(platform_wsi_defines INTERFACE VK_USE_PLATFORM_SCREEN_QNX)
256    endif()
257else()
258    message(FATAL_ERROR "Unsupported Platform!")
259endif()
260
261add_library(loader_common_options INTERFACE)
262target_compile_definitions(loader_common_options INTERFACE API_NAME="Vulkan")
263target_link_libraries(loader_common_options INTERFACE platform_wsi_defines)
264
265# Enable beta Vulkan extensions
266target_compile_definitions(loader_common_options INTERFACE VK_ENABLE_BETA_EXTENSIONS)
267
268target_compile_features(loader_common_options INTERFACE c_std_99)
269target_compile_features(loader_common_options INTERFACE cxx_std_11)
270set(LOADER_STANDARD_C_PROPERTIES PROPERTIES C_STANDARD 99 C_STANDARD_REQUIRED YES C_EXTENSIONS OFF)
271set(LOADER_STANDARD_CXX_PROPERTIES PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED YES CXX_EXTENSIONS OFF)
272
273option(ENABLE_WERROR "Enable warnings as errors" ON)
274
275# Set warnings as errors and the main diagnostic flags
276# Must be set first so the warning silencing later on works properly
277# Note that clang-cl.exe should use MSVC flavor flags, not GNU
278if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" MATCHES "MSVC"))
279    if (ENABLE_WERROR)
280        target_compile_options(loader_common_options INTERFACE /WX)
281    endif()
282    target_compile_options(loader_common_options INTERFACE /W4)
283elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
284    # using GCC or Clang with the regular front end
285    if (ENABLE_WERROR)
286        target_compile_options(loader_common_options INTERFACE -Werror)
287    endif()
288    target_compile_options(loader_common_options INTERFACE -Wall -Wextra)
289endif()
290
291if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
292    target_compile_options(loader_common_options INTERFACE -Wno-unused-parameter -Wno-unused-function -Wno-missing-field-initializers)
293
294    # need to prepend /clang: to compiler arguments when using clang-cl
295    if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" MATCHES "MSVC")
296        target_compile_options(loader_common_options INTERFACE /clang:-fno-strict-aliasing /clang:-fno-builtin-memcmp)
297    else()
298        target_compile_options(loader_common_options INTERFACE -fno-strict-aliasing -fno-builtin-memcmp)
299    endif()
300
301    # For GCC version 7.1 or greater, we need to disable the implicit fallthrough warning since there's no consistent way to satisfy
302    # all compilers until they all accept the C++17 standard
303    if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
304        target_compile_options(loader_common_options INTERFACE -Wno-stringop-truncation -Wno-stringop-overflow)
305        if(CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 7.1)
306            target_compile_options(loader_common_options INTERFACE -Wimplicit-fallthrough=0)
307        endif()
308    endif()
309
310    if(UNIX)
311        target_compile_options(loader_common_options INTERFACE -fvisibility=hidden)
312    endif()
313
314    target_compile_options(loader_common_options INTERFACE -Wpointer-arith)
315endif()
316
317if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC" OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" MATCHES "MSVC"))
318    # /GR-: Disable RTTI
319    # /guard:cf: Enable control flow guard
320    # /wd4100: Disable warning on unreferenced formal parameter
321    # /wd4152: Disable warning on conversion of a function pointer to a data pointer
322    # /wd4201: Disable warning on anonymous struct/unions
323    target_compile_options(loader_common_options INTERFACE /GR- /guard:cf /wd4100 /wd4152 /wd4201)
324
325    # Enable control flow guard
326    if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
327        target_link_options(loader_common_options INTERFACE "LINKER:/guard:cf")
328    else()
329        set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /guard:cf")
330        set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /guard:cf")
331    endif()
332
333    # Prevent <windows.h> from polluting the code. guards against things like MIN and MAX
334    target_compile_definitions(loader_common_options INTERFACE WIN32_LEAN_AND_MEAN)
335endif()
336
337# DEBUG enables runtime loader ICD verification
338# Add git branch and tag info in debug mode
339target_compile_definitions(loader_common_options INTERFACE $<$<CONFIG:DEBUG>:DEBUG;GIT_BRANCH_NAME="${GIT_BRANCH_NAME}";GIT_TAG_INFO="${GIT_TAG_INFO}">)
340
341# Check for the existance of the secure_getenv or __secure_getenv commands
342include(CheckFunctionExists)
343include(CheckIncludeFile)
344
345check_function_exists(secure_getenv HAVE_SECURE_GETENV)
346check_function_exists(__secure_getenv HAVE___SECURE_GETENV)
347
348if (HAVE_SECURE_GETENV)
349    target_compile_definitions(loader_common_options INTERFACE HAVE_SECURE_GETENV)
350endif()
351if (HAVE___SECURE_GETENV)
352    target_compile_definitions(loader_common_options INTERFACE HAVE___SECURE_GETENV)
353endif()
354if(NOT MSVC AND NOT (HAVE_SECURE_GETENV OR HAVE___SECURE_GETENV))
355    message(WARNING "Using non-secure environmental lookups. This loader will not properly disable environent variables when run with elevated permissions.")
356endif()
357
358# Optional codegen target
359if(PYTHONINTERP_FOUND)
360    add_custom_target(VulkanLoader_generated_source
361                      COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/scripts/generate_source.py
362                              ${VulkanRegistry_DIR} --incremental
363                      )
364else()
365    message("WARNING: VulkanLoader_generated_source target requires python 3")
366endif()
367
368
369if(UNIX)
370    target_compile_definitions(loader_common_options INTERFACE FALLBACK_CONFIG_DIRS="${FALLBACK_CONFIG_DIRS}" FALLBACK_DATA_DIRS="${FALLBACK_DATA_DIRS}")
371
372    if(NOT (SYSCONFDIR STREQUAL ""))
373        # SYSCONFDIR is specified, use it and do not force /etc.
374        target_compile_definitions(loader_common_options INTERFACE SYSCONFDIR="${SYSCONFDIR}")
375    else()
376        target_compile_definitions(loader_common_options INTERFACE SYSCONFDIR="${CMAKE_INSTALL_FULL_SYSCONFDIR}")
377
378        # Make sure /etc is searched by the loader
379        if(NOT (CMAKE_INSTALL_FULL_SYSCONFDIR STREQUAL "/etc"))
380            target_compile_definitions(loader_common_options INTERFACE EXTRASYSCONFDIR="/etc")
381        endif()
382    endif()
383endif()
384
385# uninstall target
386if(NOT TARGET uninstall)
387    configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
388                   "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
389                   IMMEDIATE
390                   @ONLY)
391    add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
392    set_target_properties(uninstall PROPERTIES FOLDER ${LOADER_HELPER_FOLDER})
393endif()
394
395add_subdirectory(loader)
396
397if(BUILD_TESTS)
398    # Set gtest build configuration
399    # Attempt to enable if it is available.
400    if(TARGET gtest)
401        # Already enabled as a target (perhaps by a project enclosing this one)
402        message(STATUS "Vulkan-Loader/external: " "googletest already configured - using it")
403    elseif(IS_DIRECTORY "${GOOGLETEST_INSTALL_DIR}/googletest")
404        set(BUILD_GTEST ON CACHE BOOL "Builds the googletest subproject")
405        set(BUILD_GMOCK OFF CACHE BOOL "Builds the googlemock subproject")
406        set(gtest_force_shared_crt ON CACHE BOOL "Link gtest runtimes dynamically" FORCE)
407        set(BUILD_SHARED_LIBS ON CACHE BOOL "Build shared libraries")
408        # The googletest directory exists, so enable it as a target.
409        message(STATUS "Vulkan-Loader/external: " "googletest found - configuring it for tests")
410        add_subdirectory("${GOOGLETEST_INSTALL_DIR}")
411    else()
412        message(SEND_ERROR "Could not find googletest directory. Be sure to run update_deps.py with the --tests option to download the appropriate version of googletest")
413        set(BUILD_TESTS OFF)
414    endif()
415    if (WIN32)
416        if(TARGET detours)
417            # Already enabled as a target (perhaps by a project enclosing this one)
418            message(STATUS "Vulkan-Loader/external: " "detours already configured - using it")
419        else()
420            if(IS_DIRECTORY ${DETOURS_INSTALL_DIR})
421                # The detours directory exists, so enable it as a target.
422                message(STATUS "Vulkan-Loader/external: " "detours found - configuring it for tests")
423            else()
424                message(SEND_ERROR "Could not find detours directory. Be sure to run update_deps.py with the --tests option to download the appropriate version of detours")
425                set(BUILD_TESTS OFF)
426            endif()
427            add_library(detours STATIC
428                ${DETOURS_INSTALL_DIR}/src/creatwth.cpp
429                ${DETOURS_INSTALL_DIR}/src/detours.cpp
430                ${DETOURS_INSTALL_DIR}/src/detours.h
431                ${DETOURS_INSTALL_DIR}/src/detver.h
432                ${DETOURS_INSTALL_DIR}/src/disasm.cpp
433                ${DETOURS_INSTALL_DIR}/src/disolarm.cpp
434                ${DETOURS_INSTALL_DIR}/src/disolarm64.cpp
435                ${DETOURS_INSTALL_DIR}/src/disolia64.cpp
436                ${DETOURS_INSTALL_DIR}/src/disolx64.cpp
437                ${DETOURS_INSTALL_DIR}/src/disolx86.cpp
438                ${DETOURS_INSTALL_DIR}/src/image.cpp
439                ${DETOURS_INSTALL_DIR}/src/modules.cpp
440                )
441            target_include_directories(detours PUBLIC ${DETOURS_INSTALL_DIR}/src)
442
443            macro(GET_WIN32_WINNT version)
444                if(WIN32 AND CMAKE_SYSTEM_VERSION)
445            		set(ver ${CMAKE_SYSTEM_VERSION})
446            		string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver})
447            		string(REGEX MATCH "^([0-9]+)" verMajor ${ver})
448            		# Check for Windows 10, b/c we'll need to convert to hex 'A'.
449            		if("${verMajor}" MATCHES "10")
450            			set(verMajor "A")
451            			string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver})
452            		endif("${verMajor}" MATCHES "10")
453            		# Remove all remaining '.' characters.
454            		string(REPLACE "." "" ver ${ver})
455            		# Prepend each digit with a zero.
456            		string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver})
457            		set(${version} "0x${ver}")
458                endif()
459            endmacro()
460
461            set(DETOURS_MAJOR_VERSION "4")
462            set(DETOURS_MINOR_VERSION "0")
463            set(DETOURS_PATCH_VERSION "1")
464            set(DETOURS_VERSION "${DETOURS_MAJOR_VERSION}.${DETOURS_MINOR_VERSION}.${DETOURS_PATCH_VERSION}")
465
466            target_include_directories(detours PUBLIC ${DETOURS_INSTALL_DIR}/src)
467
468            if(MSVC_VERSION GREATER_EQUAL 1700)
469                target_compile_definitions(detours PUBLIC DETOURS_CL_17_OR_NEWER)
470            endif(MSVC_VERSION GREATER_EQUAL 1700)
471            GET_WIN32_WINNT(ver)
472            if(ver EQUAL 0x0700)
473                target_compile_definitions(detours PUBLIC _USING_V110_SDK71_ DETOURS_WIN_7)
474            endif(ver EQUAL 0x0700)
475            target_compile_definitions(detours PUBLIC "_WIN32_WINNT=${ver}")
476
477            if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
478                target_compile_definitions(detours PUBLIC "DETOURS_TARGET_PROCESSOR=X64" DETOURS_X64 DETOURS_64BIT _AMD64_)
479            else("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
480                target_compile_definitions(detours PUBLIC "DETOURS_TARGET_PROCESSOR=X86" DETOURS_X86 _X86_)
481            endif("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
482
483            target_compile_definitions(detours PUBLIC  "DETOURS_VERSION=0x4c0c1" WIN32_LEAN_AND_MEAN)
484
485            if(MSVC)
486                target_compile_definitions(detours PUBLIC  "_CRT_SECURE_NO_WARNINGS=1")
487                set_target_properties(detours PROPERTIES COMPILE_FLAGS /EHsc)
488            endif()
489
490            # Silence errors found in clang-cl
491            if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND "${CMAKE_CXX_SIMULATE_ID}" MATCHES "MSVC")
492                target_compile_options(detours PRIVATE -Wno-sizeof-pointer-memaccess -Wno-microsoft-goto -Wno-microsoft-cast)
493            endif()
494        endif()
495    endif()
496
497    if (BUILD_TESTS)
498        add_subdirectory(tests ${CMAKE_BINARY_DIR}/tests)
499    endif()
500
501endif()
502