CMakeLists.txt 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. cmake_minimum_required(VERSION 3.15 FATAL_ERROR)
  2. project(JoltPhysics CXX)
  3. # Ability to turn ON/OFF individual applications
  4. option(TARGET_UNIT_TESTS "Build Unit Tests" ON)
  5. option(TARGET_HELLO_WORLD "Build Hello World" ON)
  6. option(TARGET_PERFORMANCE_TEST "Build Performance Test" ON)
  7. option(TARGET_SAMPLES "Build Samples" ON)
  8. option(TARGET_VIEWER "Build JoltViewer" ON)
  9. # Select X86 processor features to use (if everything is off it will be SSE2 compatible)
  10. option(USE_SSE4_1 "Enable SSE4.1" ON)
  11. option(USE_SSE4_2 "Enable SSE4.2" ON)
  12. option(USE_AVX "Enable AVX" ON)
  13. option(USE_AVX2 "Enable AVX2" ON)
  14. option(USE_LZCNT "Enable LZCNT" ON)
  15. option(USE_TZCNT "Enable TZCNT" ON)
  16. option(USE_F16C "Enable F16C" ON)
  17. option(USE_FMADD "Enable FMADD" ON)
  18. if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
  19. set(CMAKE_CONFIGURATION_TYPES "Debug;Release;Distribution")
  20. elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
  21. set(CMAKE_CONFIGURATION_TYPES "Debug;Release;ReleaseASAN;ReleaseUBSAN;ReleaseCoverage;Distribution")
  22. endif()
  23. if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
  24. # Fill in the path to the asan libraries
  25. set(CLANG_LIB_PATH "\"$(VSInstallDir)\\VC\\Tools\\Llvm\\x64\\lib\\clang\\${CMAKE_CXX_COMPILER_VERSION}\\lib\\windows\"")
  26. # 64 bit architecture
  27. set(CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE "x64")
  28. # Set runtime library
  29. set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
  30. # Set general compiler flags
  31. set(CMAKE_CXX_FLAGS "/std:c++17 /Zc:__cplusplus /GR- /Gm- /Wall /WX /EHsc /nologo /diagnostics:classic /FC /fp:except- /Zc:inline /Zi /DWIN32 /D_WINDOWS /DUNICODE /D_UNICODE")
  32. # Set compiler flags for various configurations
  33. set(CMAKE_CXX_FLAGS_DEBUG "/GS /Od /Ob0 /RTC1")
  34. set(CMAKE_CXX_FLAGS_RELEASE "/GS- /GL /Gy /O2 /Oi /Ot")
  35. set(CMAKE_CXX_FLAGS_DISTRIBUTION "/GS- /GL /Gy /O2 /Oi /Ot")
  36. set(CMAKE_CXX_FLAGS_RELEASEASAN "-fsanitize=address /Od")
  37. set(CMAKE_CXX_FLAGS_RELEASEUBSAN "-fsanitize=undefined,implicit-conversion")
  38. set(CMAKE_CXX_FLAGS_RELEASECOVERAGE "-fprofile-instr-generate -fcoverage-mapping")
  39. # Set linker flags
  40. set(CMAKE_EXE_LINKER_FLAGS "/machine:x64 /SUBSYSTEM:WINDOWS /ignore:4221 /DEBUG:FASTLINK")
  41. if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
  42. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /fp:fast") # Clang doesn't use fast math because it cannot be turned off inside a single compilation unit
  43. if (USE_AVX2)
  44. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2")
  45. elseif (USE_AVX)
  46. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX")
  47. endif()
  48. if (USE_SSE4_1)
  49. add_compile_definitions(JPH_USE_SSE4_1)
  50. endif()
  51. if (USE_SSE4_2)
  52. add_compile_definitions(JPH_USE_SSE4_2)
  53. endif()
  54. if (USE_LZCNT)
  55. add_compile_definitions(JPH_USE_LZCNT)
  56. endif()
  57. if (USE_TZCNT)
  58. add_compile_definitions(JPH_USE_TZCNT)
  59. endif()
  60. if (USE_F16C)
  61. add_compile_definitions(JPH_USE_F16C)
  62. endif()
  63. if (USE_FMADD)
  64. add_compile_definitions(JPH_USE_FMADD)
  65. endif()
  66. set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /DJPH_FLOATING_POINT_EXCEPTIONS_ENABLED") # Clang turns Float2 into a vector sometimes causing floating point exceptions
  67. set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /DJPH_FLOATING_POINT_EXCEPTIONS_ENABLED")
  68. set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/INCREMENTAL:NO /LTCG:incremental /OPT:ICF /OPT:REF")
  69. set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "/LTCG")
  70. elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
  71. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /showFilenames")
  72. if (USE_AVX2)
  73. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx2 -mbmi -mpopcnt -mlzcnt -mf16c -mfma")
  74. elseif (USE_AVX)
  75. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx -mpopcnt")
  76. elseif (USE_SSE4_2)
  77. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2 -mpopcnt")
  78. elseif (USE_SSE4_1)
  79. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
  80. else()
  81. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
  82. endif()
  83. if (USE_LZCNT)
  84. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlzcnt")
  85. endif()
  86. if (USE_TZCNT)
  87. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mbmi")
  88. endif()
  89. if (USE_F16C)
  90. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mf16c")
  91. endif()
  92. if (USE_FMADD)
  93. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfma")
  94. endif()
  95. set(CMAKE_EXE_LINKER_FLAGS_RELEASEASAN "/SUBSYSTEM:CONSOLE /LIBPATH:${CLANG_LIB_PATH} clang_rt.asan-x86_64.lib -wholearchive:clang_rt.asan-x86_64.lib clang_rt.asan_cxx-x86_64.lib -wholearchive:clang_rt.asan_cxx-x86_64.lib")
  96. set(CMAKE_EXE_LINKER_FLAGS_RELEASEUBSAN "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LIBPATH:${CLANG_LIB_PATH}")
  97. set(CMAKE_EXE_LINKER_FLAGS_RELEASECOVERAGE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LIBPATH:${CLANG_LIB_PATH}")
  98. endif()
  99. elseif ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "iOS")
  100. # Set general compiler flags (do not use -ffast-math since it cannot be turned off in a single compilation unit)
  101. set(CMAKE_CXX_FLAGS "-g -std=c++17 -I. -Wall -Werror")
  102. if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
  103. # Somehow -Wcomment doesn't want to be turned off from code and we need this because Doxygen MathJax uses it
  104. # Also turn off automatic fused multiply add contractions, there doesn't seem to be a way to do this selectively through the macro JPH_PRECISE_MATH_OFF
  105. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-comment -ffp-contract=off")
  106. endif()
  107. # Platform specific compiler flags
  108. if ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64" OR "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64")
  109. # X64
  110. if (USE_AVX2)
  111. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx2 -mbmi -mpopcnt -mlzcnt -mf16c -mfma")
  112. elseif (USE_AVX)
  113. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx -mpopcnt")
  114. elseif (USE_SSE4_2)
  115. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2 -mpopcnt")
  116. elseif (USE_SSE4_1)
  117. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")
  118. else()
  119. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
  120. endif()
  121. if (USE_LZCNT)
  122. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mlzcnt")
  123. endif()
  124. if (USE_TZCNT)
  125. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mbmi")
  126. endif()
  127. if (USE_F16C)
  128. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mf16c")
  129. endif()
  130. if (USE_FMADD)
  131. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfma")
  132. endif()
  133. elseif ("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")
  134. # ARM64
  135. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  136. endif()
  137. # Set compiler flags for various configurations
  138. set(CMAKE_CXX_FLAGS_RELEASE "-O3")
  139. set(CMAKE_CXX_FLAGS_DISTRIBUTION "-O3")
  140. set(CMAKE_CXX_FLAGS_RELEASEASAN "-fsanitize=address")
  141. set(CMAKE_CXX_FLAGS_RELEASEUBSAN "-fsanitize=undefined,implicit-conversion")
  142. set(CMAKE_CXX_FLAGS_RELEASECOVERAGE "-fprofile-instr-generate -fcoverage-mapping")
  143. # Set linker flags
  144. set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")
  145. endif()
  146. # Set linker flags
  147. set(CMAKE_EXE_LINKER_FLAGS_DISTRIBUTION "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
  148. # Set repository root
  149. set(PHYSICS_REPO_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../)
  150. # Make Jolt Library
  151. include(${PHYSICS_REPO_ROOT}/Jolt/Jolt.cmake)
  152. if (IOS)
  153. # Ensure that we enable SSE4.2 for the x86_64 build, CMAKE_SYSTEM_PROCESSOR is not set for iOS
  154. set_property(TARGET Jolt PROPERTY XCODE_ATTRIBUTE_OTHER_CPLUSPLUSFLAGS[arch=x86_64] "$(inherited) -msse4.2 -mpopcnt")
  155. endif()
  156. if (TARGET_UNIT_TESTS)
  157. # Create UnitTests executable
  158. include(${PHYSICS_REPO_ROOT}/UnitTests/UnitTests.cmake)
  159. add_executable(UnitTests ${UNIT_TESTS_SRC_FILES})
  160. target_include_directories(UnitTests PUBLIC ${UNIT_TESTS_ROOT})
  161. target_link_libraries (UnitTests LINK_PUBLIC Jolt)
  162. if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
  163. target_link_options(UnitTests PUBLIC "/SUBSYSTEM:CONSOLE")
  164. endif()
  165. if (IOS)
  166. # Set the bundle information
  167. set_property(TARGET UnitTests PROPERTY MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/iOS/UnitTestsInfo.plist")
  168. set_property(TARGET UnitTests PROPERTY XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.joltphysics.unittests")
  169. # Ensure that we enable SSE4.2 for the x86_64 build, CMAKE_SYSTEM_PROCESSOR is not set for iOS
  170. set_property(TARGET UnitTests PROPERTY XCODE_ATTRIBUTE_OTHER_CPLUSPLUSFLAGS[arch=x86_64] "$(inherited) -msse4.2 -mpopcnt")
  171. endif()
  172. # Register unit tests as a test so that it can be run with:
  173. # ctest --output-on-failure
  174. enable_testing()
  175. add_test(UnitTests UnitTests)
  176. endif()
  177. if (TARGET_HELLO_WORLD)
  178. # Example 'Hello World' application
  179. include(${PHYSICS_REPO_ROOT}/HelloWorld/HelloWorld.cmake)
  180. add_executable(HelloWorld ${HELLO_WORLD_SRC_FILES})
  181. target_include_directories(HelloWorld PUBLIC ${HELLO_WORLD_ROOT})
  182. target_link_libraries (HelloWorld LINK_PUBLIC Jolt)
  183. if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
  184. target_link_options(HelloWorld PUBLIC "/SUBSYSTEM:CONSOLE")
  185. endif()
  186. endif()
  187. if (TARGET_PERFORMANCE_TEST)
  188. # Performance Test application
  189. include(${PHYSICS_REPO_ROOT}/PerformanceTest/PerformanceTest.cmake)
  190. add_executable(PerformanceTest ${PERFORMANCE_TEST_SRC_FILES})
  191. target_include_directories(PerformanceTest PUBLIC ${PERFORMANCE_TEST_ROOT})
  192. target_link_libraries (PerformanceTest LINK_PUBLIC Jolt)
  193. if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
  194. target_link_options(PerformanceTest PUBLIC "/SUBSYSTEM:CONSOLE")
  195. endif()
  196. set_property(TARGET PerformanceTest PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${PHYSICS_REPO_ROOT}")
  197. endif()
  198. if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
  199. # Windows only targets
  200. if (TARGET_SAMPLES OR TARGET_VIEWER)
  201. include(${PHYSICS_REPO_ROOT}/TestFramework/TestFramework.cmake)
  202. endif()
  203. if (TARGET_SAMPLES)
  204. include(${PHYSICS_REPO_ROOT}/Samples/Samples.cmake)
  205. endif()
  206. if (TARGET_VIEWER)
  207. include(${PHYSICS_REPO_ROOT}/JoltViewer/JoltViewer.cmake)
  208. endif()
  209. endif()