CMakeLists.txt 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. cmake_minimum_required(VERSION 3.12)
  2. project(dynarmic LANGUAGES C CXX ASM VERSION 6.7.0)
  3. # Determine if we're built as a subproject (using add_subdirectory)
  4. # or if this is the master project.
  5. set(MASTER_PROJECT OFF)
  6. if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
  7. set(MASTER_PROJECT ON)
  8. endif()
  9. if (MASTER_PROJECT)
  10. include(CTest)
  11. endif()
  12. # Dynarmic project options
  13. option(DYNARMIC_ENABLE_CPU_FEATURE_DETECTION "Turning this off causes dynarmic to assume the host CPU doesn't support anything later than SSE3" ON)
  14. option(DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT "Enables support for systems that require W^X" OFF)
  15. option(DYNARMIC_FATAL_ERRORS "Errors are fatal" OFF)
  16. option(DYNARMIC_IGNORE_ASSERTS "Ignore asserts" OFF)
  17. option(DYNARMIC_TESTS "Build tests" ${BUILD_TESTING})
  18. option(DYNARMIC_TESTS_USE_UNICORN "Enable fuzzing tests against unicorn" OFF)
  19. option(DYNARMIC_USE_LLVM "Support disassembly of jitted x86_64 code using LLVM" OFF)
  20. option(DYNARMIC_USE_PRECOMPILED_HEADERS "Use precompiled headers" ON)
  21. option(DYNARMIC_USE_BUNDLED_EXTERNALS "Use all bundled externals (useful when e.g. cross-compiling)" OFF)
  22. option(DYNARMIC_WARNINGS_AS_ERRORS "Warnings as errors" ${MASTER_PROJECT})
  23. if (NOT DEFINED DYNARMIC_FRONTENDS)
  24. set(DYNARMIC_FRONTENDS "A32;A64" CACHE STRING "Selects which frontends to enable")
  25. endif()
  26. # Default to a Release build
  27. if (NOT CMAKE_BUILD_TYPE)
  28. set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
  29. message(STATUS "Defaulting to a Release build")
  30. endif()
  31. # Set hard requirements for C++
  32. set(CMAKE_CXX_STANDARD 20)
  33. set(CMAKE_CXX_STANDARD_REQUIRED ON)
  34. set(CMAKE_CXX_EXTENSIONS OFF)
  35. # Disable in-source builds
  36. set(CMAKE_DISABLE_SOURCE_CHANGES ON)
  37. set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
  38. if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
  39. message(SEND_ERROR "In-source builds are not allowed.")
  40. endif()
  41. # Add the module directory to the list of paths
  42. list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules")
  43. # Compiler flags
  44. if (MSVC)
  45. set(DYNARMIC_CXX_FLAGS
  46. /experimental:external
  47. /external:W0
  48. /external:anglebrackets
  49. /W4
  50. /w44263 # Non-virtual member function hides base class virtual function
  51. /w44265 # Class has virtual functions, but destructor is not virtual
  52. /w44456 # Declaration of 'var' hides previous local declaration
  53. /w44457 # Declaration of 'var' hides function parameter
  54. /w44458 # Declaration of 'var' hides class member
  55. /w44459 # Declaration of 'var' hides global definition
  56. /w44946 # Reinterpret-cast between related types
  57. /wd4592 # Symbol will be dynamically initialized (implementation limitation)
  58. /permissive- # Stricter C++ standards conformance
  59. /MP
  60. /Zi
  61. /Zo
  62. /EHsc
  63. /Zc:externConstexpr # Allows external linkage for variables declared "extern constexpr", as the standard permits.
  64. /Zc:inline # Omits inline functions from object-file output.
  65. /Zc:throwingNew # Assumes new (without std::nothrow) never returns null.
  66. /volatile:iso # Use strict standard-abiding volatile semantics
  67. /bigobj # Increase number of sections in .obj files
  68. /DNOMINMAX)
  69. if (DYNARMIC_WARNINGS_AS_ERRORS)
  70. list(APPEND DYNARMIC_CXX_FLAGS
  71. /WX)
  72. endif()
  73. if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
  74. list(APPEND DYNARMIC_CXX_FLAGS
  75. -Qunused-arguments
  76. -Wno-missing-braces)
  77. endif()
  78. else()
  79. set(DYNARMIC_CXX_FLAGS
  80. -Wall
  81. -Wextra
  82. -Wcast-qual
  83. -pedantic
  84. -Wno-missing-braces)
  85. if (DYNARMIC_WARNINGS_AS_ERRORS)
  86. list(APPEND DYNARMIC_CXX_FLAGS
  87. -pedantic-errors
  88. -Werror)
  89. endif()
  90. if (DYNARMIC_FATAL_ERRORS)
  91. list(APPEND DYNARMIC_CXX_FLAGS
  92. -Wfatal-errors)
  93. endif()
  94. if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
  95. # GCC produces bogus -Warray-bounds warnings from xbyak headers for code paths that are not
  96. # actually reachable. Specifically, it happens in cases where some code casts an Operand&
  97. # to Address& after first checking isMEM(), and that code is inlined in a situation where
  98. # GCC knows that the variable is actually a Reg64. isMEM() will never return true for a
  99. # Reg64, but GCC doesn't know that.
  100. list(APPEND DYNARMIC_CXX_FLAGS -Wno-array-bounds)
  101. endif()
  102. if (CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang")
  103. # Bracket depth determines maximum size of a fold expression in Clang since 9c9974c3ccb6.
  104. # And this in turns limits the size of a std::array.
  105. list(APPEND DYNARMIC_CXX_FLAGS -fbracket-depth=1024)
  106. endif()
  107. endif()
  108. # Arch detection
  109. include(DetectArchitecture)
  110. if (NOT DEFINED ARCHITECTURE)
  111. message(FATAL_ERROR "Unsupported architecture encountered. Ending CMake generation.")
  112. endif()
  113. message(STATUS "Target architecture: ${ARCHITECTURE}")
  114. # Forced use of individual bundled libraries for non-REQUIRED library is possible with e.g. cmake -DCMAKE_DISABLE_FIND_PACKAGE_fmt=ON ...
  115. if (DYNARMIC_USE_BUNDLED_EXTERNALS)
  116. set(CMAKE_DISABLE_FIND_PACKAGE_biscuit ON)
  117. set(CMAKE_DISABLE_FIND_PACKAGE_Catch2 ON)
  118. set(CMAKE_DISABLE_FIND_PACKAGE_fmt ON)
  119. set(CMAKE_DISABLE_FIND_PACKAGE_mcl ON)
  120. set(CMAKE_DISABLE_FIND_PACKAGE_oaknut ON)
  121. set(CMAKE_DISABLE_FIND_PACKAGE_tsl-robin-map ON)
  122. set(CMAKE_DISABLE_FIND_PACKAGE_xbyak ON)
  123. set(CMAKE_DISABLE_FIND_PACKAGE_Zydis ON)
  124. endif()
  125. find_package(Boost 1.57 REQUIRED)
  126. find_package(fmt 9 CONFIG)
  127. find_package(mcl 0.1.12 EXACT CONFIG)
  128. find_package(tsl-robin-map CONFIG)
  129. if ("arm64" IN_LIST ARCHITECTURE OR DYNARMIC_TESTS)
  130. find_package(oaknut 2.0.1 CONFIG)
  131. endif()
  132. if ("riscv" IN_LIST ARCHITECTURE)
  133. find_package(biscuit 0.9.1 QUIET)
  134. endif()
  135. if ("x86_64" IN_LIST ARCHITECTURE)
  136. find_package(xbyak 7 CONFIG)
  137. find_package(Zydis 4 CONFIG)
  138. endif()
  139. if (DYNARMIC_USE_LLVM)
  140. find_package(LLVM REQUIRED)
  141. separate_arguments(LLVM_DEFINITIONS)
  142. endif()
  143. if (DYNARMIC_TESTS)
  144. find_package(Catch2 3 CONFIG)
  145. if (DYNARMIC_TESTS_USE_UNICORN)
  146. find_package(Unicorn REQUIRED)
  147. endif()
  148. endif()
  149. # Pull in externals CMakeLists for libs where available
  150. add_subdirectory(externals)
  151. # Dynarmic project files
  152. add_subdirectory(src/dynarmic)
  153. if (DYNARMIC_TESTS)
  154. add_subdirectory(tests)
  155. endif()
  156. #
  157. # Install
  158. #
  159. include(GNUInstallDirs)
  160. include(CMakePackageConfigHelpers)
  161. install(TARGETS dynarmic EXPORT dynarmicTargets)
  162. install(EXPORT dynarmicTargets
  163. NAMESPACE dynarmic::
  164. DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/dynarmic"
  165. )
  166. configure_package_config_file(CMakeModules/dynarmicConfig.cmake.in
  167. dynarmicConfig.cmake
  168. INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/dynarmic"
  169. )
  170. write_basic_package_version_file(dynarmicConfigVersion.cmake
  171. COMPATIBILITY SameMajorVersion
  172. )
  173. install(FILES
  174. "${CMAKE_CURRENT_BINARY_DIR}/dynarmicConfig.cmake"
  175. "${CMAKE_CURRENT_BINARY_DIR}/dynarmicConfigVersion.cmake"
  176. DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/dynarmic"
  177. )
  178. install(DIRECTORY src/dynarmic TYPE INCLUDE FILES_MATCHING PATTERN "*.h")