You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Toolset.cmake 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. option (ENABLE_FAST_MATH "Build rspamd with fast math compiler flag [default: ON]" ON)
  2. option (ENABLE_ANALYZER "Build rspamd with static analyzer [default: OFF]" OFF)
  3. option (ENABLE_STATIC_LIBCXX "Build rspamd with static lib(std)c++ [default: OFF]" OFF)
  4. option (ENABLE_COMPILE_TIME "Show compile time [default: OFF]" OFF)
  5. option (ENABLE_LIBCXX "Use libc++ instead of libstdc++" OFF)
  6. if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
  7. SET (COMPILER_GCC 1)
  8. elseif(CMAKE_C_COMPILER_ID MATCHES "Clang|AppleClang")
  9. SET (COMPILER_CLANG 1)
  10. endif()
  11. set(CMAKE_POSITION_INDEPENDENT_CODE ON)
  12. SET (COMPILER_FAST_MATH "")
  13. if (ENABLE_FAST_MATH MATCHES "ON")
  14. # We need to keep nans and infinities, so cannot keep all fast math there
  15. IF (COMPILER_CLANG)
  16. SET (COMPILER_FAST_MATH "-fassociative-math -freciprocal-math -fno-signed-zeros -ffp-contract=fast")
  17. ELSE()
  18. SET (COMPILER_FAST_MATH "-funsafe-math-optimizations -fno-math-errno")
  19. ENDIF ()
  20. endif ()
  21. if (CMAKE_GENERATOR STREQUAL "Ninja")
  22. # Turn on colored output. https://github.com/ninja-build/ninja/wiki/FAQ
  23. set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always")
  24. set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color=always")
  25. endif ()
  26. if (COMPILER_GCC)
  27. # Require minimum version of gcc
  28. set (GCC_MINIMUM_VERSION 8)
  29. if (CMAKE_C_COMPILER_VERSION VERSION_LESS ${GCC_MINIMUM_VERSION} AND NOT CMAKE_VERSION VERSION_LESS 2.8.9)
  30. message (FATAL_ERROR "GCC version must be at least ${GCC_MINIMUM_VERSION}.")
  31. endif ()
  32. if (ENABLE_LIBCXX MATCHES "ON")
  33. # XXX: too complicated to implement for now
  34. endif ()
  35. elseif (COMPILER_CLANG)
  36. # Require minimum version of clang
  37. set (CLANG_MINIMUM_VERSION 7)
  38. if (CMAKE_C_COMPILER_VERSION VERSION_LESS ${CLANG_MINIMUM_VERSION})
  39. message (FATAL_ERROR "Clang version must be at least ${CLANG_MINIMUM_VERSION}.")
  40. endif ()
  41. # Hack to fix try_compile
  42. SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-command-line-argument")
  43. SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-command-line-argument")
  44. SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-ignored-optimization-argument")
  45. SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-ignored-optimization-argument")
  46. if (ENABLE_LIBCXX MATCHES "AUTO")
  47. include(CheckCXXSourceCompiles)
  48. set(OLD_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
  49. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
  50. check_cxx_source_compiles("
  51. #include <version>
  52. int main() { return 0; }
  53. " HAVE_LIBCXX )
  54. if (HAVE_LIBCXX)
  55. SET(ENABLE_LIBCXX "ON")
  56. else()
  57. SET(ENABLE_LIBCXX "OFF")
  58. endif()
  59. set(CMAKE_CXX_FLAGS "${OLD_CMAKE_CXX_FLAGS}")
  60. endif()
  61. if (ENABLE_LIBCXX MATCHES "ON")
  62. set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
  63. set(CLANG_DEFAULT_CXX_STDLIB "libc++")
  64. endif ()
  65. else ()
  66. message (WARNING "You are using an unsupported compiler ${CMAKE_C_COMPILER_ID}. Compilation has only been tested with Clang 4+ and GCC 4+.")
  67. endif ()
  68. option(LINKER_NAME "Linker name or full path")
  69. find_program(LLD_PATH NAMES "ld.lld" "lld")
  70. find_program(GOLD_PATH NAMES "ld.gold" "gold")
  71. if(NOT LINKER_NAME)
  72. if(LLD_PATH)
  73. set(LINKER_NAME "lld")
  74. elseif(GOLD_PATH)
  75. set(LINKER_NAME "gold")
  76. else()
  77. message(STATUS "Use generic 'ld' as a linker")
  78. endif()
  79. endif()
  80. if(LINKER_NAME)
  81. set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=${LINKER_NAME}")
  82. set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=${LINKER_NAME}")
  83. message(STATUS "Using custom linker by name: ${LINKER_NAME}")
  84. endif ()
  85. option (ENABLE_STATIC "Enable static compiling [default: OFF]" OFF)
  86. if (ENABLE_STATIC MATCHES "ON")
  87. MESSAGE(STATUS "Static build of rspamd implies that the target binary will be *GPL* licensed")
  88. SET(GPL_RSPAMD_BINARY 1)
  89. SET(CMAKE_SKIP_INSTALL_RPATH ON)
  90. SET(BUILD_STATIC 1)
  91. SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
  92. SET(BUILD_SHARED_LIBS OFF)
  93. SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
  94. SET(LINK_TYPE "STATIC")
  95. SET(NO_SHARED "ON")
  96. # Dirty hack for cmake
  97. SET(CMAKE_EXE_LINK_DYNAMIC_C_FLAGS) # remove -Wl,-Bdynamic
  98. SET(CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS)
  99. SET(CMAKE_SHARED_LIBRARY_C_FLAGS) # remove -fPIC
  100. SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS)
  101. SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) # remove -rdynamic
  102. SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
  103. else ()
  104. if (NO_SHARED MATCHES "OFF")
  105. SET(LINK_TYPE "SHARED")
  106. else ()
  107. SET(LINK_TYPE "STATIC")
  108. endif ()
  109. endif ()
  110. # Legacy options support
  111. option (ENABLE_COVERAGE "Build rspamd with code coverage options [default: OFF]" OFF)
  112. option (ENABLE_OPTIMIZATION "Enable extra optimizations [default: OFF]" OFF)
  113. option (SKIP_RELINK_RPATH "Skip relinking and full RPATH for the install tree" OFF)
  114. option (ENABLE_FULL_DEBUG "Build rspamd with all possible debug [default: OFF]" OFF)
  115. if(NOT CMAKE_BUILD_TYPE)
  116. if (ENABLE_FULL_DEBUG MATCHES "ON")
  117. set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
  118. endif()
  119. if (ENABLE_COVERAGE MATCHES "ON")
  120. set(CMAKE_BUILD_TYPE Coverage CACHE STRING "" FORCE)
  121. endif()
  122. if (ENABLE_OPTIMIZATION MATCHES "ON")
  123. set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
  124. endif()
  125. endif()
  126. if (CMAKE_CONFIGURATION_TYPES) # multiconfig generator?
  127. set (CMAKE_CONFIGURATION_TYPES "Debug;RelWithDebInfo;Release;Coverage" CACHE STRING "" FORCE)
  128. else()
  129. if (NOT CMAKE_BUILD_TYPE)
  130. if (NOT SANITIZE)
  131. message(STATUS "Defaulting to release build.")
  132. set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
  133. else ()
  134. message(STATUS "Defaulting to debug build due to sanitizers being enabled.")
  135. set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
  136. endif ()
  137. endif()
  138. set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build")
  139. set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;Coverage")
  140. endif()
  141. string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
  142. message (STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE_UC}")
  143. set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS} -O1 --coverage -fno-inline -fno-default-inline -fno-inline-small-functions ${COMPILER_FAST_MATH}")
  144. set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS} -O1 --coverage -fno-inline -fno-default-inline -fno-inline-small-functions ${COMPILER_FAST_MATH}")
  145. if (COMPILER_GCC)
  146. # GCC flags
  147. set (COMPILER_DEBUG_FLAGS "-g -ggdb -g3 -ggdb3")
  148. set (CXX_COMMON_FLAGS "")
  149. set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} -O2 ${COMPILER_FAST_MATH} ${COMPILER_DEBUG_FLAGS}")
  150. set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -O2 ${COMPILER_FAST_MATH} ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}")
  151. set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 ${COMPILER_FAST_MATH} -fomit-frame-pointer")
  152. set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 ${COMPILER_FAST_MATH} -fomit-frame-pointer ${CXX_COMMON_FLAGS}")
  153. if (ENABLE_FULL_DEBUG MATCHES "ON")
  154. if (ENABLE_ANALYZER MATCHES "ON")
  155. # Check support of -fanalyzer
  156. CHECK_C_COMPILER_FLAG(-fanalyzer SUPPORT_FANALYZER)
  157. if (SUPPORT_FANALYZER)
  158. set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fanalyzer")
  159. #set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fanalyzer")
  160. endif()
  161. endif ()
  162. set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 ${COMPILER_DEBUG_FLAGS}")
  163. set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}")
  164. else()
  165. set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Og ${COMPILER_DEBUG_FLAGS}")
  166. set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}")
  167. endif()
  168. elseif (COMPILER_CLANG)
  169. # Clang flags
  170. set (COMPILER_DEBUG_FLAGS "-g -glldb -gdwarf-aranges -gdwarf-4")
  171. set (CXX_COMMON_FLAGS "")
  172. set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2 -fomit-frame-pointer ${COMPILER_FAST_MATH}")
  173. set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -fomit-frame-pointer ${COMPILER_FAST_MATH} ${CXX_COMMON_FLAGS}")
  174. set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} -O2 ${COMPILER_FAST_MATH} ${COMPILER_DEBUG_FLAGS}")
  175. set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -O2 ${COMPILER_FAST_MATH} ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}")
  176. set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 ${COMPILER_DEBUG_FLAGS}")
  177. set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}")
  178. endif()
  179. if (CMAKE_BUILD_TYPE_UC MATCHES "RELEASE|RELWITHDEBINFO")
  180. set(ENABLE_LTO_INIT ON)
  181. else()
  182. set(ENABLE_LTO_INIT OFF)
  183. endif()
  184. option(ENABLE_LTO "Build rspamd with Link Time Optimization if supported [default: ${ENABLE_LTO_INIT}]" ${ENABLE_LTO_INIT})
  185. if (CMAKE_BUILD_TYPE_UC MATCHES "COVERAGE")
  186. set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
  187. message (STATUS "IPO not enabled for COVERAGE build")
  188. elseif (ENABLE_LTO)
  189. if (${CMAKE_VERSION} VERSION_GREATER "3.9.0")
  190. cmake_policy (SET CMP0069 NEW)
  191. include (CheckIPOSupported)
  192. check_ipo_supported (RESULT SUPPORT_LTO OUTPUT LTO_DIAG )
  193. if (SUPPORT_LTO)
  194. set (CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
  195. message (STATUS "Enable IPO for the ${CMAKE_BUILD_TYPE} build")
  196. else ()
  197. message(WARNING "IPO is not supported: ${LTO_DIAG}")
  198. endif ()
  199. endif ()
  200. else ()
  201. message (STATUS "IPO not enabled for the ${CMAKE_BUILD_TYPE} build")
  202. endif ()
  203. if (ENABLE_STATIC_LIBCXX MATCHES "ON")
  204. set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++")
  205. set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++")
  206. endif()
  207. if (ENABLE_COMPILE_TIME MATCHES "ON")
  208. set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "/usr/bin/time")
  209. endif()
  210. message (STATUS "Final CFLAGS: ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
  211. message (STATUS "Final CXXFLAGS: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
  212. message (STATUS "Final link flags for shlib: ${CMAKE_SHARED_LINKER_FLAGS}")
  213. message (STATUS "Final link flags for exe: ${CMAKE_EXE_LINKER_FLAGS}")