CMakeLists.txt 13 KB

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