if (MSVC)
  list(APPEND CMAKE_CONFIGURATION_TYPES ReleaseStatic)
  set(BUILD_SHARED_LIBS Off)
  set(CMAKE_C_FLAGS_RELEASESTATIC ${CMAKE_C_FLAGS_RELEASE})
  set(CMAKE_CXX_FLAGS_RELEASESTATIC ${CMAKE_CXX_FLAGS_RELEASE})
  set(CMAKE_EXE_LINKER_FLAGS_RELEASESTATIC ${CMAKE_EXE_LINKER_FLAGS_RELEASE})
  foreach(flag_var CMAKE_C_FLAGS_RELEASESTATIC CMAKE_CXX_FLAGS_RELEASESTATIC)
   if(${flag_var} MATCHES "/MD")
      string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
   endif()
  endforeach()

  list(APPEND CMAKE_CONFIGURATION_TYPES DebugStatic)
  set(BUILD_SHARED_LIBS Off)
  set(CMAKE_C_FLAGS_DEBUGSTATIC ${CMAKE_C_FLAGS_DEBUG})
  set(CMAKE_CXX_FLAGS_DEBUGSTATIC ${CMAKE_CXX_FLAGS_DEBUG})
  set(CMAKE_EXE_LINKER_FLAGS_DEBUGSTATIC ${CMAKE_EXE_LINKER_FLAGS_DEBUG})
  foreach(flag_var CMAKE_C_FLAGS_DEBUGSTATIC CMAKE_CXX_FLAGS_DEBUGSTATIC)
   if(${flag_var} MATCHES "/MDd")
      string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}")
   endif()
  endforeach()
else()
  include(CheckCXXCompilerFlag)

  set(CMAKE_REQUIRED_LIBRARIES "-fsanitize=undefined")
  check_cxx_compiler_flag("-fsanitize=undefined -fno-sanitize-recover=all" UBSAN_FOUND)

  set(CMAKE_REQUIRED_LIBRARIES "-fsanitize=thread")
  check_cxx_compiler_flag("-fsanitize=thread -fno-sanitize-recover=all" TSAN_FOUND)

  set(CMAKE_REQUIRED_LIBRARIES "-fsanitize=address")
  check_cxx_compiler_flag("-fsanitize=address -fno-sanitize-recover=all" ASAN_FOUND)

  set(CMAKE_REQUIRED_LIBRARIES "-pg")
  check_cxx_compiler_flag("-pg" GPROF_FOUND)

  set(CMAKE_REQUIRED_LIBRARIES "--coverage")
  check_cxx_compiler_flag("--coverage" GCOV_FOUND)

  unset(CMAKE_REQUIRED_LIBRARIES)

  if (UBSAN_FOUND)
    message(STATUS "UB sanitizer available. Adding UBsan build type")
    list(APPEND CMAKE_CONFIGURATION_TYPES UBsan)
    set(CMAKE_C_FLAGS_UBSAN "${CMAKE_C_FLAGS_DEBUG} -fsanitize=undefined -fno-sanitize-recover=all")
    set(CMAKE_CXX_FLAGS_UBSAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined -fno-sanitize-recover=all")
    set(CMAKE_EXE_LINKER_FLAGS_UBSAN "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fsanitize=undefined -fno-sanitize-recover=all")
  endif()

  if (TSAN_FOUND)
    message(STATUS "Thread sanitizer available. Adding Tsan build type")
    list(APPEND CMAKE_CONFIGURATION_TYPES Tsan)
    set(CMAKE_C_FLAGS_TSAN "${CMAKE_C_FLAGS_DEBUG} -fsanitize=thread -fno-sanitize-recover=all")
    set(CMAKE_CXX_FLAGS_TSAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=thread -fno-sanitize-recover=all")
    set(CMAKE_EXE_LINKER_FLAGS_TSAN "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fsanitize=thread -fno-sanitize-recover=all")
  endif()

  if (ASAN_FOUND)
    message(STATUS "Address sanitizer available. Adding Asan build type")
    list(APPEND CMAKE_CONFIGURATION_TYPES Asan)
    set(CMAKE_C_FLAGS_ASAN "${CMAKE_C_FLAGS_DEBUG} -fsanitize=address -fno-sanitize-recover=all")
    set(CMAKE_CXX_FLAGS_ASAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=address -fno-sanitize-recover=all")
    set(CMAKE_EXE_LINKER_FLAGS_ASAN "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fsanitize=address -fno-sanitize-recover=all")
  endif()

  if (GPROF_FOUND)
    message(STATUS "GProf profiler available. Adding GProf build type")
    list(APPEND CMAKE_CONFIGURATION_TYPES GProf)
    set(CMAKE_C_FLAGS_GPROF "${CMAKE_C_FLAGS_RELWITHDEBINFO} -pg")
    set(CMAKE_CXX_FLAGS_GPROF "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -pg")
    set(CMAKE_EXE_LINKER_FLAGS_GPROF "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -pg")
  endif()

  if (GCOV_FOUND)
    message(STATUS "GCov coverage measurment available. Adding GCov build type")
    list(APPEND CMAKE_CONFIGURATION_TYPES GCov)
    set(CMAKE_C_FLAGS_GCOV "${CMAKE_C_FLAGS_DEBUG} --coverage")
    set(CMAKE_CXX_FLAGS_GCOV "${CMAKE_CXX_FLAGS_DEBUG} --coverage")
    set(CMAKE_EXE_LINKER_FLAGS_GCOV "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
  endif()
endif()
