1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# Configuration for code analysis tools: runtime checking and coverage.
# Any test that needs runtime checks should use TEST_EXE_PREFIX and TEST_ENV.
# Normally they are set as a result of the RUNTIME_CHECK value,
# but can be set directly for unsupported tools or unusual flags
# e.g. -DTEST_EXE_PREFIX=rr or -DTEST_EXE_PREFIX="valgrind --tool=massif"
set(TEST_EXE_PREFIX "" CACHE STRING "Prefix for test executable command line")
set(TEST_WRAP_PREFIX "" CACHE STRING "Prefix for interpreter tests (e.g. python, ruby) that load proton as an extension")
set(TEST_ENV "" CACHE STRING "Extra environment for tests: name1=value1;name2=value2")
mark_as_advanced(TEST_EXE_PREFIX TEST_WRAP_PREFIX TEST_ENV)
# Check for valgrind
find_program(VALGRIND_EXECUTABLE valgrind DOC "location of valgrind program")
set(VALGRIND_SUPPRESSIONS "${CMAKE_SOURCE_DIR}/tests/valgrind.supp" CACHE STRING "Suppressions file for valgrind")
set(VALGRIND_COMMON_ARGS "--error-exitcode=42 --quiet --suppressions=${VALGRIND_SUPPRESSIONS}")
mark_as_advanced(VALGRIND_EXECUTABLE VALGRIND_SUPPRESSIONS VALGRIND_COMMON_ARGS)
# Check for compiler sanitizers
if((CMAKE_C_COMPILER_ID MATCHES "GNU"
AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.8)
OR (CMAKE_C_COMPILER_ID MATCHES "Clang"
AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 4.1))
set(HAS_SANITIZERS TRUE)
endif()
# Valid values for RUNTIME_CHECK
set(runtime_checks OFF asan tsan memcheck helgrind)
# Set the default
if(NOT CMAKE_BUILD_TYPE MATCHES "Coverage" AND VALGRIND_EXECUTABLE)
set(RUNTIME_CHECK_DEFAULT "memcheck")
endif()
# Deprecated options to enable runtime checks
macro(deprecated_enable_check old new doc)
if (${old})
message("WARNING: option ${old} is deprecated, use RUNTIME_CHECK=${new} instead")
set(RUNTIME_CHECK_DEFAULT ${new})
endif()
unset(${old} CACHE)
endmacro()
deprecated_enable_check(ENABLE_VALGRIND memcheck "Use valgrind to detect run-time problems")
deprecated_enable_check(ENABLE_SANITIZERS asan "Compile with memory sanitizers (asan, ubsan)")
deprecated_enable_check(ENABLE_TSAN tsan "Compile with thread sanitizer (tsan)")
set(RUNTIME_CHECK ${RUNTIME_CHECK_DEFAULT} CACHE STRING "Enable runtime checks. Valid values: ${runtime_checks}")
if(CMAKE_BUILD_TYPE MATCHES "Coverage" AND RUNTIME_CHECK)
message(FATAL_ERROR "Cannot set RUNTIME_CHECK with CMAKE_BUILD_TYPE=Coverage")
endif()
macro(assert_has_sanitizers)
if(NOT HAS_SANITIZERS)
message(FATAL_ERROR "compiler sanitizers are not available")
endif()
endmacro()
macro(assert_has_valgrind)
if(NOT VALGRIND_EXECUTABLE)
message(FATAL_ERROR "valgrind is not available")
endif()
endmacro()
if(RUNTIME_CHECK STREQUAL "memcheck")
assert_has_valgrind()
message(STATUS "Runtime memory checker: valgrind memcheck")
set(TEST_EXE_PREFIX "${VALGRIND_EXECUTABLE} --tool=memcheck --leak-check=full ${VALGRIND_COMMON_ARGS}")
# TODO aconway 2018-09-06: NO TEST_WRAP_PREFIX, need --trace-children + many suppressions
elseif(RUNTIME_CHECK STREQUAL "helgrind")
assert_has_valgrind()
message(STATUS "Runtime race checker: valgrind helgrind")
set(TEST_EXE_PREFIX "${VALGRIND_EXECUTABLE} --tool=helgrind ${VALGRIND_COMMON_ARGS}")
# TODO aconway 2018-09-06: NO TEST_WRAP_PREFIX, need --trace-children + many suppressions
elseif(RUNTIME_CHECK STREQUAL "asan")
assert_has_sanitizers()
message(STATUS "Runtime memory checker: gcc/clang memory sanitizers")
# clang defaults to static sanitizer libs (which is preferred), but then we cannot LD_PRELOAD
if (CMAKE_C_COMPILER_ID MATCHES "Clang")
set(CLANG_ASAN_FLAG "-shared-libasan")
endif()
set(SANITIZE_FLAGS "-g -fno-omit-frame-pointer ${CLANG_ASAN_FLAG} -fsanitize=address,undefined -fsanitize-recover=vptr")
set(TEST_WRAP_PREFIX "${CMAKE_SOURCE_DIR}/tests/preload_asan.sh $<TARGET_FILE:qpid-proton-core>")
list(APPEND TEST_ENV "UBSAN_OPTIONS=suppressions=${CMAKE_SOURCE_DIR}/tests/ubsan.supp")
list(APPEND TEST_ENV "LSAN_OPTIONS=suppressions=${CMAKE_SOURCE_DIR}/tests/lsan.supp")
elseif(RUNTIME_CHECK STREQUAL "tsan")
assert_has_sanitizers()
message(STATUS "Runtime race checker: gcc/clang thread sanitizer")
set(SANITIZE_FLAGS "-g -fno-omit-frame-pointer -fsanitize=thread")
set(TEST_WRAP_PREFIX "${CMAKE_SOURCE_DIR}/tests/preload_tsan.sh $<TARGET_FILE:qpid-proton-core>")
list(APPEND TEST_ENV "TSAN_OPTIONS=second_deadlock_stack=1 suppressions=${CMAKE_SOURCE_DIR}/tests/tsan.supp")
elseif(RUNTIME_CHECK)
message(FATAL_ERROR "'RUNTIME_CHECK=${RUNTIME_CHECK}' is invalid, valid values: ${runtime_checks}")
endif()
if(SANITIZE_FLAGS)
set(ENABLE_UNDEFINED_ERROR OFF CACHE BOOL "Disabled for sanitizers" FORCE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS}")
endif()
if(TEST_EXE_PREFIX)
# Add TEST_EXE_PREFIX to TEST_ENV so test runner scripts can use it.
list(APPEND TEST_ENV "TEST_EXE_PREFIX=${TEST_EXE_PREFIX}")
# Make a CMake-list form of TEST_EXE_PREFIX for (pn_)add_test() commands
separate_arguments(TEST_EXE_PREFIX_CMD UNIX_COMMAND "${TEST_EXE_PREFIX}")
endif()
separate_arguments(TEST_WRAP_PREFIX_CMD UNIX_COMMAND "${TEST_WRAP_PREFIX}")
|