Rapid spam filtering system https://rspamd.com/
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.

777 lines
26 KiB

11 years ago
15 years ago
16 years ago
16 years ago
11 years ago
12 years ago
12 years ago
12 years ago
  1. #
  2. # Rspamd - rapid antispam system
  3. #
  4. # Cmake configuration file
  5. #
  6. ############################# INITIAL SECTION #############################################
  7. CMAKE_MINIMUM_REQUIRED(VERSION 3.12 FATAL_ERROR)
  8. SET(RSPAMD_VERSION_MAJOR 3)
  9. SET(RSPAMD_VERSION_MINOR 2)
  10. # Keep two digits all the time
  11. SET(RSPAMD_VERSION_MAJOR_NUM ${RSPAMD_VERSION_MAJOR}0)
  12. SET(RSPAMD_VERSION_MINOR_NUM ${RSPAMD_VERSION_MINOR}0)
  13. IF(GIT_ID)
  14. SET(GIT_VERSION 1)
  15. SET(RSPAMD_ID "${GIT_ID}")
  16. ENDIF()
  17. SET(RSPAMD_VERSION "${RSPAMD_VERSION_MAJOR}.${RSPAMD_VERSION_MINOR}")
  18. PROJECT(rspamd VERSION "${RSPAMD_VERSION}" LANGUAGES C CXX ASM)
  19. CMAKE_POLICY(SET CMP0075 NEW)
  20. # This is supported merely with cmake 3.1
  21. SET(CMAKE_C_STANDARD 11)
  22. SET(CMAKE_CXX_STANDARD 17)
  23. SET(CMAKE_C_STANDARD_REQUIRED ON)
  24. SET(CMAKE_CXX_STANDARD_REQUIRED ON)
  25. LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/")
  26. SET(RSPAMD_MASTER_SITE_URL "https://rspamd.com")
  27. IF(NOT RSPAMD_USER)
  28. SET(RSPAMD_USER "nobody")
  29. SET(RSPAMD_GROUP "nobody")
  30. ENDIF(NOT RSPAMD_USER)
  31. # Default for SysV Init
  32. SET(RSPAMD_WORKER_NORMAL "*:11333")
  33. SET(RSPAMD_WORKER_CONTROLLER "*:11334")
  34. ############################# OPTIONS SECTION #############################################
  35. OPTION(ENABLE_LUAJIT "Link with libluajit [default: ON]" ON)
  36. OPTION(ENABLE_URL_INCLUDE "Enable urls in ucl includes (requires libcurl or libfetch) [default: OFF]" OFF)
  37. OPTION(NO_SHARED "Build internal libs static [default: ON]" ON)
  38. OPTION(INSTALL_WEBUI "Install web interface [default: ON]" ON)
  39. OPTION(WANT_SYSTEMD_UNITS "Install systemd unit files on Linux [default: OFF]" OFF)
  40. OPTION(ENABLE_SNOWBALL "Enable snowball stemmer [default: ON]" ON)
  41. OPTION(ENABLE_CLANG_PLUGIN "Enable clang static analysing plugin [default: OFF]" OFF)
  42. OPTION(ENABLE_PCRE2 "Enable pcre2 instead of pcre [default: ON]" ON)
  43. OPTION(ENABLE_JEMALLOC "Build rspamd with jemalloc allocator [default: OFF]" OFF)
  44. OPTION(ENABLE_UTILS "Build rspamd internal utils [default: OFF]" OFF)
  45. OPTION(ENABLE_LIBUNWIND "Use libunwind to print crash traces [default: OFF]" OFF)
  46. OPTION(ENABLE_LUA_TRACE "Trace all Lua C API invocations [default: OFF]" OFF)
  47. OPTION(ENABLE_LUA_REPL "Enables Lua repl (requires C++11 compiler) [default: ON]" ON)
  48. OPTION(SYSTEM_ZSTD "Use system zstd instead of bundled one [default: OFF]" OFF)
  49. OPTION(SYSTEM_FMT "Use system fmt instead of bundled one [defalut: OFF]" OFF)
  50. OPTION(SYSTEM_DOCTEST "Use system doctest instead of bundled one [default: OFF]" OFF)
  51. ############################# INCLUDE SECTION #############################################
  52. INCLUDE(CheckIncludeFiles)
  53. INCLUDE(CheckFunctionExists)
  54. INCLUDE(CheckSymbolExists)
  55. INCLUDE(CheckCSourceCompiles)
  56. INCLUDE(CheckCSourceRuns)
  57. INCLUDE(CheckLibraryExists)
  58. INCLUDE(CheckCCompilerFlag)
  59. INCLUDE(CMakeParseArguments)
  60. INCLUDE(FindArch)
  61. INCLUDE(AsmOp)
  62. INCLUDE(FindRagel)
  63. INCLUDE(ProcessPackage)
  64. IF(NOT RAGEL_FOUND)
  65. MESSAGE(FATAL_ERROR "Ragel is required to build rspamd")
  66. ENDIF()
  67. FIND_PACKAGE(PkgConfig REQUIRED)
  68. FIND_PACKAGE(Perl REQUIRED)
  69. INCLUDE(Toolset)
  70. INCLUDE(Sanitizer)
  71. INCLUDE(ArchDep)
  72. INCLUDE(Paths)
  73. IF(ENABLE_PCRE2 MATCHES "ON")
  74. SET(WITH_PCRE2 1)
  75. # For utf8 API
  76. LIST(APPEND CMAKE_REQUIRED_DEFINITIONS "-DPCRE2_CODE_UNIT_WIDTH=8")
  77. ENDIF()
  78. ############################# CONFIG SECTION #############################################
  79. # Initial set
  80. # Prefer local include dirs to system ones
  81. INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/"
  82. "${CMAKE_SOURCE_DIR}/src"
  83. "${CMAKE_SOURCE_DIR}/src/libutil"
  84. "${CMAKE_SOURCE_DIR}/src/libserver"
  85. "${CMAKE_SOURCE_DIR}/src/libmime"
  86. "${CMAKE_SOURCE_DIR}/src/libstat"
  87. "${CMAKE_SOURCE_DIR}/src/libcryptobox"
  88. "${CMAKE_SOURCE_DIR}/contrib/libucl"
  89. "${CMAKE_SOURCE_DIR}/contrib/replxx/include"
  90. "${CMAKE_SOURCE_DIR}/contrib/uthash"
  91. "${CMAKE_SOURCE_DIR}/contrib/http-parser"
  92. "${CMAKE_SOURCE_DIR}/contrib/fpconv"
  93. "${CMAKE_SOURCE_DIR}/contrib/libottery"
  94. "${CMAKE_SOURCE_DIR}/contrib/xxhash"
  95. "${CMAKE_SOURCE_DIR}/contrib/cdb"
  96. "${CMAKE_SOURCE_DIR}/contrib/snowball/include"
  97. "${CMAKE_SOURCE_DIR}/contrib/librdns"
  98. "${CMAKE_SOURCE_DIR}/contrib/aho-corasick"
  99. "${CMAKE_SOURCE_DIR}/contrib/lc-btrie"
  100. "${CMAKE_SOURCE_DIR}/contrib/lua-lpeg"
  101. "${CMAKE_SOURCE_DIR}/contrib/frozen/include"
  102. "${CMAKE_SOURCE_DIR}/contrib/fu2/include"
  103. "${CMAKE_BINARY_DIR}/src" #Stored in the binary dir
  104. "${CMAKE_BINARY_DIR}/src/libcryptobox")
  105. SET(TAR "tar")
  106. INCLUDE(OSDep)
  107. # Now find libraries and headers
  108. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES "m")
  109. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES "pthread")
  110. IF(ENABLE_LUAJIT MATCHES "ON")
  111. ProcessPackage(LIBLUAJIT LIBRARY "luajit"
  112. "luajit-2.1"
  113. "luajit2.1"
  114. "luajit-2.0"
  115. "luajit2.0"
  116. "luajit-5.1"
  117. INCLUDE luajit.h INCLUDE_SUFFIXES
  118. "include/luajit-2.1"
  119. "include/luajit-2.0"
  120. "include/luajit"
  121. ROOT ${LUA_ROOT}
  122. MODULES luajit)
  123. SET(WITH_LUAJIT 1)
  124. ELSE(ENABLE_LUAJIT MATCHES "ON")
  125. ProcessPackage(LIBLUA LIBRARY "lua"
  126. "lua-5.3"
  127. LIB_SUFFIXES "lua5.3"
  128. INCLUDE lua.h INCLUDE_SUFFIXES
  129. "include/lua-5.3"
  130. "include/lua5.3"
  131. "include/lua53"
  132. "include/lua"
  133. ROOT ${LUA_ROOT}
  134. MODULES lua53
  135. OPTIONAL)
  136. IF (NOT WITH_LIBLUA)
  137. ProcessPackage(LIBLUA LIBRARY "lua"
  138. "lua-5.4"
  139. LIB_SUFFIXES "lua5.4"
  140. INCLUDE lua.h INCLUDE_SUFFIXES
  141. "include/lua-5.4"
  142. "include/lua5.4"
  143. "include/lua54"
  144. "include/lua"
  145. ROOT ${LUA_ROOT}
  146. MODULES lua54
  147. OPTIONAL)
  148. IF (NOT WITH_LIBLUA)
  149. ProcessPackage(LIBLUA LIBRARY "lua"
  150. "lua-5.2"
  151. LIB_SUFFIXES "lua5.2"
  152. INCLUDE lua.h INCLUDE_SUFFIXES
  153. "include/lua-5.2"
  154. "include/lua5.2"
  155. "include/lua52"
  156. "include/lua"
  157. ROOT ${LUA_ROOT}
  158. MODULES lua52
  159. OPTIONAL)
  160. IF (NOT WITH_LIBLUA)
  161. ProcessPackage(LIBLUA LIBRARY "lua"
  162. "lua-5.1"
  163. INCLUDE lua.h INCLUDE_SUFFIXES
  164. "include/lua-5.1"
  165. "include/lua5.1"
  166. "include/lua51"
  167. "include/lua"
  168. ROOT ${LUA_ROOT}
  169. MODULES lua51)
  170. ENDIF()
  171. ENDIF()
  172. ENDIF()
  173. ENDIF(ENABLE_LUAJIT MATCHES "ON")
  174. IF(ENABLE_JEMALLOC MATCHES "ON" AND NOT SANITIZE)
  175. ProcessPackage(JEMALLOC LIBRARY jemalloc_pic jemalloc INCLUDE jemalloc.h INCLUDE_SUFFIXES include/jemalloc
  176. ROOT ${JEMALLOC_ROOT_DIR})
  177. SET(WITH_JEMALLOC "1")
  178. ENDIF()
  179. IF(ENABLE_LIBUNWIND MATCHES "ON")
  180. ProcessPackage(LIBUNWIND LIBRARY unwind INCLUDE libunwind.h INCLUDE_SUFFIXES include/libunwind
  181. ROOT ${LIBUNWIND_ROOT_DIR} MODULES libunwind)
  182. SET(WITH_LIBUNWIND "1")
  183. ENDIF()
  184. ProcessPackage(GLIB2 LIBRARY glib-2.0 INCLUDE glib.h
  185. INCLUDE_SUFFIXES include/glib include/glib-2.0
  186. ROOT ${GLIB_ROOT_DIR} MODULES glib-2.0>=2.28)
  187. IF(ENABLE_PCRE2 MATCHES "ON")
  188. ProcessPackage(PCRE LIBRARY pcre2 pcre2-8 INCLUDE pcre2.h INCLUDE_SUFFIXES include/pcre2
  189. ROOT ${PCRE_ROOT_DIR} MODULES pcre2 pcre2-8 libpcre2 libpcre2-8)
  190. ELSE()
  191. ProcessPackage(PCRE LIBRARY pcre INCLUDE pcre.h INCLUDE_SUFFIXES include/pcre
  192. ROOT ${PCRE_ROOT_DIR} MODULES pcre libpcre pcre3 libpcre3)
  193. ENDIF()
  194. ProcessPackage(SQLITE3 LIBRARY sqlite3 INCLUDE sqlite3.h INCLUDE_SUFFIXES include/sqlite3 include/sqlite
  195. ROOT ${SQLITE3_ROOT_DIR} MODULES sqlite3 sqlite)
  196. ProcessPackage(ICUDATA LIBRARY icudata INCLUDE unicode/ucnv.h
  197. ROOT ${ICU_ROOT_DIR} MODULES icu-uc)
  198. ProcessPackage(ICUC LIBRARY icuuc INCLUDE unicode/ucnv.h
  199. ROOT ${ICU_ROOT_DIR} MODULES icu-uc)
  200. ProcessPackage(ICUIO LIBRARY icuio INCLUDE unicode/ucnv.h
  201. ROOT ${ICU_ROOT_DIR} MODULES icu-io)
  202. ProcessPackage(ICUI18N LIBRARY icui18n INCLUDE unicode/ucnv.h
  203. ROOT ${ICU_ROOT_DIR} MODULES icu-i18n)
  204. ProcessPackage(LIBCRYPT LIBRARY crypto INCLUDE openssl/evp.h
  205. ROOT ${OPENSSL_ROOT_DIR} MODULES openssl libcrypt)
  206. ProcessPackage(LIBSSL LIBRARY ssl INCLUDE openssl/ssl.h
  207. ROOT ${OPENSSL_ROOT_DIR} MODULES openssl libssl)
  208. ProcessPackage(LIBZ LIBRARY z INCLUDE zlib.h INCLUDE_SUFFIXES include/zlib
  209. ROOT ${LIBZ_ROOT_DIR} MODULES z)
  210. ProcessPackage(SODIUM LIBRARY sodium INCLUDE sodium.h
  211. INCLUDE_SUFFIXES include/libsodium include/sodium
  212. ROOT ${LIBSODIUM_ROOT_DIR} MODULES libsodium>=1.0.0)
  213. include (CompilerWarnings)
  214. include (Hyperscan)
  215. include (Openblas)
  216. IF(ENABLE_LUA_TRACE)
  217. SET(WITH_LUA_TRACE 1)
  218. ENDIF(ENABLE_LUA_TRACE)
  219. SET(CMAKE_C_FLAGS "${CMAKE_C_OPT_FLAGS} ${CMAKE_C_FLAGS}")
  220. SET(CMAKE_CXX_FLAGS "${CMAKE_C_OPT_FLAGS} ${CMAKE_CXX_FLAGS}")
  221. ADD_DEFINITIONS(-DHAVE_CONFIG_H)
  222. ADD_DEFINITIONS(-DDOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS)
  223. # Workaround for https://github.com/onqtam/doctest/issues/356
  224. ADD_DEFINITIONS(-DDOCTEST_CONFIG_USE_STD_HEADERS)
  225. ADD_DEFINITIONS(-DU_CHARSET_IS_UTF8)
  226. # Check platform specific includes
  227. CHECK_INCLUDE_FILES(sys/types.h HAVE_SYS_TYPES_H)
  228. CHECK_INCLUDE_FILES(sys/uio.h HAVE_SYS_UIO_H)
  229. CHECK_INCLUDE_FILES(fcntl.h HAVE_FCNTL_H)
  230. CHECK_INCLUDE_FILES(math.h HAVE_MATH_H)
  231. CHECK_INCLUDE_FILES(stdio.h HAVE_STDIO_H)
  232. CHECK_INCLUDE_FILES(stdlib.h HAVE_STDLIB_H)
  233. CHECK_INCLUDE_FILES(string.h HAVE_STRING_H)
  234. CHECK_INCLUDE_FILES(strings.h HAVE_STRINGS_H)
  235. CHECK_INCLUDE_FILES(time.h HAVE_TIME_H)
  236. CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H)
  237. CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H)
  238. CHECK_INCLUDE_FILES(inttypes.h HAVE_INTTYPES_H)
  239. CHECK_INCLUDE_FILES(stdbool.h HAVE_STDBOOL_H)
  240. CHECK_INCLUDE_FILES(endian.h HAVE_ENDIAN_H)
  241. CHECK_INCLUDE_FILES(sys/endian.h HAVE_SYS_ENDIAN_H)
  242. CHECK_INCLUDE_FILES(machine/endian.h HAVE_MACHINE_ENDIAN_H)
  243. CHECK_INCLUDE_FILES(sys/socket.h HAVE_SYS_SOCKET_H)
  244. CHECK_INCLUDE_FILES(sys/mman.h HAVE_SYS_MMAN_H)
  245. CHECK_INCLUDE_FILES(sys/un.h HAVE_SYS_UN_H)
  246. CHECK_INCLUDE_FILES(sys/stat.h HAVE_SYS_STAT_H)
  247. CHECK_INCLUDE_FILES(sys/wait.h HAVE_SYS_WAIT_H)
  248. CHECK_INCLUDE_FILES(sys/param.h HAVE_SYS_PARAM_H)
  249. CHECK_INCLUDE_FILES(sys/cdefs.h HAVE_SYS_CDEFS_H)
  250. CHECK_INCLUDE_FILES(sys/file.h HAVE_SYS_FILE_H)
  251. CHECK_INCLUDE_FILES(sys/resource.h HAVE_SYS_RESOURCE_H)
  252. CHECK_INCLUDE_FILES(netinet/in.h HAVE_NETINET_IN_H)
  253. CHECK_INCLUDE_FILES(netinet/tcp.h HAVE_NETINET_TCP_H)
  254. CHECK_INCLUDE_FILES(arpa/inet.h HAVE_ARPA_INET_H)
  255. CHECK_INCLUDE_FILES(netdb.h HAVE_NETDB_H)
  256. CHECK_INCLUDE_FILES(syslog.h HAVE_SYSLOG_H)
  257. CHECK_INCLUDE_FILES(siginfo.h HAVE_SIGINFO_H)
  258. CHECK_INCLUDE_FILES(locale.h HAVE_LOCALE_H)
  259. CHECK_INCLUDE_FILES(libgen.h HAVE_LIBGEN_H)
  260. CHECK_INCLUDE_FILES(pwd.h HAVE_PWD_H)
  261. CHECK_INCLUDE_FILES(grp.h HAVE_GRP_H)
  262. CHECK_INCLUDE_FILES(glob.h HAVE_GLOB_H)
  263. CHECK_INCLUDE_FILES(poll.h HAVE_POLL_H)
  264. CHECK_INCLUDE_FILES(readpassphrase.h HAVE_READPASSPHRASE_H)
  265. CHECK_INCLUDE_FILES(termios.h HAVE_TERMIOS_H)
  266. CHECK_INCLUDE_FILES(paths.h HAVE_PATHS_H)
  267. CHECK_INCLUDE_FILES(ctype.h HAVE_CTYPE_H)
  268. CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H)
  269. CHECK_INCLUDE_FILES(cpuid.h HAVE_CPUID_H)
  270. CHECK_INCLUDE_FILES(dirent.h HAVE_DIRENT_H)
  271. CHECK_INCLUDE_FILES(ucontext.h HAVE_UCONTEXT_H)
  272. CHECK_INCLUDE_FILES(sys/ucontext.h HAVE_SYS_UCONTEXT_H) # OSX specific
  273. # Check platform API
  274. CHECK_FUNCTION_EXISTS(setproctitle HAVE_SETPROCTITLE)
  275. CHECK_FUNCTION_EXISTS(getpagesize HAVE_GETPAGESIZE)
  276. CHECK_FUNCTION_EXISTS(nanosleep HAVE_NANOSLEEP)
  277. CHECK_FUNCTION_EXISTS(flock HAVE_FLOCK)
  278. CHECK_LIBRARY_EXISTS(m tanh "" HAVE_TANH)
  279. CHECK_FUNCTION_EXISTS(mkstemp HAVE_MKSTEMP)
  280. CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME)
  281. # Check macros
  282. CHECK_SYMBOL_EXISTS(PATH_MAX limits.h HAVE_PATH_MAX)
  283. CHECK_SYMBOL_EXISTS(MAXPATHLEN sys/param.h HAVE_MAXPATHLEN)
  284. CHECK_SYMBOL_EXISTS(MAP_ANON sys/mman.h HAVE_MMAP_ANON)
  285. CHECK_SYMBOL_EXISTS(IPV6_V6ONLY "sys/socket.h;netinet/in.h" HAVE_IPV6_V6ONLY)
  286. CHECK_SYMBOL_EXISTS(posix_fallocate fcntl.h HAVE_POSIX_FALLOCATE)
  287. CHECK_SYMBOL_EXISTS(fallocate fcntl.h HAVE_FALLOCATE)
  288. CHECK_SYMBOL_EXISTS(_SC_NPROCESSORS_ONLN unistd.h HAVE_SC_NPROCESSORS_ONLN)
  289. CHECK_SYMBOL_EXISTS(setbit sys/param.h PARAM_H_HAS_BITSET)
  290. CHECK_SYMBOL_EXISTS(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO)
  291. CHECK_SYMBOL_EXISTS(sched_yield "sched.h" HAVE_SCHED_YIELD)
  292. CHECK_SYMBOL_EXISTS(nftw "sys/types.h;ftw.h" HAVE_NFTW)
  293. CHECK_SYMBOL_EXISTS(memrchr "string.h" HAVE_MEMRCHR)
  294. IF(ENABLE_PCRE2 MATCHES "ON")
  295. LIST(APPEND CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE}")
  296. CHECK_SYMBOL_EXISTS(PCRE2_CONFIG_JIT "pcre2.h" HAVE_PCRE_JIT)
  297. ELSE()
  298. LIST(APPEND CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE}")
  299. CHECK_SYMBOL_EXISTS(PCRE_CONFIG_JIT "pcre.h" HAVE_PCRE_JIT)
  300. ENDIF()
  301. CHECK_SYMBOL_EXISTS(SOCK_SEQPACKET "sys/types.h;sys/socket.h" HAVE_SOCK_SEQPACKET)
  302. CHECK_SYMBOL_EXISTS(O_NOFOLLOW "sys/types.h;sys/fcntl.h" HAVE_ONOFOLLOW)
  303. CHECK_SYMBOL_EXISTS(O_CLOEXEC "sys/types.h;sys/fcntl.h" HAVE_OCLOEXEC)
  304. # OpenSSL specific stuff
  305. LIST(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSL_INCLUDE}")
  306. IF(LIBCRYPT_LIBRARY_PATH)
  307. SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-L${LIBCRYPT_LIBRARY_PATH};${LIBCRYPT_LIBRARY}")
  308. SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-L${LIBSSL_LIBRARY_PATH};${LIBSSL_LIBRARY}")
  309. ELSE()
  310. SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-lcrypt;-lssl")
  311. ENDIF()
  312. CHECK_SYMBOL_EXISTS(SSL_set_tlsext_host_name "openssl/ssl.h" HAVE_SSL_TLSEXT_HOSTNAME)
  313. CHECK_SYMBOL_EXISTS(FIPS_mode "openssl/crypto.h" HAVE_FIPS_MODE)
  314. CHECK_SYMBOL_EXISTS(dirfd "sys/types.h;unistd.h;dirent.h" HAVE_DIRFD)
  315. CHECK_SYMBOL_EXISTS(fpathconf "sys/types.h;unistd.h" HAVE_FPATHCONF)
  316. CHECK_SYMBOL_EXISTS(sigaltstack "signal.h" HAVE_SIGALTSTACK)
  317. CHECK_SYMBOL_EXISTS(open_memstream "stdio.h" HAVE_OPENMEMSTREAM)
  318. CHECK_SYMBOL_EXISTS(fmemopen "stdio.h" HAVE_FMEMOPEN)
  319. CHECK_SYMBOL_EXISTS(clock_getcpuclockid "sys/types.h;time.h" HAVE_CLOCK_GETCPUCLOCKID)
  320. CHECK_SYMBOL_EXISTS(RUSAGE_SELF "sys/types.h;sys/resource.h" HAVE_RUSAGE_SELF)
  321. IF(ENABLE_PCRE2 MATCHES "ON")
  322. IF(HAVE_PCRE_JIT)
  323. SET(HAVE_PCRE_JIT_FAST 1)
  324. ENDIF()
  325. ELSE()
  326. LIST(APPEND CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE}")
  327. IF(PCRE_LIBRARY_PATH)
  328. SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-L${PCRE_LIBRARY_PATH};${PCRE_LIBRARY}")
  329. ELSE(PCRE_LIBRARY_PATH)
  330. SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-lpcre")
  331. ENDIF(PCRE_LIBRARY_PATH)
  332. # Some PCRE implementations are lacking of pcre_jit_exec fast path
  333. SET(_PCRE_FAST_TEST "
  334. #include \"pcre.h\"
  335. int main (void)
  336. {
  337. int rc;
  338. int ovector[30];
  339. pcre *re;
  340. pcre_extra *extra;
  341. pcre_jit_stack *jit_stack;
  342. re = pcre_compile(\"abc\", 0, NULL, NULL, NULL);
  343. extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, NULL);
  344. jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024);
  345. pcre_assign_jit_stack(extra, NULL, jit_stack);
  346. rc = pcre_jit_exec(re, extra, \"abc\", 3, 0, 0, ovector, 30, jit_stack);
  347. return rc;
  348. }
  349. ")
  350. CHECK_C_SOURCE_COMPILES("${_PCRE_FAST_TEST}" HAVE_PCRE_JIT_FAST)
  351. IF(HAVE_PCRE_JIT_FAST)
  352. MESSAGE(STATUS "pcre_jit_exec is supported")
  353. ELSE(HAVE_PCRE_JIT_FAST)
  354. MESSAGE(STATUS "pcre_jit_exec is -NOT- supported")
  355. ENDIF(HAVE_PCRE_JIT_FAST)
  356. ENDIF()
  357. FILE(WRITE ${CMAKE_BINARY_DIR}/pthread_setpshared.c "
  358. #include <pthread.h>
  359. #include <stdlib.h>
  360. int main (void)
  361. {
  362. pthread_mutexattr_t mattr;
  363. if (pthread_mutexattr_init(&mattr) != 0) return 0;
  364. if (pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED) != 0) return 0;
  365. if (pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST) != 0) return 0;
  366. return 1;
  367. }
  368. ")
  369. TRY_RUN(_CAN_RUN _CAN_COMPILE
  370. "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}/pthread_setpshared.c"
  371. CMAKE_FLAGS CMAKE_C_FLAGS="-pthread")
  372. IF(_CAN_RUN EQUAL 1)
  373. SET(HAVE_PTHREAD_PROCESS_SHARED 1 CACHE INTERNAL "")
  374. ENDIF(_CAN_RUN EQUAL 1)
  375. IF(HAVE_PTHREAD_PROCESS_SHARED)
  376. MESSAGE(STATUS "pthread_mutexattr_setpshared is supported")
  377. ELSE(HAVE_PTHREAD_PROCESS_SHARED)
  378. MESSAGE(STATUS "pthread_mutexattr_setpshared is -NOT- supported")
  379. ENDIF(HAVE_PTHREAD_PROCESS_SHARED)
  380. IF(NOT HAVE_GETADDRINFO)
  381. MESSAGE(FATAL_ERROR "Your system does not support getaddrinfo call, please consider upgrading it to run rspamd")
  382. ENDIF(NOT HAVE_GETADDRINFO)
  383. IF(HAVE_SIGINFO_H)
  384. CHECK_SYMBOL_EXISTS(SA_SIGINFO "signal.h;siginfo.h" HAVE_SA_SIGINFO)
  385. ELSE(HAVE_SIGINFO_H)
  386. CHECK_SYMBOL_EXISTS(SA_SIGINFO "signal.h" HAVE_SA_SIGINFO)
  387. ENDIF(HAVE_SIGINFO_H)
  388. IF(NOT CMAKE_SYSTEM_NAME STREQUAL "SunOS")
  389. IF(HAVE_CLOCK_GETTIME)
  390. CHECK_SYMBOL_EXISTS(CLOCK_PROCESS_CPUTIME_ID time.h HAVE_CLOCK_PROCESS_CPUTIME_ID)
  391. CHECK_SYMBOL_EXISTS(CLOCK_VIRTUAL time.h HAVE_CLOCK_VIRTUAL)
  392. ELSE(HAVE_CLOCK_GETTIME)
  393. CHECK_INCLUDE_FILES(sys/timeb.h HAVE_SYS_TIMEB_H)
  394. ENDIF(HAVE_CLOCK_GETTIME)
  395. ENDIF(NOT CMAKE_SYSTEM_NAME STREQUAL "SunOS")
  396. CHECK_C_SOURCE_RUNS("
  397. #include <stdbool.h>
  398. int main(int argc, char **argv) {
  399. int a = 0, b = 0;
  400. if (__atomic_compare_exchange_n(&a, &b, 1, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED)) {
  401. return 0;
  402. }
  403. return -1;
  404. }
  405. " HAVE_ATOMIC_BUILTINS)
  406. IF(NOT HAVE_ATOMIC_BUILTINS)
  407. MESSAGE(STATUS "atomic builtins are -NOT- supported")
  408. ELSE()
  409. MESSAGE(STATUS "atomic builtins are supported")
  410. ENDIF()
  411. CHECK_C_SOURCE_RUNS("
  412. #include <x86intrin.h>
  413. int main(int argc, char **argv) {
  414. __builtin_ia32_lfence ();
  415. if (__builtin_ia32_rdtsc()) {
  416. return 0;
  417. }
  418. return -1;
  419. }
  420. " HAVE_RDTSC)
  421. IF(NOT HAVE_RDTSC)
  422. MESSAGE(STATUS "rdtsc intrinsic is -NOT- supported")
  423. ELSE()
  424. MESSAGE(STATUS "rdtsc intrinsic is supported")
  425. ENDIF()
  426. IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
  427. # In linux, we need to mount /run/shm to test which could be unavailable
  428. # on a build system. On the other hand, we know that linux has stupid
  429. # but compatible shmem support, so we assume this macro as true
  430. SET(HAVE_SANE_SHMEM 1)
  431. CHECK_C_SOURCE_COMPILES ("#define _GNU_SOURCE
  432. #include <sys/socket.h>
  433. int main (int argc, char **argv) {
  434. return ((int*)(&recvmmsg))[argc];
  435. }" HAVE_RECVMMSG)
  436. CHECK_C_SOURCE_COMPILES ("#define _GNU_SOURCE
  437. #include <fcntl.h>
  438. int main (int argc, char **argv) {
  439. return ((int*)(&readahead))[argc];
  440. }" HAVE_READAHEAD)
  441. ELSE()
  442. CHECK_C_SOURCE_RUNS("
  443. #include <sys/mman.h>
  444. #include <fcntl.h>
  445. #include <unistd.h>
  446. #define TEST_NAME \"/test-shmem-work\"
  447. int
  448. main (int argc, char **argv)
  449. {
  450. int fd;
  451. fd = shm_open (TEST_NAME, O_RDWR | O_CREAT | O_EXCL, 00600);
  452. if (fd == -1) {
  453. return -1;
  454. }
  455. if (ftruncate (fd, 100) == -1) {
  456. shm_unlink (TEST_NAME);
  457. close (fd);
  458. return -1;
  459. }
  460. if (ftruncate (fd, 200) == -1) {
  461. shm_unlink (TEST_NAME);
  462. close (fd);
  463. return -1;
  464. }
  465. if (ftruncate (fd, 300) == -1) {
  466. shm_unlink (TEST_NAME);
  467. close (fd);
  468. return -1;
  469. }
  470. close (fd);
  471. shm_unlink (TEST_NAME);
  472. return 0;
  473. }
  474. " HAVE_SANE_SHMEM)
  475. IF(NOT HAVE_SANE_SHMEM)
  476. MESSAGE(STATUS "shmem support is NOT compatible with POSIX")
  477. ELSE()
  478. MESSAGE(STATUS "shmem support is compatible with POSIX")
  479. ENDIF()
  480. ENDIF()
  481. IF(ENABLE_URL_INCLUDE MATCHES "ON")
  482. FIND_LIBRARY(LIBFETCH_LIBRARY HINTS "${RSPAMD_SEARCH_PATH}"
  483. NAMES fetch PATHS PATH_SUFFIXES lib64 lib
  484. PATHS ${RSPAMD_DEFAULT_LIBRARY_PATHS}
  485. DOC "Path where the libfetch library can be found")
  486. IF(LIBFETCH_LIBRARY)
  487. FIND_FILE(HAVE_FETCH_H HINTS "${RSPAMD_SEARCH_PATH}"
  488. NAMES fetch.h
  489. PATH_SUFFIXES include
  490. PATHS ${RSPAMD_DEFAULT_INCLUDE_PATHS}
  491. DOC "Path to libfetch header")
  492. ELSE(LIBFETCH_LIBRARY)
  493. # Try to find libcurl
  494. ProcessPackage(CURL LIBRARY curl INCLUDE curl.h INCLUDE_SUFFIXES include/curl
  495. ROOT ${CURL_ROOT})
  496. IF(NOT WITH_CURL)
  497. MESSAGE(WARNING "Neither libcurl nor libfetch were found, no support of URL includes in configuration")
  498. ENDIF(NOT WITH_CURL)
  499. ENDIF(LIBFETCH_LIBRARY)
  500. ENDIF(ENABLE_URL_INCLUDE MATCHES "ON")
  501. IF(NOT DESTDIR)
  502. SET(DESTDIR $ENV{DESTDIR})
  503. ENDIF(NOT DESTDIR)
  504. ################################ SUBDIRS SECTION ###########################
  505. ADD_SUBDIRECTORY(contrib/hiredis)
  506. SET(WITH_HIREDIS 1)
  507. INCLUDE_DIRECTORIES(BEFORE "${CMAKE_SOURCE_DIR}/contrib/hiredis")
  508. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}")
  509. IF(HAVE_FETCH_H)
  510. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES fetch)
  511. ENDIF(HAVE_FETCH_H)
  512. IF(WITH_DB)
  513. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES db)
  514. ENDIF(WITH_DB)
  515. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES "${LUA_LIBRARY}")
  516. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES ucl)
  517. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rdns)
  518. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES ottery)
  519. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES xxhash)
  520. IF(GLIB_COMPAT)
  521. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES glibadditions)
  522. ENDIF(GLIB_COMPAT)
  523. ADD_SUBDIRECTORY(contrib/xxhash)
  524. ADD_SUBDIRECTORY(contrib/cdb)
  525. ADD_SUBDIRECTORY(contrib/http-parser)
  526. ADD_SUBDIRECTORY(contrib/fpconv)
  527. ADD_SUBDIRECTORY(contrib/lc-btrie)
  528. ADD_SUBDIRECTORY(contrib/libottery)
  529. IF(SYSTEM_ZSTD MATCHES "OFF")
  530. ADD_SUBDIRECTORY(contrib/zstd)
  531. ELSE()
  532. ProcessPackage(LIBZSTD LIBRARY zstd INCLUDE zstd.h
  533. ROOT ${LIBZSTD_ROOT_DIR} MODULES zstd)
  534. ADD_DEFINITIONS(-DSYS_ZSTD)
  535. ENDIF()
  536. IF(ENABLE_SNOWBALL MATCHES "ON")
  537. ADD_SUBDIRECTORY(contrib/snowball)
  538. SET(WITH_SNOWBALL 1)
  539. ENDIF()
  540. ADD_SUBDIRECTORY(contrib/libucl)
  541. ADD_SUBDIRECTORY(contrib/librdns)
  542. ADD_SUBDIRECTORY(contrib/aho-corasick)
  543. ADD_SUBDIRECTORY(contrib/lua-lpeg)
  544. ADD_SUBDIRECTORY(contrib/t1ha)
  545. ADD_SUBDIRECTORY(contrib/libev)
  546. ADD_SUBDIRECTORY(contrib/kann)
  547. ADD_SUBDIRECTORY(contrib/fastutf8)
  548. ADD_SUBDIRECTORY(contrib/google-ced)
  549. IF(SYSTEM_FMT MATCHES "OFF")
  550. ADD_SUBDIRECTORY(contrib/fmt)
  551. INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/contrib/fmt/include")
  552. ELSE()
  553. find_package(fmt)
  554. ENDIF()
  555. IF(SYSTEM_DOCTEST MATCHES "OFF")
  556. ADD_SUBDIRECTORY(contrib/doctest)
  557. INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/contrib/doctest")
  558. ELSE()
  559. find_package(doctest)
  560. ENDIF()
  561. IF (NOT WITH_LUAJIT)
  562. ADD_SUBDIRECTORY(contrib/lua-bit)
  563. ENDIF()
  564. IF (ENABLE_LUA_REPL MATCHES "ON")
  565. ADD_SUBDIRECTORY(contrib/replxx)
  566. SET(WITH_LUA_REPL 1)
  567. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-replxx)
  568. ENDIF()
  569. IF (ENABLE_SNOWBALL MATCHES "ON")
  570. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES stemmer)
  571. ENDIF()
  572. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-hiredis)
  573. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-actrie)
  574. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-t1ha)
  575. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-ev)
  576. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-kann)
  577. LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-ced)
  578. IF(ENABLE_CLANG_PLUGIN MATCHES "ON")
  579. ADD_SUBDIRECTORY(clang-plugin)
  580. ENDIF()
  581. ADD_SUBDIRECTORY(src)
  582. ADD_SUBDIRECTORY(test)
  583. ADD_SUBDIRECTORY(utils)
  584. ############################ TARGETS SECTION ###############################
  585. CONFIGURE_FILE(config.h.in src/config.h)
  586. ##################### INSTALLATION ##########################################
  587. # Binaries
  588. # Configs
  589. INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${CONFDIR})")
  590. INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${SHAREDIR})")
  591. INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${LUALIBDIR})")
  592. INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${PLUGINSDIR})")
  593. INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${RULESDIR})")
  594. # Install configs only if they are unchanged
  595. LIST(LENGTH CONFFILES CONFLIST_COUNT)
  596. MATH(EXPR CONFLIST_MAX ${CONFLIST_COUNT}-1)
  597. FILE(GLOB_RECURSE CONF_FILES RELATIVE "${CMAKE_SOURCE_DIR}/conf" CONFIGURE_DEPENDS
  598. "${CMAKE_SOURCE_DIR}/conf/*.conf"
  599. "${CMAKE_SOURCE_DIR}/conf/*.inc" )
  600. FOREACH(CONF_FILE ${CONF_FILES})
  601. GET_FILENAME_COMPONENT(_rp ${CONF_FILE} PATH)
  602. INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${CONFDIR}/${_rp})")
  603. INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/conf/${CONF_FILE}"
  604. DESTINATION ${CONFDIR}/${_rp})
  605. ENDFOREACH(CONF_FILE)
  606. # Lua plugins
  607. FILE(GLOB LUA_PLUGINS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/src/plugins/lua" CONFIGURE_DEPENDS
  608. "${CMAKE_CURRENT_SOURCE_DIR}/src/plugins/lua/*.lua" )
  609. FOREACH(LUA_PLUGIN ${LUA_PLUGINS})
  610. GET_FILENAME_COMPONENT(_rp ${LUA_PLUGIN} PATH)
  611. INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${PLUGINSDIR}/${_rp})")
  612. INSTALL(FILES "src/plugins/lua/${LUA_PLUGIN}" DESTINATION ${PLUGINSDIR}/${_rp})
  613. ENDFOREACH(LUA_PLUGIN)
  614. # Install TLD list
  615. INSTALL(FILES "contrib/publicsuffix/effective_tld_names.dat" DESTINATION
  616. "${SHAREDIR}")
  617. # Install languages data
  618. INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${SHAREDIR}/languages)")
  619. FILE(GLOB LANGUAGES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/languages-data/*.json")
  620. FOREACH(_LANG ${LANGUAGES})
  621. INSTALL(FILES "${_LANG}" DESTINATION ${SHAREDIR}/languages)
  622. ENDFOREACH()
  623. INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/languages-data/stop_words" DESTINATION ${SHAREDIR}/languages)
  624. # Lua config
  625. FILE(GLOB_RECURSE LUA_CONFIGS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/rules" CONFIGURE_DEPENDS
  626. "${CMAKE_CURRENT_SOURCE_DIR}/rules/*.lua")
  627. FOREACH(LUA_CONF ${LUA_CONFIGS})
  628. GET_FILENAME_COMPONENT(_rp ${LUA_CONF} PATH)
  629. INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${RULESDIR}/${_rp})")
  630. INSTALL(FILES "rules/${LUA_CONF}" DESTINATION ${RULESDIR}/${_rp})
  631. ENDFOREACH(LUA_CONF)
  632. # Lua libs
  633. FILE(GLOB_RECURSE LUA_LIBS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/lualib" CONFIGURE_DEPENDS
  634. "${CMAKE_CURRENT_SOURCE_DIR}/lualib/*.lua")
  635. FOREACH(LUA_LIB ${LUA_LIBS})
  636. GET_FILENAME_COMPONENT(_rp ${LUA_LIB} PATH)
  637. INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${LUALIBDIR}/${_rp})")
  638. INSTALL(FILES "lualib/${LUA_LIB}" DESTINATION ${LUALIBDIR}/${_rp})
  639. ENDFOREACH(LUA_LIB)
  640. # Install lua fun library
  641. INSTALL(FILES "contrib/lua-fun/fun.lua" DESTINATION ${LUALIBDIR})
  642. INSTALL(FILES "contrib/lua-argparse/argparse.lua" DESTINATION ${LUALIBDIR})
  643. INSTALL(FILES "contrib/lua-tableshape/tableshape.lua" DESTINATION ${LUALIBDIR})
  644. INSTALL(FILES "contrib/lua-lupa/lupa.lua" DESTINATION ${LUALIBDIR})
  645. INSTALL(FILES "contrib/lua-lpeg/lpegre.lua" DESTINATION ${LUALIBDIR})
  646. # systemd unit
  647. IF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND WANT_SYSTEMD_UNITS MATCHES "ON")
  648. INSTALL(FILES "rspamd.service" DESTINATION ${SYSTEMDDIR})
  649. ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND WANT_SYSTEMD_UNITS MATCHES "ON")
  650. # Manual pages
  651. INSTALL(FILES "doc/rspamd.8" DESTINATION ${MANDIR}/man8)
  652. INSTALL(FILES "doc/rspamc.1" DESTINATION ${MANDIR}/man1)
  653. INSTALL(FILES "doc/rspamadm.1" DESTINATION ${MANDIR}/man1)
  654. # Utils
  655. INSTALL(PROGRAMS "utils/rspamd_stats.pl" RENAME rspamd_stats DESTINATION bin)
  656. # Install webui
  657. IF(INSTALL_WEBUI MATCHES "ON")
  658. INSTALL(DIRECTORY "interface/" DESTINATION ${WWWDIR} PATTERN ".git" EXCLUDE)
  659. ENDIF(INSTALL_WEBUI MATCHES "ON")
  660. INSTALL(DIRECTORY "contrib/elastic/" DESTINATION "${SHAREDIR}/elastic" PATTERN ".git" EXCLUDE)
  661. ADD_CUSTOM_TARGET(dist ${CMAKE_SOURCE_DIR}/dist.sh
  662. "${CMAKE_BINARY_DIR}/rspamd-${RSPAMD_VERSION}.tar.xz" "${TAR}"
  663. COMMENT "Create source distribution"
  664. WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
  665. IF(NOT DEBIAN_BUILD)
  666. ADD_CUSTOM_TARGET(check DEPENDS rspamd-test-cxx rspamd-test)
  667. ADD_CUSTOM_TARGET(run-test DEPENDS check
  668. COMMAND test/rspamd-test-cxx
  669. COMMAND sh -c 'LUA_PATH="${CMAKE_SOURCE_DIR}/lualib/?.lua\;${CMAKE_SOURCE_DIR}/lualib/?/?.lua\;${CMAKE_SOURCE_DIR}/lualib/?/init.lua\;${CMAKE_SOURCE_DIR}/contrib/lua-?/?.lua"
  670. test/rspamd-test -p /rspamd/lua')
  671. ENDIF(NOT DEBIAN_BUILD)
  672. # PVS Studio
  673. find_program(_PVS_STUDIO "pvs-studio-analyzer")
  674. if(_PVS_STUDIO)
  675. include(PVS-Studio)
  676. pvs_studio_add_target(TARGET ${PROJECT_NAME}.analyze
  677. ANALYZE ${PROJECT_NAME} rspamd-server rspamadm rspamc
  678. OUTPUT FORMAT errorfile
  679. LOG target_${PROJECT_NAME}.err)
  680. endif()