diff --git a/src/DynamicProjectOptions.cmake b/src/DynamicProjectOptions.cmake index 4cf62520..bd7cec7e 100644 --- a/src/DynamicProjectOptions.cmake +++ b/src/DynamicProjectOptions.cmake @@ -1,5 +1,7 @@ include_guard() +include("${CMAKE_CURRENT_LIST_DIR}/Sanitizers.cmake") + #[[.rst: ``dynamic_project_options`` @@ -101,16 +103,26 @@ macro(dynamic_project_options) ) endif() - if(((CMAKE_CXX_COMPILER_ID MATCHES ".*Clang.*") AND (NOT WIN32)) - OR ((CMAKE_CXX_COMPILER_ID MATCHES ".*GNU.*") AND (NOT WIN32) AND (NOT APPLE)) + check_sanitizers_support( + ENABLE_SANITIZER_ADDRESS + ENABLE_SANITIZER_UNDEFINED_BEHAVIOR + ENABLE_SANITIZER_LEAK + ENABLE_SANITIZER_THREAD + ENABLE_SANITIZER_MEMORY ) - set(SUPPORTS_UBSAN ON) + + if(ENABLE_SANITIZER_ADDRESS) set(SUPPORTS_ASAN ON) else() - set(SUPPORTS_UBSAN OFF) set(SUPPORTS_ASAN OFF) endif() + if(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR) + set(SUPPORTS_UBSAN ON) + else() + set(SUPPORTS_UBSAN OFF) + endif() + # ccache, clang-tidy, cppcheck are only supported with Ninja and Makefile based generators # note that it is possible to use Ninja with cl, so this still allows clang-tidy on Windows # with CL. diff --git a/src/Sanitizers.cmake b/src/Sanitizers.cmake index 830f209e..df927a9b 100644 --- a/src/Sanitizers.cmake +++ b/src/Sanitizers.cmake @@ -1,5 +1,7 @@ include_guard() +include("${CMAKE_CURRENT_LIST_DIR}/Utilities.cmake") + # Enable the sanitizers for the given project function( enable_sanitizers @@ -133,11 +135,28 @@ function( ) set(SANITIZERS "") if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "Windows") - list(APPEND SANITIZERS "address") - list(APPEND SANITIZERS "undefined") - list(APPEND SANITIZERS "leak") - list(APPEND SANITIZERS "thread") - list(APPEND SANITIZERS "memory") + set(HAS_SANITIZER_SUPPORT ON) + + # Disable gcc sanitizer on some macos according to https://github.com/orgs/Homebrew/discussions/3384#discussioncomment-6264292 + if((CMAKE_CXX_COMPILER_ID MATCHES ".*GNU.*") AND APPLE) + detect_macos_version(MACOS_VERSION) + if(MACOS_VERSION VERSION_GREATER_EQUAL 13) + set(HAS_SANITIZER_SUPPORT OFF) + endif() + + detect_architecture(ARCHITECTURE) + if(ARCHITECTURE STREQUAL "arm64") + set(HAS_SANITIZER_SUPPORT OFF) + endif() + endif() + + if (HAS_SANITIZER_SUPPORT) + list(APPEND SANITIZERS "address") + list(APPEND SANITIZERS "undefined") + list(APPEND SANITIZERS "leak") + list(APPEND SANITIZERS "thread") + list(APPEND SANITIZERS "memory") + endif() elseif(MSVC) # or it is MSVC and has run vcvarsall string(FIND "$ENV{PATH}" "$ENV{VSINSTALLDIR}" index_of_vs_install_dir)