CMakeLists.txt 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. CMAKE_MINIMUM_REQUIRED(VERSION 3.15)
  2. message("++ CMake version ${CMAKE_VERSION}")
  3. include(ProcessorCount)
  4. project(AnKi)
  5. ################################################################################
  6. # Funcs #
  7. ################################################################################
  8. function(anki_install_executable EXE)
  9. if(NOT ANDROID)
  10. add_custom_command(TARGET ${EXE} POST_BUILD
  11. COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/Binaries
  12. COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${EXE}> ${CMAKE_BINARY_DIR}/Binaries)
  13. endif()
  14. endfunction()
  15. macro(anki_new_executable)
  16. if(NOT ANDROID)
  17. add_executable(${ARGV})
  18. # Move the target to another dir
  19. set_target_properties(${ARGV0} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Binaries)
  20. # Move the target to another dir using a different way as well because cor some reason it doesn't work on windows
  21. add_custom_command(TARGET ${ARGV0} POST_BUILD
  22. COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/Binaries
  23. COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${ARGV0}> ${CMAKE_BINARY_DIR}/Binaries/$<TARGET_FILE_NAME:${ARGV0}>)
  24. else()
  25. set(_SKIP TRUE)
  26. foreach(ARG ${ARGV})
  27. if(_SKIP)
  28. set(_SKIP FALSE)
  29. else()
  30. list(APPEND _TMP_LIST ${ARG})
  31. endif()
  32. endforeach()
  33. add_library(${ARGV0} SHARED ${_TMP_LIST})
  34. endif()
  35. endmacro()
  36. ################################################################################
  37. # Determin the system to build for. Do that first #
  38. ################################################################################
  39. if(WIN32)
  40. if(NOT WINDOWS)
  41. set(WINDOWS TRUE)
  42. message("++ Building for windows")
  43. endif()
  44. elseif(UNIX AND NOT APPLE)
  45. if(CMAKE_SYSTEM_NAME MATCHES ".*Linux")
  46. set(LINUX TRUE)
  47. message("++ Building for Linux")
  48. elseif(ANDROID)
  49. message("++ Building for Android")
  50. else()
  51. message(FATAL_ERROR "Unknown unix")
  52. endif()
  53. elseif(APPLE)
  54. if(CMAKE_SYSTEM_NAME MATCHES ".*MacOS.*")
  55. set(MACOS TRUE)
  56. message("++ Building for MacOS")
  57. else()
  58. message(FATAL_ERROR "Unknown apple")
  59. endif()
  60. else()
  61. message(FATAL_ERROR "Unknown system")
  62. endif()
  63. # Indentify compiler
  64. set(GCC FALSE)
  65. set(CLANG FALSE)
  66. set(CLANG_WINDOWS FALSE)
  67. if(${CMAKE_C_COMPILER_ID} MATCHES "GNU")
  68. set(GCC TRUE)
  69. message("++ Compiler identified as GCC")
  70. endif()
  71. if(${CMAKE_C_COMPILER_ID} MATCHES "Clang")
  72. message("++ Compiler identified as Clang")
  73. set(CLANG TRUE)
  74. if(WINDOWS)
  75. # It's clang for windows
  76. message("++ Compiler identified as Clang for Windows")
  77. set(CLANG_WINDOWS TRUE)
  78. endif()
  79. endif()
  80. if(MSVC)
  81. message("++ Compiler identified as MSVC")
  82. endif()
  83. # Identify the target system
  84. set(X86 FALSE)
  85. set(ARM FALSE)
  86. if(GCC OR CLANG)
  87. execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpmachine OUTPUT_VARIABLE target_arch)
  88. if(${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch" OR ${target_arch} MATCHES "aarch")
  89. set(ARM TRUE)
  90. elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86.*" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "AMD64.*")
  91. set(X86 TRUE)
  92. else()
  93. message(FATAL_ERROR "Couldn't find the target architecture from: ${target_arch} or ${CMAKE_SYSTEM_PROCESSOR}")
  94. endif()
  95. elseif(MSVC)
  96. if(${CMAKE_CXX_COMPILER_ARCHITECTURE_ID} MATCHES "arm" OR ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID} MATCHES "ARM")
  97. set(ARM TRUE)
  98. elseif(${CMAKE_CXX_COMPILER_ARCHITECTURE_ID} MATCHES "x64")
  99. set(X86 TRUE)
  100. else()
  101. message(FATAL_ERROR "Couldn't find the target architecture from: ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}")
  102. endif()
  103. else()
  104. message(FATAL_ERROR "Couldn't find the target architecture")
  105. endif()
  106. if(X86)
  107. message("++ Target architecture is X86")
  108. elseif(ARM)
  109. message("++ Target architecture is ARM")
  110. endif()
  111. ################################################################################
  112. # Configuration #
  113. ################################################################################
  114. set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
  115. option(ANKI_EXTRA_CHECKS "Debugging checks (assertions)" OFF)
  116. option(ANKI_LTO "LTO compilation" OFF)
  117. option(ANKI_BUILD_TOOLS "Build tools" ON)
  118. option(ANKI_BUILD_TESTS "Build unit tests" OFF)
  119. option(ANKI_BUILD_SANDBOX "Build sandbox application" ON)
  120. option(ANKI_BUILD_SAMPLES "Build sample applications" ON)
  121. option(ANKI_STRIP "Strip the symbols from the executables" OFF)
  122. option(ANKI_TRACE "Enable performance tracing. Small overhead" OFF)
  123. if(ANKI_TRACE)
  124. set(_ANKI_TRACING_ENABLED 1)
  125. else()
  126. set(_ANKI_TRACING_ENABLED 0)
  127. endif()
  128. option(ANKI_STATS "Enable performance statistics. Small overhead" ON)
  129. if(ANKI_STATS)
  130. set(_ANKI_STATS_ENABLED 1)
  131. else()
  132. set(_ANKI_STATS_ENABLED 0)
  133. endif()
  134. option(ANKI_SIMD "Enable SIMD optimizations" ON)
  135. option(ANKI_ADDRESS_SANITIZER "Enable address sanitizer (-fsanitize=address)" OFF)
  136. option(ANKI_HEADLESS "Build a headless application" OFF)
  137. option(ANKI_SHADER_FULL_PRECISION "Build shaders with full precision" OFF)
  138. set(ANKI_OVERRIDE_SHADER_COMPILER "" CACHE FILEPATH "Set the ShaderCompiler to be used to compile all shaders")
  139. option(ANKI_DLSS "Integrate DLSS if supported" OFF)
  140. if(ANDROID)
  141. option(ANKI_PLATFORM_MOBILE "Build for a mobile platform" ON)
  142. else()
  143. option(ANKI_PLATFORM_MOBILE "Build for a mobile platform" OFF)
  144. endif()
  145. # Take a wild guess on the windowing system
  146. if(ANKI_HEADLESS)
  147. set(SDL FALSE)
  148. elseif(LINUX)
  149. set(SDL TRUE)
  150. elseif(WINDOWS)
  151. set(SDL TRUE)
  152. elseif(ANDROID)
  153. set(SDL FALSE)
  154. elseif(MACOS)
  155. set(SDL TRUE)
  156. else()
  157. message(FATAL_ERROR "Couldn't determine the window backend. You need to specify it manually.")
  158. endif()
  159. set(ANKI_GR_BACKEND "VULKAN" CACHE STRING "The graphics API to use (VULKAN or DIRECTX)")
  160. option(ANKI_D3D_EXPERIMENTAL "Enable some experimental DX features" ON)
  161. if(${ANKI_GR_BACKEND} STREQUAL "DIRECTX")
  162. set(DIRECTX TRUE)
  163. set(VULKAN FALSE)
  164. elseif(${ANKI_GR_BACKEND} STREQUAL "VULKAN")
  165. set(DIRECTX FALSE)
  166. set(VULKAN TRUE)
  167. else()
  168. message(FATAL_ERROR "Wrong ANKI_GR_BACKEND")
  169. endif()
  170. if(NOT DEFINED CMAKE_BUILD_TYPE)
  171. message(FATAL_ERROR "You need to define CMAKE_BUILD_TYPE")
  172. endif()
  173. ################################################################################
  174. # Common compiler & linker flags #
  175. ################################################################################
  176. if(MINGW)
  177. add_compile_options(-mconsole)
  178. endif()
  179. add_definitions(
  180. -DSPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS
  181. -DANKI_BUILD
  182. -DIMGUI_USER_CONFIG=<AnKi/Ui/ImGuiConfig.h>)
  183. if(NOT MSVC)
  184. # When building AnKi define this special flag
  185. if(NOT CLANG_WINDOWS)
  186. #add_compile_options(-fPIC)
  187. endif()
  188. add_compile_options(-fno-exceptions)
  189. if(LINUX)
  190. add_compile_options(-fvisibility=hidden)
  191. endif()
  192. if(GCC)
  193. add_compile_options(-static-libstdc++)
  194. endif()
  195. if(X86)
  196. add_compile_options(-msse4)
  197. endif()
  198. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
  199. if(ANKI_STRIP)
  200. set(LINKER_FLAGS "${LINKER_FLAGS} -s ")
  201. add_compile_options(-s)
  202. endif()
  203. if(ANKI_ADDRESS_SANITIZER)
  204. add_compile_options(-fsanitize=address)
  205. add_link_options(-fsanitize=address)
  206. endif()
  207. if(${CMAKE_BUILD_TYPE} STREQUAL "Release")
  208. add_compile_options(-O3)
  209. add_definitions(-DNDEBUG)
  210. elseif(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo")
  211. add_compile_options(-O3 -g3 -fno-omit-frame-pointer)
  212. set(LINKER_FLAGS "${LINKER_FLAGS} -rdynamic ") # For backtrace()
  213. elseif(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
  214. add_compile_options(-O0 -g3)
  215. set(LINKER_FLAGS "${LINKER_FLAGS} -rdynamic ") # For backtrace()
  216. else()
  217. message(FATAL_ERROR "Wrong CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
  218. endif()
  219. # Set the flags to cmake now
  220. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LINKER_FLAGS}")
  221. else()
  222. #ProcessorCount(PC)
  223. string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
  224. add_compile_options(
  225. /MP
  226. /EHsc # Disable exceptions
  227. /GR-) # Disable RTTI
  228. if(${CMAKE_BUILD_TYPE} STREQUAL "Release" OR ${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo")
  229. add_compile_options(/GS-) # Disable "Control stack checking calls"
  230. endif()
  231. add_definitions(
  232. -D_CRT_SECURE_NO_WARNINGS=1 # Disable some string function warnings
  233. -D_ITERATOR_DEBUG_LEVEL=0
  234. -D_HAS_EXCEPTIONS=0)
  235. # Full paths in compiler diagnostics else you can't click on visual studio have it open the file+line
  236. add_compile_options(/FC)
  237. endif()
  238. # Use LLD or mold linker
  239. if(UNIX AND NOT APPLE)
  240. execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=lld -Wl,--version ERROR_QUIET OUTPUT_VARIABLE ld_version)
  241. execute_process(COMMAND ${CMAKE_C_COMPILER} -fuse-ld=mold -Wl,--version ERROR_QUIET OUTPUT_VARIABLE mold_version)
  242. if("${mold_version}" MATCHES "compatible with GNU")
  243. message("++ Will use mold linker")
  244. set(CMAKE_LINKER_TYPE "MOLD")
  245. elseif("${ld_version}" MATCHES "compatible with GNU linkers")
  246. message("++ Will use LLD linker")
  247. set(CMAKE_LINKER_TYPE "LLD")
  248. endif()
  249. endif()
  250. if(ANKI_LTO)
  251. set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
  252. endif()
  253. ################################################################################
  254. # Thirdparty #
  255. ################################################################################
  256. set(ANKI_EXTERN_SUB_DIRS TinyXml2 Lua ZLib ImGui MeshOptimizer SpirvCross "Jolt/Build")
  257. # Jolt config
  258. option(USE_STATIC_MSVC_RUNTIME_LIBRARY "Use the static MSVC runtime library" OFF)
  259. set(USE_STATIC_MSVC_RUNTIME_LIBRARY OFF)
  260. option(DEBUG_RENDERER_IN_DISTRIBUTION "Enable debug renderer in all builds" ON)
  261. set(DEBUG_RENDERER_IN_DISTRIBUTION ON)
  262. if(ANKI_EXTRA_CHECKS)
  263. option(USE_ASSERTS "Enable asserts" ON)
  264. set(USE_ASSERTS ON)
  265. endif()
  266. if((LINUX OR MACOS OR WINDOWS) AND GL)
  267. set(ANKI_EXTERN_SUB_DIRS ${ANKI_EXTERN_SUB_DIRS} GLEW)
  268. endif()
  269. # SDL
  270. if(SDL)
  271. message("++ Configuring SDL3")
  272. option(SDL_STATIC "Build a static version of the library" ON)
  273. option(SDL_DYNAMIC "Build a static version of the library" OFF)
  274. add_subdirectory(ThirdParty/Sdl3)
  275. message("++ End configuring SDL3")
  276. # Include first the build directory.
  277. set(SDL3_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty/Sdl3/include")
  278. endif()
  279. # glslang
  280. message("++ Configuring SPIRV-tools")
  281. add_subdirectory(ThirdParty/SpirvTools)
  282. message("++ End configuring SPIRV-tools")
  283. if(LINUX OR WINDOWS)
  284. message("++ Configuring reproc")
  285. set(REPROC++ OFF)
  286. add_subdirectory(ThirdParty/Reproc)
  287. message("++ End configuring reproc")
  288. endif()
  289. foreach(TMP ${ANKI_EXTERN_SUB_DIRS})
  290. add_subdirectory(ThirdParty/${TMP})
  291. endforeach()
  292. if(ANDROID)
  293. add_library(AnKiAndroidNativeGlue ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
  294. set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
  295. add_subdirectory(ThirdParty/HwcPipe)
  296. add_subdirectory(ThirdParty/StreamlineAnnotate)
  297. endif()
  298. # DLSS
  299. if(ANKI_DLSS)
  300. add_subdirectory(ThirdParty/DlssSdk)
  301. set(_ANKI_DLSS_ENABLED 1)
  302. else()
  303. set(_ANKI_DLSS_ENABLED 0)
  304. endif()
  305. ################################################################################
  306. # AnKi #
  307. ################################################################################
  308. # Revision
  309. find_package(Git)
  310. if(GIT_FOUND)
  311. execute_process(COMMAND
  312. "${GIT_EXECUTABLE}" log -1 --date=short --format=%h
  313. WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
  314. OUTPUT_VARIABLE GIT_COMMIT
  315. ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
  316. set(ANKI_REVISION "\"${GIT_COMMIT}\"")
  317. else()
  318. set(ANKI_REVISION "\"unknown\"")
  319. endif()
  320. # Doxygen
  321. configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Docs/Doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
  322. find_package(Doxygen)
  323. if(DOXYGEN_FOUND)
  324. message("++ Doxygen found")
  325. add_custom_target(doc ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
  326. WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
  327. COMMENT "Generating API documentation with Doxygen" VERBATIM)
  328. endif()
  329. # Config.h
  330. set(ANKI_VERSION_MAJOR 0)
  331. set(ANKI_VERSION_MINOR 1)
  332. message("++ AnKi version: ${ANKI_VERSION_MAJOR}.${ANKI_VERSION_MINOR}")
  333. if(ANKI_EXTRA_CHECKS)
  334. set(_ANKI_EXTRA_CHECKS 1)
  335. else()
  336. set(_ANKI_EXTRA_CHECKS 0)
  337. endif()
  338. if(ANKI_SIMD)
  339. set(_ANKI_ENABLE_SIMD 1)
  340. else()
  341. set(_ANKI_ENABLE_SIMD 0)
  342. endif()
  343. if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
  344. set(ANKI_DEBUG_SYMBOLS 1)
  345. set(ANKI_OPTIMIZE 0)
  346. elseif(${CMAKE_BUILD_TYPE} STREQUAL "Release")
  347. set(ANKI_DEBUG_SYMBOLS 0)
  348. set(ANKI_OPTIMIZE 1)
  349. elseif(${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo")
  350. set(ANKI_DEBUG_SYMBOLS 1)
  351. set(ANKI_OPTIMIZE 1)
  352. else()
  353. message(FATAL_ERROR "Wrong CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
  354. endif()
  355. if(ANKI_BUILD_TESTS)
  356. set(ANKI_TESTS 1)
  357. else()
  358. set(ANKI_TESTS 0)
  359. endif()
  360. if(ANKI_HEADLESS)
  361. set(_ANKI_WINDOWING_SYSTEM 0)
  362. elseif(SDL)
  363. set(_ANKI_WINDOWING_SYSTEM 1)
  364. else()
  365. set(_ANKI_WINDOWING_SYSTEM 2)
  366. endif()
  367. if(ANKI_PLATFORM_MOBILE)
  368. message("++ Compiling for a mobile platform")
  369. set(_ANKI_PLATFORM_MOBILE 1)
  370. else()
  371. message("++ NOT compiling for a mobile platform")
  372. set(_ANKI_PLATFORM_MOBILE 0)
  373. endif()
  374. if(VULKAN)
  375. set(_ANKI_GR_BACKEND 0)
  376. else()
  377. set(_ANKI_GR_BACKEND 1)
  378. endif()
  379. configure_file("AnKi/Config.h.cmake" "${CMAKE_CURRENT_BINARY_DIR}/AnKi/Config.h")
  380. # Include & lib directories
  381. include_directories(
  382. "ThirdParty/Khronos"
  383. "${CMAKE_CURRENT_BINARY_DIR}"
  384. "ThirdParty"
  385. "ThirdParty/ZLib"
  386. "ThirdParty/Jolt"
  387. ${CMAKE_CURRENT_SOURCE_DIR})
  388. if(SDL3_INCLUDE_DIRS)
  389. include_directories("${SDL3_INCLUDE_DIRS}")
  390. endif()
  391. if(LINUX OR MACOS OR WINDOWS)
  392. include_directories("ThirdParty/GLEW/include")
  393. else()
  394. #include_directories("ThirdParty/GLES3/include")
  395. endif()
  396. if(ANDROID)
  397. include_directories("${ANDROID_NDK}/sources/android/native_app_glue")
  398. endif()
  399. if(LINUX)
  400. set(THIRD_PARTY_LIBS ${THIRD_PARTY_LIBS} pthread dl)
  401. endif()
  402. if(ANKI_DLSS)
  403. set(THIRD_PARTY_LIBS ${THIRD_PARTY_LIBS} AnKiNgx)
  404. endif()
  405. # AnKi compiler flags (Mainly warnings)
  406. if(NOT MSVC)
  407. add_compile_options(
  408. -pedantic
  409. -Wno-unknown-warning-option
  410. -Wno-nontrivial-memcall
  411. -Wall
  412. -W
  413. -Wextra
  414. -Wstrict-aliasing
  415. -Wwrite-strings
  416. -Wunused
  417. -Wundef
  418. -Wno-ignored-attributes
  419. -Wno-implicit-fallthrough
  420. -Wunused-result
  421. -Wconversion
  422. -Wno-sign-conversion
  423. -Wno-keyword-macro
  424. -Wno-string-conversion
  425. -Wno-class-memaccess
  426. -Wunused-variable)
  427. set(CMAKE_CXX_STANDARD 20)
  428. else()
  429. string(REPLACE "/W3" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
  430. add_compile_options(
  431. /std:c++20
  432. /W4
  433. /wd4324
  434. /wd4456
  435. /wd4127
  436. /wd4457)
  437. endif()
  438. # Add AnKi sub libraries
  439. add_subdirectory(AnKi)
  440. if(MSVC)
  441. add_library(AnKi INTERFACE AnKi.natvis)
  442. else()
  443. add_library(AnKi INTERFACE)
  444. endif()
  445. target_link_libraries(AnKi INTERFACE AnKiCore ${THIRD_PARTY_LIBS})
  446. add_dependencies(AnKi AnKiShaders)
  447. ################################################################################
  448. # AnKi extra #
  449. ################################################################################
  450. if(ANKI_BUILD_TESTS)
  451. add_subdirectory(Tests)
  452. endif()
  453. if(ANKI_BUILD_TOOLS)
  454. add_subdirectory(Tools)
  455. endif()
  456. if(ANKI_BUILD_SANDBOX)
  457. add_subdirectory(Sandbox)
  458. endif()
  459. if(ANKI_BUILD_SAMPLES)
  460. add_subdirectory(Samples)
  461. endif()