Skip to content

Commit 79d19e7

Browse files
committed
Add sanitizer flags to cmake
1 parent 2c540e0 commit 79d19e7

File tree

2 files changed

+67
-6
lines changed

2 files changed

+67
-6
lines changed

CMakeLists.txt

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ option(UMF_BUILD_BENCHMARKS "Build UMF benchmarks" OFF)
2626
option(UMF_ENABLE_POOL_TRACKING "Build UMF with pool tracking" ON)
2727
option(UMF_DEVELOPER_MODE "Enable developer checks, treats warnings as errors" OFF)
2828
option(UMF_FORMAT_CODE_STYLE "Format UMF code with clang-format" OFF)
29+
option(USE_ASAN "Enable AddressSanitizer checks" OFF)
30+
option(USE_UBSAN "Enable UndefinedBehaviorSanitizer checks" OFF)
31+
option(USE_TSAN "Enable ThreadSanitizer checks" OFF)
2932

3033
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
3134
set(LINUX TRUE)
@@ -57,6 +60,17 @@ if(MSVC)
5760
set(CUSTOM_COMMAND_BINARY_DIR ${CUSTOM_COMMAND_BINARY_DIR}/$<CONFIG>)
5861
endif()
5962

63+
# Sanitizer flags
64+
if(USE_ASAN)
65+
add_sanitizer_flag(address)
66+
endif()
67+
if(USE_UBSAN)
68+
add_sanitizer_flag(undefined)
69+
endif()
70+
if(USE_TSAN)
71+
add_sanitizer_flag(thread)
72+
endif()
73+
6074
# A header only library to specify include directories in transitive
6175
# dependencies.
6276
add_library(umf_headers INTERFACE)
@@ -94,7 +108,7 @@ endif()
94108
if(UMF_FORMAT_CODE_STYLE)
95109
find_program(CLANG_FORMAT NAMES clang-format-15 clang-format-15.0 clang-format)
96110

97-
if(CLANG_FORMAT)
111+
if(CLANG_FORMAT)
98112
get_program_version_major_minor(${CLANG_FORMAT} CLANG_FORMAT_VERSION)
99113
message(STATUS "Found clang-format: ${CLANG_FORMAT} (version: ${CLANG_FORMAT_VERSION})")
100114

@@ -105,7 +119,7 @@ if(UMF_FORMAT_CODE_STYLE)
105119
else()
106120
message(FATAL_ERROR "UMF_FORMAT_CODE_STYLE=ON, but clang-format not found (required version: ${CLANG_FORMAT_REQUIRED})")
107121
endif()
108-
122+
109123
# Obtain files for clang-format check
110124
set(format_glob)
111125
foreach(DIR IN ITEMS include src test benchmark)
@@ -123,11 +137,11 @@ if(UMF_FORMAT_CODE_STYLE)
123137
file(GLOB_RECURSE format_list ${format_glob})
124138

125139
message(STATUS "Adding clang-format-check and clang-format-apply make targets")
126-
140+
127141
add_custom_target(clang-format-check
128142
COMMAND ${CLANG_FORMAT}
129-
--style=file
130-
--dry-run
143+
--style=file
144+
--dry-run
131145
-Werror
132146
${format_list}
133147
COMMENT "Check files formatting using clang-format")
@@ -137,7 +151,7 @@ if(UMF_FORMAT_CODE_STYLE)
137151
--style=file
138152
--i
139153
${format_list}
140-
COMMENT "Format files using clang-format")
154+
COMMENT "Format files using clang-format")
141155
endif()
142156

143157
# Add license to the installation path

cmake/helpers.cmake

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
# helpers.cmake -- helper functions for top-level CMakeLists.txt
77
#
88

9+
# CMake modules that check whether the C/C++ compiler supports a given flag
10+
include(CheckCCompilerFlag)
11+
include(CheckCXXCompilerFlag)
12+
913
# Sets ${ret} to version of program specified by ${name} in major.minor format
1014
function(get_program_version_major_minor name ret)
1115
execute_process(COMMAND ${name} --version
@@ -104,3 +108,46 @@ function(add_umf_library)
104108
add_umf_target_compile_options(${ARG_NAME})
105109
add_umf_target_link_options(${ARG_NAME})
106110
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

Comments
 (0)