diff --git a/cmake/modules/Sanitizers.cmake b/cmake/modules/Sanitizers.cmake new file mode 100644 --- /dev/null +++ b/cmake/modules/Sanitizers.cmake @@ -0,0 +1,39 @@ +# Check if the requested sanitizers are supported, and set the appropriated +# flags. +function(enable_sanitizers) + # Build the -fsanitize= option + list(JOIN ARGN "," _fsanitize_option_list) + set(_fsanitize_option -fsanitize=${_fsanitize_option_list}) + + include(SanitizeHelper) + sanitize_c_cxx_definition("supports_" ${_fsanitize_option} _sanitizers_compile) + + # check_cxx_source_compiles() runs the compilation and link phases at the + # same time, so add the flag under test for both. + set(CMAKE_REQUIRED_FLAGS ${_fsanitize_option}) + set(_save_linker_flags ${CMAKE_EXE_LINKER_FLAGS}) + string(APPEND CMAKE_EXE_LINKER_FLAGS " ${_fsanitize_option}") + + include(CheckCXXSourceCompiles) + check_cxx_source_compiles(" + #include + #include + extern \"C\" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { return 0; } + __attribute__((weak)) int main() { return 0; } + " ${_sanitizers_compile}) + + set(CMAKE_EXE_LINKER_FLAGS ${_save_linker_flags}) + + if(NOT ${_sanitizers_compile}) + message(FATAL_ERROR "The sanitizers option is not supported: ${_fsanitize_option}") + endif() + + # Some sanitizers require some extra options to be efficient + if("address" IN_LIST ARGN OR "undefined" IN_LIST ARGN) + include(AddCompilerFlags) + add_compiler_flags(-fno-omit-frame-pointer -fno-optimize-sibling-calls) + endif() + + add_compile_options(${_fsanitize_option}) + add_link_options(${_fsanitize_option}) +endfunction() diff --git a/contrib/teamcity/build-configurations.sh b/contrib/teamcity/build-configurations.sh --- a/contrib/teamcity/build-configurations.sh +++ b/contrib/teamcity/build-configurations.sh @@ -67,6 +67,8 @@ "-DCRYPTO_USE_ASM=OFF" "-DENABLE_SANITIZERS=address" "-DCCACHE=OFF" + "-DCMAKE_C_COMPILER=clang" + "-DCMAKE_CXX_COMPILER=clang++" ) CMAKE_FLAGS="${CMAKE_FLAGS[*]}" "${CI_SCRIPTS_DIR}"/build_cmake.sh ninja check check-functional diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,18 +51,9 @@ include(ClangTidy) endif() -# Allow usage of sanitizers by setting ECM_ENABLE_SANITIZERS if(ENABLE_SANITIZERS) - set(ECM_ENABLE_SANITIZERS ${ENABLE_SANITIZERS}) - find_package(ECM NO_MODULE) - if(ECM_MODULE_PATH) - list(APPEND CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) - include(ECMEnableSanitizers) - else() - message(FATAL_ERROR - "ECM is required to enable the sanitizers (https://api.kde.org/ecm/manual/ecm.7.html). Try installing 'extra-cmake-modules' package." - ) - endif() + include(Sanitizers) + enable_sanitizers(${ENABLE_SANITIZERS}) endif() include(AddCompilerFlags)