diff options
Diffstat (limited to '')
-rw-r--r-- | cmake/modules/FindSanitizers.cmake | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/cmake/modules/FindSanitizers.cmake b/cmake/modules/FindSanitizers.cmake new file mode 100644 index 00000000..0f4c8606 --- /dev/null +++ b/cmake/modules/FindSanitizers.cmake @@ -0,0 +1,76 @@ +if(NOT Sanitizers_FIND_COMPONENTS) + set(Sanitizers_FIND_COMPONENTS + address undefined_behavior) +endif() +if(HAVE_JEMALLOC) + message(WARNING "JeMalloc does not work well with sanitizers") +endif() + +set(Sanitizers_COMPILE_OPTIONS) + +foreach(component ${Sanitizers_FIND_COMPONENTS}) + if(component STREQUAL "address") + set(Sanitizers_address_COMPILE_OPTIONS "-fsanitize=address") + elseif(component STREQUAL "leak") + set(Sanitizers_leak_COMPILE_OPTIONS "-fsanitize=leak") + elseif(component STREQUAL "thread") + if ("address" IN_LIST ${Sanitizers_FIND_COMPONENTS} OR + "leak" IN_LIST ${Sanitizers_FIND_COMPONENTS}) + message(SEND_ERROR "Cannot combine -fsanitize-leak w/ -fsanitize-thread") + elseif(NOT CMAKE_POSITION_INDEPENDENT_CODE) + message(SEND_ERROR "TSan requires all code to be position independent") + endif() + set(Sanitizers_thread_COMPILE_OPTIONS "-fsanitize=thread") + elseif(component STREQUAL "undefined_behavior") + # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88684 + set(Sanitizers_undefined_behavior_COMPILE_OPTIONS "-fsanitize=undefined;-fno-sanitize=vptr") + else() + message(SEND_ERROR "Unsupported sanitizer: ${component}") + endif() + list(APPEND Sanitizers_COMPILE_OPTIONS "${Sanitizers_${component}_COMPILE_OPTIONS}") +endforeach() + +if(Sanitizers_address_COMPILE_OPTIONS OR Sanitizers_leak_COMPILE_OPTIONS) + # ASAN_LIBRARY will be read by ceph.in to preload the asan library + find_library(ASAN_LIBRARY + NAMES + libasan.so.5 + libasan.so.4 + libasan.so.3) +endif() + +if(Sanitizers_COMPILE_OPTIONS) + list(APPEND Sanitizers_COMPILE_OPTIONS + "-fno-omit-frame-pointer") +endif() + +include(CheckCXXSourceCompiles) +set(CMAKE_REQUIRED_FLAGS ${Sanitizers_COMPILE_OPTIONS}) +set(CMAKE_REQUIRED_LIBRARIES ${Sanitizers_COMPILE_OPTIONS}) +check_cxx_source_compiles("int main() {}" + Sanitizers_ARE_SUPPORTED) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Sanitizers + REQUIRED_VARS + Sanitizers_COMPILE_OPTIONS + Sanitizers_ARE_SUPPORTED) + +if(Sanitizers_FOUND) + if(NOT TARGET Sanitizers::Sanitizers) + add_library(Sanitizers::Sanitizers INTERFACE IMPORTED) + set_target_properties(Sanitizers::Sanitizers PROPERTIES + INTERFACE_COMPILE_OPTIONS "${Sanitizers_COMPILE_OPTIONS}" + INTERFACE_LINK_LIBRARIES "${Sanitizers_COMPILE_OPTIONS}") + endif() + foreach(component ${Sanitizers_FIND_COMPONENTS}) + if(NOT TARGET Sanitizers::${component}) + set(target Sanitizers::${component}) + set(compile_option "${Sanitizers_${component}_COMPILE_OPTIONS}") + add_library(${target} INTERFACE IMPORTED) + set_target_properties(${target} PROPERTIES + INTERFACE_COMPILE_OPTIONS "${compile_option}" + INTERFACE_LINK_LIBRARIES "${compile_option}") + endif() + endforeach() +endif() |