-
Notifications
You must be signed in to change notification settings - Fork 292
/
Copy pathCMakeLists.txt
572 lines (505 loc) · 24.5 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
# ~~~
# Copyright (c) 2014-2023 The Khronos Group Inc.
# Copyright (c) 2014-2023 Valve Corporation
# Copyright (c) 2014-2023 LunarG, Inc.
# Copyright (c) 2021 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# Copyright (c) 2023-2023 RasterGrid Kft.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ~~~
include(CheckIncludeFile)
add_library(loader_specific_options INTERFACE)
target_link_libraries(loader_specific_options INTERFACE loader_common_options Vulkan::Headers)
target_include_directories(loader_specific_options INTERFACE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/generated ${CMAKE_CURRENT_BINARY_DIR})
if(WIN32)
if(ENABLE_WIN10_ONECORE)
# Note: When linking your app or driver to OneCore.lib, be sure to remove any links to non-umbrella libs (such as
# kernel32.lib).
set(CMAKE_C_STANDARD_LIBRARIES " ") # space is intentional
endif()
# ~~~
# Only generate the loader.rc file with CMake if BUILD_DLL_VERSIONINFO was set.
# This feature is for the Vulkan Runtime build
# Otherwise rely on the checked in loader.rc from the python script
# ~~~
if (NOT "$CACHE{BUILD_DLL_VERSIONINFO}" STREQUAL "")
string(TIMESTAMP CURRENT_YEAR "%Y")
set(LOADER_CUR_COPYRIGHT_YEAR "${CURRENT_YEAR}")
set(LOADER_RC_VERSION "$CACHE{BUILD_DLL_VERSIONINFO}")
set(LOADER_VER_FILE_VERSION_STR "\"${LOADER_RC_VERSION}\"")
set(LOADER_VER_FILE_DESCRIPTION_STR "\"Vulkan Loader\"")
# RC file wants the value of FILEVERSION to separated by commas
string(REPLACE "." ", " LOADER_VER_FILE_VERSION "${LOADER_RC_VERSION}")
# Configure the file to include the versioning info
# Place it in the build directory - the GN build will use the checked in file
configure_file(loader.rc.in ${CMAKE_CURRENT_BINARY_DIR}/loader.rc)
endif()
else()
# Used to make alloca() and secure_getenv() available
target_compile_definitions(loader_specific_options INTERFACE _GNU_SOURCE)
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
target_compile_definitions(loader_specific_options INTERFACE __BSD_VISIBLE=1)
endif()
check_include_file("alloca.h" HAVE_ALLOCA_H)
if(HAVE_ALLOCA_H)
target_compile_definitions(loader_specific_options INTERFACE HAVE_ALLOCA_H)
endif()
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
endif()
set(NORMAL_LOADER_SRCS
allocation.c
allocation.h
cJSON.c
cJSON.h
debug_utils.c
debug_utils.h
extension_manual.c
extension_manual.h
loader_environment.c
loader_environment.h
gpa_helper.c
gpa_helper.h
loader.c
loader.h
log.c
log.h
loader_json.c
loader_json.h
settings.c
settings.h
terminator.c
trampoline.c
unknown_function_handling.c
unknown_function_handling.h
wsi.c
wsi.h
)
if(WIN32)
list(APPEND NORMAL_LOADER_SRCS loader_windows.c dirent_on_windows.c)
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|DragonFly|GNU")
list(APPEND NORMAL_LOADER_SRCS loader_linux.c)
target_compile_definitions(loader_specific_options INTERFACE LOADER_ENABLE_LINUX_SORT)
endif()
if ("${CMAKE_OSX_ARCHITECTURES}" MATCHES ";")
set(APPLE_UNIVERSAL_BINARY ON)
# When building a universal binary we cannot enable USE_GAS
# Since USE_GAS assumes only 1 architecture (arm64, x64, etc).
set(USE_GAS OFF)
endif()
set(OPT_LOADER_SRCS dev_ext_trampoline.c phys_dev_ext.c)
set(ASM_FAILURE_MSG "Support for unknown physical device and device functions is disabled due to missing the required assembly support code. \
To support unknown functions, assembly must be added for the platform.\n")
set(ARMASM_CMAKE_FAILURE_MSG "Support for unknown physical device and device functions is disabled due to the CMake version ${CMAKE_VERSION} \
being older than 3.26. Please update CMake to version 3.26 or newer.\n")
# Check for assembler support
if(WIN32 AND NOT USE_GAS)
option(USE_MASM "Use MASM" ON)
if(USE_MASM AND MINGW)
find_program(JWASM_FOUND NAMES jwasm uasm)
if (JWASM_FOUND)
set(CMAKE_ASM_MASM_COMPILER ${JWASM_FOUND})
execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpmachine OUTPUT_VARIABLE COMPILER_VERSION_OUTPUT)
if (COMPILER_VERSION_OUTPUT)
if (COMPILER_VERSION_OUTPUT MATCHES "x86_64")
set(JWASM_FLAGS -win64)
else()
# jwasm requires setting the cpu to at least 386 for setting a flat model
set(JWASM_FLAGS -3 -coff)
endif()
endif()
endif()
endif()
if (USE_MASM)
if(SYSTEM_PROCESSOR MATCHES "arm")
if(CMAKE_VERSION VERSION_LESS "3.26.0")
set(ASM_FAILURE_MSG ${ARMASM_CMAKE_FAILURE_MSG})
else()
enable_language(ASM_MARMASM)
set(LOADER_ASM_DIALECT "MARMASM")
endif()
else()
enable_language(ASM_MASM)
set(LOADER_ASM_DIALECT "MASM")
endif()
endif()
# Test if the detected compiler actually works.
# Unfortunately, CMake's detection of ASM_MASM is not reliable, so we need to do this ourselves.
if(SYSTEM_PROCESSOR MATCHES "arm")
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm [=[
test_func FUNCTION
mov r0, #0
bx lr
ENDFUNC
END
]=])
else()
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm [=[
test_func FUNCTION
mov x1, 26
ldr x0, [x0, x1]
ENDFUNC
END
]=])
endif()
else()
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm [=[
.model flat
.code
extrn _start:near
xor eax, eax
ret
end
]=])
else()
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm [=[
.code
extrn start:near
xor rax, rax
ret
end
]=])
endif()
endif ()
if(MINGW)
set(CMAKE_ASM_MASM_FLAGS ${CMAKE_ASM_MASM_FLAGS} ${JWASM_FLAGS})
set(CMAKE_ASM_MARMASM_FLAGS ${CMAKE_ASM_MARMASM_FLAGS} ${JWASM_FLAGS})
elseif(NOT CMAKE_CL_64 AND NOT JWASM_FOUND AND CMAKE_SIZEOF_VOID_P EQUAL 4)
set(CMAKE_ASM_MASM_FLAGS ${CMAKE_ASM_MASM_FLAGS} /safeseh) # /safeseh is only needed in x86
endif()
# try_compile does not work here due to the same reasons as static above.
if(SYSTEM_PROCESSOR MATCHES "arm")
execute_process(COMMAND ${CMAKE_ASM_MARMASM_COMPILER} ${CMAKE_ASM_MARMASM_FLAGS} ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm
RESULT_VARIABLE ASM_COMPILER_WORKS
OUTPUT_QUIET ERROR_QUIET)
else()
execute_process(COMMAND ${CMAKE_ASM_MASM_COMPILER} ${CMAKE_ASM_MASM_FLAGS} -c -Fo ${CMAKE_CURRENT_BINARY_DIR}/masm_check.obj ${CMAKE_CURRENT_BINARY_DIR}/masm_check.asm
RESULT_VARIABLE ASM_COMPILER_WORKS
OUTPUT_QUIET ERROR_QUIET)
endif()
# Convert the return code to a boolean
if(ASM_COMPILER_WORKS EQUAL 0)
set(ASM_COMPILER_WORKS true)
else()
set(ASM_COMPILER_WORKS false)
endif()
if(ASM_COMPILER_WORKS)
add_executable(asm_offset asm_offset.c)
target_link_libraries(asm_offset PRIVATE loader_specific_options)
# If am emulator is provided (Like Wine), or running on native, run asm_offset to generate gen_defines.asm
if (CMAKE_CROSSCOMPILING_EMULATOR OR NOT CMAKE_CROSSCOMPILING)
add_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset ${LOADER_ASM_DIALECT})
else()
# Forces compiler to write the intermediate asm file, needed so that we can get sizeof/offset of info out of it.
target_compile_options(asm_offset PRIVATE "/Fa$<TARGET_FILE_DIR:asm_offset>/asm_offset.asm" /FA)
# Force off optimization so that the output assembly includes all the necessary info - optimizer would get rid of it otherwise.
target_compile_options(asm_offset PRIVATE /Od)
find_package(Python3 REQUIRED QUIET)
# Run parse_asm_values.py on asm_offset's assembly file to generate the gen_defines.asm, which the asm code depends on
add_custom_command(TARGET asm_offset POST_BUILD
COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/scripts/parse_asm_values.py "${CMAKE_CURRENT_BINARY_DIR}/gen_defines.asm"
"$<TARGET_FILE_DIR:asm_offset>/asm_offset.asm" "${LOADER_ASM_DIALECT}" "${CMAKE_C_COMPILER_ID}" "${SYSTEM_PROCESSOR}"
BYPRODUCTS gen_defines.asm
)
endif()
add_custom_target(loader_asm_gen_files DEPENDS gen_defines.asm)
set_target_properties(loader_asm_gen_files PROPERTIES FOLDER ${LOADER_HELPER_FOLDER})
if(SYSTEM_PROCESSOR MATCHES "arm")
list(APPEND OPT_LOADER_SRCS unknown_ext_chain_marmasm.asm)
else()
list(APPEND OPT_LOADER_SRCS unknown_ext_chain_masm.asm)
endif()
set(UNKNOWN_FUNCTIONS_SUPPORTED ON)
else()
message(WARNING "Could not find working ${} assembler\n${ASM_FAILURE_MSG}")
endif()
elseif(UNIX OR MINGW OR (WIN32 AND USE_GAS)) # i.e.: Linux & Apple & MinGW & Windows using Clang-CL
option(USE_GAS "Use GAS" ON)
if(USE_GAS)
if (APPLE_UNIVERSAL_BINARY)
message(FATAL_ERROR "USE_GAS cannot be used when compiling a universal binary!")
endif()
enable_language(ASM)
set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
if(WIN32 AND ${SYSTEM_PROCESSOR} MATCHES "arm64")
# In this particular case, we are using the same approach as for NASM
# This specifically avoids CMake issue #18889
execute_process(COMMAND ${CMAKE_ASM_COMPILER} ${CMAKE_ASM_FLAGS} -c -o ${CMAKE_CURRENT_BINARY_DIR}/asm_test_aarch64.obj ${CMAKE_CURRENT_SOURCE_DIR}/asm_test_aarch64.S
RESULT_VARIABLE WIN_ARM64_ASSEMBLER_WORKS
OUTPUT_QUIET ERROR_QUIET)
if(WIN_ARM64_ASSEMBLER_WORKS EQUAL 0)
set(ASSEMBLER_WORKS true)
endif()
if(ASSEMBLER_WORKS)
list(APPEND OPT_LOADER_SRCS unknown_ext_chain_gas_aarch.S)
endif()
elseif (${SYSTEM_PROCESSOR} MATCHES "aarch64|arm64")
try_compile(ASSEMBLER_WORKS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/asm_test_aarch64.S OUTPUT_VARIABLE TRY_COMPILE_OUTPUT)
if(ASSEMBLER_WORKS)
list(APPEND OPT_LOADER_SRCS unknown_ext_chain_gas_aarch.S)
endif()
elseif (${SYSTEM_PROCESSOR} MATCHES "aarch32|armhf|armv7l|armv8l")
try_compile(ASSEMBLER_WORKS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/asm_test_aarch32.S OUTPUT_VARIABLE TRY_COMPILE_OUTPUT)
if(ASSEMBLER_WORKS)
list(APPEND OPT_LOADER_SRCS unknown_ext_chain_gas_aarch.S)
endif()
# Covers x86_64, amd64, x86, i386, i686, I386, I686
elseif(${SYSTEM_PROCESSOR} MATCHES "amd64|86")
check_include_file("cet.h" HAVE_CET_H)
if(HAVE_CET_H)
target_compile_definitions(loader_specific_options INTERFACE HAVE_CET_H)
endif()
try_compile(ASSEMBLER_WORKS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/asm_test_x86.S)
if(ASSEMBLER_WORKS)
list(APPEND OPT_LOADER_SRCS unknown_ext_chain_gas_x86.S)
endif()
endif()
endif()
# When compiling for x86 on x64, we can't use CMAKE_SYSTEM_PROCESSOR to determine which architecture to use,
# Instead, check the size of void* and if its 4, set ASM_OFFSET_SYSTEM_PROCESSOR to x86 if we aren't on arm
if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
set(ASM_OFFSET_SYSTEM_PROCESSOR ${SYSTEM_PROCESSOR}) # x86_64 or aarch64/arm64
string(REPLACE amd64 x86_64 ASM_OFFSET_SYSTEM_PROCESSOR "${ASM_OFFSET_SYSTEM_PROCESSOR}")
else()
if(${SYSTEM_PROCESSOR} MATCHES "86")
set(ASM_OFFSET_SYSTEM_PROCESSOR "x86")
else()
set(ASM_OFFSET_SYSTEM_PROCESSOR ${SYSTEM_PROCESSOR})
endif()
endif()
if(ASSEMBLER_WORKS)
add_executable(asm_offset asm_offset.c)
target_link_libraries(asm_offset loader_specific_options)
# If not cross compiling, run asm_offset to generage gen_defines.asm
if (NOT CMAKE_CROSSCOMPILING)
add_custom_command(OUTPUT gen_defines.asm DEPENDS asm_offset COMMAND asm_offset GAS)
else()
# Forces compiler to write the intermediate asm file, needed so that we can get sizeof/offset of info out of it.
# If with lto, compiler will output IR instead of asm, so we need to explicitly disable lto here.
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
target_compile_options(asm_offset PRIVATE -save-temps=obj -fno-lto)
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
target_compile_options(asm_offset PRIVATE -save-temps=obj -fno-lto -fno-whole-program-vtables -fno-virtual-function-elimination)
else()
target_compile_options(asm_offset PRIVATE -save-temps=obj)
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
set(ASM_OFFSET_EXECUTABLE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/gen_defines.asm")
set(ASM_OFFSET_INTERMEDIATE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/CMakeFiles/asm_offset.dir/asm_offset.c.s")
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang")
set(ASM_OFFSET_EXECUTABLE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/gen_defines.asm")
set(ASM_OFFSET_INTERMEDIATE_LOCATION "$<TARGET_FILE_DIR:asm_offset>/CMakeFiles/asm_offset.dir/asm_offset.s")
elseif(CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
# Need to use the current binary dir since the asm_offset.s file is in that folder rather than the bundle
set(ASM_OFFSET_EXECUTABLE_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/gen_defines.asm")
set(ASM_OFFSET_INTERMEDIATE_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/asm_offset.dir/asm_offset.s")
else()
message(FATAL_ERROR "C_COMPILER_ID not supported!")
endif()
message(STATUS "CMAKE_CROSSCOMPILING FALSE")
find_package(Python3 REQUIRED QUIET)
# Run parse_asm_values.py on asm_offset's assembly file to generate the gen_defines.asm, which the asm code depends on
add_custom_command(TARGET asm_offset POST_BUILD
COMMAND Python3::Interpreter ${PROJECT_SOURCE_DIR}/scripts/parse_asm_values.py "${ASM_OFFSET_EXECUTABLE_LOCATION}"
"${ASM_OFFSET_INTERMEDIATE_LOCATION}" "GAS" "${CMAKE_C_COMPILER_ID}" "${ASM_OFFSET_SYSTEM_PROCESSOR}"
BYPRODUCTS gen_defines.asm
)
endif()
add_custom_target(loader_asm_gen_files DEPENDS gen_defines.asm)
if (APPLE)
set(MODIFY_UNKNOWN_FUNCTION_DECLS ON)
endif()
set(UNKNOWN_FUNCTIONS_SUPPORTED ON)
else()
if(USE_GAS)
message(WARNING "Could not find working ${ASM_OFFSET_SYSTEM_PROCESSOR} GAS assembler\n${ASM_FAILURE_MSG}")
else()
message(WARNING "Assembly sources have been disabled\n${ASM_FAILURE_MSG}")
endif()
endif()
endif()
if(UNKNOWN_FUNCTIONS_SUPPORTED)
list(APPEND NORMAL_LOADER_SRCS ${OPT_LOADER_SRCS})
endif()
if(WIN32)
# If BUILD_DLL_VERSIONINFO was set, use the loader.rc in the build dir, otherwise use the checked in file
set(RC_FILE_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/loader.rc)
if (NOT "$CACHE{BUILD_DLL_VERSIONINFO}" STREQUAL "")
set(RC_FILE_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/loader.rc)
endif()
add_library(vulkan
SHARED
${NORMAL_LOADER_SRCS}
${CMAKE_CURRENT_SOURCE_DIR}/${API_TYPE}-1.def
${RC_FILE_LOCATION})
target_link_libraries(vulkan PRIVATE loader_specific_options)
# when adding the suffix the import and runtime library names must be consistent
# mingw: libvulkan-1.dll.a / vulkan-1.dll
# msvc: vulkan-1.lib / vulkan-1.dll
set_target_properties(vulkan
PROPERTIES
OUTPUT_NAME ${API_TYPE}-1)
if(MINGW)
# generate the same DLL with mingw
set_target_properties(vulkan
PROPERTIES
PREFIX "")
endif()
if(MSVC AND ENABLE_WIN10_ONECORE)
target_link_libraries(vulkan PRIVATE OneCoreUAP.lib LIBCMT.LIB LIBCMTD.LIB LIBVCRUNTIME.LIB LIBUCRT.LIB)
set_target_properties(vulkan PROPERTIES LINK_FLAGS "/NODEFAULTLIB")
else()
target_link_libraries(vulkan PRIVATE cfgmgr32)
endif()
else()
if(APPLE)
option(APPLE_STATIC_LOADER "Build a loader that can be statically linked. Intended for Chromium usage/testing.")
mark_as_advanced(APPLE_STATIC_LOADER)
endif()
if(APPLE_STATIC_LOADER)
add_library(vulkan STATIC)
target_compile_definitions(vulkan PRIVATE APPLE_STATIC_LOADER)
message(WARNING "The APPLE_STATIC_LOADER option has been set. Note that this will only work on MacOS and is not supported "
"or tested as part of the loader. Use it at your own risk.")
else()
add_library(vulkan SHARED)
endif()
target_sources(vulkan PRIVATE ${NORMAL_LOADER_SRCS})
set_target_properties(vulkan PROPERTIES
SOVERSION "1"
VERSION "${VULKAN_LOADER_VERSION}"
)
target_link_libraries(vulkan PRIVATE ${CMAKE_DL_LIBS} m Threads::Threads)
set_target_properties(vulkan PROPERTIES OUTPUT_NAME ${API_TYPE})
if (LOADER_ENABLE_ADDRESS_SANITIZER)
target_compile_options(vulkan PUBLIC -fsanitize=address)
target_link_options(vulkan PUBLIC -fsanitize=address)
endif()
if (LOADER_ENABLE_THREAD_SANITIZER)
target_compile_options(vulkan PUBLIC -fsanitize=thread)
target_link_options(vulkan PUBLIC -fsanitize=thread)
endif()
if (LOADER_ENABLE_UNDEFINED_BEHAVIOR_SANITIZER)
target_compile_options(vulkan PUBLIC -fsanitize=undefined)
target_link_options(vulkan PUBLIC -fsanitize=undefined)
endif()
if(APPLE)
find_library(COREFOUNDATION_LIBRARY NAMES CoreFoundation)
target_link_libraries(vulkan PRIVATE "-framework CoreFoundation")
# Build vulkan.framework
# Use GLOB_RECURSE to find all the header files and populate the vulkan.framework headers with them
# Use CONFIGURE_DEPENDS to ensure that if the header files are updated, this list is also updated
get_target_property(VulkanHeaders_INCLUDE_DIRS Vulkan::Headers INTERFACE_INCLUDE_DIRECTORIES)
file(GLOB_RECURSE CONFIGURE_DEPENDS FRAMEWORK_HEADERS ${VulkanHeaders_INCLUDE_DIRS})
add_library(vulkan-framework SHARED)
target_sources(vulkan-framework PRIVATE ${NORMAL_LOADER_SRCS} ${FRAMEWORK_HEADERS})
if (UNKNOWN_FUNCTIONS_SUPPORTED)
add_dependencies(vulkan-framework loader_asm_gen_files)
endif()
target_link_libraries(vulkan-framework ${CMAKE_DL_LIBS} Threads::Threads -lm "-framework CoreFoundation")
target_link_libraries(vulkan-framework loader_specific_options)
if (MODIFY_UNKNOWN_FUNCTION_DECLS)
# Modifies the names of functions as they appearin the assembly code so that the
# unknown function handling will work
target_compile_definitions(vulkan PRIVATE MODIFY_UNKNOWN_FUNCTION_DECLS)
target_compile_definitions(vulkan-framework PRIVATE MODIFY_UNKNOWN_FUNCTION_DECLS)
endif()
# The FRAMEWORK_VERSION needs to be "A" here so that Xcode code-signing works when a user adds their framework to an Xcode
# project and does "Sign on Copy". It would have been nicer to use "1" to denote Vulkan 1. Although Apple docs say that a
# framework version does not have to be "A", this part of the Apple toolchain expects it.
# https://forums.developer.apple.com/thread/65963
set_target_properties(vulkan-framework PROPERTIES
OUTPUT_NAME vulkan
FRAMEWORK TRUE
FRAMEWORK_VERSION A
VERSION "${VULKAN_LOADER_VERSION}"
MACOSX_FRAMEWORK_BUNDLE_VERSION "${VULKAN_LOADER_VERSION}"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${VULKAN_LOADER_VERSION}"
SOVERSION "1.0.0"
MACOSX_FRAMEWORK_IDENTIFIER com.lunarg.vulkanFramework
PUBLIC_HEADER "${FRAMEWORK_HEADERS}"
)
# Workaround linker warning: https://github.com/KhronosGroup/Vulkan-Loader/issues/1332
#
# MACHO_CURRENT_VERSION specifically applies to the -current_version linker option which is the
# linker warning we are trying to address.
set(APPLE_VULKAN_LOADER_VERSION "${VULKAN_LOADER_VERSION_MAJOR}.${VULKAN_LOADER_VERSION_MINOR}.0")
set_target_properties(vulkan PROPERTIES MACHO_CURRENT_VERSION "${APPLE_VULKAN_LOADER_VERSION}")
set_target_properties(vulkan-framework PROPERTIES MACHO_CURRENT_VERSION "${APPLE_VULKAN_LOADER_VERSION}")
install(TARGETS vulkan-framework
PUBLIC_HEADER DESTINATION vulkan
FRAMEWORK DESTINATION loader
)
endif()
endif()
option(LOADER_USE_UNSAFE_FILE_SEARCH "Allows the loader to search in unsafe locations")
if (LOADER_USE_UNSAFE_FILE_SEARCH)
target_compile_definitions(vulkan PRIVATE LOADER_USE_UNSAFE_FILE_SEARCH)
endif()
# common attributes of the vulkan library
target_link_libraries(vulkan PRIVATE loader_specific_options)
target_link_libraries(vulkan PRIVATE Vulkan::Headers)
add_library(Vulkan::Loader ALIAS vulkan)
if (UNKNOWN_FUNCTIONS_SUPPORTED)
target_compile_definitions(vulkan PRIVATE UNKNOWN_FUNCTIONS_SUPPORTED)
add_dependencies(vulkan loader_asm_gen_files)
endif()
if (BUILD_TESTS)
target_compile_definitions(vulkan PRIVATE SHOULD_EXPORT_TEST_FUNCTIONS)
endif()
if (APPLE_STATIC_LOADER)
# TLDR: This feature only exists at the request of Google for Chromium. No other project should use this!
message(NOTICE "Apple STATIC lib: it will be built but not installed, and vulkan.pc and VulkanLoaderConfig.cmake won't be generated!")
return()
endif()
# Generate CMake Configuration File (IE: VulkanLoaderConfig.cmake)
install(TARGETS vulkan EXPORT VulkanLoaderConfig)
set_target_properties(vulkan PROPERTIES EXPORT_NAME "Loader")
install(EXPORT VulkanLoaderConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VulkanLoader NAMESPACE Vulkan::)
# Generate CMake Version File (IE: VulkanLoaderConfigVersion.cmake)
include(CMakePackageConfigHelpers)
set(version_config "${CMAKE_CURRENT_BINARY_DIR}/generated/VulkanLoaderConfigVersion.cmake")
write_basic_package_version_file("${version_config}" COMPATIBILITY SameMajorVersion)
install(FILES "${version_config}" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/VulkanLoader)
# Generate PkgConfig File (IE: vulkan.pc)
# NOTE: Hopefully in the future CMake can generate .pc files natively.
# https://gitlab.kitware.com/cmake/cmake/-/issues/22621
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
if(WIN32)
if(MINGW)
set(VULKAN_LIB_SUFFIX "-1.dll")
else()
set(VULKAN_LIB_SUFFIX "-1")
endif()
endif()
# BUG: The following code will NOT work well with `cmake --install ... --prefix <dir>`
# due to this code relying on CMAKE_INSTALL_PREFIX being defined at configure time.
#
# NOTE: vulkan.pc essentially cover both Vulkan-Loader and Vulkan-Headers for legacy reasons.
if ("${CMAKE_INSTALL_PREFIX}" STREQUAL "")
set(CMAKE_INSTALL_LIBDIR_PC ${CMAKE_INSTALL_FULL_LIBDIR})
set(CMAKE_INSTALL_INCLUDEDIR_PC ${CMAKE_INSTALL_FULL_INCLUDEDIR})
else()
file(RELATIVE_PATH CMAKE_INSTALL_LIBDIR_PC ${CMAKE_INSTALL_PREFIX} ${CMAKE_INSTALL_FULL_LIBDIR})
file(RELATIVE_PATH CMAKE_INSTALL_INCLUDEDIR_PC ${CMAKE_INSTALL_PREFIX} ${CMAKE_INSTALL_FULL_INCLUDEDIR})
endif()
configure_file("vulkan.pc.in" "vulkan.pc" @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/vulkan.pc" DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" RENAME "${API_TYPE}.pc")
endif()
if (CODE_COVERAGE)
target_code_coverage(vulkan AUTO ALL)
endif()