diff options
Diffstat (limited to 'cmake/Toolset.cmake')
-rw-r--r-- | cmake/Toolset.cmake | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/cmake/Toolset.cmake b/cmake/Toolset.cmake new file mode 100644 index 0000000..4e7017d --- /dev/null +++ b/cmake/Toolset.cmake @@ -0,0 +1,252 @@ +option (ENABLE_FAST_MATH "Build rspamd with fast math compiler flag [default: ON]" ON) +option (ENABLE_ANALYZER "Build rspamd with static analyzer [default: OFF]" OFF) +option (ENABLE_STATIC_LIBCXX "Build rspamd with static lib(std)c++ [default: OFF]" OFF) +option (ENABLE_COMPILE_TIME "Show compile time [default: OFF]" OFF) +option (ENABLE_LIBCXX "Use libc++ instead of libstdc++" OFF) + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU") + SET (COMPILER_GCC 1) +elseif(CMAKE_C_COMPILER_ID MATCHES "Clang|AppleClang") + SET (COMPILER_CLANG 1) +endif() + +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +SET (COMPILER_FAST_MATH "") +if (ENABLE_FAST_MATH MATCHES "ON") + # We need to keep nans and infinities, so cannot keep all fast math there + IF (COMPILER_CLANG) + SET (COMPILER_FAST_MATH "-fassociative-math -freciprocal-math -fno-signed-zeros -ffp-contract=fast") + ELSE() + SET (COMPILER_FAST_MATH "-funsafe-math-optimizations -fno-math-errno") + ENDIF () +endif () + +if (CMAKE_GENERATOR STREQUAL "Ninja") + # Turn on colored output. https://github.com/ninja-build/ninja/wiki/FAQ + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color=always") +endif () + +if (COMPILER_GCC) + # Require minimum version of gcc + set (GCC_MINIMUM_VERSION 8) + if (CMAKE_C_COMPILER_VERSION VERSION_LESS ${GCC_MINIMUM_VERSION} AND NOT CMAKE_VERSION VERSION_LESS 2.8.9) + message (FATAL_ERROR "GCC version must be at least ${GCC_MINIMUM_VERSION}.") + endif () + if (ENABLE_LIBCXX MATCHES "ON") + # XXX: too complicated to implement for now + endif () +elseif (COMPILER_CLANG) + # Require minimum version of clang + set (CLANG_MINIMUM_VERSION 7) + if (CMAKE_C_COMPILER_VERSION VERSION_LESS ${CLANG_MINIMUM_VERSION}) + message (FATAL_ERROR "Clang version must be at least ${CLANG_MINIMUM_VERSION}.") + endif () + # Hack to fix try_compile + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-command-line-argument") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-command-line-argument") + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-ignored-optimization-argument") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-ignored-optimization-argument") + if (ENABLE_LIBCXX MATCHES "AUTO") + include(CheckCXXSourceCompiles) + set(OLD_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + check_cxx_source_compiles(" +#include <version> +int main() { return 0; } + " HAVE_LIBCXX ) + if (HAVE_LIBCXX) + SET(ENABLE_LIBCXX "ON") + else() + SET(ENABLE_LIBCXX "OFF") + endif() + set(CMAKE_CXX_FLAGS "${OLD_CMAKE_CXX_FLAGS}") + endif() + if (ENABLE_LIBCXX MATCHES "ON") + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + set(CLANG_DEFAULT_CXX_STDLIB "libc++") + endif () +else () + message (WARNING "You are using an unsupported compiler ${CMAKE_C_COMPILER_ID}. Compilation has only been tested with Clang 4+ and GCC 4+.") +endif () + +option(LINKER_NAME "Linker name or full path") + +find_program(LLD_PATH NAMES "ld.lld" "lld") +find_program(GOLD_PATH NAMES "ld.gold" "gold") + +if(NOT LINKER_NAME) + if(LLD_PATH) + if (COMPILER_CLANG) + set(LINKER_NAME "lld") + elseif(NOT SANITIZE) + if(GOLD_PATH) + set(LINKER_NAME "gold") + else() + message(STATUS "Use generic 'ld' as a linker: gold not found") + endif() + else() + message(STATUS "Use generic 'ld' as a linker: sanitizers are enabled") + endif() + elseif(GOLD_PATH) + set(LINKER_NAME "gold") + else() + message(STATUS "Use generic 'ld' as a linker") + endif() +endif() + +if(LINKER_NAME) + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=${LINKER_NAME}") + set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=${LINKER_NAME}") + + message(STATUS "Using custom linker by name: ${LINKER_NAME}") +endif () + +option (ENABLE_STATIC "Enable static compiling [default: OFF]" OFF) + +if (ENABLE_STATIC MATCHES "ON") + MESSAGE(STATUS "Static build of rspamd implies that the target binary will be *GPL* licensed") + SET(GPL_RSPAMD_BINARY 1) + SET(CMAKE_SKIP_INSTALL_RPATH ON) + SET(BUILD_STATIC 1) + SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a") + SET(BUILD_SHARED_LIBS OFF) + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") + SET(LINK_TYPE "STATIC") + SET(NO_SHARED "ON") + # Dirty hack for cmake + SET(CMAKE_EXE_LINK_DYNAMIC_C_FLAGS) # remove -Wl,-Bdynamic + SET(CMAKE_EXE_LINK_DYNAMIC_CXX_FLAGS) + SET(CMAKE_SHARED_LIBRARY_C_FLAGS) # remove -fPIC + SET(CMAKE_SHARED_LIBRARY_CXX_FLAGS) + SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) # remove -rdynamic + SET(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) +else () + if (NO_SHARED MATCHES "OFF") + SET(LINK_TYPE "SHARED") + else () + SET(LINK_TYPE "STATIC") + endif () +endif () + + +# Legacy options support +option (ENABLE_COVERAGE "Build rspamd with code coverage options [default: OFF]" OFF) +option (ENABLE_OPTIMIZATION "Enable extra optimizations [default: OFF]" OFF) +option (SKIP_RELINK_RPATH "Skip relinking and full RPATH for the install tree" OFF) +option (ENABLE_FULL_DEBUG "Build rspamd with all possible debug [default: OFF]" OFF) + +if(NOT CMAKE_BUILD_TYPE) + if (ENABLE_FULL_DEBUG MATCHES "ON") + set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE) + endif() + if (ENABLE_COVERAGE MATCHES "ON") + set(CMAKE_BUILD_TYPE Coverage CACHE STRING "" FORCE) + endif() + if (ENABLE_OPTIMIZATION MATCHES "ON") + set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE) + endif() +endif() + +if (CMAKE_CONFIGURATION_TYPES) # multiconfig generator? + set (CMAKE_CONFIGURATION_TYPES "Debug;RelWithDebInfo;Release;Coverage" CACHE STRING "" FORCE) +else() + if (NOT CMAKE_BUILD_TYPE) + if (NOT SANITIZE) + message(STATUS "Defaulting to release build.") + set(CMAKE_BUILD_TYPE Release CACHE STRING "" FORCE) + else () + message(STATUS "Defaulting to debug build due to sanitizers being enabled.") + set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE) + endif () + endif() + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "Choose the type of build") + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug;Release;Coverage") +endif() + +string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC) +message (STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE_UC}") +set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS} -O1 --coverage -fno-inline -fno-default-inline -fno-inline-small-functions ${COMPILER_FAST_MATH}") +set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS} -O1 --coverage -fno-inline -fno-default-inline -fno-inline-small-functions ${COMPILER_FAST_MATH}") + +if (COMPILER_GCC) + # GCC flags + set (COMPILER_DEBUG_FLAGS "-g -ggdb -g3 -ggdb3") + set (CXX_COMMON_FLAGS "") + set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} -O2 ${COMPILER_FAST_MATH} ${COMPILER_DEBUG_FLAGS}") + set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -O2 ${COMPILER_FAST_MATH} ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}") + + set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 ${COMPILER_FAST_MATH} -fomit-frame-pointer") + set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 ${COMPILER_FAST_MATH} -fomit-frame-pointer ${CXX_COMMON_FLAGS}") + + if (ENABLE_FULL_DEBUG MATCHES "ON") + if (ENABLE_ANALYZER MATCHES "ON") + # Check support of -fanalyzer + CHECK_C_COMPILER_FLAG(-fanalyzer SUPPORT_FANALYZER) + if (SUPPORT_FANALYZER) + set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fanalyzer") + #set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fanalyzer") + endif() + endif () + set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 ${COMPILER_DEBUG_FLAGS}") + set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}") + else() + set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Og ${COMPILER_DEBUG_FLAGS}") + set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}") + endif() +elseif (COMPILER_CLANG) + # Clang flags + set (COMPILER_DEBUG_FLAGS "-g -glldb -gdwarf-aranges -gdwarf-4") + set (CXX_COMMON_FLAGS "") + set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O2 -fomit-frame-pointer ${COMPILER_FAST_MATH}") + set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -fomit-frame-pointer ${COMPILER_FAST_MATH} ${CXX_COMMON_FLAGS}") + + set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} -O2 ${COMPILER_FAST_MATH} ${COMPILER_DEBUG_FLAGS}") + set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -O2 ${COMPILER_FAST_MATH} ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}") + + set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0 ${COMPILER_DEBUG_FLAGS}") + set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 ${COMPILER_DEBUG_FLAGS} ${CXX_COMMON_FLAGS}") +endif() + + +if (CMAKE_BUILD_TYPE_UC MATCHES "RELEASE|RELWITHDEBINFO") + set(ENABLE_LTO_INIT ON) +else() + set(ENABLE_LTO_INIT OFF) +endif() +option(ENABLE_LTO "Build rspamd with Link Time Optimization if supported [default: ${ENABLE_LTO_INIT}]" ${ENABLE_LTO_INIT}) + +if (CMAKE_BUILD_TYPE_UC MATCHES "COVERAGE") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") + message (STATUS "IPO not enabled for COVERAGE build") +elseif (ENABLE_LTO) + if (${CMAKE_VERSION} VERSION_GREATER "3.9.0") + cmake_policy (SET CMP0069 NEW) + include (CheckIPOSupported) + check_ipo_supported (RESULT SUPPORT_LTO OUTPUT LTO_DIAG ) + if (SUPPORT_LTO) + set (CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) + message (STATUS "Enable IPO for the ${CMAKE_BUILD_TYPE} build") + else () + message(WARNING "IPO is not supported: ${LTO_DIAG}") + endif () + endif () +else () + message (STATUS "IPO not enabled for the ${CMAKE_BUILD_TYPE} build") +endif () + +if (ENABLE_STATIC_LIBCXX MATCHES "ON") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++") + set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libstdc++") +endif() + +if (ENABLE_COMPILE_TIME MATCHES "ON") + set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "/usr/bin/time") +endif() + +message (STATUS "Final CFLAGS: ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UC}}") +message (STATUS "Final CXXFLAGS: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE_UC}}") +message (STATUS "Final link flags for shlib: ${CMAKE_SHARED_LINKER_FLAGS}") +message (STATUS "Final link flags for exe: ${CMAKE_EXE_LINKER_FLAGS}") + |