aboutsummaryrefslogtreecommitdiffstats
path: root/cmake
diff options
context:
space:
mode:
Diffstat (limited to 'cmake')
-rw-r--r--cmake/AddDependencySubdirectories.cmake107
-rw-r--r--cmake/CheckSymbols.cmake146
-rw-r--r--cmake/CheckSystemFeatures.cmake207
-rw-r--r--cmake/CheckSystemHeaders.cmake139
-rw-r--r--cmake/CheckURLInclude.cmake51
-rw-r--r--cmake/InstallRspamdFiles.cmake104
-rw-r--r--cmake/OSDep.cmake175
-rw-r--r--cmake/Sanitizer.cmake145
-rw-r--r--cmake/SetupPVSStudio.cmake56
9 files changed, 1003 insertions, 127 deletions
diff --git a/cmake/AddDependencySubdirectories.cmake b/cmake/AddDependencySubdirectories.cmake
new file mode 100644
index 000000000..866204ff5
--- /dev/null
+++ b/cmake/AddDependencySubdirectories.cmake
@@ -0,0 +1,107 @@
+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)
+ 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)
+
+ # Utilities
+ add_subdirectory(utils)
+
+ # Propagate variables to parent scope
+ set(RSPAMD_REQUIRED_LIBRARIES ${RSPAMD_REQUIRED_LIBRARIES} 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/OSDep.cmake b/cmake/OSDep.cmake
index f2bd56cec..2f23ada4b 100644
--- a/cmake/OSDep.cmake
+++ b/cmake/OSDep.cmake
@@ -1,67 +1,108 @@
-# Platform specific configuration
-IF(CMAKE_SYSTEM_NAME MATCHES "^.*BSD$|DragonFly")
- ADD_COMPILE_OPTIONS(-DFREEBSD -D_BSD_SOURCE)
- SET(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_BSD_SOURCE")
- CONFIGURE_FILE(freebsd/rspamd.sh.in freebsd/rspamd @ONLY)
- MESSAGE(STATUS "Configuring for BSD system")
- # Find util library
- ProcessPackage(LIBUTIL LIBRARY util INCLUDE libutil.h
- ROOT ${LIBUTIL_ROOT_DIR} OPTIONAL)
- IF(WITH_LIBUTIL)
- SET(HAVE_LIBUTIL_H 1)
- LIST(APPEND CMAKE_REQUIRED_LIBRARIES util)
- CHECK_FUNCTION_EXISTS(pidfile_open HAVE_PIDFILE)
- CHECK_FUNCTION_EXISTS(pidfile_fileno HAVE_PIDFILE_FILENO)
- ENDIF()
- IF(CMAKE_SYSTEM_NAME MATCHES "^NetBSD$")
- LIST(APPEND CMAKE_REQUIRED_LIBRARIES rt)
- ENDIF()
- SET(TAR "gtar")
-ENDIF()
-
-IF(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
- ADD_COMPILE_OPTIONS(-D_BSD_SOURCE -DDARWIN)
- SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS} -undefined dynamic_lookup")
- IF(ENABLE_LUAJIT MATCHES "ON")
- IF ("${ARCH}" STREQUAL "x86_64")
- SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pagezero_size 10000 -image_base 100000000")
- ENDIF()
- ENDIF(ENABLE_LUAJIT MATCHES "ON")
- MESSAGE(STATUS "Configuring for Darwin")
- SET(TAR "gnutar")
- SET(CMAKE_FIND_FRAMEWORK "NEVER")
-ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
-
-IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
- ADD_COMPILE_OPTIONS(-D_GNU_SOURCE -DLINUX)
- SET(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_GNU_SOURCE")
- # Workaround with architecture specific includes
- #IF(IS_DIRECTORY "/usr/include/${CMAKE_SYSTEM_PROCESSOR}-linux-gnu/")
- # INCLUDE_DIRECTORIES("/usr/include/${CMAKE_SYSTEM_PROCESSOR}-linux-gnu/")
- # LIST(APPEND CMAKE_REQUIRED_INCLUDES "/usr/include/${CMAKE_SYSTEM_PROCESSOR}-linux-gnu/")
- #ENDIF(IS_DIRECTORY "/usr/include/${CMAKE_SYSTEM_PROCESSOR}-linux-gnu/")
-
- LIST(APPEND CMAKE_REQUIRED_LIBRARIES rt)
- LIST(APPEND CMAKE_REQUIRED_LIBRARIES dl)
- LIST(APPEND CMAKE_REQUIRED_LIBRARIES resolv)
- MESSAGE(STATUS "Configuring for Linux")
- IF(EXISTS "/etc/debian_version")
- SET(LINUX_START_SCRIPT "rspamd_debian.in")
- ELSE(EXISTS "/etc/debian_version")
- SET(LINUX_START_SCRIPT "rspamd_rh.in")
- ENDIF(EXISTS "/etc/debian_version")
-ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
-
-IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
- ADD_COMPILE_OPTIONS(-D__EXTENSIONS__ -DSOLARIS -D_POSIX_SOURCE -D_POSIX_C_SOURCE=200112)
- LIST(APPEND CMAKE_REQUIRED_LIBRARIES rt)
- LIST(APPEND CMAKE_REQUIRED_LIBRARIES dl)
- LIST(APPEND CMAKE_REQUIRED_LIBRARIES resolv)
- LIST(APPEND CMAKE_REQUIRED_LIBRARIES nsl)
- LIST(APPEND CMAKE_REQUIRED_LIBRARIES socket)
- LIST(APPEND CMAKE_REQUIRED_LIBRARIES umem)
- # Ugly hack, but FindOpenSSL on Solaris does not link with libcrypto
- SET(CMAKE_VERBOSE_MAKEFILE ON)
- SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE)
- SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib:${RSPAMD_LIBDIR}")
-ENDIF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") \ No newline at end of file
+# OSDep.cmake - Platform-specific configuration as a function
+
+function(ConfigurePlatformSpecifics)
+ # Configure for BSD systems
+ if (CMAKE_SYSTEM_NAME MATCHES "^.*BSD$|DragonFly")
+ # Add BSD-specific compiler flags
+ add_compile_definitions(FREEBSD _BSD_SOURCE)
+ set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_BSD_SOURCE" PARENT_SCOPE)
+
+ # Configure FreeBSD startup script
+ configure_file(freebsd/rspamd.sh.in freebsd/rspamd @ONLY)
+ message(STATUS "Configuring for BSD system")
+
+ # Find util library
+ ProcessPackage(LIBUTIL LIBRARY util INCLUDE libutil.h
+ ROOT ${LIBUTIL_ROOT_DIR} OPTIONAL)
+
+ if (WITH_LIBUTIL)
+ set(HAVE_LIBUTIL_H 1)
+ list(APPEND CMAKE_REQUIRED_LIBRARIES util)
+ list(APPEND RSPAMD_REQUIRED_LIBRARIES util)
+
+ # Check for pidfile functions
+ check_function_exists(pidfile_open HAVE_PIDFILE)
+ check_function_exists(pidfile_fileno HAVE_PIDFILE_FILENO)
+
+ # Propagate variables to parent scope
+ set(HAVE_PIDFILE ${HAVE_PIDFILE} PARENT_SCOPE)
+ set(HAVE_PIDFILE_FILENO ${HAVE_PIDFILE_FILENO} PARENT_SCOPE)
+ set(HAVE_LIBUTIL_H ${HAVE_LIBUTIL_H} PARENT_SCOPE)
+ endif ()
+
+ # NetBSD-specific libraries
+ if (CMAKE_SYSTEM_NAME MATCHES "^NetBSD$")
+ list(APPEND CMAKE_REQUIRED_LIBRARIES rt)
+ list(APPEND RSPAMD_REQUIRED_LIBRARIES rt)
+ endif ()
+
+ set(TAR "gtar" PARENT_SCOPE)
+ endif ()
+
+ # Configure for macOS (Darwin)
+ if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
+ # Add macOS-specific compiler flags
+ add_compile_definitions(_BSD_SOURCE DARWIN)
+
+ # Configure dynamic linking behavior
+ set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS} -undefined dynamic_lookup" PARENT_SCOPE)
+
+ # Special handling for LUAJIT on x86_64 macOS
+ if (ENABLE_LUAJIT AND "${ARCH}" STREQUAL "x86_64")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pagezero_size 10000 -image_base 100000000" PARENT_SCOPE)
+ endif ()
+
+ message(STATUS "Configuring for Darwin")
+ set(TAR "gnutar" PARENT_SCOPE)
+ set(CMAKE_FIND_FRAMEWORK "NEVER" PARENT_SCOPE)
+ endif ()
+
+ # Configure for Linux systems
+ if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
+ # Add Linux-specific compiler flags
+ add_compile_definitions(_GNU_SOURCE LINUX)
+ set(CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS} -D_GNU_SOURCE" PARENT_SCOPE)
+
+ # Required Linux libraries
+ set(LINUX_REQUIRED_LIBS dl rt resolv)
+ foreach (lib ${LINUX_REQUIRED_LIBS})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${lib})
+ list(APPEND RSPAMD_REQUIRED_LIBRARIES ${lib})
+ endforeach ()
+
+ message(STATUS "Configuring for Linux")
+
+ # Determine init script based on distribution
+ if (EXISTS "/etc/debian_version")
+ set(LINUX_START_SCRIPT "rspamd_debian.in" PARENT_SCOPE)
+ else ()
+ set(LINUX_START_SCRIPT "rspamd_rh.in" PARENT_SCOPE)
+ endif ()
+ endif ()
+
+ # Configure for Solaris systems
+ if (CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+ # Add Solaris-specific compiler flags
+ add_compile_definitions(__EXTENSIONS__ SOLARIS _POSIX_SOURCE _POSIX_C_SOURCE=200112)
+
+ # Required Solaris libraries
+ set(SOLARIS_REQUIRED_LIBS rt dl resolv nsl socket umem)
+ foreach (lib ${SOLARIS_REQUIRED_LIBS})
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${lib})
+ list(APPEND RSPAMD_REQUIRED_LIBRARIES ${lib})
+ endforeach ()
+
+ # Configure Solaris-specific build settings
+ set(CMAKE_VERBOSE_MAKEFILE ON PARENT_SCOPE)
+ set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE PARENT_SCOPE)
+ set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib:${RSPAMD_LIBDIR}" PARENT_SCOPE)
+ endif ()
+
+ # Always propagate required libraries to parent scope
+ set(RSPAMD_REQUIRED_LIBRARIES ${RSPAMD_REQUIRED_LIBRARIES} PARENT_SCOPE)
+ set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} PARENT_SCOPE)
+
+ # Log platform-specific configuration
+ message(STATUS "Platform: ${CMAKE_SYSTEM_NAME}")
+ message(STATUS "Platform-specific required libraries: ${RSPAMD_REQUIRED_LIBRARIES}")
+endfunction()
diff --git a/cmake/Sanitizer.cmake b/cmake/Sanitizer.cmake
index c2587066f..79ee3f686 100644
--- a/cmake/Sanitizer.cmake
+++ b/cmake/Sanitizer.cmake
@@ -1,75 +1,100 @@
+# Sanitizer configuration
# Ported from Clickhouse: https://github.com/ClickHouse/ClickHouse/blob/master/cmake/sanitize.cmake
-set (SAN_FLAGS "${SAN_FLAGS} -g -fno-omit-frame-pointer -DSANITIZER")
-# O1 is normally set by clang, and -Og by gcc
-if (COMPILER_GCC)
- if (ENABLE_FULL_DEBUG MATCHES "ON")
- set (SAN_FLAGS "${SAN_FLAGS} -O0")
- else()
- set (SAN_FLAGS "${SAN_FLAGS} -Og")
- endif()
-else ()
- if (ENABLE_FULL_DEBUG MATCHES "ON")
- set (SAN_FLAGS "${SAN_FLAGS} -O0")
- else()
- set (SAN_FLAGS "${SAN_FLAGS} -O1")
- endif()
-endif ()
-if (SANITIZE)
- if (ENABLE_JEMALLOC MATCHES "ON")
- message (STATUS "Jemalloc support is useless in case of build with sanitizers")
- set (ENABLE_JEMALLOC "OFF")
+# Define a function to configure sanitizers
+function(configure_sanitizers)
+ # Skip configuration if no sanitizer is specified
+ if (NOT SANITIZE)
+ return()
endif ()
- string(REPLACE "," ";" SANITIZE_LIST ${SANITIZE})
- foreach(SANITIZE ${SANITIZE_LIST})
- if (SANITIZE STREQUAL "address")
- set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope")
- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope")
- set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope")
- if (COMPILER_GCC)
- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libasan")
- set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libasan")
- set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libasan")
- endif ()
+ # Base sanitizer flags
+ add_compile_options(-g -fno-omit-frame-pointer)
+ add_compile_definitions(SANITIZER)
+
+ # Set optimization level based on compiler and debug settings
+ if (CMAKE_C_COMPILER_ID MATCHES "GNU")
+ if (ENABLE_FULL_DEBUG)
+ add_compile_options(-O0)
+ else ()
+ add_compile_options(-Og)
+ endif ()
+ else ()
+ if (ENABLE_FULL_DEBUG)
+ add_compile_options(-O0)
+ else ()
+ add_compile_options(-O1)
+ endif ()
+ endif ()
+
+ # Jemalloc conflicts with sanitizers
+ if (ENABLE_JEMALLOC)
+ message(STATUS "Disabling jemalloc as it's incompatible with sanitizers")
+ set(ENABLE_JEMALLOC OFF PARENT_SCOPE)
+ endif ()
- elseif (SANITIZE STREQUAL "leak")
- set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak")
- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=leak")
- set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=leak")
+ # Process the specified sanitizers
+ string(REPLACE "," ";" SANITIZE_LIST "${SANITIZE}")
- elseif (SANITIZE STREQUAL "memory")
- set (MSAN_FLAGS "-fsanitize=memory -fsanitize-memory-track-origins -fno-optimize-sibling-calls")
+ foreach (SANITIZER_TYPE IN LISTS SANITIZE_LIST)
+ if (SANITIZER_TYPE STREQUAL "address")
+ # Address Sanitizer (ASan)
+ add_compile_options(-fsanitize=address -fsanitize-address-use-after-scope)
+ add_link_options(-fsanitize=address -fsanitize-address-use-after-scope)
- set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MSAN_FLAGS}")
- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MSAN_FLAGS}")
- set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=memory")
+ if (CMAKE_C_COMPILER_ID MATCHES "GNU")
+ add_compile_options(-static-libasan)
+ add_link_options(-static-libasan)
+ endif ()
+
+ elseif (SANITIZER_TYPE STREQUAL "leak")
+ # Leak Sanitizer (LSan)
+ add_compile_options(-fsanitize=leak)
+ add_link_options(-fsanitize=leak)
+
+ elseif (SANITIZER_TYPE STREQUAL "memory")
+ # Memory Sanitizer (MSan)
+ add_compile_options(
+ -fsanitize=memory
+ -fsanitize-memory-track-origins
+ -fno-optimize-sibling-calls
+ )
+ add_link_options(-fsanitize=memory)
- if (COMPILER_GCC)
- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libmsan")
- set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libmsan")
- set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libmsan")
+ if (CMAKE_C_COMPILER_ID MATCHES "GNU")
+ add_compile_options(-static-libmsan)
+ add_link_options(-static-libmsan)
endif ()
- elseif (SANITIZE STREQUAL "undefined")
- set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined -fno-sanitize-recover=all")
- set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined")
+ elseif (SANITIZER_TYPE STREQUAL "undefined")
+ # Undefined Behavior Sanitizer (UBSan)
+ add_compile_options(-fsanitize=undefined -fno-sanitize-recover=all)
+ add_link_options(-fsanitize=undefined)
- if (COMPILER_GCC)
- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libubsan")
- set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libubsan")
- set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libubsan")
+ if (CMAKE_C_COMPILER_ID MATCHES "GNU")
+ add_compile_options(-static-libubsan)
+ add_link_options(-static-libubsan)
endif ()
+
else ()
- message (FATAL_ERROR "Unknown sanitizer type: ${SANITIZE}")
+ message(FATAL_ERROR "Unknown sanitizer type: ${SANITIZER_TYPE}")
endif ()
+
+ message(STATUS "Configured sanitizer: ${SANITIZER_TYPE}")
endforeach ()
- set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SAN_FLAGS}")
- set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SAN_FLAGS}")
- message (STATUS "Add sanitizer: ${SANITIZE}")
- # Disable sanitizing on make stage e.g. for snowball compiler
- set (ENV{ASAN_OPTIONS} "detect_leaks=0")
- message (STATUS "Sanitizer CFLAGS: ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
- message (STATUS "Sanitizer CXXFLAGS: ${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
-endif() \ No newline at end of file
+
+ # Set environment variable to disable leak detection during the build phase
+ set(ENV{ASAN_OPTIONS} "detect_leaks=0")
+
+ # Log the final configuration
+ get_directory_property(COMPILE_OPTIONS COMPILE_OPTIONS)
+ get_directory_property(LINK_OPTIONS LINK_OPTIONS)
+ message(STATUS "Sanitizer compile options: ${COMPILE_OPTIONS}")
+ message(STATUS "Sanitizer link options: ${LINK_OPTIONS}")
+
+ # Propagate the modified variable to parent scope
+ set(ENABLE_JEMALLOC ${ENABLE_JEMALLOC} PARENT_SCOPE)
+endfunction()
+
+# Execute the configuration
+configure_sanitizers()
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()