aboutsummaryrefslogtreecommitdiffstats
path: root/CMakeLists.txt
blob: 7735884c30e20c7c26745d77f9b94c2bf953b4eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
#
# Rspamd - rapid antispam system
#
# Cmake configuration file
#

############################# INITIAL SECTION #############################################
cmake_minimum_required(VERSION 3.15 FATAL_ERROR)

# 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)

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}")

project(rspamd
        VERSION "${RSPAMD_VERSION}"
        LANGUAGES C CXX ASM
        DESCRIPTION "Rapid spam filtering system"
        HOMEPAGE_URL "https://rspamd.com"
)

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)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/")

set(RSPAMD_MASTER_SITE_URL "https://rspamd.com")

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")

############################# OPTIONS SECTION #############################################
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 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(ArchDep)
include(Paths)

include(OSDep)
ConfigurePlatformSpecifics()

if (ENABLE_PCRE2)
    set(WITH_PCRE2 1)
    # For utf8 API
    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}/"
        "${CMAKE_SOURCE_DIR}/src"
        "${CMAKE_SOURCE_DIR}/src/libutil"
        "${CMAKE_SOURCE_DIR}/src/libserver"
        "${CMAKE_SOURCE_DIR}/src/libmime"
        "${CMAKE_SOURCE_DIR}/src/libstat"
        "${CMAKE_SOURCE_DIR}/src/libcryptobox"
        "${CMAKE_SOURCE_DIR}/contrib/libucl"
        "${CMAKE_SOURCE_DIR}/contrib/replxx/include"
        "${CMAKE_SOURCE_DIR}/contrib/uthash"
        "${CMAKE_SOURCE_DIR}/contrib/http-parser"
        "${CMAKE_SOURCE_DIR}/contrib/fpconv"
        "${CMAKE_SOURCE_DIR}/contrib/libottery"
        "${CMAKE_SOURCE_DIR}/contrib/cdb"
        "${CMAKE_SOURCE_DIR}/contrib/snowball/include"
        "${CMAKE_SOURCE_DIR}/contrib/librdns"
        "${CMAKE_SOURCE_DIR}/contrib/aho-corasick"
        "${CMAKE_SOURCE_DIR}/contrib/lc-btrie"
        "${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"
)

set(TAR "tar")
include(OSDep)

# Now find libraries and headers
list(APPEND RSPAMD_REQUIRED_LIBRARIES "m")
list(APPEND RSPAMD_REQUIRED_LIBRARIES "pthread")

# Lua setup
if (ENABLE_LUAJIT)
    ProcessPackage(LIBLUAJIT LIBRARY "luajit"
            "luajit-2.1"
            "luajit2.1"
            "luajit-2.0"
            "luajit2.0"
            "luajit-5.1"
            INCLUDE luajit.h INCLUDE_SUFFIXES
            "include/luajit-2.1"
            "include/luajit-2.0"
            "include/luajit"
            ROOT ${LUA_ROOT}
            MODULES luajit)
    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"
            INCLUDE lua.h INCLUDE_SUFFIXES
            "include/lua-5.3"
            "include/lua5.3"
            "include/lua53"
            "include/lua"
            ROOT ${LUA_ROOT}
            MODULES lua53
            OPTIONAL)

    if (NOT WITH_LIBLUA)
        ProcessPackage(LIBLUA LIBRARY "lua"
                "lua-5.4"
                LIB_SUFFIXES "lua5.4"
                INCLUDE lua.h INCLUDE_SUFFIXES
                "include/lua-5.4"
                "include/lua5.4"
                "include/lua54"
                "include/lua"
                ROOT ${LUA_ROOT}
                MODULES lua54
                OPTIONAL)
        if (NOT WITH_LIBLUA)
            ProcessPackage(LIBLUA LIBRARY "lua"
                    "lua-5.2"
                    LIB_SUFFIXES "lua5.2"
                    INCLUDE lua.h INCLUDE_SUFFIXES
                    "include/lua-5.2"
                    "include/lua5.2"
                    "include/lua52"
                    "include/lua"
                    ROOT ${LUA_ROOT}
                    MODULES lua52
                    OPTIONAL)

            if (NOT WITH_LIBLUA)
                ProcessPackage(LIBLUA LIBRARY "lua"
                        "lua-5.1"
                        INCLUDE lua.h INCLUDE_SUFFIXES
                        "include/lua-5.1"
                        "include/lua5.1"
                        "include/lua51"
                        "include/lua"
                        ROOT ${LUA_ROOT}
                        MODULES lua51)
            endif ()
        endif ()
    endif ()
endif ()

# 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 ()

# 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)

# 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 ()
    ProcessPackage(PCRE LIBRARY pcre INCLUDE pcre.h INCLUDE_SUFFIXES include/pcre
            ROOT ${PCRE_ROOT_DIR} MODULES pcre libpcre pcre3 libpcre3)
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
        ROOT ${ICU_ROOT_DIR} MODULES icu-uc)
ProcessPackage(ICUC LIBRARY icuuc INCLUDE unicode/ucnv.h
        ROOT ${ICU_ROOT_DIR} MODULES icu-uc)
ProcessPackage(ICUIO LIBRARY icuio INCLUDE unicode/ucnv.h
        ROOT ${ICU_ROOT_DIR} MODULES icu-io)
ProcessPackage(ICUI18N LIBRARY icui18n INCLUDE unicode/ucnv.h
        ROOT ${ICU_ROOT_DIR} MODULES icu-i18n)
ProcessPackage(LIBCRYPT LIBRARY crypto INCLUDE openssl/evp.h
        ROOT ${OPENSSL_ROOT_DIR} MODULES openssl libcrypt)
ProcessPackage(LIBSSL LIBRARY ssl INCLUDE openssl/ssl.h
        ROOT ${OPENSSL_ROOT_DIR} MODULES openssl libssl)
ProcessPackage(LIBZ LIBRARY z INCLUDE zlib.h INCLUDE_SUFFIXES include/zlib
        ROOT ${LIBZ_ROOT_DIR} MODULES z)
ProcessPackage(SODIUM LIBRARY sodium INCLUDE sodium.h
        INCLUDE_SUFFIXES include/libsodium include/sodium
        ROOT ${LIBSODIUM_ROOT_DIR} MODULES libsodium>=1.0.0)
ProcessPackage(LIBARCHIVE LIBRARY archive INCLUDE archive.h
        ROOT ${LIBARCHIVE_ROOT_DIR} MODULES libarchive>=3.0.0)

if (ENABLE_FASTTEXT)
    ProcessPackage(FASTTEXT LIBRARY fasttext INCLUDE fasttext/fasttext.h
            ROOT ${FASTTEXT_ROOT_DIR} MODULES fasttext)
    set(WITH_FASTTEXT "1")
endif ()

# Include common compiler and platform specific configurations
include(CompilerWarnings)
include(Hyperscan)
include(Openblas)

# Lua tracing
if (ENABLE_LUA_TRACE)
    set(WITH_LUA_TRACE 1)
endif ()

# 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}")

# 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)
# Disable zstd deprecation warnings, as they are not relevant for us
add_definitions(-DZSTD_DISABLE_DEPRECATE_WARNINGS)

# Check platform specific includes
include(CheckSystemHeaders)

# Check macros, functions, and features
include(CheckSystemFeatures)

# 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 required subdirectories for dependencies
include(AddDependencySubdirectories)
AddDependencySubdirectories()

############################ TARGETS SECTION ###############################

# Generate config.h
configure_file(config.h.in src/config.h)

##################### INSTALLATION ##########################################
# Setup installation targets
include(InstallRspamdFiles)
InstallRspamdFiles()

# 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})

# Tests
# Include CTest for testing support
include(CTest)
enable_testing()
add_subdirectory(test)

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')

# Setup PVS Studio if available
include(SetupPVSStudio)
SetupPVSStudio()