-
Notifications
You must be signed in to change notification settings - Fork 491
/
CMakeLists.txt
472 lines (376 loc) · 18 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
cmake_minimum_required(VERSION 3.15)
cmake_policy(SET CMP0077 NEW)
cmake_policy(SET CMP0091 NEW)
cmake_policy(SET CMP0104 NEW)
cmake_policy(SET CMP0057 NEW)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
project(Falcor
DESCRIPTION "Falcor Realtime Rendering Framework"
LANGUAGES CXX C
)
# -----------------------------------------------------------------------------
# Configuration options
# -----------------------------------------------------------------------------
# Enable/disable asserts. AUTO enables asserts in debug builds.
set(FALCOR_ENABLE_ASSERTS "AUTO" CACHE STRING "Enable asserts")
set_property(CACHE FALCOR_ENABLE_ASSERTS PROPERTY STRINGS AUTO ON OFF)
# Enable/disable the profiler.
set(FALCOR_ENABLE_PROFILER ON CACHE BOOL "Enable profiler")
# Enable/disable using system Python distribution. This requires Python 3.7 to be available.
set(FALCOR_USE_SYSTEM_PYTHON OFF CACHE BOOL "Use system Python distribution")
# Enable/disable USD.
set(FALCOR_ENABLE_USD ON CACHE BOOL "Enable USD")
# Enable/disable Address Sanitizer.
set(FALCOR_ENABLE_ASAN OFF CACHE BOOL "Enable Address Sanitizer")
# Header validation.
# If enabled, additional targets are generated to validate that headers are self sufficient.
set(FALCOR_VALIDATE_HEADERS OFF CACHE BOOL "Enable header validation")
# Precompiled headers.
# If enabled, precompiled headers are used to speed up compilation.
set(FALCOR_PRECOMPILED_HEADERS ON CACHE BOOL "Enable precompiled headers")
# -----------------------------------------------------------------------------
# Check platform
# -----------------------------------------------------------------------------
if(${CMAKE_SYSTEM_NAME} MATCHES "Window")
set(FALCOR_PLATFORM "Windows")
set(FALCOR_WINDOWS TRUE)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(FALCOR_PLATFORM "Linux")
set(FALCOR_LINUX TRUE)
else()
message(FATAL_ERROR "Unsupported platform!")
endif()
message(STATUS "Platform: ${FALCOR_PLATFORM}")
# Check if D3D12/Vulkan are available.
set(FALCOR_HAS_D3D12 ${FALCOR_WINDOWS})
set(FALCOR_HAS_VULKAN ON)
# -----------------------------------------------------------------------------
# git submodules
# -----------------------------------------------------------------------------
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/external/pybind11/CMakeLists.txt)
message(STATUS "Updating git submodules ...")
find_package(Git REQUIRED)
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule update --init
COMMAND_ERROR_IS_FATAL ANY
)
endif()
# -----------------------------------------------------------------------------
# Packman
# -----------------------------------------------------------------------------
# Falcor uses packman to pull binary dependencies. We need to pull the dependencies
# before CMake starts configuring the project as some of the configuration relies
# on these dependencies being available. We also add additional targets to pull
# the dependencies when the project is built such that they are updated automatically
# if the manifest files change.
if(FALCOR_WINDOWS)
set(PACKMAN "${CMAKE_SOURCE_DIR}/tools/packman/packman.cmd")
set(PACKMAN_PLATFORM "windows-x86_64")
elseif(FALCOR_LINUX)
set(PACKMAN "${CMAKE_SOURCE_DIR}/tools/packman/packman")
set(PACKMAN_PLATFORM "linux-x86_64")
endif()
# Pull dependencies at configure time.
message(STATUS "Updating packman dependencies ...")
execute_process(
COMMAND ${PACKMAN} pull ${CMAKE_SOURCE_DIR}/dependencies.xml --platform ${PACKMAN_PLATFORM}
COMMAND_ERROR_IS_FATAL ANY
)
# -----------------------------------------------------------------------------
# Misc
# -----------------------------------------------------------------------------
# Setup workaround for re-running mt.exe when it fails due to a race condition with AV software.
include(mt-retry)
# Embed git information.
include(git_version)
git_version_setup()
# On Linux, we build with RPATH set to $ORIGIN to make build relocatable.
# Also, we link with precompiled libraries that are compiled with _GLIBCXX_USE_CXX11_ABI=0,
# so we need to compile with the same flag to avoid ABI incompatibilities.
if(FALCOR_LINUX)
set(CMAKE_INSTALL_RPATH $ORIGIN)
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -D_GLIBCXX_USE_CXX11_ABI=0)
endif()
# -----------------------------------------------------------------------------
# CUDA
# -----------------------------------------------------------------------------
# Set default CUDA architecture to 75 (Turing).
# This can be overwritten for individual targets using the CUDA_ARCHITECTURE property.
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(CMAKE_CUDA_ARCHITECTURES 75-virtual)
endif()
include(CheckLanguage)
check_language(CUDA)
if(CMAKE_CUDA_COMPILER)
message(STATUS "Enabling CUDA support.")
enable_language(CUDA)
find_package(CUDAToolkit REQUIRED)
set(FALCOR_HAS_CUDA ON)
else()
set(FALCOR_HAS_CUDA OFF)
endif()
# -----------------------------------------------------------------------------
# Python
# -----------------------------------------------------------------------------
if(FALCOR_USE_SYSTEM_PYTHON)
find_package(Python COMPONENTS Interpreter Development REQUIRED)
else()
set(Python_ROOT_DIR ${CMAKE_SOURCE_DIR}/external/packman/python)
find_package(Python COMPONENTS Interpreter Development REQUIRED)
endif()
if(FALCOR_WINDOWS)
set(TOOLS_PYTHON ${CMAKE_SOURCE_DIR}/tools/.packman/python/python)
elseif(FALCOR_LINUX)
set(TOOLS_PYTHON ${Python_EXECUTABLE})
endif()
# -----------------------------------------------------------------------------
# Global setup
# -----------------------------------------------------------------------------
# Require builds to be outside of source tree.
file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/CMakeLists.txt" LOC_PATH)
if(EXISTS "${LOC_PATH}")
message(FATAL_ERROR "You cannot build in a source directory (or any directory with a CMakeLists.txt file). Please use a build directory instead.")
endif()
# Enable folders (for Visual Studio).
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Setup available build configurations.
if(NOT SETUP_CONFIGURATION_TYPES)
set(SETUP_CONFIGURATION_TYPES 1)
if(CMAKE_CONFIGURATION_TYPES)
# multi config generator
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "" FORCE)
else()
# single config generator
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build")
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release")
endif()
endif()
set(FALCOR_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(FALCOR_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
if(CMAKE_CONFIGURATION_TYPES)
set(FALCOR_OUTPUT_DIRECTORY ${FALCOR_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>)
else()
set(FALCOR_OUTPUT_DIRECTORY ${FALCOR_RUNTIME_OUTPUT_DIRECTORY})
endif()
set(FALCOR_SHADER_OUTPUT_DIRECTORY ${FALCOR_OUTPUT_DIRECTORY}/shaders)
set(FALCOR_PLUGIN_OUTPUT_DIRECTORY ${FALCOR_OUTPUT_DIRECTORY}/plugins)
# -----------------------------------------------------------------------------
# External dependencies
# -----------------------------------------------------------------------------
add_subdirectory(external)
message(STATUS "Feature flags:")
message(STATUS "FALCOR_HAS_D3D12: ${FALCOR_HAS_D3D12}")
message(STATUS "FALCOR_HAS_VULKAN: ${FALCOR_HAS_VULKAN}")
message(STATUS "FALCOR_HAS_AFTERMATH: ${FALCOR_HAS_AFTERMATH}")
message(STATUS "FALCOR_HAS_NVAPI: ${FALCOR_HAS_NVAPI}")
message(STATUS "FALCOR_HAS_PIX: ${FALCOR_HAS_PIX}")
message(STATUS "FALCOR_HAS_CUDA: ${FALCOR_HAS_CUDA}")
message(STATUS "FALCOR_HAS_OPTIX: ${FALCOR_HAS_OPTIX}")
message(STATUS "FALCOR_HAS_D3D12_AGILITY_SDK: ${FALCOR_HAS_D3D12_AGILITY_SDK}")
message(STATUS "FALCOR_HAS_NRD: ${FALCOR_HAS_NRD}")
message(STATUS "FALCOR_HAS_DLSS: ${FALCOR_HAS_DLSS}")
message(STATUS "FALCOR_HAS_NV_USD: ${FALCOR_HAS_NV_USD}")
message(STATUS "FALCOR_HAS_MDL_SDK: ${FALCOR_HAS_MDL_SDK}")
message(STATUS "FALCOR_ENABLE_USD: ${FALCOR_ENABLE_USD}")
# -----------------------------------------------------------------------------
# Packman dependencies
# -----------------------------------------------------------------------------
add_custom_target(packman_dependencies DEPENDS packman_dependencies_stamp)
set_target_properties(packman_dependencies PROPERTIES FOLDER "Misc")
add_custom_command(
OUTPUT packman_dependencies_stamp
COMMAND ${PACKMAN} pull ${CMAKE_SOURCE_DIR}/dependencies.xml --platform ${PACKMAN_PLATFORM}
COMMAND ${CMAKE_COMMAND} -E touch packman_dependencies_stamp
MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/dependencies.xml
COMMENT "Updating packman dependencies"
)
# -----------------------------------------------------------------------------
# Shader file handling
# -----------------------------------------------------------------------------
# Regex for matching shader files.
set(SHADER_EXTENSION_REGEX "\.(slang|slangh|hlsli|hlsl)$")
# Setup build rules to copy all shaders of a target to the output directory.
# The specified output_dir is relative to the global shader output directory (FALCOR_SHADER_OUTPUT_DIRECTORY).
function(target_copy_shaders target output_dir)
get_target_property(target_source_dir ${target} SOURCE_DIR)
set(shader_output_dir ${FALCOR_SHADER_OUTPUT_DIRECTORY}/${output_dir})
# Get list of all target sources.
get_target_property(target_sources_ ${target} SOURCES)
# Create custom commands for copying shader sources.
foreach(file ${target_sources_})
if(${file} MATCHES ${SHADER_EXTENSION_REGEX})
if(IS_ABSOLUTE ${file})
file(RELATIVE_PATH file ${target_source_dir} ${file})
endif()
set(src_file ${target_source_dir}/${file})
set(dst_file ${shader_output_dir}/${file})
add_custom_command(
OUTPUT ${dst_file}
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${src_file} ${dst_file}
MAIN_DEPENDENCY ${src_file}
COMMENT "${target}: Copying shader ${file}"
)
endif()
endforeach()
endfunction()
# -----------------------------------------------------------------------------
# Data file handling
# -----------------------------------------------------------------------------
add_custom_target(copy_data_folder ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/data ${FALCOR_OUTPUT_DIRECTORY}/data
)
set_target_properties(copy_data_folder PROPERTIES FOLDER "Misc")
add_custom_target(copy_scripts_folder ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/scripts ${FALCOR_OUTPUT_DIRECTORY}/scripts
)
set_target_properties(copy_scripts_folder PROPERTIES FOLDER "Misc")
# -----------------------------------------------------------------------------
# Falcor applications
# -----------------------------------------------------------------------------
# Create a Falcor application and link the main Falcor library.
function(add_falcor_executable target)
add_executable(${target})
target_link_libraries(${target} PRIVATE Falcor)
set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${FALCOR_RUNTIME_OUTPUT_DIRECTORY})
set_target_properties(${target} PROPERTIES VS_DEBUGGER_ENVIRONMENT "FALCOR_DEVMODE=1")
endfunction()
# -----------------------------------------------------------------------------
# Plugins
# -----------------------------------------------------------------------------
# Global render pass target list.
set_property(GLOBAL PROPERTY FALCOR_PLUGIN_TARGETS)
# Create a Falcor plugin.
function(add_plugin target)
add_library(${target} SHARED)
target_link_libraries(${target} PRIVATE Falcor)
set_target_properties(${target} PROPERTIES
PREFIX ""
RUNTIME_OUTPUT_DIRECTORY ${FALCOR_PLUGIN_OUTPUT_DIRECTORY}
LIBRARY_OUTPUT_DIRECTORY ${FALCOR_PLUGIN_OUTPUT_DIRECTORY}
INSTALL_RPATH "\$ORIGIN/../"
)
# Add target to global plugin target list.
set_property(GLOBAL APPEND PROPERTY FALCOR_PLUGIN_TARGETS ${target})
endfunction()
# -----------------------------------------------------------------------------
# Helpers
# -----------------------------------------------------------------------------
# Helper function to create a source group for Visual Studio.
# This adds all the target's sources to a source group in the given folder.
function(target_source_group target folder)
set_target_properties(${target} PROPERTIES FOLDER ${folder})
get_target_property(target_source_dir ${target} SOURCE_DIR)
get_target_property(target_sources_ ${target} SOURCES)
source_group(TREE ${target_source_dir} FILES ${target_sources_} PREFIX "")
endfunction()
# -----------------------------------------------------------------------------
# Deploy dependencies
# -----------------------------------------------------------------------------
# We currently use the legacy batch files for deploying additional binaries.
# TODO: This should be replaced with a better approach allowing individual
# targets to deploy dependencies.
set(source_dir ${CMAKE_SOURCE_DIR})
set(output_dir ${FALCOR_OUTPUT_DIRECTORY})
file(TO_NATIVE_PATH ${source_dir} source_dir)
file(TO_NATIVE_PATH ${output_dir} output_dir)
if(FALCOR_WINDOWS)
add_custom_target(deploy_dependencies ALL
COMMAND ${CMAKE_SOURCE_DIR}/build_scripts/deploycommon.bat ${source_dir} ${output_dir} $<CONFIG> ${FALCOR_SLANG_DIR} ${FALCOR_DLSS_DIR}
)
elseif(FALCOR_LINUX)
add_custom_target(deploy_dependencies ALL
COMMAND ${CMAKE_SOURCE_DIR}/build_scripts/deploycommon.sh ${source_dir} ${output_dir} $<CONFIG> ${FALCOR_SLANG_DIR} ${FALCOR_DLSS_DIR}
)
endif()
set_target_properties(deploy_dependencies PROPERTIES FOLDER "Misc")
# -----------------------------------------------------------------------------
# Header validation
# -----------------------------------------------------------------------------
# Helper function to validate header files of a target to be self sufficient.
# This creates a new target with "VH" suffix that compiles one
# translation unit for each header file found in the supplied targets sources list.
function(validate_headers target)
if(NOT FALCOR_VALIDATE_HEADERS)
return()
endif()
cmake_parse_arguments(PARSE_ARGV 1 validate_header_args "" "" "IGNORE")
set(ignore_files ${validate_header_args_IGNORE})
message(STATUS "Setting up header validation for target: ${target}")
# Create a new target for validating headers.
set(validate_target ${target}VH)
add_library(${validate_target} OBJECT)
# Copy properties from original target.
foreach(property INCLUDE_DIRECTORIES LINK_LIBRARIES COMPILE_DEFINITIONS COMPILE_FEATURES)
get_target_property(value ${target} ${property})
if(value)
set_property(TARGET ${validate_target} PROPERTY ${property} ${value})
endif()
endforeach()
# Add target source directory as an include directory.
get_target_property(target_source_dir ${target} SOURCE_DIR)
target_include_directories(${validate_target} PRIVATE ${target_source_dir})
# Get list of source files.
get_target_property(sources ${target} SOURCES)
# Create a list of CPP files, each including one header.
set(validate_sources "")
foreach(file ${sources})
if(${file} MATCHES "^[^.][^.].*\\.h$" AND NOT ${file} IN_LIST ignore_files)
string(SHA1 id ${file})
# shorten to help avoid super long file names
string(SUBSTRING ${id} 0, 8, id)
set(cpp_file ${validate_target}/${id}.cpp)
set(cpp_content "#include \"${file}\"\n")
file(CONFIGURE OUTPUT ${cpp_file} CONTENT ${cpp_content})
list(APPEND validate_sources ${CMAKE_CURRENT_BINARY_DIR}/${cpp_file})
endif()
endforeach()
target_compile_options(${validate_target} PRIVATE $<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/bigobj>)
target_sources(${validate_target} PRIVATE ${validate_sources})
set_target_properties(${validate_target} PROPERTIES FOLDER "Validation")
endfunction()
# -----------------------------------------------------------------------------
# Ninja log analyzer
# -----------------------------------------------------------------------------
if(${CMAKE_GENERATOR} MATCHES "Ninja")
add_custom_target(ninja_log_analyzer ALL
COMMAND ${TOOLS_PYTHON} ${CMAKE_SOURCE_DIR}/tools/ninja_log_analyzer.py ${CMAKE_CURRENT_BINARY_DIR}/.ninja_log -c 10
)
add_dependencies(ninja_log_analyzer Falcor FalcorPython FalcorTest Mogwai ${plugin_targets})
set_target_properties(ninja_log_analyzer PROPERTIES FOLDER "Misc")
endif()
# -----------------------------------------------------------------------------
# Project sources
# -----------------------------------------------------------------------------
add_subdirectory(Source/Falcor)
add_subdirectory(Source/Modules)
add_subdirectory(Source/Mogwai)
add_subdirectory(Source/plugins)
add_subdirectory(Source/RenderPasses)
add_subdirectory(Source/Samples)
add_subdirectory(Source/Tools)
add_dependencies(Falcor copy_data_folder copy_scripts_folder)
# Make Falcor core library depend on deploying all dependencies.
add_dependencies(Falcor deploy_dependencies)
# Get list of all plugin targets.
get_property(plugin_targets GLOBAL PROPERTY FALCOR_PLUGIN_TARGETS)
# Generate plugins.json file.
if(plugin_targets)
set(json ${plugin_targets})
list(TRANSFORM json PREPEND "\"")
list(TRANSFORM json APPEND "\"")
list(JOIN json ", " json)
string(PREPEND json "[ ")
string(APPEND json " ]")
file(GENERATE OUTPUT ${FALCOR_PLUGIN_OUTPUT_DIRECTORY}/plugins.json CONTENT ${json})
endif()
# Generate settings.toml file.
file(GENERATE OUTPUT ${FALCOR_OUTPUT_DIRECTORY}/settings.json CONTENT "{ \"standardsearchpath\" : { \"media\" : \"\${FALCOR_MEDIA_FOLDERS}\", \"mdl\" : \"\${FALCOR_MDL_PATHS}\" }}")
# Make Mogwai and FalcorPython depend on all plugins.
if(plugin_targets)
add_dependencies(Mogwai ${plugin_targets})
add_dependencies(FalcorPython ${plugin_targets})
add_dependencies(Mogwai FalcorPython)
endif()
# Make Mogwai the default startup project in VS.
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT Mogwai)