diff options
author | Vsevolod Stakhov <vsevolod@rspamd.com> | 2025-03-29 10:17:13 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rspamd.com> | 2025-03-29 10:17:13 +0000 |
commit | 39caa76911f19a472eab9fb21d19b43ca63f79ee (patch) | |
tree | 2b9067612ac71f77b3a63ffd73c35ab32acb547e | |
parent | 4c98aab6f670c659dff4c7e0cf392576f7850732 (diff) | |
download | rspamd-39caa76911f19a472eab9fb21d19b43ca63f79ee.tar.gz rspamd-39caa76911f19a472eab9fb21d19b43ca63f79ee.zip |
[Project] Modernize cmake
-rw-r--r-- | CMakeLists.txt | 803 | ||||
-rw-r--r-- | cmake/AddDependencySubdirectories.cmake | 114 | ||||
-rw-r--r-- | cmake/CheckSymbols.cmake | 146 | ||||
-rw-r--r-- | cmake/CheckSystemFeatures.cmake | 207 | ||||
-rw-r--r-- | cmake/CheckSystemHeaders.cmake | 139 | ||||
-rw-r--r-- | cmake/CheckURLInclude.cmake | 51 | ||||
-rw-r--r-- | cmake/InstallRspamdFiles.cmake | 104 | ||||
-rw-r--r-- | cmake/SetupPVSStudio.cmake | 56 | ||||
-rw-r--r-- | contrib/xxhash/CMakeLists.txt | 18 | ||||
-rw-r--r-- | src/CMakeLists.txt | 532 | ||||
-rw-r--r-- | src/rspamadm/lua_repl.c | 4 |
11 files changed, 1281 insertions, 893 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f3fa193cc..87f106425 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,107 +5,116 @@ # ############################# INITIAL SECTION ############################################# -CMAKE_MINIMUM_REQUIRED(VERSION 3.15 FATAL_ERROR) +cmake_minimum_required(VERSION 3.15 FATAL_ERROR) -SET(RSPAMD_VERSION_MAJOR 3) -SET(RSPAMD_VERSION_MINOR 11) -SET(RSPAMD_VERSION_PATCH 2) +# Define version variables +set(RSPAMD_VERSION_MAJOR 3) +set(RSPAMD_VERSION_MINOR 11) +set(RSPAMD_VERSION_PATCH 2) # Keep two digits all the time -SET(RSPAMD_VERSION_MAJOR_NUM ${RSPAMD_VERSION_MAJOR}0) -SET(RSPAMD_VERSION_MINOR_NUM ${RSPAMD_VERSION_MINOR}0) -SET(RSPAMD_VERSION_PATCH_NUM ${RSPAMD_VERSION_PATCH}0) +set(RSPAMD_VERSION_MAJOR_NUM ${RSPAMD_VERSION_MAJOR}0) +set(RSPAMD_VERSION_MINOR_NUM ${RSPAMD_VERSION_MINOR}0) +set(RSPAMD_VERSION_PATCH_NUM ${RSPAMD_VERSION_PATCH}0) -IF (GIT_ID) - SET(GIT_VERSION 1) - SET(RSPAMD_ID "${GIT_ID}") -ENDIF () +if (GIT_ID) + set(GIT_VERSION 1) + set(RSPAMD_ID "${GIT_ID}") +endif () + +set(RSPAMD_VERSION "${RSPAMD_VERSION_MAJOR}.${RSPAMD_VERSION_MINOR}.${RSPAMD_VERSION_PATCH}") -SET(RSPAMD_VERSION "${RSPAMD_VERSION_MAJOR}.${RSPAMD_VERSION_MINOR}.${RSPAMD_VERSION_PATCH}") +project(rspamd + VERSION "${RSPAMD_VERSION}" + LANGUAGES C CXX ASM + DESCRIPTION "Rapid spam filtering system" + HOMEPAGE_URL "https://rspamd.com" +) -PROJECT(rspamd VERSION "${RSPAMD_VERSION}" LANGUAGES C CXX ASM) +cmake_policy(SET CMP0075 NEW) -CMAKE_POLICY(SET CMP0075 NEW) +# Language standards +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -# This is supported merely with cmake 3.1 -SET(CMAKE_C_STANDARD 11) -SET(CMAKE_CXX_STANDARD 20) -SET(CMAKE_C_STANDARD_REQUIRED ON) -SET(CMAKE_CXX_STANDARD_REQUIRED ON) -LIST(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/") +list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/") -SET(RSPAMD_MASTER_SITE_URL "https://rspamd.com") +set(RSPAMD_MASTER_SITE_URL "https://rspamd.com") -IF (NOT RSPAMD_USER) - SET(RSPAMD_USER "nobody") - SET(RSPAMD_GROUP "nobody") -ENDIF (NOT RSPAMD_USER) +if (NOT RSPAMD_USER) + set(RSPAMD_USER "nobody") + set(RSPAMD_GROUP "nobody") +endif () # Default for SysV Init -SET(RSPAMD_WORKER_NORMAL "*:11333") -SET(RSPAMD_WORKER_CONTROLLER "*:11334") +set(RSPAMD_WORKER_NORMAL "*:11333") +set(RSPAMD_WORKER_CONTROLLER "*:11334") ############################# OPTIONS SECTION ############################################# -OPTION(ENABLE_LUAJIT "Link with libluajit [default: ON]" ON) -OPTION(ENABLE_URL_INCLUDE "Enable urls in ucl includes (requires libcurl or libfetch) [default: OFF]" OFF) -OPTION(NO_SHARED "Build internal libs static [default: ON]" ON) -OPTION(INSTALL_WEBUI "Install web interface [default: ON]" ON) -OPTION(INSTALL_EXAMPLES "Install examples of the configuration and Lua [default: ON]" ON) -OPTION(WANT_SYSTEMD_UNITS "Install systemd unit files on Linux [default: OFF]" OFF) -OPTION(ENABLE_SNOWBALL "Enable snowball stemmer [default: ON]" ON) -OPTION(ENABLE_CLANG_PLUGIN "Enable clang static analysing plugin [default: OFF]" OFF) -OPTION(ENABLE_PCRE2 "Enable pcre2 instead of pcre [default: ON]" ON) -OPTION(ENABLE_JEMALLOC "Build rspamd with jemalloc allocator [default: OFF]" OFF) -OPTION(ENABLE_UTILS "Build rspamd internal utils [default: OFF]" OFF) -OPTION(ENABLE_LIBUNWIND "Obsoleted [default: OFF]" OFF) -OPTION(ENABLE_LUA_TRACE "Trace all Lua C API invocations [default: OFF]" OFF) -OPTION(ENABLE_LUA_REPL "Enables Lua repl (requires C++11 compiler) [default: ON]" ON) -OPTION(ENABLE_FASTTEXT "Link with FastText library [default: OFF]" OFF) -OPTION(ENABLE_BACKWARD "Build rspamd with backward-cpp stacktrace [default: ON]" ON) -OPTION(SYSTEM_ZSTD "Use system zstd instead of bundled one [default: OFF]" OFF) -OPTION(SYSTEM_DOCTEST "Use system doctest instead of bundled one [default: OFF]" OFF) -OPTION(SYSTEM_XXHASH "Use system xxhash instead of bundled one [default: OFF]" OFF) +option(ENABLE_LUAJIT "Link with libluajit" ON) +option(ENABLE_URL_INCLUDE "Enable URLs in UCL includes (requires libcurl or libfetch)" OFF) +option(NO_SHARED "Build internal libs static" ON) +option(INSTALL_WEBUI "Install web interface" ON) +option(INSTALL_EXAMPLES "Install examples of the configuration and Lua" ON) +option(WANT_SYSTEMD_UNITS "Install systemd unit files on Linux" OFF) +option(ENABLE_SNOWBALL "Enable snowball stemmer" ON) +option(ENABLE_CLANG_PLUGIN "Enable clang static analysing plugin" OFF) +option(ENABLE_PCRE2 "Enable pcre2 instead of pcre" ON) +option(ENABLE_JEMALLOC "Build rspamd with jemalloc allocator" OFF) +option(ENABLE_UTILS "Build rspamd internal utils" OFF) +option(ENABLE_LIBUNWIND "Obsoleted" OFF) # Deprecated option +option(ENABLE_LUA_TRACE "Trace all Lua C API invocations" OFF) +option(ENABLE_FASTTEXT "Link with FastText library" OFF) +option(ENABLE_BACKWARD "Build rspamd with backward-cpp stacktrace" ON) +option(SYSTEM_ZSTD "Use system zstd instead of bundled one" OFF) +option(SYSTEM_DOCTEST "Use system doctest instead of bundled one" OFF) +option(SYSTEM_XXHASH "Use system xxhash instead of bundled one" OFF) ############################# INCLUDE SECTION ############################################# -INCLUDE(CheckIncludeFiles) -INCLUDE(CheckFunctionExists) -INCLUDE(CheckSymbolExists) -INCLUDE(CheckCSourceCompiles) -INCLUDE(CheckCSourceRuns) -INCLUDE(CheckLibraryExists) -INCLUDE(CheckCCompilerFlag) -INCLUDE(CMakeParseArguments) -INCLUDE(FindArch) -INCLUDE(AsmOp) -INCLUDE(FindRagel) -INCLUDE(ProcessPackage) - -IF (NOT RAGEL_FOUND) - MESSAGE(FATAL_ERROR "Ragel is required to build rspamd") -ENDIF () - -FIND_PACKAGE(PkgConfig REQUIRED) -FIND_PACKAGE(Perl REQUIRED) +include(CheckIncludeFiles) +include(CheckFunctionExists) +include(CheckSymbolExists) +include(CheckCSourceCompiles) +include(CheckCSourceRuns) +include(CheckLibraryExists) +include(CheckCCompilerFlag) +include(CMakeParseArguments) +include(FindArch) +include(AsmOp) +include(FindRagel) +include(ProcessPackage) + +if (NOT RAGEL_FOUND) + message(FATAL_ERROR "Ragel is required to build rspamd") +endif () +# Find required packages +find_package(PkgConfig REQUIRED) +find_package(Perl REQUIRED) +# Sanitizer setup option(SANITIZE "Enable sanitizer: address, memory, undefined, leak (comma separated list)" "") -INCLUDE(Toolset) -INCLUDE(Sanitizer) +include(Toolset) +include(Sanitizer) -INCLUDE(ArchDep) -INCLUDE(Paths) +include(ArchDep) +include(Paths) -IF (ENABLE_PCRE2 MATCHES "ON") - SET(WITH_PCRE2 1) +if (ENABLE_PCRE2) + set(WITH_PCRE2 1) # For utf8 API - LIST(APPEND CMAKE_REQUIRED_DEFINITIONS "-DPCRE2_CODE_UNIT_WIDTH=8") -ENDIF () -############################# CONFIG SECTION ############################################# -# Initial set + list(APPEND CMAKE_REQUIRED_DEFINITIONS "-DPCRE2_CODE_UNIT_WIDTH=8") +endif () +############################# CONFIG SECTION ############################################# +# Include directories # Prefer local include dirs to system ones -INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/" +include_directories( + "${CMAKE_SOURCE_DIR}/" "${CMAKE_SOURCE_DIR}/src" "${CMAKE_SOURCE_DIR}/src/libutil" "${CMAKE_SOURCE_DIR}/src/libserver" @@ -126,17 +135,19 @@ INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/" "${CMAKE_SOURCE_DIR}/contrib/lua-lpeg" "${CMAKE_SOURCE_DIR}/contrib/frozen/include" "${CMAKE_SOURCE_DIR}/contrib/fu2/include" - "${CMAKE_BINARY_DIR}/src" #Stored in the binary dir - "${CMAKE_BINARY_DIR}/src/libcryptobox") + "${CMAKE_BINARY_DIR}/src" # Stored in the binary dir + "${CMAKE_BINARY_DIR}/src/libcryptobox" +) -SET(TAR "tar") -INCLUDE(OSDep) +set(TAR "tar") +include(OSDep) # Now find libraries and headers -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES "m") -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES "pthread") +list(APPEND RSPAMD_REQUIRED_LIBRARIES "m") +list(APPEND RSPAMD_REQUIRED_LIBRARIES "pthread") -IF (ENABLE_LUAJIT MATCHES "ON") +# Lua setup +if (ENABLE_LUAJIT) ProcessPackage(LIBLUAJIT LIBRARY "luajit" "luajit-2.1" "luajit2.1" @@ -149,9 +160,9 @@ IF (ENABLE_LUAJIT MATCHES "ON") "include/luajit" ROOT ${LUA_ROOT} MODULES luajit) - SET(WITH_LUAJIT 1) -ELSE (ENABLE_LUAJIT MATCHES "ON") - + set(WITH_LUAJIT 1) +else () + # Try to find Lua (5.3, 5.4, 5.2, or 5.1 in that order) ProcessPackage(LIBLUA LIBRARY "lua" "lua-5.3" LIB_SUFFIXES "lua5.3" @@ -164,7 +175,7 @@ ELSE (ENABLE_LUAJIT MATCHES "ON") MODULES lua53 OPTIONAL) - IF (NOT WITH_LIBLUA) + if (NOT WITH_LIBLUA) ProcessPackage(LIBLUA LIBRARY "lua" "lua-5.4" LIB_SUFFIXES "lua5.4" @@ -176,7 +187,7 @@ ELSE (ENABLE_LUAJIT MATCHES "ON") ROOT ${LUA_ROOT} MODULES lua54 OPTIONAL) - IF (NOT WITH_LIBLUA) + if (NOT WITH_LIBLUA) ProcessPackage(LIBLUA LIBRARY "lua" "lua-5.2" LIB_SUFFIXES "lua5.2" @@ -189,7 +200,7 @@ ELSE (ENABLE_LUAJIT MATCHES "ON") MODULES lua52 OPTIONAL) - IF (NOT WITH_LIBLUA) + if (NOT WITH_LIBLUA) ProcessPackage(LIBLUA LIBRARY "lua" "lua-5.1" INCLUDE lua.h INCLUDE_SUFFIXES @@ -199,29 +210,33 @@ ELSE (ENABLE_LUAJIT MATCHES "ON") "include/lua" ROOT ${LUA_ROOT} MODULES lua51) - ENDIF () - ENDIF () - ENDIF () -ENDIF (ENABLE_LUAJIT MATCHES "ON") + endif () + endif () + endif () +endif () -IF (ENABLE_JEMALLOC MATCHES "ON" AND NOT SANITIZE) +# Memory allocator +if (ENABLE_JEMALLOC AND NOT SANITIZE) ProcessPackage(JEMALLOC LIBRARY jemalloc_pic jemalloc INCLUDE jemalloc/jemalloc.h ROOT ${JEMALLOC_ROOT_DIR}) - SET(WITH_JEMALLOC "1") -ENDIF () + set(WITH_JEMALLOC "1") +endif () +# Required libraries ProcessPackage(GLIB2 LIBRARY glib-2.0 INCLUDE glib.h INCLUDE_SUFFIXES include/glib include/glib-2.0 ROOT ${GLIB_ROOT_DIR} MODULES glib-2.0>=2.28) -IF (ENABLE_PCRE2 MATCHES "ON") +# PCRE setup +if (ENABLE_PCRE2) ProcessPackage(PCRE LIBRARY pcre2 pcre2-8 INCLUDE pcre2.h INCLUDE_SUFFIXES include/pcre2 ROOT ${PCRE_ROOT_DIR} MODULES pcre2 pcre2-8 libpcre2 libpcre2-8) -ELSE () +else () ProcessPackage(PCRE LIBRARY pcre INCLUDE pcre.h INCLUDE_SUFFIXES include/pcre ROOT ${PCRE_ROOT_DIR} MODULES pcre libpcre pcre3 libpcre3) -ENDIF () +endif () +# Other dependencies ProcessPackage(SQLITE3 LIBRARY sqlite3 INCLUDE sqlite3.h INCLUDE_SUFFIXES include/sqlite3 include/sqlite ROOT ${SQLITE3_ROOT_DIR} MODULES sqlite3 sqlite) ProcessPackage(ICUDATA LIBRARY icudata INCLUDE unicode/ucnv.h @@ -244,573 +259,89 @@ ProcessPackage(SODIUM LIBRARY sodium INCLUDE sodium.h ProcessPackage(LIBARCHIVE LIBRARY archive INCLUDE archive.h ROOT ${LIBARCHIVE_ROOT_DIR} MODULES libarchive>=3.0.0) -if (ENABLE_FASTTEXT MATCHES "ON") +if (ENABLE_FASTTEXT) ProcessPackage(FASTTEXT LIBRARY fasttext INCLUDE fasttext/fasttext.h ROOT ${FASTTEXT_ROOT_DIR} MODULES fasttext) - SET(WITH_FASTTEXT "1") + set(WITH_FASTTEXT "1") endif () +# Include common compiler and platform specific configurations include(CompilerWarnings) include(Hyperscan) include(Openblas) -IF (ENABLE_LUA_TRACE) - SET(WITH_LUA_TRACE 1) -ENDIF (ENABLE_LUA_TRACE) +# Lua tracing +if (ENABLE_LUA_TRACE) + set(WITH_LUA_TRACE 1) +endif () -SET(CMAKE_C_FLAGS "${CMAKE_C_OPT_FLAGS} ${CMAKE_C_FLAGS}") -SET(CMAKE_CXX_FLAGS "${CMAKE_C_OPT_FLAGS} ${CMAKE_CXX_FLAGS}") +# Configure compiler flags +set(CMAKE_C_FLAGS "${CMAKE_C_OPT_FLAGS} ${CMAKE_C_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_C_OPT_FLAGS} ${CMAKE_CXX_FLAGS}") -ADD_DEFINITIONS(-DHAVE_CONFIG_H) -ADD_DEFINITIONS(-DDOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS) -ADD_DEFINITIONS(-DFMT_HEADER_ONLY) +# Define macros for compilation +add_definitions(-DHAVE_CONFIG_H) +add_definitions(-DDOCTEST_CONFIG_NO_MULTI_LANE_ATOMICS) +add_definitions(-DFMT_HEADER_ONLY) # Workaround for https://github.com/onqtam/doctest/issues/356 -ADD_DEFINITIONS(-DDOCTEST_CONFIG_USE_STD_HEADERS) -ADD_DEFINITIONS(-DU_CHARSET_IS_UTF8) +add_definitions(-DDOCTEST_CONFIG_USE_STD_HEADERS) +add_definitions(-DU_CHARSET_IS_UTF8) # Disable zstd deprecation warnings, as they are not relevant for us -ADD_DEFINITIONS(-DZSTD_DISABLE_DEPRECATE_WARNINGS) +add_definitions(-DZSTD_DISABLE_DEPRECATE_WARNINGS) # Check platform specific includes -CHECK_INCLUDE_FILES(sys/types.h HAVE_SYS_TYPES_H) -CHECK_INCLUDE_FILES(sys/uio.h HAVE_SYS_UIO_H) - -CHECK_INCLUDE_FILES(fcntl.h HAVE_FCNTL_H) -CHECK_INCLUDE_FILES(math.h HAVE_MATH_H) -CHECK_INCLUDE_FILES(stdio.h HAVE_STDIO_H) -CHECK_INCLUDE_FILES(stdlib.h HAVE_STDLIB_H) -CHECK_INCLUDE_FILES(string.h HAVE_STRING_H) -CHECK_INCLUDE_FILES(strings.h HAVE_STRINGS_H) -CHECK_INCLUDE_FILES(time.h HAVE_TIME_H) -CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H) -CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H) -CHECK_INCLUDE_FILES(inttypes.h HAVE_INTTYPES_H) -CHECK_INCLUDE_FILES(stdbool.h HAVE_STDBOOL_H) -CHECK_INCLUDE_FILES(endian.h HAVE_ENDIAN_H) -CHECK_INCLUDE_FILES(sys/endian.h HAVE_SYS_ENDIAN_H) -CHECK_INCLUDE_FILES(machine/endian.h HAVE_MACHINE_ENDIAN_H) -CHECK_INCLUDE_FILES(sys/socket.h HAVE_SYS_SOCKET_H) -CHECK_INCLUDE_FILES(sys/mman.h HAVE_SYS_MMAN_H) -CHECK_INCLUDE_FILES(sys/un.h HAVE_SYS_UN_H) -CHECK_INCLUDE_FILES(sys/stat.h HAVE_SYS_STAT_H) -CHECK_INCLUDE_FILES(sys/wait.h HAVE_SYS_WAIT_H) -CHECK_INCLUDE_FILES(sys/param.h HAVE_SYS_PARAM_H) -CHECK_INCLUDE_FILES(sys/file.h HAVE_SYS_FILE_H) -CHECK_INCLUDE_FILES(sys/resource.h HAVE_SYS_RESOURCE_H) -CHECK_INCLUDE_FILES(netinet/in.h HAVE_NETINET_IN_H) -CHECK_INCLUDE_FILES(netinet/tcp.h HAVE_NETINET_TCP_H) -CHECK_INCLUDE_FILES(arpa/inet.h HAVE_ARPA_INET_H) -CHECK_INCLUDE_FILES(netdb.h HAVE_NETDB_H) -CHECK_INCLUDE_FILES(syslog.h HAVE_SYSLOG_H) -CHECK_INCLUDE_FILES(siginfo.h HAVE_SIGINFO_H) -CHECK_INCLUDE_FILES(locale.h HAVE_LOCALE_H) -CHECK_INCLUDE_FILES(libgen.h HAVE_LIBGEN_H) -CHECK_INCLUDE_FILES(pwd.h HAVE_PWD_H) -CHECK_INCLUDE_FILES(grp.h HAVE_GRP_H) -CHECK_INCLUDE_FILES(glob.h HAVE_GLOB_H) -CHECK_INCLUDE_FILES(poll.h HAVE_POLL_H) -CHECK_INCLUDE_FILES(readpassphrase.h HAVE_READPASSPHRASE_H) -CHECK_INCLUDE_FILES(termios.h HAVE_TERMIOS_H) -CHECK_INCLUDE_FILES(paths.h HAVE_PATHS_H) -CHECK_INCLUDE_FILES(ctype.h HAVE_CTYPE_H) -CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H) -CHECK_INCLUDE_FILES(cpuid.h HAVE_CPUID_H) -CHECK_INCLUDE_FILES(dirent.h HAVE_DIRENT_H) -CHECK_INCLUDE_FILES(ucontext.h HAVE_UCONTEXT_H) -CHECK_INCLUDE_FILES(sys/ucontext.h HAVE_SYS_UCONTEXT_H) # OSX specific - -# Check platform API -IF (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") - # setproctitle is broken badly in Linux, never try it - CHECK_FUNCTION_EXISTS(setproctitle HAVE_SETPROCTITLE) -ENDIF () -CHECK_FUNCTION_EXISTS(getpagesize HAVE_GETPAGESIZE) -CHECK_FUNCTION_EXISTS(nanosleep HAVE_NANOSLEEP) -CHECK_FUNCTION_EXISTS(flock HAVE_FLOCK) -CHECK_LIBRARY_EXISTS(m tanh "" HAVE_TANH) -CHECK_FUNCTION_EXISTS(mkstemp HAVE_MKSTEMP) -CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME) - -# Check macros -CHECK_SYMBOL_EXISTS(PATH_MAX limits.h HAVE_PATH_MAX) -CHECK_SYMBOL_EXISTS(MAXPATHLEN sys/param.h HAVE_MAXPATHLEN) -CHECK_SYMBOL_EXISTS(MAP_ANON sys/mman.h HAVE_MMAP_ANON) -CHECK_SYMBOL_EXISTS(IPV6_V6ONLY "sys/socket.h;netinet/in.h" HAVE_IPV6_V6ONLY) -CHECK_SYMBOL_EXISTS(posix_fallocate fcntl.h HAVE_POSIX_FALLOCATE) -CHECK_SYMBOL_EXISTS(fallocate fcntl.h HAVE_FALLOCATE) -CHECK_SYMBOL_EXISTS(_SC_NPROCESSORS_ONLN unistd.h HAVE_SC_NPROCESSORS_ONLN) -CHECK_SYMBOL_EXISTS(setbit sys/param.h PARAM_H_HAS_BITSET) -CHECK_SYMBOL_EXISTS(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO) -CHECK_SYMBOL_EXISTS(sched_yield "sched.h" HAVE_SCHED_YIELD) -CHECK_SYMBOL_EXISTS(nftw "sys/types.h;ftw.h" HAVE_NFTW) -CHECK_SYMBOL_EXISTS(memrchr "string.h" HAVE_MEMRCHR) -IF (ENABLE_PCRE2 MATCHES "ON") - LIST(APPEND CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE}") - CHECK_SYMBOL_EXISTS(PCRE2_CONFIG_JIT "pcre2.h" HAVE_PCRE_JIT) -ELSE () - LIST(APPEND CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE}") - CHECK_SYMBOL_EXISTS(PCRE_CONFIG_JIT "pcre.h" HAVE_PCRE_JIT) -ENDIF () -CHECK_SYMBOL_EXISTS(SOCK_SEQPACKET "sys/types.h;sys/socket.h" HAVE_SOCK_SEQPACKET) -CHECK_SYMBOL_EXISTS(O_NOFOLLOW "sys/types.h;sys/fcntl.h" HAVE_ONOFOLLOW) -CHECK_SYMBOL_EXISTS(O_CLOEXEC "sys/types.h;sys/fcntl.h" HAVE_OCLOEXEC) - -# OpenSSL specific stuff -LIST(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSL_INCLUDE}") -IF (LIBCRYPT_LIBRARY_PATH) - SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-L${LIBCRYPT_LIBRARY_PATH};${LIBCRYPT_LIBRARY}") - SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-L${LIBSSL_LIBRARY_PATH};${LIBSSL_LIBRARY}") -ELSE () - SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-lcrypt;-lssl") -ENDIF () - -CHECK_SYMBOL_EXISTS(SSL_set_tlsext_host_name "openssl/ssl.h" HAVE_SSL_TLSEXT_HOSTNAME) -CHECK_SYMBOL_EXISTS(FIPS_mode "openssl/crypto.h" HAVE_FIPS_MODE) - -CHECK_SYMBOL_EXISTS(dirfd "sys/types.h;unistd.h;dirent.h" HAVE_DIRFD) -CHECK_SYMBOL_EXISTS(fpathconf "sys/types.h;unistd.h" HAVE_FPATHCONF) -CHECK_SYMBOL_EXISTS(sigaltstack "signal.h" HAVE_SIGALTSTACK) -CHECK_SYMBOL_EXISTS(open_memstream "stdio.h" HAVE_OPENMEMSTREAM) -CHECK_SYMBOL_EXISTS(fmemopen "stdio.h" HAVE_FMEMOPEN) -CHECK_SYMBOL_EXISTS(clock_getcpuclockid "sys/types.h;time.h" HAVE_CLOCK_GETCPUCLOCKID) -CHECK_SYMBOL_EXISTS(RUSAGE_SELF "sys/types.h;sys/resource.h" HAVE_RUSAGE_SELF) -CHECK_SYMBOL_EXISTS(ffsll "strings.h" HAVE_FFSLL) - -IF (ENABLE_PCRE2 MATCHES "ON") - IF (HAVE_PCRE_JIT) - SET(HAVE_PCRE_JIT_FAST 1) - ENDIF () -ELSE () - LIST(APPEND CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE}") - IF (PCRE_LIBRARY_PATH) - SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-L${PCRE_LIBRARY_PATH};${PCRE_LIBRARY}") - ELSE (PCRE_LIBRARY_PATH) - SET(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-lpcre") - ENDIF (PCRE_LIBRARY_PATH) - # Some PCRE implementations are lacking of pcre_jit_exec fast path - SET(_PCRE_FAST_TEST " -#include \"pcre.h\" -int main (void) -{ - int rc; - int ovector[30]; - pcre *re; - pcre_extra *extra; - pcre_jit_stack *jit_stack; - - re = pcre_compile(\"abc\", 0, NULL, NULL, NULL); - extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, NULL); - jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024); - pcre_assign_jit_stack(extra, NULL, jit_stack); - rc = pcre_jit_exec(re, extra, \"abc\", 3, 0, 0, ovector, 30, jit_stack); - - return rc; -} -") - CHECK_C_SOURCE_COMPILES("${_PCRE_FAST_TEST}" HAVE_PCRE_JIT_FAST) - IF (HAVE_PCRE_JIT_FAST) - MESSAGE(STATUS "pcre_jit_exec is supported") - ELSE (HAVE_PCRE_JIT_FAST) - MESSAGE(STATUS "pcre_jit_exec is -NOT- supported") - ENDIF (HAVE_PCRE_JIT_FAST) -ENDIF () - -CHECK_C_COMPILER_FLAG(-fPIC SUPPORT_FPIC) -IF (SUPPORT_FPIC) - ADD_COMPILE_OPTIONS("-fPIC") -ENDIF (SUPPORT_FPIC) - -FILE(WRITE ${CMAKE_BINARY_DIR}/pthread_setpshared.c " -#include <pthread.h> -#include <stdlib.h> -int main (void) -{ - pthread_mutexattr_t mattr; - if (pthread_mutexattr_init(&mattr) != 0) return 0; - if (pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED) != 0) return 0; - if (pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST) != 0) return 0; - return 1; -} -") -TRY_RUN(_CAN_RUN _CAN_COMPILE - "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}/pthread_setpshared.c" - CMAKE_FLAGS CMAKE_C_FLAGS="-pthread") -IF (_CAN_RUN EQUAL 1) - SET(HAVE_PTHREAD_PROCESS_SHARED 1 CACHE INTERNAL "") -ENDIF (_CAN_RUN EQUAL 1) -IF (HAVE_PTHREAD_PROCESS_SHARED) - MESSAGE(STATUS "pthread_mutexattr_setpshared is supported") -ELSE (HAVE_PTHREAD_PROCESS_SHARED) - MESSAGE(STATUS "pthread_mutexattr_setpshared is -NOT- supported") -ENDIF (HAVE_PTHREAD_PROCESS_SHARED) - -IF (NOT HAVE_GETADDRINFO) - MESSAGE(FATAL_ERROR "Your system does not support getaddrinfo call, please consider upgrading it to run rspamd") -ENDIF (NOT HAVE_GETADDRINFO) -IF (HAVE_SIGINFO_H) - CHECK_SYMBOL_EXISTS(SA_SIGINFO "signal.h;siginfo.h" HAVE_SA_SIGINFO) -ELSE (HAVE_SIGINFO_H) - CHECK_SYMBOL_EXISTS(SA_SIGINFO "signal.h" HAVE_SA_SIGINFO) -ENDIF (HAVE_SIGINFO_H) - -IF (NOT CMAKE_SYSTEM_NAME STREQUAL "SunOS") - IF (HAVE_CLOCK_GETTIME) - CHECK_SYMBOL_EXISTS(CLOCK_PROCESS_CPUTIME_ID time.h HAVE_CLOCK_PROCESS_CPUTIME_ID) - CHECK_SYMBOL_EXISTS(CLOCK_VIRTUAL time.h HAVE_CLOCK_VIRTUAL) - ELSE (HAVE_CLOCK_GETTIME) - CHECK_INCLUDE_FILES(sys/timeb.h HAVE_SYS_TIMEB_H) - ENDIF (HAVE_CLOCK_GETTIME) -ENDIF (NOT CMAKE_SYSTEM_NAME STREQUAL "SunOS") - -CHECK_C_SOURCE_RUNS(" -#include <stdbool.h> -int main(int argc, char **argv) { - int a = 0, b = 0; - if (__atomic_compare_exchange_n(&a, &b, 1, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED)) { - return 0; - } - return -1; -} -" HAVE_ATOMIC_BUILTINS) - -CHECK_C_SOURCE_RUNS("#include <stdio.h> -int main() { - __builtin_cpu_init(); - printf(\"%d\", __builtin_cpu_supports(\"avx\")); - return 0; -}" HAVE_BUILTIN_CPU_SUPPORTS) - -IF (NOT HAVE_ATOMIC_BUILTINS) - MESSAGE(STATUS "atomic builtins are -NOT- supported") -ELSE () - MESSAGE(STATUS "atomic builtins are supported") -ENDIF () - -CHECK_LIBRARY_EXISTS(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC) -IF (HAVE_LIBATOMIC) - list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") -endif () +include(CheckSystemHeaders) +# Check macros, functions, and features +include(CheckSystemFeatures) -CHECK_C_SOURCE_RUNS(" -#include <x86intrin.h> -int main(int argc, char **argv) { - __builtin_ia32_lfence (); - if (__builtin_ia32_rdtsc()) { - return 0; - } - return -1; -} -" HAVE_RDTSC) - -IF (NOT HAVE_RDTSC) - MESSAGE(STATUS "rdtsc intrinsic is -NOT- supported") -ELSE () - MESSAGE(STATUS "rdtsc intrinsic is supported") -ENDIF () - -IF (CMAKE_SYSTEM_NAME STREQUAL "Linux") - # In linux, we need to mount /run/shm to test which could be unavailable - # on a build system. On the other hand, we know that linux has stupid - # but compatible shmem support, so we assume this macro as true - SET(HAVE_SANE_SHMEM 1) - CHECK_C_SOURCE_COMPILES("#define _GNU_SOURCE - #include <sys/socket.h> - int main (int argc, char **argv) { - return ((int*)(&recvmmsg))[argc]; - }" HAVE_RECVMMSG) - CHECK_C_SOURCE_COMPILES("#define _GNU_SOURCE - #include <fcntl.h> - int main (int argc, char **argv) { - return ((int*)(&readahead))[argc]; - }" HAVE_READAHEAD) -ELSE () - CHECK_C_SOURCE_RUNS(" - #include <sys/mman.h> - #include <fcntl.h> - #include <unistd.h> - #define TEST_NAME \"/test-shmem-work\" - int - main (int argc, char **argv) - { - int fd; - - fd = shm_open (TEST_NAME, O_RDWR | O_CREAT | O_EXCL, 00600); - if (fd == -1) { - return -1; - } - if (ftruncate (fd, 100) == -1) { - shm_unlink (TEST_NAME); - close (fd); - return -1; - } - - if (ftruncate (fd, 200) == -1) { - shm_unlink (TEST_NAME); - close (fd); - return -1; - } - if (ftruncate (fd, 300) == -1) { - shm_unlink (TEST_NAME); - close (fd); - return -1; - } - - close (fd); - shm_unlink (TEST_NAME); - return 0; - } - " HAVE_SANE_SHMEM) - IF (NOT HAVE_SANE_SHMEM) - MESSAGE(STATUS "shmem support is NOT compatible with POSIX") - ELSE () - MESSAGE(STATUS "shmem support is compatible with POSIX") - ENDIF () -ENDIF () - -IF (ENABLE_URL_INCLUDE MATCHES "ON") - FIND_LIBRARY(LIBFETCH_LIBRARY HINTS "${RSPAMD_SEARCH_PATH}" - NAMES fetch PATHS PATH_SUFFIXES lib64 lib - PATHS ${RSPAMD_DEFAULT_LIBRARY_PATHS} - DOC "Path where the libfetch library can be found") - IF (LIBFETCH_LIBRARY) - FIND_FILE(HAVE_FETCH_H HINTS "${RSPAMD_SEARCH_PATH}" - NAMES fetch.h - PATH_SUFFIXES include - PATHS ${RSPAMD_DEFAULT_INCLUDE_PATHS} - DOC "Path to libfetch header") - ELSE (LIBFETCH_LIBRARY) - # Try to find libcurl - ProcessPackage(CURL LIBRARY curl INCLUDE curl.h INCLUDE_SUFFIXES include/curl - ROOT ${CURL_ROOT}) - IF (NOT WITH_CURL) - MESSAGE(WARNING "Neither libcurl nor libfetch were found, no support of URL includes in configuration") - ENDIF (NOT WITH_CURL) - ENDIF (LIBFETCH_LIBRARY) -ENDIF (ENABLE_URL_INCLUDE MATCHES "ON") - -IF (NOT DESTDIR) - SET(DESTDIR $ENV{DESTDIR}) -ENDIF (NOT DESTDIR) +# Check symbols and functions +include(CheckSymbols) +# Configure PIC support +check_c_compiler_flag(-fPIC SUPPORT_FPIC) +if (SUPPORT_FPIC) + add_compile_options("-fPIC") +endif () + +# Support for URL includes +include(CheckURLInclude) +if (ENABLE_URL_INCLUDE) + CheckURLIncludeSupport() +endif () + +# Ensure DESTDIR is set +if (NOT DESTDIR) + set(DESTDIR $ENV{DESTDIR}) +endif () ################################ SUBDIRS SECTION ########################### -ADD_SUBDIRECTORY(contrib/hiredis) -INCLUDE_DIRECTORIES(BEFORE "${CMAKE_SOURCE_DIR}/contrib/hiredis") - -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") -IF (HAVE_FETCH_H) - LIST(APPEND RSPAMD_REQUIRED_LIBRARIES fetch) -ENDIF (HAVE_FETCH_H) - -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES "${LUA_LIBRARY}") -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES ucl) -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rdns) -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES ottery) -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES xxhash) - -IF (SYSTEM_XXHASH MATCHES "OFF") - ADD_SUBDIRECTORY(contrib/xxhash) - INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/contrib/xxhash") -ELSE () - ProcessPackage(XXHASH LIBRARY xxhash INCLUDE xxhash.h - ROOT ${LIBXXHASH_ROOT_DIR} MODULES xxhash libxxhash) -ENDIF () -ADD_SUBDIRECTORY(contrib/cdb) -ADD_SUBDIRECTORY(contrib/http-parser) -ADD_SUBDIRECTORY(contrib/fpconv) -ADD_SUBDIRECTORY(contrib/lc-btrie) -ADD_SUBDIRECTORY(contrib/libottery) -ADD_SUBDIRECTORY(contrib/simdutf) -INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/contrib/simdutf/include") -IF (SYSTEM_ZSTD MATCHES "OFF") - ADD_SUBDIRECTORY(contrib/zstd) -ELSE () - ProcessPackage(LIBZSTD LIBRARY zstd INCLUDE zstd.h - ROOT ${LIBZSTD_ROOT_DIR} MODULES zstd libzstd) - ADD_DEFINITIONS(-DSYS_ZSTD) -ENDIF () -IF (ENABLE_SNOWBALL MATCHES "ON") - ADD_SUBDIRECTORY(contrib/snowball) - SET(WITH_SNOWBALL 1) -ENDIF () -ADD_SUBDIRECTORY(contrib/libucl) -ADD_SUBDIRECTORY(contrib/librdns) -ADD_SUBDIRECTORY(contrib/aho-corasick) -ADD_SUBDIRECTORY(contrib/lua-lpeg) -ADD_SUBDIRECTORY(contrib/t1ha) -ADD_SUBDIRECTORY(contrib/libev) -ADD_SUBDIRECTORY(contrib/kann) -ADD_SUBDIRECTORY(contrib/google-ced) -IF (ENABLE_BACKWARD MATCHES "ON") - ADD_SUBDIRECTORY(contrib/backward-cpp) - message(STATUS "Backward-cpp config: ${BACKWARD_DEFINITIONS}") -ELSE () - set(BACKWARD_ENABLE) - macro(add_backward target) - # do nothing - endmacro() -ENDIF () -IF (BACKWARD_LIBRARIES) - message(STATUS "Backward-cpp libraries: ${BACKWARD_LIBRARIES}") -ENDIF () - -IF (SYSTEM_DOCTEST MATCHES "OFF") - ADD_SUBDIRECTORY(contrib/doctest) - INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/contrib/doctest") -ELSE () - find_package(doctest) -ENDIF () - -IF (NOT WITH_LUAJIT) - ADD_SUBDIRECTORY(contrib/lua-bit) -ENDIF () - -IF (ENABLE_LUA_REPL MATCHES "ON") - ADD_SUBDIRECTORY(contrib/replxx) - SET(WITH_LUA_REPL 1) - LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-replxx) -ENDIF () - -IF (ENABLE_SNOWBALL MATCHES "ON") - LIST(APPEND RSPAMD_REQUIRED_LIBRARIES stemmer) -ENDIF () -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-hiredis) - -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-actrie) -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-t1ha) -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-ev) -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-kann) -LIST(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-ced) - -IF (ENABLE_CLANG_PLUGIN MATCHES "ON") - ADD_SUBDIRECTORY(clang-plugin) -ENDIF () - -ADD_SUBDIRECTORY(src) -enable_testing() -ADD_SUBDIRECTORY(test) -ADD_SUBDIRECTORY(utils) +# Add required subdirectories for dependencies +include(AddDependencySubdirectories) +AddDependencySubdirectories() ############################ TARGETS SECTION ############################### -CONFIGURE_FILE(config.h.in src/config.h) +# Generate config.h +configure_file(config.h.in src/config.h) ##################### INSTALLATION ########################################## +# Setup installation targets +include(InstallRspamdFiles) +InstallRspamdFiles() -# Binaries - -# Configs -INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${CONFDIR})") -INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${SHAREDIR})") -INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${LUALIBDIR})") -INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${PLUGINSDIR})") -INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${RULESDIR})") - -# Install configs only if they are unchanged -LIST(LENGTH CONFFILES CONFLIST_COUNT) -MATH(EXPR CONFLIST_MAX ${CONFLIST_COUNT}-1) - -SET(GLOB_PATTERNS "${CMAKE_SOURCE_DIR}/conf/*.conf;${CMAKE_SOURCE_DIR}/conf/*.inc") -IF (INSTALL_EXAMPLES MATCHES "ON") - LIST(APPEND GLOB_PATTERNS "${CMAKE_SOURCE_DIR}/conf/*.lua.example") - LIST(APPEND GLOB_PATTERNS "${CMAKE_SOURCE_DIR}/conf/*.conf.example") -ENDIF () - -FILE(GLOB_RECURSE CONF_FILES RELATIVE "${CMAKE_SOURCE_DIR}/conf" CONFIGURE_DEPENDS - ${GLOB_PATTERNS}) -FOREACH (CONF_FILE ${CONF_FILES}) - GET_FILENAME_COMPONENT(_rp ${CONF_FILE} PATH) - INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${CONFDIR}/${_rp})") - INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/conf/${CONF_FILE}" - DESTINATION ${CONFDIR}/${_rp}) -ENDFOREACH (CONF_FILE) - -# Lua plugins - -FILE(GLOB LUA_PLUGINS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/src/plugins/lua" CONFIGURE_DEPENDS - "${CMAKE_CURRENT_SOURCE_DIR}/src/plugins/lua/*.lua") -FOREACH (LUA_PLUGIN ${LUA_PLUGINS}) - GET_FILENAME_COMPONENT(_rp ${LUA_PLUGIN} PATH) - INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${PLUGINSDIR}/${_rp})") - INSTALL(FILES "src/plugins/lua/${LUA_PLUGIN}" DESTINATION ${PLUGINSDIR}/${_rp}) -ENDFOREACH (LUA_PLUGIN) - - -# Install TLD list -INSTALL(FILES "contrib/publicsuffix/effective_tld_names.dat" DESTINATION - "${SHAREDIR}") - -# Install languages data -INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${SHAREDIR}/languages)") -FILE(GLOB LANGUAGES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/languages-data/*.json") -FOREACH (_LANG ${LANGUAGES}) - INSTALL(FILES "${_LANG}" DESTINATION ${SHAREDIR}/languages) -ENDFOREACH () -INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/languages-data/stop_words" DESTINATION ${SHAREDIR}/languages) - -# Lua config -FILE(GLOB_RECURSE LUA_CONFIGS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/rules" CONFIGURE_DEPENDS - "${CMAKE_CURRENT_SOURCE_DIR}/rules/*.lua") -FOREACH (LUA_CONF ${LUA_CONFIGS}) - GET_FILENAME_COMPONENT(_rp ${LUA_CONF} PATH) - INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${RULESDIR}/${_rp})") - INSTALL(FILES "rules/${LUA_CONF}" DESTINATION ${RULESDIR}/${_rp}) -ENDFOREACH (LUA_CONF) - -# Lua libs -FILE(GLOB_RECURSE LUA_LIBS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/lualib" CONFIGURE_DEPENDS - "${CMAKE_CURRENT_SOURCE_DIR}/lualib/*.lua") -FOREACH (LUA_LIB ${LUA_LIBS}) - GET_FILENAME_COMPONENT(_rp ${LUA_LIB} PATH) - INSTALL(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${LUALIBDIR}/${_rp})") - INSTALL(FILES "lualib/${LUA_LIB}" DESTINATION ${LUALIBDIR}/${_rp}) -ENDFOREACH (LUA_LIB) - -# Install lua fun library -INSTALL(FILES "contrib/lua-fun/fun.lua" DESTINATION ${LUALIBDIR}) -INSTALL(FILES "contrib/lua-argparse/argparse.lua" DESTINATION ${LUALIBDIR}) -INSTALL(FILES "contrib/lua-tableshape/tableshape.lua" DESTINATION ${LUALIBDIR}) -INSTALL(FILES "contrib/lua-lupa/lupa.lua" DESTINATION ${LUALIBDIR}) -INSTALL(FILES "contrib/lua-lpeg/lpegre.lua" DESTINATION ${LUALIBDIR}) - -# systemd unit -IF (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND WANT_SYSTEMD_UNITS MATCHES "ON") - INSTALL(FILES "rspamd.service" DESTINATION ${SYSTEMDDIR}) -ENDIF (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND WANT_SYSTEMD_UNITS MATCHES "ON") - -# Manual pages -INSTALL(FILES "doc/rspamd.8" DESTINATION ${MANDIR}/man8) -INSTALL(FILES "doc/rspamc.1" DESTINATION ${MANDIR}/man1) -INSTALL(FILES "doc/rspamadm.1" DESTINATION ${MANDIR}/man1) - -# Utils -INSTALL(PROGRAMS "utils/rspamd_stats.pl" RENAME rspamd_stats DESTINATION bin) - -# Install webui -IF (INSTALL_WEBUI MATCHES "ON") - INSTALL(DIRECTORY "interface/" DESTINATION ${WWWDIR} PATTERN ".git" EXCLUDE) -ENDIF (INSTALL_WEBUI MATCHES "ON") - - -ADD_CUSTOM_TARGET(dist ${CMAKE_SOURCE_DIR}/dist.sh +# Build distribution and testing targets +add_custom_target(dist ${CMAKE_SOURCE_DIR}/dist.sh "${CMAKE_BINARY_DIR}/rspamd-${RSPAMD_VERSION}.tar.xz" "${TAR}" COMMENT "Create source distribution" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) -ADD_CUSTOM_TARGET(check DEPENDS rspamd-test-cxx rspamd-test) -ADD_CUSTOM_TARGET(run-test DEPENDS check +add_custom_target(check DEPENDS rspamd-test-cxx rspamd-test) +add_custom_target(run-test DEPENDS check COMMAND test/rspamd-test-cxx 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" test/rspamd-test -p /rspamd/lua') - -# PVS Studio -find_program(_PVS_STUDIO "pvs-studio-analyzer") - -if (_PVS_STUDIO) - include(PVS-Studio) - pvs_studio_add_target(TARGET ${PROJECT_NAME}.analyze - ANALYZE ${PROJECT_NAME} rspamd-server rspamadm rspamc - OUTPUT FORMAT errorfile - LOG target_${PROJECT_NAME}.err) -endif () +# Setup PVS Studio if available +include(SetupPVSStudio) +SetupPVSStudio() diff --git a/cmake/AddDependencySubdirectories.cmake b/cmake/AddDependencySubdirectories.cmake new file mode 100644 index 000000000..9c252187c --- /dev/null +++ b/cmake/AddDependencySubdirectories.cmake @@ -0,0 +1,114 @@ +function(AddDependencySubdirectories) + # Core dependencies + add_subdirectory(contrib/hiredis) + include_directories(BEFORE "${CMAKE_SOURCE_DIR}/contrib/hiredis") + + # Configure xxhash + if (SYSTEM_XXHASH MATCHES "OFF") + add_subdirectory(contrib/xxhash) + include_directories("${CMAKE_SOURCE_DIR}/contrib/xxhash") + else () + ProcessPackage(XXHASH LIBRARY xxhash INCLUDE xxhash.h + ROOT ${LIBXXHASH_ROOT_DIR} MODULES xxhash libxxhash) + endif () + + # Add essential dependencies + add_subdirectory(contrib/cdb) + add_subdirectory(contrib/http-parser) + add_subdirectory(contrib/fpconv) + add_subdirectory(contrib/lc-btrie) + add_subdirectory(contrib/libottery) + add_subdirectory(contrib/simdutf) + include_directories("${CMAKE_SOURCE_DIR}/contrib/simdutf/include") + + # Configure zstd + if (SYSTEM_ZSTD MATCHES "OFF") + add_subdirectory(contrib/zstd) + else () + ProcessPackage(LIBZSTD LIBRARY zstd INCLUDE zstd.h + ROOT ${LIBZSTD_ROOT_DIR} MODULES zstd libzstd) + add_definitions(-DSYS_ZSTD) + endif () + + # Optional dependencies based on configuration + if (ENABLE_SNOWBALL) + add_subdirectory(contrib/snowball) + set(WITH_SNOWBALL 1 PARENT_SCOPE) + endif () + + # Core libraries + add_subdirectory(contrib/libucl) + add_subdirectory(contrib/librdns) + add_subdirectory(contrib/aho-corasick) + add_subdirectory(contrib/lua-lpeg) + add_subdirectory(contrib/t1ha) + add_subdirectory(contrib/libev) + add_subdirectory(contrib/kann) + add_subdirectory(contrib/google-ced) + + # Backward-cpp for stacktraces + if (ENABLE_BACKWARD) + add_subdirectory(contrib/backward-cpp) + message(STATUS "Backward-cpp config: ${BACKWARD_DEFINITIONS}") + else () + set(BACKWARD_ENABLE) + macro(add_backward target) + # do nothing + endmacro() + endif () + + if (BACKWARD_LIBRARIES) + message(STATUS "Backward-cpp libraries: ${BACKWARD_LIBRARIES}") + endif () + + # Doctest for testing + if (SYSTEM_DOCTEST MATCHES "OFF") + add_subdirectory(contrib/doctest) + include_directories("${CMAKE_SOURCE_DIR}/contrib/doctest") + else () + find_package(doctest) + endif () + + # Lua-specific dependencies + if (NOT WITH_LUAJIT) + add_subdirectory(contrib/lua-bit) + endif () + + # Lua REPL support + add_subdirectory(contrib/replxx) + set(WITH_LUA_REPL 1 PARENT_SCOPE) + list(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-replxx) + + # Update the required libraries list based on dependencies + if (ENABLE_SNOWBALL) + list(APPEND RSPAMD_REQUIRED_LIBRARIES stemmer) + endif () + + # Add core required libraries + list(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-hiredis) + list(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-actrie) + list(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-t1ha) + list(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-ev) + list(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-kann) + list(APPEND RSPAMD_REQUIRED_LIBRARIES rspamd-ced) + + # Clang plugin (optional) + if (ENABLE_CLANG_PLUGIN) + add_subdirectory(clang-plugin) + endif () + + # Main source code + add_subdirectory(src) + + # Enable testing + enable_testing() + add_subdirectory(test) + + # Utilities + add_subdirectory(utils) + + # Propagate variables to parent scope + set(RSPAMD_REQUIRED_LIBRARIES ${RSPAMD_REQUIRED_LIBRARIES} PARENT_SCOPE) + set(WITH_SNOWBALL ${WITH_SNOWBALL} PARENT_SCOPE) + set(WITH_LUA_REPL ${WITH_LUA_REPL} PARENT_SCOPE) +endfunction() diff --git a/cmake/CheckSymbols.cmake b/cmake/CheckSymbols.cmake new file mode 100644 index 000000000..10207dd5b --- /dev/null +++ b/cmake/CheckSymbols.cmake @@ -0,0 +1,146 @@ +# Function to check for atomic builtins, CPU features, and other specialized symbols +function(CheckSymbols) + # Check for atomic builtins + check_c_source_runs(" + #include <stdbool.h> + int main(int argc, char **argv) { + int a = 0, b = 0; + if (__atomic_compare_exchange_n(&a, &b, 1, false, __ATOMIC_RELEASE, __ATOMIC_RELAXED)) { + return 0; + } + return -1; + } + " HAVE_ATOMIC_BUILTINS) + + if (NOT HAVE_ATOMIC_BUILTINS) + message(STATUS "atomic builtins are -NOT- supported") + else () + message(STATUS "atomic builtins are supported") + endif () + + # Check for libatomic + check_library_exists(atomic __atomic_fetch_add_4 "" HAVE_LIBATOMIC) + if (HAVE_LIBATOMIC) + list(APPEND CMAKE_REQUIRED_LIBRARIES "atomic") + list(APPEND RSPAMD_REQUIRED_LIBRARIES "atomic") + set(RSPAMD_REQUIRED_LIBRARIES "${RSPAMD_REQUIRED_LIBRARIES}" PARENT_SCOPE) + endif () + + # Check for CPU feature intrinsics + check_c_source_runs(" + #include <stdio.h> + int main() { + __builtin_cpu_init(); + printf(\"%d\", __builtin_cpu_supports(\"avx\")); + return 0; + }" HAVE_BUILTIN_CPU_SUPPORTS) + + if (HAVE_BUILTIN_CPU_SUPPORTS) + message(STATUS "CPU feature detection via __builtin_cpu_supports is supported") + else () + message(STATUS "CPU feature detection via __builtin_cpu_supports is NOT supported") + endif () + + # Check for RDTSC + check_c_source_runs(" + #include <x86intrin.h> + int main(int argc, char **argv) { + __builtin_ia32_lfence(); + if (__builtin_ia32_rdtsc()) { + return 0; + } + return -1; + } + " HAVE_RDTSC) + + if (NOT HAVE_RDTSC) + message(STATUS "rdtsc intrinsic is -NOT- supported") + else () + message(STATUS "rdtsc intrinsic is supported") + endif () + + # Check for POSIX shared memory support + if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") + # For non-Linux systems, test shmem capability + check_c_source_runs(" + #include <sys/mman.h> + #include <fcntl.h> + #include <unistd.h> + #define TEST_NAME \"/test-shmem-work\" + int + main(int argc, char **argv) + { + int fd; + + fd = shm_open(TEST_NAME, O_RDWR | O_CREAT | O_EXCL, 00600); + if (fd == -1) { + return -1; + } + if (ftruncate(fd, 100) == -1) { + shm_unlink(TEST_NAME); + close(fd); + return -1; + } + + if (ftruncate(fd, 200) == -1) { + shm_unlink(TEST_NAME); + close(fd); + return -1; + } + if (ftruncate(fd, 300) == -1) { + shm_unlink(TEST_NAME); + close(fd); + return -1; + } + + close(fd); + shm_unlink(TEST_NAME); + return 0; + } + " HAVE_SANE_SHMEM) + + if (NOT HAVE_SANE_SHMEM) + message(STATUS "shmem support is NOT compatible with POSIX") + else () + message(STATUS "shmem support is compatible with POSIX") + endif () + endif () + + # Check for pthread shared mutexes and robust mutexes + file(WRITE ${CMAKE_BINARY_DIR}/pthread_setpshared.c " + #include <pthread.h> + #include <stdlib.h> + int main(void) + { + pthread_mutexattr_t mattr; + if (pthread_mutexattr_init(&mattr) != 0) return 0; + if (pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED) != 0) return 0; + if (pthread_mutexattr_setrobust(&mattr, PTHREAD_MUTEX_ROBUST) != 0) return 0; + return 1; + } + ") + + try_run(_CAN_RUN _CAN_COMPILE + "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}/pthread_setpshared.c" + CMAKE_FLAGS CMAKE_C_FLAGS="-pthread") + + if (_CAN_RUN EQUAL 1) + set(HAVE_PTHREAD_PROCESS_SHARED 1 CACHE INTERNAL "") + endif () + + if (HAVE_PTHREAD_PROCESS_SHARED) + message(STATUS "pthread_mutexattr_setpshared is supported") + else () + message(STATUS "pthread_mutexattr_setpshared is -NOT- supported") + endif () + + # Propagate variables to parent scope + set(HAVE_ATOMIC_BUILTINS ${HAVE_ATOMIC_BUILTINS} PARENT_SCOPE) + set(HAVE_LIBATOMIC ${HAVE_LIBATOMIC} PARENT_SCOPE) + set(HAVE_BUILTIN_CPU_SUPPORTS ${HAVE_BUILTIN_CPU_SUPPORTS} PARENT_SCOPE) + set(HAVE_RDTSC ${HAVE_RDTSC} PARENT_SCOPE) + set(HAVE_SANE_SHMEM ${HAVE_SANE_SHMEM} PARENT_SCOPE) + set(HAVE_PTHREAD_PROCESS_SHARED ${HAVE_PTHREAD_PROCESS_SHARED} PARENT_SCOPE) +endfunction() + +CheckSymbols()
\ No newline at end of file diff --git a/cmake/CheckSystemFeatures.cmake b/cmake/CheckSystemFeatures.cmake new file mode 100644 index 000000000..0a15749fd --- /dev/null +++ b/cmake/CheckSystemFeatures.cmake @@ -0,0 +1,207 @@ +# CheckSystemFeatures.cmake +# Checks for various system features, functions, and functionality + +# Check platform API and features +function(CheckSystemFeatures) + # Process-related functions + if (NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") + # setproctitle is broken badly in Linux, never try it + check_function_exists(setproctitle HAVE_SETPROCTITLE) + endif () + + # Memory and file management + check_function_exists(getpagesize HAVE_GETPAGESIZE) + check_function_exists(nanosleep HAVE_NANOSLEEP) + check_function_exists(flock HAVE_FLOCK) + check_library_exists(m tanh "" HAVE_TANH) + check_function_exists(mkstemp HAVE_MKSTEMP) + check_function_exists(clock_gettime HAVE_CLOCK_GETTIME) + + # Check macros and constants + check_symbol_exists(PATH_MAX limits.h HAVE_PATH_MAX) + check_symbol_exists(MAXPATHLEN sys/param.h HAVE_MAXPATHLEN) + check_symbol_exists(MAP_ANON sys/mman.h HAVE_MMAP_ANON) + check_symbol_exists(IPV6_V6ONLY "sys/socket.h;netinet/in.h" HAVE_IPV6_V6ONLY) + check_symbol_exists(posix_fallocate fcntl.h HAVE_POSIX_FALLOCATE) + check_symbol_exists(fallocate fcntl.h HAVE_FALLOCATE) + check_symbol_exists(_SC_NPROCESSORS_ONLN unistd.h HAVE_SC_NPROCESSORS_ONLN) + check_symbol_exists(setbit sys/param.h PARAM_H_HAS_BITSET) + check_symbol_exists(getaddrinfo "sys/types.h;sys/socket.h;netdb.h" HAVE_GETADDRINFO) + check_symbol_exists(sched_yield "sched.h" HAVE_SCHED_YIELD) + check_symbol_exists(nftw "sys/types.h;ftw.h" HAVE_NFTW) + check_symbol_exists(memrchr "string.h" HAVE_MEMRCHR) + + # Check if PCRE has JIT support + if (ENABLE_PCRE2) + list(APPEND CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE}") + check_symbol_exists(PCRE2_CONFIG_JIT "pcre2.h" HAVE_PCRE_JIT) + else () + list(APPEND CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE}") + check_symbol_exists(PCRE_CONFIG_JIT "pcre.h" HAVE_PCRE_JIT) + endif () + + # Socket features + check_symbol_exists(SOCK_SEQPACKET "sys/types.h;sys/socket.h" HAVE_SOCK_SEQPACKET) + + # File handling features + check_symbol_exists(O_NOFOLLOW "sys/types.h;sys/fcntl.h" HAVE_ONOFOLLOW) + check_symbol_exists(O_CLOEXEC "sys/types.h;sys/fcntl.h" HAVE_OCLOEXEC) + + # OpenSSL specific stuff + list(APPEND CMAKE_REQUIRED_INCLUDES "${LIBSSL_INCLUDE}") + if (LIBCRYPT_LIBRARY_PATH) + set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-L${LIBCRYPT_LIBRARY_PATH};${LIBCRYPT_LIBRARY}") + set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-L${LIBSSL_LIBRARY_PATH};${LIBSSL_LIBRARY}") + else () + set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-lcrypt;-lssl") + endif () + + check_symbol_exists(SSL_set_tlsext_host_name "openssl/ssl.h" HAVE_SSL_TLSEXT_HOSTNAME) + check_symbol_exists(FIPS_mode "openssl/crypto.h" HAVE_FIPS_MODE) + + # Directory and file path operations + check_symbol_exists(dirfd "sys/types.h;unistd.h;dirent.h" HAVE_DIRFD) + check_symbol_exists(fpathconf "sys/types.h;unistd.h" HAVE_FPATHCONF) + + # Signal handling and memory operations + check_symbol_exists(sigaltstack "signal.h" HAVE_SIGALTSTACK) + check_symbol_exists(open_memstream "stdio.h" HAVE_OPENMEMSTREAM) + check_symbol_exists(fmemopen "stdio.h" HAVE_FMEMOPEN) + check_symbol_exists(clock_getcpuclockid "sys/types.h;time.h" HAVE_CLOCK_GETCPUCLOCKID) + check_symbol_exists(RUSAGE_SELF "sys/types.h;sys/resource.h" HAVE_RUSAGE_SELF) + check_symbol_exists(ffsll "strings.h" HAVE_FFSLL) + + # Check for PCRE JIT fast path + if (ENABLE_PCRE2) + if (HAVE_PCRE_JIT) + set(HAVE_PCRE_JIT_FAST 1) + message(STATUS "PCRE2 JIT is supported") + else () + message(STATUS "PCRE2 JIT is NOT supported") + endif () + else () + list(APPEND CMAKE_REQUIRED_INCLUDES "${PCRE_INCLUDE}") + if (PCRE_LIBRARY_PATH) + set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-L${PCRE_LIBRARY_PATH};${PCRE_LIBRARY}") + else () + set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES};-lpcre") + endif () + + # Check for PCRE JIT fast path + set(_PCRE_FAST_TEST " +#include \"pcre.h\" +int main (void) +{ + int rc; + int ovector[30]; + pcre *re; + pcre_extra *extra; + pcre_jit_stack *jit_stack; + + re = pcre_compile(\"abc\", 0, NULL, NULL, NULL); + extra = pcre_study(re, PCRE_STUDY_JIT_COMPILE, NULL); + jit_stack = pcre_jit_stack_alloc(32*1024, 512*1024); + pcre_assign_jit_stack(extra, NULL, jit_stack); + rc = pcre_jit_exec(re, extra, \"abc\", 3, 0, 0, ovector, 30, jit_stack); + + return rc; +} +") + check_c_source_compiles("${_PCRE_FAST_TEST}" HAVE_PCRE_JIT_FAST) + if (HAVE_PCRE_JIT_FAST) + message(STATUS "pcre_jit_exec is supported") + else () + message(STATUS "pcre_jit_exec is NOT supported") + endif () + endif () + + # Critical checks + if (NOT HAVE_GETADDRINFO) + message(FATAL_ERROR "Your system does not support getaddrinfo call, please consider upgrading it to run rspamd") + endif () + + # Check for signal information + if (HAVE_SIGINFO_H) + check_symbol_exists(SA_SIGINFO "signal.h;siginfo.h" HAVE_SA_SIGINFO) + else () + check_symbol_exists(SA_SIGINFO "signal.h" HAVE_SA_SIGINFO) + endif () + + # Clock and timer features + if (NOT CMAKE_SYSTEM_NAME STREQUAL "SunOS") + if (HAVE_CLOCK_GETTIME) + check_symbol_exists(CLOCK_PROCESS_CPUTIME_ID time.h HAVE_CLOCK_PROCESS_CPUTIME_ID) + check_symbol_exists(CLOCK_VIRTUAL time.h HAVE_CLOCK_VIRTUAL) + else () + check_include_files(sys/timeb.h HAVE_SYS_TIMEB_H) + endif () + endif () + + # Linux-specific features + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + # In linux, we need to mount /run/shm to test which could be unavailable + # on a build system. On the other hand, we know that linux has stupid + # but compatible shmem support, so we assume this macro as true + set(HAVE_SANE_SHMEM 1) + + check_c_source_compiles("#define _GNU_SOURCE + #include <sys/socket.h> + int main (int argc, char **argv) { + return ((int*)(&recvmmsg))[argc]; + }" HAVE_RECVMMSG) + + check_c_source_compiles("#define _GNU_SOURCE + #include <fcntl.h> + int main (int argc, char **argv) { + return ((int*)(&readahead))[argc]; + }" HAVE_READAHEAD) + endif () + + # Propagate variables to parent scope + set(HAVE_PCRE_JIT_FAST ${HAVE_PCRE_JIT_FAST} PARENT_SCOPE) + set(HAVE_SANE_SHMEM ${HAVE_SANE_SHMEM} PARENT_SCOPE) + set(HAVE_GETPAGESIZE ${HAVE_GETPAGESIZE} PARENT_SCOPE) + set(HAVE_NANOSLEEP ${HAVE_NANOSLEEP} PARENT_SCOPE) + set(HAVE_FLOCK ${HAVE_FLOCK} PARENT_SCOPE) + set(HAVE_TANH ${HAVE_TANH} PARENT_SCOPE) + set(HAVE_MKSTEMP ${HAVE_MKSTEMP} PARENT_SCOPE) + set(HAVE_CLOCK_GETTIME ${HAVE_CLOCK_GETTIME} PARENT_SCOPE) + set(HAVE_PATH_MAX ${HAVE_PATH_MAX} PARENT_SCOPE) + set(HAVE_MAXPATHLEN ${HAVE_MAXPATHLEN} PARENT_SCOPE) + set(HAVE_MMAP_ANON ${HAVE_MMAP_ANON} PARENT_SCOPE) + set(HAVE_IPV6_V6ONLY ${HAVE_IPV6_V6ONLY} PARENT_SCOPE) + set(HAVE_POSIX_FALLOCATE ${HAVE_POSIX_FALLOCATE} PARENT_SCOPE) + set(HAVE_FALLOCATE ${HAVE_FALLOCATE} PARENT_SCOPE) + set(HAVE_SC_NPROCESSORS_ONLN ${HAVE_SC_NPROCESSORS_ONLN} PARENT_SCOPE) + set(PARAM_H_HAS_BITSET ${PARAM_H_HAS_BITSET} PARENT_SCOPE) + set(HAVE_GETADDRINFO ${HAVE_GETADDRINFO} PARENT_SCOPE) + set(HAVE_SCHED_YIELD ${HAVE_SCHED_YIELD} PARENT_SCOPE) + set(HAVE_NFTW ${HAVE_NFTW} PARENT_SCOPE) + set(HAVE_MEMRCHR ${HAVE_MEMRCHR} PARENT_SCOPE) + set(HAVE_PCRE_JIT ${HAVE_PCRE_JIT} PARENT_SCOPE) + set(HAVE_SOCK_SEQPACKET ${HAVE_SOCK_SEQPACKET} PARENT_SCOPE) + set(HAVE_ONOFOLLOW ${HAVE_ONOFOLLOW} PARENT_SCOPE) + set(HAVE_OCLOEXEC ${HAVE_OCLOEXEC} PARENT_SCOPE) + set(HAVE_SSL_TLSEXT_HOSTNAME ${HAVE_SSL_TLSEXT_HOSTNAME} PARENT_SCOPE) + set(HAVE_FIPS_MODE ${HAVE_FIPS_MODE} PARENT_SCOPE) + set(HAVE_DIRFD ${HAVE_DIRFD} PARENT_SCOPE) + set(HAVE_FPATHCONF ${HAVE_FPATHCONF} PARENT_SCOPE) + set(HAVE_SIGALTSTACK ${HAVE_SIGALTSTACK} PARENT_SCOPE) + set(HAVE_OPENMEMSTREAM ${HAVE_OPENMEMSTREAM} PARENT_SCOPE) + set(HAVE_FMEMOPEN ${HAVE_FMEMOPEN} PARENT_SCOPE) + set(HAVE_CLOCK_GETCPUCLOCKID ${HAVE_CLOCK_GETCPUCLOCKID} PARENT_SCOPE) + set(HAVE_RUSAGE_SELF ${HAVE_RUSAGE_SELF} PARENT_SCOPE) + set(HAVE_FFSLL ${HAVE_FFSLL} PARENT_SCOPE) + set(HAVE_SA_SIGINFO ${HAVE_SA_SIGINFO} PARENT_SCOPE) + set(HAVE_CLOCK_PROCESS_CPUTIME_ID ${HAVE_CLOCK_PROCESS_CPUTIME_ID} PARENT_SCOPE) + set(HAVE_CLOCK_VIRTUAL ${HAVE_CLOCK_VIRTUAL} PARENT_SCOPE) + + # Linux-specific features propagation + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(HAVE_RECVMMSG ${HAVE_RECVMMSG} PARENT_SCOPE) + set(HAVE_READAHEAD ${HAVE_READAHEAD} PARENT_SCOPE) + endif () +endfunction() + +# Execute the function +CheckSystemFeatures() diff --git a/cmake/CheckSystemHeaders.cmake b/cmake/CheckSystemHeaders.cmake new file mode 100644 index 000000000..232814eba --- /dev/null +++ b/cmake/CheckSystemHeaders.cmake @@ -0,0 +1,139 @@ +# CheckSystemHeaders.cmake +# Checks for the existence of system headers + +# Check platform specific includes +function(CheckSystemHeaders) + # Basic system headers + check_include_files(sys/types.h HAVE_SYS_TYPES_H) + check_include_files(sys/uio.h HAVE_SYS_UIO_H) + + # Standard C headers + check_include_files(fcntl.h HAVE_FCNTL_H) + check_include_files(math.h HAVE_MATH_H) + check_include_files(stdio.h HAVE_STDIO_H) + check_include_files(stdlib.h HAVE_STDLIB_H) + check_include_files(string.h HAVE_STRING_H) + check_include_files(strings.h HAVE_STRINGS_H) + check_include_files(time.h HAVE_TIME_H) + check_include_files(unistd.h HAVE_UNISTD_H) + + # Data type headers + check_include_files(stdint.h HAVE_STDINT_H) + check_include_files(inttypes.h HAVE_INTTYPES_H) + check_include_files(stdbool.h HAVE_STDBOOL_H) + + # Endian-related headers + check_include_files(endian.h HAVE_ENDIAN_H) + check_include_files(sys/endian.h HAVE_SYS_ENDIAN_H) + check_include_files(machine/endian.h HAVE_MACHINE_ENDIAN_H) + + # System utility headers + check_include_files(sys/socket.h HAVE_SYS_SOCKET_H) + check_include_files(sys/mman.h HAVE_SYS_MMAN_H) + check_include_files(sys/un.h HAVE_SYS_UN_H) + check_include_files(sys/stat.h HAVE_SYS_STAT_H) + check_include_files(sys/wait.h HAVE_SYS_WAIT_H) + check_include_files(sys/param.h HAVE_SYS_PARAM_H) + check_include_files(sys/file.h HAVE_SYS_FILE_H) + check_include_files(sys/resource.h HAVE_SYS_RESOURCE_H) + + # Network-related headers + check_include_files(netinet/in.h HAVE_NETINET_IN_H) + check_include_files(netinet/tcp.h HAVE_NETINET_TCP_H) + check_include_files(arpa/inet.h HAVE_ARPA_INET_H) + check_include_files(netdb.h HAVE_NETDB_H) + + # System logging and signal handling + check_include_files(syslog.h HAVE_SYSLOG_H) + check_include_files(siginfo.h HAVE_SIGINFO_H) + + # Internationalization and user/groups + check_include_files(locale.h HAVE_LOCALE_H) + check_include_files(libgen.h HAVE_LIBGEN_H) + check_include_files(pwd.h HAVE_PWD_H) + check_include_files(grp.h HAVE_GRP_H) + + # File and path handling + check_include_files(glob.h HAVE_GLOB_H) + check_include_files(poll.h HAVE_POLL_H) + check_include_files(readpassphrase.h HAVE_READPASSPHRASE_H) + check_include_files(termios.h HAVE_TERMIOS_H) + check_include_files(paths.h HAVE_PATHS_H) + + # Other utilities + check_include_files(ctype.h HAVE_CTYPE_H) + check_include_files(cpuid.h HAVE_CPUID_H) + check_include_files(dirent.h HAVE_DIRENT_H) + + # Context-related headers + check_include_files(ucontext.h HAVE_UCONTEXT_H) + check_include_files(sys/ucontext.h HAVE_SYS_UCONTEXT_H) # OSX specific + + # Time and memory + check_include_files(sys/timeb.h HAVE_SYS_TIMEB_H) + + # Log the results for important headers + if (NOT HAVE_SYS_TYPES_H) + message(WARNING "sys/types.h not found - this may cause problems") + endif () + + if (NOT HAVE_SYS_SOCKET_H) + message(WARNING "sys/socket.h not found - networking functionality may be limited") + endif () + + # Return results to parent scope + foreach (var + HAVE_SYS_TYPES_H + HAVE_SYS_UIO_H + HAVE_FCNTL_H + HAVE_MATH_H + HAVE_STDIO_H + HAVE_STDLIB_H + HAVE_STRING_H + HAVE_STRINGS_H + HAVE_TIME_H + HAVE_UNISTD_H + HAVE_STDINT_H + HAVE_INTTYPES_H + HAVE_STDBOOL_H + HAVE_ENDIAN_H + HAVE_SYS_ENDIAN_H + HAVE_MACHINE_ENDIAN_H + HAVE_SYS_SOCKET_H + HAVE_SYS_MMAN_H + HAVE_SYS_UN_H + HAVE_SYS_STAT_H + HAVE_SYS_WAIT_H + HAVE_SYS_PARAM_H + HAVE_SYS_FILE_H + HAVE_SYS_RESOURCE_H + HAVE_NETINET_IN_H + HAVE_NETINET_TCP_H + HAVE_ARPA_INET_H + HAVE_NETDB_H + HAVE_SYSLOG_H + HAVE_SIGINFO_H + HAVE_LOCALE_H + HAVE_LIBGEN_H + HAVE_PWD_H + HAVE_GRP_H + HAVE_GLOB_H + HAVE_POLL_H + HAVE_READPASSPHRASE_H + HAVE_TERMIOS_H + HAVE_PATHS_H + HAVE_CTYPE_H + HAVE_UNISTD_H + HAVE_CPUID_H + HAVE_DIRENT_H + HAVE_UCONTEXT_H + HAVE_SYS_UCONTEXT_H + HAVE_SYS_TIMEB_H) + if (${var}) + set(${var} ${${var}} PARENT_SCOPE) + endif () + endforeach () +endfunction() + +# Execute the function +CheckSystemHeaders() diff --git a/cmake/CheckURLInclude.cmake b/cmake/CheckURLInclude.cmake new file mode 100644 index 000000000..12cecacd9 --- /dev/null +++ b/cmake/CheckURLInclude.cmake @@ -0,0 +1,51 @@ +include(CheckIncludeFiles) +include(CheckLibraryExists) + +# Function to check for URL include support (libcurl or libfetch) +function(CheckURLIncludeSupport) + # First try to find libfetch + find_library(LIBFETCH_LIBRARY HINTS "${RSPAMD_SEARCH_PATH}" + NAMES fetch PATHS PATH_SUFFIXES lib64 lib + PATHS ${RSPAMD_DEFAULT_LIBRARY_PATHS} + DOC "Path where the libfetch library can be found") + + if (LIBFETCH_LIBRARY) + # Found libfetch library, now check for header + find_file(HAVE_FETCH_H HINTS "${RSPAMD_SEARCH_PATH}" + NAMES fetch.h + PATH_SUFFIXES include + PATHS ${RSPAMD_DEFAULT_INCLUDE_PATHS} + DOC "Path to libfetch header") + + if (HAVE_FETCH_H) + message(STATUS "Found libfetch: ${LIBFETCH_LIBRARY}") + list(APPEND RSPAMD_REQUIRED_LIBRARIES "fetch") + set(WITH_FETCH 1) + set(WITH_FETCH ${WITH_FETCH} PARENT_SCOPE) + else () + message(STATUS "Found libfetch library but missing fetch.h header") + endif () + else () + # Try to find libcurl as an alternative + ProcessPackage(CURL LIBRARY curl INCLUDE curl.h INCLUDE_SUFFIXES include/curl + ROOT ${CURL_ROOT}) + + if (WITH_CURL) + message(STATUS "Found libcurl for URL includes") + set(WITH_CURL ${WITH_CURL} PARENT_SCOPE) + else () + message(WARNING "Neither libcurl nor libfetch were found, no support of URL includes in configuration") + endif () + endif () + + # Propagate variables to parent scope + if (HAVE_FETCH_H) + set(HAVE_FETCH_H ${HAVE_FETCH_H} PARENT_SCOPE) + set(LIBFETCH_LIBRARY ${LIBFETCH_LIBRARY} PARENT_SCOPE) + endif () + + # Update the global RSPAMD_REQUIRED_LIBRARIES list + if (HAVE_FETCH_H) + set(RSPAMD_REQUIRED_LIBRARIES ${RSPAMD_REQUIRED_LIBRARIES} PARENT_SCOPE) + endif () +endfunction() diff --git a/cmake/InstallRspamdFiles.cmake b/cmake/InstallRspamdFiles.cmake new file mode 100644 index 000000000..b6b631cdc --- /dev/null +++ b/cmake/InstallRspamdFiles.cmake @@ -0,0 +1,104 @@ +# InstallRspamdFiles.cmake +# Manages the installation of Rspamd files, configurations, and components + +function(InstallRspamdFiles) + # Create necessary directories + install(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${CONFDIR})") + install(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${SHAREDIR})") + install(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${LUALIBDIR})") + install(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${PLUGINSDIR})") + install(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${RULESDIR})") + + # Install configuration files + set(GLOB_PATTERNS "${CMAKE_SOURCE_DIR}/conf/*.conf;${CMAKE_SOURCE_DIR}/conf/*.inc") + if (INSTALL_EXAMPLES) + list(APPEND GLOB_PATTERNS "${CMAKE_SOURCE_DIR}/conf/*.lua.example") + list(APPEND GLOB_PATTERNS "${CMAKE_SOURCE_DIR}/conf/*.conf.example") + endif () + + file(GLOB_RECURSE CONF_FILES RELATIVE "${CMAKE_SOURCE_DIR}/conf" CONFIGURE_DEPENDS + ${GLOB_PATTERNS}) + foreach (CONF_FILE ${CONF_FILES}) + get_filename_component(_rp ${CONF_FILE} PATH) + install(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${CONFDIR}/${_rp})") + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/conf/${CONF_FILE}" + DESTINATION ${CONFDIR}/${_rp}) + endforeach () + + # Install Lua plugins + file(GLOB LUA_PLUGINS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/src/plugins/lua" CONFIGURE_DEPENDS + "${CMAKE_CURRENT_SOURCE_DIR}/src/plugins/lua/*.lua") + foreach (LUA_PLUGIN ${LUA_PLUGINS}) + get_filename_component(_rp ${LUA_PLUGIN} PATH) + install(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${PLUGINSDIR}/${_rp})") + install(FILES "src/plugins/lua/${LUA_PLUGIN}" DESTINATION ${PLUGINSDIR}/${_rp}) + endforeach () + + # Install TLD list + install(FILES "contrib/publicsuffix/effective_tld_names.dat" DESTINATION + "${SHAREDIR}") + + # Install language data + install(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${SHAREDIR}/languages)") + file(GLOB LANGUAGES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/languages-data/*.json") + foreach (_LANG ${LANGUAGES}) + install(FILES "${_LANG}" DESTINATION ${SHAREDIR}/languages) + endforeach () + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/languages-data/stop_words" + DESTINATION ${SHAREDIR}/languages) + + # Install Lua rules + file(GLOB_RECURSE LUA_CONFIGS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/rules" CONFIGURE_DEPENDS + "${CMAKE_CURRENT_SOURCE_DIR}/rules/*.lua") + foreach (LUA_CONF ${LUA_CONFIGS}) + get_filename_component(_rp ${LUA_CONF} PATH) + install(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${RULESDIR}/${_rp})") + install(FILES "rules/${LUA_CONF}" DESTINATION ${RULESDIR}/${_rp}) + endforeach () + + # Install Lua libraries + file(GLOB_RECURSE LUA_LIBS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/lualib" CONFIGURE_DEPENDS + "${CMAKE_CURRENT_SOURCE_DIR}/lualib/*.lua") + foreach (LUA_LIB ${LUA_LIBS}) + get_filename_component(_rp ${LUA_LIB} PATH) + install(CODE "FILE(MAKE_DIRECTORY \$ENV{DESTDIR}${LUALIBDIR}/${_rp})") + install(FILES "lualib/${LUA_LIB}" DESTINATION ${LUALIBDIR}/${_rp}) + endforeach () + + # Install third-party Lua libraries + install(FILES "contrib/lua-fun/fun.lua" DESTINATION ${LUALIBDIR}) + install(FILES "contrib/lua-argparse/argparse.lua" DESTINATION ${LUALIBDIR}) + install(FILES "contrib/lua-tableshape/tableshape.lua" DESTINATION ${LUALIBDIR}) + install(FILES "contrib/lua-lupa/lupa.lua" DESTINATION ${LUALIBDIR}) + install(FILES "contrib/lua-lpeg/lpegre.lua" DESTINATION ${LUALIBDIR}) + + # Install systemd unit if on Linux and requested + if (CMAKE_SYSTEM_NAME STREQUAL "Linux" AND WANT_SYSTEMD_UNITS) + install(FILES "rspamd.service" DESTINATION ${SYSTEMDDIR}) + endif () + + # Install man pages + install(FILES "doc/rspamd.8" DESTINATION ${MANDIR}/man8) + install(FILES "doc/rspamc.1" DESTINATION ${MANDIR}/man1) + install(FILES "doc/rspamadm.1" DESTINATION ${MANDIR}/man1) + + # Install utilities + install(PROGRAMS "utils/rspamd_stats.pl" RENAME rspamd_stats DESTINATION bin) + + # Install web UI if requested + if (INSTALL_WEBUI) + install(DIRECTORY "interface/" DESTINATION ${WWWDIR} PATTERN ".git" EXCLUDE) + endif () + + # Log installation paths + message(STATUS "Rspamd will be installed in the following directories:") + message(STATUS " - Binaries: ${CMAKE_INSTALL_PREFIX}/bin") + message(STATUS " - Configuration: ${CONFDIR}") + message(STATUS " - Rules: ${RULESDIR}") + message(STATUS " - Lua libraries: ${LUALIBDIR}") + message(STATUS " - Plugins: ${PLUGINSDIR}") + message(STATUS " - Shared data: ${SHAREDIR}") + if (INSTALL_WEBUI) + message(STATUS " - Web UI: ${WWWDIR}") + endif () +endfunction() diff --git a/cmake/SetupPVSStudio.cmake b/cmake/SetupPVSStudio.cmake new file mode 100644 index 000000000..92fa560f0 --- /dev/null +++ b/cmake/SetupPVSStudio.cmake @@ -0,0 +1,56 @@ +# SetupPVSStudio.cmake +# Configures PVS-Studio static code analysis if available + +function(SetupPVSStudio) + # Try to find PVS-Studio analyzer + find_program(_PVS_STUDIO "pvs-studio-analyzer") + + if (_PVS_STUDIO) + message(STATUS "Found PVS-Studio analyzer: ${_PVS_STUDIO}") + + # Include the PVS-Studio module + include(PVS-Studio) + + # Get a list of source directories to analyze + set(_ANALYZE_TARGETS + ${PROJECT_NAME} # Main project + rspamd-server # Server component + rspamadm # Admin utility + rspamc # Client utility + ) + + # Setup analysis target + pvs_studio_add_target( + TARGET ${PROJECT_NAME}.analyze # Target name for running analysis + ANALYZE ${_ANALYZE_TARGETS} # What to analyze + OUTPUT FORMAT errorfile # Output format + LOG target_${PROJECT_NAME}.err # Log file path + ARGS + # Additional pvs-studio-analyzer arguments + --exclude-path "${CMAKE_SOURCE_DIR}/contrib" # Exclude third-party code + ) + + # Add a help message for the target + add_custom_command( + TARGET ${PROJECT_NAME}.analyze + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E echo "PVS-Studio analysis complete. Results in target_${PROJECT_NAME}.err" + ) + + # Create a report target that converts the error file to a more readable format + add_custom_target(${PROJECT_NAME}.analyze-report + COMMAND ${CMAKE_COMMAND} -E echo "Generating HTML report from PVS-Studio results..." + COMMAND plog-converter -a GA:1,2,3 -t fullhtml -o pvs-report target_${PROJECT_NAME}.err + COMMAND ${CMAKE_COMMAND} -E echo "Report generated in pvs-report/ directory" + DEPENDS ${PROJECT_NAME}.analyze + COMMENT "Converting PVS-Studio output to HTML report" + VERBATIM + ) + + message(STATUS "PVS-Studio targets added:") + message(STATUS " - ${PROJECT_NAME}.analyze: Run the analysis") + message(STATUS " - ${PROJECT_NAME}.analyze-report: Generate HTML report from analysis results") + else () + message(STATUS "PVS-Studio analyzer not found. Static analysis disabled.") + endif () +endfunction() diff --git a/contrib/xxhash/CMakeLists.txt b/contrib/xxhash/CMakeLists.txt index fa69efbe0..5091d261d 100644 --- a/contrib/xxhash/CMakeLists.txt +++ b/contrib/xxhash/CMakeLists.txt @@ -1,13 +1,13 @@ SET(XXHASHSRC xxhash.c) -ADD_LIBRARY(xxhash STATIC ${XXHASHSRC}) +ADD_LIBRARY(rspamd-xxhash STATIC ${XXHASHSRC}) -IF(ENABLE_FULL_DEBUG MATCHES "OFF") -if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") - SET_TARGET_PROPERTIES(xxhash PROPERTIES COMPILE_FLAGS "-O3") -endif () -else() -ADD_DEFINITIONS(-DXXH_NO_INLINE_HINTS=1) -ENDIF() +IF (ENABLE_FULL_DEBUG MATCHES "OFF") + if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + SET_TARGET_PROPERTIES(rspamd-xxhash PROPERTIES COMPILE_FLAGS "-O3") + endif () +else () + ADD_DEFINITIONS(-DXXH_NO_INLINE_HINTS=1) +ENDIF () -set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DXXH_NO_INLINE_HINTS=1" PARENT_SCOPE) +set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DXXH_NO_INLINE_HINTS=1" PARENT_SCOPE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 92edb0b6a..e4d3c7d81 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,246 +1,286 @@ -MACRO(_AddModulesForced MLIST) -# Generate unique string for this build - SET(MODULES_C "${CMAKE_CURRENT_BINARY_DIR}/modules.c") - FILE(WRITE "${MODULES_C}" - "#include \"rspamd.h\"\n") - - # Handle even old cmake - LIST(LENGTH ${MLIST} MLIST_COUNT) - MATH(EXPR MLIST_MAX ${MLIST_COUNT}-1) - - FOREACH(MOD_IDX RANGE ${MLIST_MAX}) - LIST(GET ${MLIST} ${MOD_IDX} MOD) - FILE(APPEND "${MODULES_C}" "extern module_t ${MOD}_module;\n") - ENDFOREACH(MOD_IDX RANGE ${MLIST_MAX}) - - FILE(APPEND "${MODULES_C}" "\n\nmodule_t *modules[] = {\n") - - FOREACH(MOD_IDX RANGE ${MLIST_MAX}) - LIST(GET ${MLIST} ${MOD_IDX} MOD) - FILE(APPEND "${MODULES_C}" "&${MOD}_module,\n") - ENDFOREACH(MOD_IDX RANGE ${MLIST_MAX}) - - FILE(APPEND "${MODULES_C}" "NULL\n};\n") -ENDMACRO(_AddModulesForced MLIST) - -MACRO(_AddWorkersForced WLIST) - SET(WORKERS_C "${CMAKE_CURRENT_BINARY_DIR}/workers.c") - FILE(WRITE "${WORKERS_C}" - "#include \"rspamd.h\"\n") - - # Handle even old cmake - LIST(LENGTH ${WLIST} WLIST_COUNT) - MATH(EXPR WLIST_MAX ${WLIST_COUNT}-1) - FOREACH(MOD_IDX RANGE ${WLIST_MAX}) - LIST(GET ${WLIST} ${MOD_IDX} WRK) - FILE(APPEND "${WORKERS_C}" "extern worker_t ${WRK}_worker;\n") - ENDFOREACH(MOD_IDX RANGE ${WLIST_MAX}) - - FILE(APPEND "${WORKERS_C}" "\n\nworker_t *workers[] = {\n") - - FOREACH(MOD_IDX RANGE ${WLIST_MAX}) - LIST(GET ${WLIST} ${MOD_IDX} WRK) - FILE(APPEND "${WORKERS_C}" "&${WRK}_worker,\n") - ENDFOREACH(MOD_IDX RANGE ${WLIST_MAX}) - FILE(APPEND "${WORKERS_C}" "NULL\n};\n") -ENDMACRO(_AddWorkersForced WLIST) - -MACRO(AddModules MLIST WLIST) - _AddModulesForced(${MLIST}) - _AddWorkersForced(${WLIST}) - #IF(NOT EXISTS "modules.c") - # _AddModulesForced(${MLIST} ${WLIST}) - #ELSE(NOT EXISTS "modules.c") - # FILE(STRINGS "modules.c" FILE_ID_RAW REGEX "^/.*[a-zA-Z0-9]+.*/$") - # STRING(REGEX MATCH "[a-zA-Z0-9]+" FILE_ID "${FILE_ID_RAW}") - # IF(NOT FILE_ID STREQUAL MODULES_ID) - # MESSAGE("Regenerate modules info") - # _AddModulesForced(${MLIST} ${WLIST}) - # ENDIF(NOT FILE_ID STREQUAL MODULES_ID) - #ENDIF(NOT EXISTS "modules.c") -ENDMACRO(AddModules MLIST WLIST) - -# Rspamd core components -IF (ENABLE_CLANG_PLUGIN MATCHES "ON") - SET(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} -Xclang -load -Xclang ${CMAKE_CURRENT_BINARY_DIR}/../clang-plugin/librspamd-clang${CMAKE_SHARED_LIBRARY_SUFFIX} -Xclang -add-plugin -Xclang rspamd-ast") - IF(CLANG_EXTRA_PLUGINS_LIBS) - FOREACH(_lib ${CLANG_EXTRA_PLUGINS_LIBS}) - SET(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} -Xclang -load -Xclang ${_lib}") - SET(CMAKE_CXX_FLAGS - "${CMAKE_CXX_FLAGS} -Xclang -load -Xclang ${_lib}") - ENDFOREACH() - ENDIF() - IF(CLANG_EXTRA_PLUGINS) - FOREACH(_plug ${CLANG_EXTRA_PLUGINS}) - SET(CMAKE_C_FLAGS - "${CMAKE_C_FLAGS} -Xclang -add-plugin -Xclang ${_plug}") - SET(CMAKE_CXX_FLAGS - "${CMAKE_C_FLAGS} -Xclang -add-plugin -Xclang ${_plug}") - ENDFOREACH() - ENDIF() -ENDIF () - -ADD_SUBDIRECTORY(lua) -ADD_SUBDIRECTORY(libcryptobox) -ADD_SUBDIRECTORY(libutil) -ADD_SUBDIRECTORY(libserver) -ADD_SUBDIRECTORY(libmime) -ADD_SUBDIRECTORY(libstat) -ADD_SUBDIRECTORY(client) -ADD_SUBDIRECTORY(rspamadm) - -SET(RSPAMDSRC controller.c - fuzzy_storage.c - rspamd.c - worker.c - rspamd_proxy.c) - -SET(PLUGINSSRC plugins/regexp.c - plugins/chartable.cxx - plugins/fuzzy_check.c - plugins/dkim_check.c - libserver/rspamd_control.c) - -SET(MODULES_LIST regexp chartable fuzzy_check dkim) -SET(WORKERS_LIST normal controller fuzzy rspamd_proxy) -IF (ENABLE_HYPERSCAN MATCHES "ON") - LIST(APPEND WORKERS_LIST "hs_helper") - LIST(APPEND RSPAMDSRC "hs_helper.c") -ENDIF() - -AddModules(MODULES_LIST WORKERS_LIST) -LIST(LENGTH PLUGINSSRC RSPAMD_MODULES_NUM) - -SET(RAGEL_DEPENDS "${CMAKE_SOURCE_DIR}/src/ragel/smtp_address.rl" - "${CMAKE_SOURCE_DIR}/src/ragel/smtp_date.rl" - "${CMAKE_SOURCE_DIR}/src/ragel/smtp_ip.rl" - "${CMAKE_SOURCE_DIR}/src/ragel/smtp_base.rl" - "${CMAKE_SOURCE_DIR}/src/ragel/content_disposition.rl") -RAGEL_TARGET(ragel_smtp_addr - INPUTS ${CMAKE_SOURCE_DIR}/src/ragel/smtp_addr_parser.rl - DEPENDS ${RAGEL_DEPENDS} - COMPILE_FLAGS -T1 - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/smtp_addr_parser.rl.c) -RAGEL_TARGET(ragel_content_disposition - INPUTS ${CMAKE_SOURCE_DIR}/src/ragel/content_disposition_parser.rl - DEPENDS ${RAGEL_DEPENDS} - COMPILE_FLAGS -G2 - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/content_disposition.rl.c) -RAGEL_TARGET(ragel_rfc2047 - INPUTS ${CMAKE_SOURCE_DIR}/src/ragel/rfc2047_parser.rl - DEPENDS ${RAGEL_DEPENDS} - COMPILE_FLAGS -G2 - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/rfc2047.rl.c) -RAGEL_TARGET(ragel_smtp_date - INPUTS ${CMAKE_SOURCE_DIR}/src/ragel/smtp_date_parser.rl - DEPENDS ${RAGEL_DEPENDS} - COMPILE_FLAGS -G2 - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/date_parser.rl.c) -RAGEL_TARGET(ragel_smtp_ip - INPUTS ${CMAKE_SOURCE_DIR}/src/ragel/smtp_ip_parser.rl - DEPENDS ${RAGEL_DEPENDS} - COMPILE_FLAGS -G2 - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ip_parser.rl.c) -# Fucking cmake... -FOREACH(_GEN ${LIBSERVER_GENERATED}) - set_source_files_properties(${_GEN} PROPERTIES GENERATED TRUE) -ENDFOREACH() -######################### LINK SECTION ############################### - -IF(ENABLE_STATIC MATCHES "ON") - ADD_LIBRARY(rspamd-server STATIC - ${RSPAMD_CRYPTOBOX} - ${RSPAMD_UTIL} - ${RSPAMD_LUA} - ${RSPAMD_SERVER} - ${RSPAMD_STAT} - ${RSPAMD_MIME} - ${CMAKE_CURRENT_BINARY_DIR}/modules.c - ${PLUGINSSRC} - "${RAGEL_ragel_smtp_addr_OUTPUTS}" - "${RAGEL_ragel_newlines_strip_OUTPUTS}" - "${RAGEL_ragel_content_type_OUTPUTS}" - "${RAGEL_ragel_content_disposition_OUTPUTS}" - "${RAGEL_ragel_rfc2047_OUTPUTS}" - "${RAGEL_ragel_smtp_date_OUTPUTS}" - "${RAGEL_ragel_smtp_ip_OUTPUTS}" - ${BACKWARD_ENABLE}) -ELSE() - ADD_LIBRARY(rspamd-server SHARED - ${RSPAMD_CRYPTOBOX} - ${RSPAMD_UTIL} - ${RSPAMD_SERVER} - ${RSPAMD_STAT} - ${RSPAMD_MIME} - ${RSPAMD_LUA} - ${CMAKE_CURRENT_BINARY_DIR}/modules.c - ${PLUGINSSRC} - "${RAGEL_ragel_smtp_addr_OUTPUTS}" - "${RAGEL_ragel_newlines_strip_OUTPUTS}" - "${RAGEL_ragel_content_type_OUTPUTS}" - "${RAGEL_ragel_content_disposition_OUTPUTS}" - "${RAGEL_ragel_rfc2047_OUTPUTS}" - "${RAGEL_ragel_smtp_date_OUTPUTS}" - "${RAGEL_ragel_smtp_ip_OUTPUTS}" - ${BACKWARD_ENABLE}) -ENDIF() - -FOREACH(_DEP ${LIBSERVER_DEPENDS}) - ADD_DEPENDENCIES(rspamd-server "${_DEP}") -ENDFOREACH() - -TARGET_LINK_LIBRARIES(rspamd-server rspamd-http-parser) -TARGET_LINK_LIBRARIES(rspamd-server rspamd-fpconv) -TARGET_LINK_LIBRARIES(rspamd-server rspamd-cdb) -TARGET_LINK_LIBRARIES(rspamd-server rspamd-lpeg) -TARGET_LINK_LIBRARIES(rspamd-server lcbtrie) -IF(SYSTEM_ZSTD MATCHES "OFF") - TARGET_LINK_LIBRARIES(rspamd-server rspamd-zstd) -ELSE() - TARGET_LINK_LIBRARIES(rspamd-server zstd) -ENDIF() -TARGET_LINK_LIBRARIES(rspamd-server rspamd-simdutf) - -IF (ENABLE_CLANG_PLUGIN MATCHES "ON") - ADD_DEPENDENCIES(rspamd-server rspamd-clang) -ENDIF() - -IF (NOT WITH_LUAJIT) - TARGET_LINK_LIBRARIES(rspamd-server rspamd-bit) -ENDIF() - -IF (ENABLE_SNOWBALL MATCHES "ON") - TARGET_LINK_LIBRARIES(rspamd-server stemmer) -ENDIF() -TARGET_LINK_LIBRARIES(rspamd-server rspamd-hiredis) - -IF (ENABLE_FANN MATCHES "ON") - TARGET_LINK_LIBRARIES(rspamd-server fann) -ENDIF () - -IF (ENABLE_HYPERSCAN MATCHES "ON") - TARGET_LINK_LIBRARIES(rspamd-server hs) -ENDIF() - -IF(WITH_BLAS) - TARGET_LINK_LIBRARIES(rspamd-server ${BLAS_REQUIRED_LIBRARIES}) -ENDIF() - -TARGET_LINK_LIBRARIES(rspamd-server ${RSPAMD_REQUIRED_LIBRARIES}) -ADD_BACKWARD(rspamd-server) - -ADD_EXECUTABLE(rspamd ${RSPAMDSRC} ${CMAKE_CURRENT_BINARY_DIR}/workers.c ${CMAKE_CURRENT_BINARY_DIR}/config.h) -ADD_BACKWARD(rspamd) -SET_TARGET_PROPERTIES(rspamd PROPERTIES LINKER_LANGUAGE CXX) -SET_TARGET_PROPERTIES(rspamd-server PROPERTIES LINKER_LANGUAGE CXX) -IF(NOT NO_TARGET_VERSIONS) - SET_TARGET_PROPERTIES(rspamd PROPERTIES VERSION ${RSPAMD_VERSION}) -ENDIF() - -#TARGET_LINK_LIBRARIES(rspamd ${RSPAMD_REQUIRED_LIBRARIES}) -TARGET_LINK_LIBRARIES(rspamd rspamd-server) - -INSTALL(TARGETS rspamd RUNTIME DESTINATION bin) -INSTALL(TARGETS rspamd-server LIBRARY DESTINATION ${RSPAMD_LIBDIR})
\ No newline at end of file +# Function to generate module registrations +function(generate_modules_list MODULE_LIST) + # Generate unique string for this build + set(MODULES_C "${CMAKE_CURRENT_BINARY_DIR}/modules.c") + file(WRITE "${MODULES_C}" + "#include \"rspamd.h\"\n") + + # Process each module + foreach (MOD IN LISTS ${MODULE_LIST}) + file(APPEND "${MODULES_C}" "extern module_t ${MOD}_module;\n") + endforeach () + + file(APPEND "${MODULES_C}" "\n\nmodule_t *modules[] = {\n") + + foreach (MOD IN LISTS ${MODULE_LIST}) + file(APPEND "${MODULES_C}" "&${MOD}_module,\n") + endforeach () + + file(APPEND "${MODULES_C}" "NULL\n};\n") + + # Return the generated file path + set(MODULES_C_PATH "${MODULES_C}" PARENT_SCOPE) +endfunction() + +# Function to generate worker registrations +function(generate_workers_list WORKER_LIST) + set(WORKERS_C "${CMAKE_CURRENT_BINARY_DIR}/workers.c") + file(WRITE "${WORKERS_C}" + "#include \"rspamd.h\"\n") + + # Process each worker + foreach (WRK IN LISTS ${WORKER_LIST}) + file(APPEND "${WORKERS_C}" "extern worker_t ${WRK}_worker;\n") + endforeach () + + file(APPEND "${WORKERS_C}" "\n\nworker_t *workers[] = {\n") + + foreach (WRK IN LISTS ${WORKER_LIST}) + file(APPEND "${WORKERS_C}" "&${WRK}_worker,\n") + endforeach () + + file(APPEND "${WORKERS_C}" "NULL\n};\n") + + # Return the generated file path + set(WORKERS_C_PATH "${WORKERS_C}" PARENT_SCOPE) +endfunction() + +# Function to generate both modules and workers +function(generate_registration_code MODULE_LIST WORKER_LIST) + generate_modules_list(${MODULE_LIST}) + generate_workers_list(${WORKER_LIST}) + + # Set parent scope variables + set(MODULES_C_PATH ${MODULES_C_PATH} PARENT_SCOPE) + set(WORKERS_C_PATH ${WORKERS_C_PATH} PARENT_SCOPE) +endfunction() + +# Configure Clang Plugin if enabled +if (ENABLE_CLANG_PLUGIN) + set(CLANG_PLUGIN_FLAGS "-Xclang -load -Xclang ${CMAKE_CURRENT_BINARY_DIR}/../clang-plugin/librspamd-clang${CMAKE_SHARED_LIBRARY_SUFFIX} -Xclang -add-plugin -Xclang rspamd-ast") + + # Apply to both C and C++ compiler flags + add_compile_options(${CLANG_PLUGIN_FLAGS}) + + # Add any extra clang plugins + if (CLANG_EXTRA_PLUGINS_LIBS) + foreach (lib ${CLANG_EXTRA_PLUGINS_LIBS}) + add_compile_options("-Xclang" "-load" "-Xclang" "${lib}") + endforeach () + endif () + + if (CLANG_EXTRA_PLUGINS) + foreach (plug ${CLANG_EXTRA_PLUGINS}) + add_compile_options("-Xclang" "-add-plugin" "-Xclang" "${plug}") + endforeach () + endif () +endif () + +# Add subdirectories for components +add_subdirectory(lua) +add_subdirectory(libcryptobox) +add_subdirectory(libutil) +add_subdirectory(libserver) +add_subdirectory(libmime) +add_subdirectory(libstat) +add_subdirectory(client) +add_subdirectory(rspamadm) + +# Define source files +set(RSPAMD_SOURCES + controller.c + fuzzy_storage.c + rspamd.c + worker.c + rspamd_proxy.c) + +set(PLUGIN_SOURCES + plugins/regexp.c + plugins/chartable.cxx + plugins/fuzzy_check.c + plugins/dkim_check.c + libserver/rspamd_control.c) + +# Define module and worker lists +set(MODULES_LIST regexp chartable fuzzy_check dkim) +set(WORKERS_LIST normal controller fuzzy rspamd_proxy) + +# Add hyperscan worker if enabled +if (ENABLE_HYPERSCAN) + list(APPEND WORKERS_LIST hs_helper) + list(APPEND RSPAMD_SOURCES hs_helper.c) +endif () + +# Generate modules and workers registration code +generate_registration_code(MODULES_LIST WORKERS_LIST) + +# Count the number of modules +list(LENGTH PLUGIN_SOURCES RSPAMD_MODULES_NUM) + +# Configure Ragel for parsers +set(RAGEL_DEPENDS + "${CMAKE_SOURCE_DIR}/src/ragel/smtp_address.rl" + "${CMAKE_SOURCE_DIR}/src/ragel/smtp_date.rl" + "${CMAKE_SOURCE_DIR}/src/ragel/smtp_ip.rl" + "${CMAKE_SOURCE_DIR}/src/ragel/smtp_base.rl" + "${CMAKE_SOURCE_DIR}/src/ragel/content_disposition.rl") + +# Generate parsers with Ragel +ragel_target(ragel_smtp_addr + INPUTS ${CMAKE_SOURCE_DIR}/src/ragel/smtp_addr_parser.rl + DEPENDS ${RAGEL_DEPENDS} + COMPILE_FLAGS -T1 + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/smtp_addr_parser.rl.c) + +ragel_target(ragel_content_disposition + INPUTS ${CMAKE_SOURCE_DIR}/src/ragel/content_disposition_parser.rl + DEPENDS ${RAGEL_DEPENDS} + COMPILE_FLAGS -G2 + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/content_disposition.rl.c) + +ragel_target(ragel_rfc2047 + INPUTS ${CMAKE_SOURCE_DIR}/src/ragel/rfc2047_parser.rl + DEPENDS ${RAGEL_DEPENDS} + COMPILE_FLAGS -G2 + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/rfc2047.rl.c) + +ragel_target(ragel_smtp_date + INPUTS ${CMAKE_SOURCE_DIR}/src/ragel/smtp_date_parser.rl + DEPENDS ${RAGEL_DEPENDS} + COMPILE_FLAGS -G2 + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/date_parser.rl.c) + +ragel_target(ragel_smtp_ip + INPUTS ${CMAKE_SOURCE_DIR}/src/ragel/smtp_ip_parser.rl + DEPENDS ${RAGEL_DEPENDS} + COMPILE_FLAGS -G2 + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ip_parser.rl.c) + +# Mark generated files correctly +foreach (_gen ${LIBSERVER_GENERATED}) + set_source_files_properties(${_gen} PROPERTIES GENERATED TRUE) +endforeach () + +# Collection of all generated Ragel outputs +set(RAGEL_OUTPUTS + ${RAGEL_ragel_smtp_addr_OUTPUTS} + ${RAGEL_ragel_newlines_strip_OUTPUTS} + ${RAGEL_ragel_content_type_OUTPUTS} + ${RAGEL_ragel_content_disposition_OUTPUTS} + ${RAGEL_ragel_rfc2047_OUTPUTS} + ${RAGEL_ragel_smtp_date_OUTPUTS} + ${RAGEL_ragel_smtp_ip_OUTPUTS}) + +# Common sources for rspamd-server +set(SERVER_COMMON_SOURCES + ${RSPAMD_CRYPTOBOX} + ${RSPAMD_UTIL} + ${RSPAMD_LUA} + ${RSPAMD_SERVER} + ${RSPAMD_STAT} + ${RSPAMD_MIME} + ${MODULES_C_PATH} + ${PLUGIN_SOURCES} + ${RAGEL_OUTPUTS} + ${BACKWARD_ENABLE}) + +# Build rspamd-server as static or shared library based on configuration +if (ENABLE_STATIC) + add_library(rspamd-server STATIC ${SERVER_COMMON_SOURCES}) +else () + add_library(rspamd-server SHARED ${SERVER_COMMON_SOURCES}) +endif () + +# Set dependencies for rspamd-server +foreach (_dep ${LIBSERVER_DEPENDS}) + add_dependencies(rspamd-server "${_dep}") +endforeach () + +# Link dependencies +target_link_libraries(rspamd-server + PRIVATE + rspamd-http-parser + rspamd-fpconv + rspamd-cdb + rspamd-lpeg + ottery + lcbtrie + rspamd-simdutf + rdns + ucl) + +# Handle xxhash dependency +if (SYSTEM_XXHASH) + target_link_libraries(rspamd-server PUBLIC xxhash) +else () + target_link_libraries(rspamd-server PRIVATE rspamd-xxhash) +endif () + +# Handle zstd dependency +if (SYSTEM_ZSTD) + target_link_libraries(rspamd-server PUBLIC zstd) +else () + target_link_libraries(rspamd-server PRIVATE rspamd-zstd) +endif () + +# Handle clang plugin dependency +if (ENABLE_CLANG_PLUGIN) + add_dependencies(rspamd-server rspamd-clang) +endif () + +# Handle Lua JIT/Lua dependency +if (NOT WITH_LUAJIT) + target_link_libraries(rspamd-server PRIVATE rspamd-bit) +endif () + +# Link additional optional dependencies +if (ENABLE_SNOWBALL) + target_link_libraries(rspamd-server PRIVATE stemmer) +endif () + +target_link_libraries(rspamd-server PRIVATE rspamd-hiredis) + +if (ENABLE_FANN) + target_link_libraries(rspamd-server PRIVATE fann) +endif () + +if (ENABLE_HYPERSCAN) + target_link_libraries(rspamd-server PUBLIC hs) +endif () + +if (WITH_BLAS) + target_link_libraries(rspamd-server PRIVATE ${BLAS_REQUIRED_LIBRARIES}) +endif () + +# Link all required system libraries +target_link_libraries(rspamd-server PUBLIC ${RSPAMD_REQUIRED_LIBRARIES}) + +# Add Backward support for stacktrace +add_backward(rspamd-server) + +# Build main rspamd executable +add_executable(rspamd + ${RSPAMD_SOURCES} + ${WORKERS_C_PATH} + ${CMAKE_CURRENT_BINARY_DIR}/config.h) + +# Configure rspamd executable +add_backward(rspamd) +set_target_properties(rspamd PROPERTIES LINKER_LANGUAGE CXX) +set_target_properties(rspamd-server PROPERTIES LINKER_LANGUAGE CXX) + +if (NOT NO_TARGET_VERSIONS) + set_target_properties(rspamd PROPERTIES VERSION ${RSPAMD_VERSION}) +endif () + +# Link rspamd executable with the server library +target_link_libraries(rspamd PRIVATE rspamd-server) + +# Install targets +install(TARGETS rspamd + RUNTIME + DESTINATION bin) + +install(TARGETS rspamd-server + LIBRARY + DESTINATION ${RSPAMD_LIBDIR}) diff --git a/src/rspamadm/lua_repl.c b/src/rspamadm/lua_repl.c index 41a319de9..9ad790d20 100644 --- a/src/rspamadm/lua_repl.c +++ b/src/rspamadm/lua_repl.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 Vsevolod Stakhov + * Copyright 2025 Vsevolod Stakhov * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -701,8 +701,8 @@ rspamadm_lua_run_repl(lua_State *L, bool is_batch) g_string_append(tb, " \n"); } } - } #endif + } } } |