5 # Enable compiler sanitizer flags.
7 # The following sanitizers are supported:
13 # - Undefined Behaviour Sanitizer
15 # All of them are implemented in Clang, depending on your version, and
16 # there is an work in progress in GCC, where some of them are currently
19 # This module will check your current compiler version to see if it
20 # supports the sanitizers that you want to enable
27 # include(ECMEnableSanitizers)
29 # to your ``CMakeLists.txt``. Note that this module is included in
30 # KDECompilerSettings, so projects using that module do not need to also
33 # The sanitizers are not enabled by default. Instead, you must set
34 # ``ECM_ENABLE_SANITIZERS`` (either in your ``CMakeLists.txt`` or on the
35 # command line) to a semicolon-separated list of sanitizers you wish to enable.
44 # The sanitizers "address", "memory" and "thread" are mutually exclusive. You
45 # cannot enable two of them in the same build.
47 # "leak" requires the "address" sanitizer.
51 # To reduce the overhead induced by the instrumentation of the sanitizers, it
52 # is advised to enable compiler optimizations (``-O1`` or higher).
57 # This is an example of usage::
61 # cmake -DECM_ENABLE_SANITIZERS='address;leak;undefined' ..
65 # Most of the sanitizers will require Clang. To enable it, use::
67 # -DCMAKE_CXX_COMPILER=clang++
71 #=============================================================================
72 # Copyright 2014 Mathieu Tarral <mathieu.tarral@gmail.com>
74 # Distributed under the OSI-approved BSD License (the "License");
75 # see accompanying file COPYING-CMAKE-SCRIPTS for details.
77 # This software is distributed WITHOUT ANY WARRANTY; without even the
78 # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
79 # See the License for more information.
80 #=============================================================================
81 # (To distribute this file outside of extra-cmake-modules, substitute the full
82 # License text for the above reference.)
84 # MACRO check_compiler_version
85 #-----------------------------
86 macro (check_compiler_version gcc_required_version clang_required_version)
89 CMAKE_CXX_COMPILER_ID MATCHES "GNU"
91 CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${gcc_required_version}
95 CMAKE_CXX_COMPILER_ID MATCHES "Clang"
97 CMAKE_CXX_COMPILER_VERSION VERSION_LESS ${clang_required_version}
101 message(FATAL_ERROR "You ask to enable the sanitizer ${CUR_SANITIZER},
102 but your compiler ${CMAKE_CXX_COMPILER_ID} version ${CMAKE_CXX_COMPILER_VERSION}
103 does not support it !
104 You should use at least GCC ${gcc_required_version} or Clang ${clang_required_version}
105 (99.99 means not implemented yet)")
109 # MACRO check_compiler_support
110 #------------------------------
111 macro (enable_sanitizer_flags sanitize_option)
112 if (${sanitize_option} MATCHES "address")
113 check_compiler_version("4.8" "3.1")
114 set(XSAN_COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer -fno-optimize-sibling-calls")
115 set(XSAN_LINKER_FLAGS "asan")
116 elseif (${sanitize_option} MATCHES "thread")
117 check_compiler_version("4.8" "3.1")
118 set(XSAN_COMPILE_FLAGS "-fsanitize=thread")
119 set(XSAN_LINKER_FLAGS "tsan")
120 elseif (${sanitize_option} MATCHES "memory")
121 check_compiler_version("99.99" "3.1")
122 set(XSAN_COMPILE_FLAGS "-fsanitize=memory")
123 elseif (${sanitize_option} MATCHES "leak")
124 check_compiler_version("4.9" "3.4")
125 set(XSAN_COMPILE_FLAGS "-fsanitize=leak")
126 set(XSAN_LINKER_FLAGS "lsan")
127 elseif (${sanitize_option} MATCHES "undefined")
128 check_compiler_version("4.9" "3.1")
129 set(XSAN_COMPILE_FLAGS "-fsanitize=undefined -fno-omit-frame-pointer -fno-optimize-sibling-calls")
131 message(FATAL_ERROR "Compiler sanitizer option \"${sanitize_option}\" not supported.")
135 # for each element of the ECM_ENABLE_SANITIZERS list
136 foreach ( CUR_SANITIZER ${ECM_ENABLE_SANITIZERS} )
138 string(TOLOWER ${CUR_SANITIZER} CUR_SANITIZER)
139 # check option and enable appropriate flags
140 enable_sanitizer_flags ( ${CUR_SANITIZER} )
141 set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${XSAN_COMPILE_FLAGS}" )
142 if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
143 link_libraries(${XSAN_LINKER_FLAGS})
145 if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
146 string(REPLACE "-Wl,--no-undefined" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
147 string(REPLACE "-Wl,--no-undefined" "" CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS}")