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 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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. if (COMPILER_CLANG)
  74. set(LINKER_NAME "lld")
  75. elseif(NOT SANITIZE)
  76. if(GOLD_PATH)
  77. set(LINKER_NAME "gold")
  78. else()
  79. message(STATUS "Use generic 'ld' as a linker: gold not found")
  80. endif()
  81. else()
  82. message(STATUS "Use generic 'ld' as a linker: sanitizers are enabled")
  83. endif()
  84. elseif(GOLD_PATH)
  85. set(LINKER_NAME "gold")
  86. else()
  87. message(STATUS "Use generic 'ld' as a linker")
  88. endif()
  89. endif()
  90. if(LINKER_NAME)
  91. set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=${LINKER_NAME}")
  92. set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=${LINKER_NAME}")
  93. message(STATUS "Using custom linker by name: ${LINKER_NAME}")
  94. endif ()
  95. option (ENABLE_STATIC "Enable static compiling [default: OFF]" OFF)
  96. if (ENABLE_STATIC MATCHES "ON")
  97. MESSAGE(STATUS "Static build of rspamd implies that the target binary will be *GPL* licensed")
  98. SET(GPL_RSPAMD_BINARY 1)
  99. SET(CMAKE_SKIP_INSTALL_RPATH ON)
  100. SET(BUILD_STATIC 1)
  101. SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
  102. SET(BUILD_SHARED_LIBS OFF)
  103. SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
  104. SET(LINK_TYPE "STATIC")
  105. SET(NO_SHARED "ON")
  106. # Dirty hack for cmake
  107. SET(CMAKE_EXE_LINK_DYNAMIC_C_FLAGS) # remove -Wl,-Bdynamic
  108. SET(CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS)
  109. SET(CMAKE_SHARED_LIBRARY_C_FLAGS) # remove -fPIC
  110. SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS)
  111. SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) # remove -rdynamic
  112. SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
  113. else ()
  114. if (NO_SHARED MATCHES "OFF")
  115. SET(LINK_TYPE "SHARED")
  116. else ()
  117. SET(LINK_TYPE "STATIC")
  118. endif ()
  119. endif ()
  120. # Legacy options support
  121. option (ENABLE_COVERAGE "Build rspamd with code coverage options [default: OFF]" OFF)
  122. option (ENABLE_OPTIMIZATION "Enable extra optimizations [default: OFF]" OFF)
  123. option (SKIP_RELINK_RPATH "Skip relinking and full RPATH for the install tree" OFF)
  124. option (ENABLE_FULL_DEBUG "Build rspamd with all possible debug [default: OFF]" OFF)
  125. if(NOT CMAKE_BUILD_TYPE)
  126. if (ENABLE_FULL_DEBUG MATCHES "ON")
  127. set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
  128. endif()
  129. if (ENABLE_COVERAGE MATCHES "ON")
  130. set(CMAKE_BUILD_TYPE Coverage CACHE STRING "" FORCE)
  131. endif()
  132. if (ENABLE_OPTIMIZATION MATCHES "ON")
  133. set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
  134. endif()
  135. endif()
  136. if (CMAKE_CONFIGURATION_TYPES) # multiconfig generator?
  137. set (CMAKE_CONFIGURATION_TYPES "Debug;RelWithDebInfo;Release;Coverage" CACHE STRING "" FORCE)
  138. else()
  139. if (NOT CMAKE_BUILD_TYPE)
  140. if (NOT SANITIZE)
  141. message(STATUS "Defaulting to release build.")
  142. set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE)
  143. else ()
  144. message(STATUS "Defaulting to debug build due to sanitizers being enabled.")
  145. set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
  146. endif ()
  147. endif()
  148. set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build")
  149. set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;Coverage")
  150. endif()
  151. string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
  152. message (STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE_UC}")
  153. set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS} -O1 --coverage -fno-inline -fno-default-inline -fno-inline-small-functions ${COMPILER_FAST_MATH}")
  154. set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS} -O1 --coverage -fno-inline -fno-default-inline -fno-inline-small-functions ${COMPILER_FAST_MATH}")
  155. if (COMPILER_GCC)
  156. # GCC flags
  157. set (COMPILER_DEBUG_FLAGS "-g -ggdb -g3 -ggdb3")
  158. set (CXX_COMMON_FLAGS "")
  159. set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} -O2 ${COMPILER_FAST_MATH} ${COMPILER_DEBUG_FLAGS}")
  160. set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -O2 ${COMPILER_FAST_MATH} ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}")
  161. set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 ${COMPILER_FAST_MATH} -fomit-frame-pointer")
  162. set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 ${COMPILER_FAST_MATH} -fomit-frame-pointer ${CXX_COMMON_FLAGS}")
  163. if (ENABLE_FULL_DEBUG MATCHES "ON")
  164. if (ENABLE_ANALYZER MATCHES "ON")
  165. # Check support of -fanalyzer
  166. CHECK_C_COMPILER_FLAG(-fanalyzer SUPPORT_FANALYZER)
  167. if (SUPPORT_FANALYZER)
  168. set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fanalyzer")
  169. #set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fanalyzer")
  170. endif()
  171. endif ()
  172. set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 ${COMPILER_DEBUG_FLAGS}")
  173. set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}")
  174. else()
  175. set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Og ${COMPILER_DEBUG_FLAGS}")
  176. set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}")
  177. endif()
  178. elseif (COMPILER_CLANG)
  179. # Clang flags
  180. set (COMPILER_DEBUG_FLAGS "-g -glldb -gdwarf-aranges -gdwarf-4")
  181. set (CXX_COMMON_FLAGS "")
  182. set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2 -fomit-frame-pointer ${COMPILER_FAST_MATH}")
  183. set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -fomit-frame-pointer ${COMPILER_FAST_MATH} ${CXX_COMMON_FLAGS}")
  184. set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} -O2 ${COMPILER_FAST_MATH} ${COMPILER_DEBUG_FLAGS}")
  185. set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -O2 ${COMPILER_FAST_MATH} ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}")
  186. set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 ${COMPILER_DEBUG_FLAGS}")
  187. set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}")
  188. endif()
  189. if (CMAKE_BUILD_TYPE_UC MATCHES "RELEASE|RELWITHDEBINFO")
  190. set(ENABLE_LTO_INIT ON)
  191. else()
  192. set(ENABLE_LTO_INIT OFF)
  193. endif()
  194. option(ENABLE_LTO "Build rspamd with Link Time Optimization if supported [default: ${ENABLE_LTO_INIT}]" ${ENABLE_LTO_INIT})
  195. if (CMAKE_BUILD_TYPE_UC MATCHES "COVERAGE")
  196. set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
  197. message (STATUS "IPO not enabled for COVERAGE build")
  198. elseif (ENABLE_LTO)
  199. if (${CMAKE_VERSION} VERSION_GREATER "3.9.0")
  200. cmake_policy (SET CMP0069 NEW)
  201. include (CheckIPOSupported)
  202. check_ipo_supported (RESULT SUPPORT_LTO OUTPUT LTO_DIAG )
  203. if (SUPPORT_LTO)
  204. set (CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
  205. message (STATUS "Enable IPO for the ${CMAKE_BUILD_TYPE} build")
  206. else ()
  207. message(WARNING "IPO is not supported: ${LTO_DIAG}")
  208. endif ()
  209. endif ()
  210. else ()
  211. message (STATUS "IPO not enabled for the ${CMAKE_BUILD_TYPE} build")
  212. endif ()
  213. if (ENABLE_STATIC_LIBCXX MATCHES "ON")
  214. set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++")
  215. set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++")
  216. endif()
  217. if (ENABLE_COMPILE_TIME MATCHES "ON")
  218. set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "/usr/bin/time")
  219. endif()
  220. message (STATUS "Final CFLAGS: ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
  221. message (STATUS "Final CXXFLAGS: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
  222. message (STATUS "Final link flags for shlib: ${CMAKE_SHARED_LINKER_FLAGS}")
  223. message (STATUS "Final link flags for exe: ${CMAKE_EXE_LINKER_FLAGS}")