|
6 | 6 | # helpers.cmake -- helper functions for top-level CMakeLists.txt
|
7 | 7 | #
|
8 | 8 |
|
| 9 | +# CMake modules that check whether the C/C++ compiler supports a given flag |
| 10 | +include(CheckCCompilerFlag) |
| 11 | +include(CheckCXXCompilerFlag) |
| 12 | + |
9 | 13 | # Sets ${ret} to version of program specified by ${name} in major.minor format
|
10 | 14 | function(get_program_version_major_minor name ret)
|
11 | 15 | execute_process(COMMAND ${name} --version
|
@@ -104,3 +108,46 @@ function(add_umf_library)
|
104 | 108 | add_umf_target_compile_options(${ARG_NAME})
|
105 | 109 | add_umf_target_link_options(${ARG_NAME})
|
106 | 110 | endfunction()
|
| 111 | + |
| 112 | +# Add sanitizer ${flag}, if it is supported, for both C and C++ compiler |
| 113 | +macro(add_sanitizer_flag flag) |
| 114 | + # Save current 'CMAKE_REQUIRED_LIBRARIES' state and temporarily extend it with |
| 115 | + # '-fsanitize=${flag}'. It is required by CMake to check the compiler for |
| 116 | + # availability of provided sanitizer ${flag}. |
| 117 | + if(WINDOWS) |
| 118 | + set(SANITIZER_FLAG "/fsanitize=${flag}") |
| 119 | + set(SANITIZER_ARGS "") |
| 120 | + else() |
| 121 | + set(SANITIZER_FLAG "-fsanitize=${flag}") |
| 122 | + set(SANITIZER_ARGS "-fno-sanitize-recover=all") |
| 123 | + endif() |
| 124 | + |
| 125 | + set(SAVED_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) |
| 126 | + set(CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES} ${SANITIZER_FLAG}") |
| 127 | + |
| 128 | + if(${flag} STREQUAL "address") |
| 129 | + set(check_name "HAS_ASAN") |
| 130 | + elseif(${flag} STREQUAL "undefined") |
| 131 | + set(check_name "HAS_UBSAN") |
| 132 | + elseif(${flag} STREQUAL "thread") |
| 133 | + set(check_name "HAS_TSAN") |
| 134 | + endif() |
| 135 | + |
| 136 | + # Check C and CXX compilers for given sanitizer flag. |
| 137 | + check_c_compiler_flag("${SANITIZER_FLAG}" "C_${check_name}") |
| 138 | + check_cxx_compiler_flag("${SANITIZER_FLAG}" "CXX_${check_name}") |
| 139 | + if (${C_${check_name}} OR ${CXX_${check_name}}) |
| 140 | + # Set appropriate linker flags for building executables. |
| 141 | + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${SANITIZER_FLAG} ${SANITIZER_ARGS}") |
| 142 | + if (${C_${check_name}}) |
| 143 | + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZER_FLAG} ${SANITIZER_ARGS}") |
| 144 | + endif() |
| 145 | + if (${CXX_${check_name}}) |
| 146 | + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZER_FLAG} ${SANITIZER_ARGS}") |
| 147 | + endif() |
| 148 | + else() |
| 149 | + message(FATAL_ERROR "${flag} sanitizer is not supported (neither by C nor CXX compiler)") |
| 150 | + endif() |
| 151 | + |
| 152 | + set(CMAKE_REQUIRED_LIBRARIES ${SAVED_CMAKE_REQUIRED_LIBRARIES}) |
| 153 | +endmacro() |
0 commit comments