123 lines
6.4 KiB
CMake
123 lines
6.4 KiB
CMake
#[=======================================================================[.rst:
|
|
SanitizerBuildTypes
|
|
--------
|
|
|
|
Add the compiler and linker flags for the sanitizer build types.
|
|
Currently, only Clang and GCC are supported.
|
|
Support for MSVC has yet to be added.
|
|
|
|
Arguments
|
|
~~~~~~~~
|
|
|
|
Provide the names for the build types through the following variables:
|
|
|
|
ASAN
|
|
LSAN
|
|
MSAN
|
|
TSAN
|
|
UBSAN
|
|
|
|
It is possible to only provide a subset of these variables to only create build types for specific sanitizers.
|
|
|
|
#]=======================================================================]
|
|
function(sanitizer_build_types)
|
|
|
|
if(ARGC EQUAL 0)
|
|
message(FATAL_ERROR "No arguments were given.")
|
|
endif()
|
|
|
|
set(prefix ARG)
|
|
set(no_values "")
|
|
set(single_values ASAN LSAN MSAN TSAN UBSAN)
|
|
set(multi_values "")
|
|
|
|
include(CMakeParseArguments)
|
|
cmake_parse_arguments(${prefix}
|
|
"${no_values}"
|
|
"${single_values}"
|
|
"${multi_values}"
|
|
${ARGN})
|
|
|
|
if(ARG_UNPARSED_ARGUMENTS)
|
|
message(FATAL_ERROR "Unexpected arguments: ${ARG_UNPARSED_ARGUMENTS}")
|
|
endif()
|
|
|
|
if(ARG_KEYWORDS_MISSING_VALUES)
|
|
message(FATAL_ERROR "Keywords missing values: ${ARG_KEYWORDS_MISSING_VALUES}")
|
|
endif()
|
|
|
|
set(_bitness 32)
|
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
set(_bitness 64)
|
|
endif()
|
|
|
|
# todo Add support for the AddressSanitizer for MSVC / 32-bit builds.
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
foreach(arg IN LISTS single_values)
|
|
if(${prefix}_${arg})
|
|
set_property(GLOBAL APPEND PROPERTY DEBUG_CONFIGURATIONS ${${prefix}_${arg}})
|
|
endif()
|
|
endforeach()
|
|
|
|
set(_asan_platforms Darwin FreeBSD Linux NetBSD Windows)
|
|
if(ARG_ASAN)
|
|
if(CMAKE_SYSTEM_NAME IN_LIST _asan_platforms)
|
|
set(CMAKE_C_FLAGS_${ARG_ASAN} "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fsanitize=address -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer -g" CACHE STRING "Flags used by the C compiler during Address Sanitizer builds.")
|
|
set(CMAKE_CXX_FLAGS_${ARG_ASAN} "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fsanitize=address -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer -g" CACHE STRING "Flags used by the C++ compiler during Address Sanitizer builds.")
|
|
set(CMAKE_EXE_LINKER_FLAGS_${ARG_ASAN} "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -fsanitize=address -fno-optimize-sibling-calls -fsanitize-address-use-after-scope -fno-omit-frame-pointer -g" CACHE STRING "Flags used by the linker during Address Sanitizer builds.")
|
|
else()
|
|
message("The address sanitizer is only available on ${_asan_platforms}")
|
|
endif()
|
|
endif()
|
|
|
|
set(_lsan_platforms Darwin Linux)
|
|
if(ARG_LSAN)
|
|
if(_bitness EQUAL 32)
|
|
message("The leak sanitizer is only available for 64-bit systems")
|
|
elseif(CMAKE_SYSTEM_NAME IN_LIST _lsan_platforms)
|
|
set(CMAKE_C_FLAGS_${ARG_LSAN} "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fsanitize=leak -fno-omit-frame-pointer -g" CACHE STRING "Flags used by the C compiler during Leak Sanitizer builds.")
|
|
set(CMAKE_CXX_FLAGS_${ARG_LSAN} "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fsanitize=leak -fno-omit-frame-pointer -g" CACHE STRING "Flags used by the C++ compiler during Leak Sanitizer builds.")
|
|
set(CMAKE_EXE_LINKER_FLAGS_${ARG_LSAN} "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -fsanitize=leak -fno-omit-frame-pointer -g" CACHE STRING "Flags used by the linker during Leak Sanitizer builds.")
|
|
else()
|
|
message("The leak sanitizer is only available on ${_lsan_platforms}")
|
|
endif()
|
|
endif()
|
|
|
|
set(_msan_platforms FreeBSD Linux NetBSD)
|
|
if(ARG_MSAN)
|
|
if(CMAKE_SYSTEM_NAME IN_LIST _msan_platforms)
|
|
set(CMAKE_C_FLAGS_${ARG_MSAN} "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fsanitize=memory -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g" CACHE STRING "Flags used by the C compiler during Memory Sanitizer builds.")
|
|
set(CMAKE_CXX_FLAGS_${ARG_MSAN} "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fsanitize=memory -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g" CACHE STRING "Flags used by the C++ compiler during Memory Sanitizer builds.")
|
|
set(CMAKE_EXE_LINKER_FLAGS_${ARG_MSAN} "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -fsanitize=memory -fno-optimize-sibling-calls -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer -g" CACHE STRING "Flags used by the linker during Memory Sanitizer builds.")
|
|
else()
|
|
message("The memory sanitizer is only available on ${_msan_platforms}")
|
|
endif()
|
|
endif()
|
|
|
|
set(_tsan_platforms Darwin FreeBSD Linux NetBSD)
|
|
if(ARG_TSAN)
|
|
if(_bitness EQUAL 32)
|
|
message("The thread sanitizer is only available for 64-bit systems")
|
|
elseif(CMAKE_SYSTEM_NAME IN_LIST _tsan_platforms)
|
|
set(CMAKE_C_FLAGS_${ARG_TSAN} "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fsanitize=thread -g" CACHE STRING "Flags used by the C compiler during Thread Sanitizer builds.")
|
|
set(CMAKE_CXX_FLAGS_${ARG_TSAN} "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fsanitize=thread -g" CACHE STRING "Flags used by the C++ compiler during Thread Sanitizer builds.")
|
|
set(CMAKE_EXE_LINKER_FLAGS_${ARG_TSAN} "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -fsanitize=thread -g" CACHE STRING "Flags used by the linker during Thread Sanitizer builds.")
|
|
else()
|
|
message("The thread sanitizer is only available on ${_tsan_platforms}")
|
|
endif()
|
|
endif()
|
|
|
|
set(_ubsan_platforms Darwin FreeBSD Linux NetBSD OpenBSD Windows)
|
|
if(ARG_UBSAN)
|
|
if(CMAKE_SYSTEM_NAME IN_LIST _ubsan_platforms)
|
|
set(CMAKE_C_FLAGS_${UBSAN} "${CMAKE_C_FLAGS_RELWITHDEBINFO} -fsanitize=undefined -g" CACHE STRING "Flags used by the C compiler during Undefined Behaviour Sanitizer builds.")
|
|
set(CMAKE_CXX_FLAGS_${UBSAN} "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -fsanitize=undefined -g" CACHE STRING "Flags used by the C++ compiler during Undefined Behaviour Sanitizer builds.")
|
|
set(CMAKE_EXE_LINKER_FLAGS_${UBSAN} "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -fsanitize=undefined -g" CACHE STRING "Flags used by the linker during Undefined Behavior Sanitizer builds.")
|
|
else()
|
|
message("The undefined behavior sanitizer is only available on ${_ubsan_platforms}")
|
|
endif()
|
|
endif()
|
|
else()
|
|
message("Sanitizers not supported for the current compiler: ${CMAKE_CXX_COMPILER_ID}.")
|
|
endif()
|
|
endfunction()
|