1 get_cmake_property(ENABLED_LANGUAGES ENABLED_LANGUAGES)
2 include(CheckCXXCompilerFlag)
3 include(CheckCCompilerFlag)
5 function(list_append var)
7 list(FIND ${var} ${arg} found)
9 list(APPEND ${var} ${arg})
12 set(${var} ${${var}} PARENT_SCOPE)
15 macro(sanitize_flag_cx)
17 string(REPLACE "+" "x" var ${arg})
18 string(REGEX REPLACE "[^A-Za-z0-9_-]+" "-" var ${var})
19 string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${SANITIZE_CX} ${arg}")
20 list(FIND ENABLED_LANGUAGES C found)
21 if(${found} GREATER -1)
22 check_c_compiler_flag(${arg} cx${var})
24 list_append(SANITIZE_CX ${arg})
27 list(FIND ENABLED_LANGUAGES CXX found)
28 if(${found} GREATER -1)
29 check_cxx_compiler_flag(${arg} cx${var})
31 list_append(SANITIZE_CX ${arg})
34 set(CMAKE_REQUIRED_FLAGS)
38 macro(sanitize_flag_ld)
40 string(REPLACE "+" "x" var ${arg})
41 string(REGEX REPLACE "[^A-Za-z0-9_-]+" "-" var ${var})
42 string(REPLACE ";" " " CMAKE_REQUIRED_FLAGS "${SANITIZE_CX} ${SANITIZE_LD} ${arg}")
43 list(FIND ENABLED_LANGUAGES C found)
44 if(${found} GREATER -1)
45 check_c_compiler_flag(${arg} ld${var})
47 list_append(SANITIZE_LD ${arg})
50 list(FIND ENABLED_LANGUAGES CXX found)
51 if(${found} GREATER -1)
52 check_cxx_compiler_flag(${arg} ld${var})
54 list_append(SANITIZE_LD ${arg})
57 set(CMAKE_REQUIRED_FLAGS)
62 CMAKE_C_COMPILER_ID MATCHES "GNU|[Cc]lang|LLVM" OR
63 CMAKE_CXX_COMPILER_ID MATCHES "GNU|[Cc]lang|LLVM"
65 sanitize_flag_cx(-fsanitize=address)
66 sanitize_flag_cx(-fsanitize=leak)
67 sanitize_flag_cx(-fsanitize=undefined)
68 sanitize_flag_cx(-fsanitize-recover=all)
69 sanitize_flag_cx(-fno-omit-frame-pointer)
71 CMAKE_C_COMPILER_ID MATCHES "GNU" OR
72 CMAKE_CXX_COMPILER_ID MATCHES "GNU"
74 sanitize_flag_ld(-static-libasan)
75 sanitize_flag_ld(-static-liblsan)
76 sanitize_flag_ld(-static-libubsan)
78 sanitize_flag_ld(-static-libsan)
81 CMAKE_C_COMPILER_ID MATCHES "MSVC" OR
82 CMAKE_CXX_COMPILER_ID MATCHES "MSVC"
84 list_append(SANITIZE_LD /INCREMENTAL:NO)
85 sanitize_flag_cx(/fsanitize=address)
88 function(target_compile_sanitize)
90 foreach(target ${ARGN})
91 if(target MATCHES "^INTERFACE|PUBLIC|PRIVATE")
94 target_compile_options(${target} ${scope} ${SANITIZE_CX})
99 function(target_link_sanitize_3_13)
100 function(string_append var)
102 string(FIND "${${var}}" "${arg}" found)
103 if(${found} EQUAL -1)
104 string(STRIP "${${var}} ${arg}" ${var})
107 set(${var} "${${var}}" PARENT_SCOPE)
109 foreach(target ${ARGN})
111 get_property(LINK_FLAGS TARGET ${target} PROPERTY LINK_FLAGS)
113 string_append(LINK_FLAGS ${SANITIZE_LD})
115 string_append(LINK_FLAGS ${SANITIZE_CX} ${SANITIZE_LD})
117 set_property(TARGET ${target} PROPERTY LINK_FLAGS "${LINK_FLAGS}")
122 function(target_link_sanitize)
123 if(CMAKE_VERSION VERSION_LESS 3.13)
124 target_link_sanitize_3_13(${ARGN})
128 foreach(target ${ARGN})
129 if(target MATCHES "^INTERFACE|PUBLIC|PRIVATE")
132 target_link_options(${target} ${scope} ${SANITIZE_LD})
134 target_link_options(${target} ${scope} ${SANITIZE_CX} ${SANITIZE_LD})