1
0

sanitizer.cmake 4.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. include(CheckCXXCompilerFlag)
  2. include(CheckCXXSourceRuns)
  3. set(ALLOWED_BUILD_TYPES Debug Release RelWithDebInfo MinSizeRel)
  4. set(ALL_SAN_FLAGS "")
  5. # No sanitizers when cross compiling to prevent stuff like this: https://github.com/whoshuu/cpr/issues/582
  6. if(NOT CMAKE_CROSSCOMPILING)
  7. # Thread sanitizer
  8. set(THREAD_SAN_FLAGS "-fsanitize=thread")
  9. set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
  10. set(CMAKE_REQUIRED_FLAGS "${THREAD_SAN_FLAGS}")
  11. check_cxx_source_runs("int main() { return 0; }" THREAD_SANITIZER_AVAILABLE)
  12. set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
  13. if(THREAD_SANITIZER_AVAILABLE)
  14. list(APPEND ALLOWED_BUILD_TYPES ThreadSan)
  15. # Do not add Thread sanitizer to all sanitizer because it is incompatible with other sanitizer
  16. endif()
  17. set(CMAKE_C_FLAGS_THREADSAN "${CMAKE_C_FLAGS_DEBUG} ${THREAD_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C compiler during thread sanitizer builds." FORCE)
  18. set(CMAKE_CXX_FLAGS_THREADSAN "${CMAKE_CXX_FLAGS_DEBUG} ${THREAD_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C++ compiler during thread sanitizer builds." FORCE)
  19. set(CMAKE_SHARED_LINKER_FLAGS_THREADSAN "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during thread sanitizer builds" FORCE)
  20. # Address sanitizer
  21. set(ADDR_SAN_FLAGS "-fsanitize=address")
  22. set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
  23. set(CMAKE_REQUIRED_FLAGS "${ADDR_SAN_FLAGS}")
  24. check_cxx_source_runs("int main() { return 0; }" ADDRESS_SANITIZER_AVAILABLE)
  25. set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
  26. if(ADDRESS_SANITIZER_AVAILABLE)
  27. list(APPEND ALLOWED_BUILD_TYPES AddrSan)
  28. set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${ADDR_SAN_FLAGS}")
  29. endif()
  30. set(CMAKE_C_FLAGS_ADDRSAN "${CMAKE_C_FLAGS_DEBUG} ${ADDR_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C compiler during address sanitizer builds." FORCE)
  31. set(CMAKE_CXX_FLAGS_ADDRSAN "${CMAKE_CXX_FLAGS_DEBUG} ${ADDR_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C++ compiler during address sanitizer builds." FORCE)
  32. set(CMAKE_SHARED_LINKER_FLAGS_ADDRSAN "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during address sanitizer builds" FORCE)
  33. # Leak sanitizer
  34. set(LEAK_SAN_FLAGS "-fsanitize=leak")
  35. check_cxx_compiler_flag(${LEAK_SAN_FLAGS} LEAK_SANITIZER_AVAILABLE)
  36. if(LEAK_SANITIZER_AVAILABLE)
  37. list(APPEND ALLOWED_BUILD_TYPES LeakSan)
  38. set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${LEAK_SAN_FLAGS}")
  39. endif()
  40. set(CMAKE_C_FLAGS_LEAKSAN "${CMAKE_C_FLAGS_DEBUG} ${LEAK_SAN_FLAGS} -fno-omit-frame-pointer" CACHE INTERNAL "Flags used by the C compiler during leak sanitizer builds." FORCE)
  41. set(CMAKE_CXX_FLAGS_LEAKSAN "${CMAKE_CXX_FLAGS_DEBUG} ${LEAK_SAN_FLAGS} -fno-omit-frame-pointer" CACHE INTERNAL "Flags used by the C++ compiler during leak sanitizer builds." FORCE)
  42. set(CMAKE_SHARED_LINKER_FLAGS_LEAKSAN "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during leak sanitizer builds" FORCE)
  43. # Undefined behavior sanitizer
  44. set(UDEF_SAN_FLAGS "-fsanitize=undefined")
  45. check_cxx_compiler_flag(${UDEF_SAN_FLAGS} UNDEFINED_BEHAVIOUR_SANITIZER_AVAILABLE)
  46. if(UNDEFINED_BEHAVIOUR_SANITIZER_AVAILABLE)
  47. list(APPEND ALLOWED_BUILD_TYPES UdefSan)
  48. set(ALL_SAN_FLAGS "${ALL_SAN_FLAGS} ${UDEF_SAN_FLAGS}")
  49. endif()
  50. set(CMAKE_C_FLAGS_UDEFSAN "${CMAKE_C_FLAGS_DEBUG} ${UDEF_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C compiler during undefined behaviour sanitizer builds." FORCE)
  51. set(CMAKE_CXX_FLAGS_UDEFSAN "${CMAKE_CXX_FLAGS_DEBUG} ${UDEF_SAN_FLAGS}" CACHE INTERNAL "Flags used by the C++ compiler during undefined behaviour sanitizer builds." FORCE)
  52. set(CMAKE_SHARED_LINKER_FLAGS_UDEFSAN "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during undefined behaviour sanitizer builds" FORCE)
  53. # All sanitizer (without thread sanitizer)
  54. if(NOT ALL_SAN_FLAGS STREQUAL "")
  55. set(PREV_FLAG ${CMAKE_REQUIRED_FLAGS})
  56. set(CMAKE_REQUIRED_FLAGS "${ALL_SAN_FLAGS}")
  57. check_cxx_source_runs("int main() { return 0; }" ALL_SANITIZERS_AVAILABLE)
  58. set(CMAKE_REQUIRED_FLAGS ${PREV_FLAG})
  59. if(ALL_SANITIZERS_AVAILABLE)
  60. list(APPEND ALLOWED_BUILD_TYPES AllSan)
  61. endif()
  62. endif()
  63. set(CMAKE_C_FLAGS_ALLSAN "${CMAKE_C_FLAGS_DEBUG} ${ALL_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C compiler during most possible sanitizer builds." FORCE)
  64. set(CMAKE_CXX_FLAGS_ALLSAN "${CMAKE_CXX_FLAGS_DEBUG} ${ALL_SAN_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls" CACHE INTERNAL "Flags used by the C++ compiler during most possible sanitizer builds." FORCE)
  65. set(CMAKE_SHARED_LINKER_FLAGS_ALLSAN "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "Flags used for the linker during most possible sanitizer builds" FORCE)
  66. endif()