1# =========================================================================== 2# http://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html 3# =========================================================================== 4# 5# SYNOPSIS 6# 7# AX_VALGRIND_CHECK() 8# 9# DESCRIPTION 10# 11# Checks whether Valgrind is present and, if so, allows running `make 12# check` under a variety of Valgrind tools to check for memory and 13# threading errors. 14# 15# Defines VALGRIND_CHECK_RULES which should be substituted in your 16# Makefile; and $enable_valgrind which can be used in subsequent configure 17# output. VALGRIND_ENABLED is defined and substituted, and corresponds to 18# the value of the --enable-valgrind option, which defaults to being 19# enabled if Valgrind is installed and disabled otherwise. 20# 21# If unit tests are written using a shell script and automake's 22# LOG_COMPILER system, the $(VALGRIND) variable can be used within the 23# shell scripts to enable Valgrind, as described here: 24# 25# https://www.gnu.org/software/gnulib/manual/html_node/Running-self_002dtests-under-valgrind.html 26# 27# Usage example: 28# 29# configure.ac: 30# 31# AX_VALGRIND_CHECK 32# 33# Makefile.am: 34# 35# @VALGRIND_CHECK_RULES@ 36# VALGRIND_SUPPRESSIONS_FILES = my-project.supp 37# EXTRA_DIST = my-project.supp 38# 39# This results in a "check-valgrind" rule being added to any Makefile.am 40# which includes "@VALGRIND_CHECK_RULES@" (assuming the module has been 41# configured with --enable-valgrind). Running `make check-valgrind` in 42# that directory will run the module's test suite (`make check`) once for 43# each of the available Valgrind tools (out of memcheck, helgrind, drd and 44# sgcheck), and will output results to test-suite-$toolname.log for each. 45# The target will succeed if there are zero errors and fail otherwise. 46# 47# Alternatively, a "check-valgrind-$TOOL" rule will be added, for $TOOL in 48# memcheck, helgrind, drd and sgcheck. These are useful because often only 49# some of those tools can be ran cleanly on a codebase. 50# 51# The macro supports running with and without libtool. 52# 53# LICENSE 54# 55# Copyright (c) 2014, 2015, 2016 Philip Withnall <philip.withnall@collabora.co.uk> 56# 57# Copying and distribution of this file, with or without modification, are 58# permitted in any medium without royalty provided the copyright notice 59# and this notice are preserved. This file is offered as-is, without any 60# warranty. 61 62#serial 9 63 64AC_DEFUN([AX_VALGRIND_CHECK],[ 65 dnl Check for --enable-valgrind 66 AC_ARG_ENABLE([valgrind], 67 [AS_HELP_STRING([--enable-valgrind], [Whether to enable Valgrind on the unit tests])], 68 [enable_valgrind=$enableval],[enable_valgrind=]) 69 70 AS_IF([test "$enable_valgrind" != "no"],[ 71 # Check for Valgrind. 72 AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind]) 73 AS_IF([test "$VALGRIND" = ""],[ 74 AS_IF([test "$enable_valgrind" = "yes"],[ 75 AC_MSG_ERROR([Could not find valgrind; either install it or reconfigure with --disable-valgrind]) 76 ],[ 77 enable_valgrind=no 78 ]) 79 ],[ 80 enable_valgrind=yes 81 ]) 82 ]) 83 84 AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"]) 85 AC_SUBST([VALGRIND_ENABLED],[$enable_valgrind]) 86 87 # Check for Valgrind tools we care about. 88 m4_define([valgrind_tool_list],[[memcheck], [helgrind], [drd], [exp-sgcheck]]) 89 90 AS_IF([test "$VALGRIND" != ""],[ 91 m4_foreach([vgtool],[valgrind_tool_list],[ 92 m4_define([vgtooln],AS_TR_SH(vgtool)) 93 m4_define([ax_cv_var],[ax_cv_valgrind_tool_]vgtooln) 94 AC_CACHE_CHECK([for Valgrind tool ]vgtool,ax_cv_var,[ 95 ax_cv_var= 96 AS_IF([`$VALGRIND --tool=vgtool --help >/dev/null 2>&1`],[ 97 ax_cv_var="vgtool" 98 ]) 99 ]) 100 101 AC_SUBST([VALGRIND_HAVE_TOOL_]vgtooln,[$ax_cv_var]) 102 ]) 103 ]) 104 105[VALGRIND_CHECK_RULES=' 106# Valgrind check 107# 108# Optional: 109# - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions 110# files to load. (Default: empty) 111# - VALGRIND_FLAGS: General flags to pass to all Valgrind tools. 112# (Default: --num-callers=30) 113# - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of: 114# memcheck, helgrind, drd, sgcheck). (Default: various) 115 116# Optional variables 117VALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES)) 118VALGRIND_FLAGS ?= --num-callers=30 119VALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no 120VALGRIND_helgrind_FLAGS ?= --history-level=approx 121VALGRIND_drd_FLAGS ?= 122VALGRIND_sgcheck_FLAGS ?= 123 124# Internal use 125valgrind_tools = memcheck helgrind drd sgcheck 126valgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools))) 127 128valgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS) 129valgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS) 130valgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS) 131valgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS) 132 133valgrind_quiet = $(valgrind_quiet_$(V)) 134valgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY)) 135valgrind_quiet_0 = --quiet 136 137# Support running with and without libtool. 138ifneq ($(LIBTOOL),) 139valgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute 140else 141valgrind_lt = 142endif 143 144# Use recursive makes in order to ignore errors during check 145check-valgrind: 146ifeq ($(VALGRIND_ENABLED),yes) 147 -$(foreach tool,$(valgrind_tools), \ 148 $(if $(VALGRIND_HAVE_TOOL_$(tool))$(VALGRIND_HAVE_TOOL_exp_$(tool)), \ 149 $(MAKE) $(AM_MAKEFLAGS) -k check-valgrind-tool VALGRIND_TOOL=$(tool); \ 150 ) \ 151 ) 152else 153 @echo "Need to reconfigure with --enable-valgrind" 154endif 155 156# Valgrind running 157VALGRIND_TESTS_ENVIRONMENT = \ 158 $(TESTS_ENVIRONMENT) \ 159 env VALGRIND=$(VALGRIND) \ 160 G_SLICE=always-malloc,debug-blocks \ 161 G_DEBUG=fatal-warnings,fatal-criticals,gc-friendly 162 163VALGRIND_LOG_COMPILER = \ 164 $(valgrind_lt) \ 165 $(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS) 166 167check-valgrind-tool: 168ifeq ($(VALGRIND_ENABLED),yes) 169 $(MAKE) check-TESTS \ 170 TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \ 171 LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \ 172 LOG_FLAGS="$(valgrind_$(VALGRIND_TOOL)_flags)" \ 173 TEST_SUITE_LOG=test-suite-$(VALGRIND_TOOL).log 174else 175 @echo "Need to reconfigure with --enable-valgrind" 176endif 177 178check-valgrind-memcheck: 179ifeq ($(VALGRIND_ENABLED),yes) 180 $(MAKE) check-TESTS \ 181 TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \ 182 LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \ 183 LOG_FLAGS="$(valgrind_memcheck_flags)" \ 184 TEST_SUITE_LOG=test-suite-memcheck.log 185else 186 @echo "Need to reconfigure with --enable-valgrind" 187endif 188 189check-valgrind-helgrind: 190ifeq ($(VALGRIND_ENABLED),yes) 191 $(MAKE) check-TESTS \ 192 TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \ 193 LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \ 194 LOG_FLAGS="$(valgrind_helgrind_flags)" \ 195 TEST_SUITE_LOG=test-suite-helgrind.log 196else 197 @echo "Need to reconfigure with --enable-valgrind" 198endif 199 200check-valgrind-drd: 201ifeq ($(VALGRIND_ENABLED),yes) 202 $(MAKE) check-TESTS \ 203 TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \ 204 LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \ 205 LOG_FLAGS="$(valgrind_drd_flags)" \ 206 TEST_SUITE_LOG=test-suite-drd.log 207else 208 @echo "Need to reconfigure with --enable-valgrind" 209endif 210 211check-valgrind-sgcheck: 212ifeq ($(VALGRIND_ENABLED),yes) 213 $(MAKE) check-TESTS \ 214 TESTS_ENVIRONMENT="$(VALGRIND_TESTS_ENVIRONMENT)" \ 215 LOG_COMPILER="$(VALGRIND_LOG_COMPILER)" \ 216 LOG_FLAGS="$(valgrind_sgcheck_flags)" \ 217 TEST_SUITE_LOG=test-suite-sgcheck.log 218else 219 @echo "Need to reconfigure with --enable-valgrind" 220endif 221 222A''M_DISTCHECK_CONFIGURE_FLAGS ?= 223A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind 224 225MOSTLYCLEANFILES ?= 226MOSTLYCLEANFILES += $(valgrind_log_files) 227 228.PHONY: check-valgrind check-valgrind-tool 229'] 230 231 AC_SUBST([VALGRIND_CHECK_RULES]) 232 m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([VALGRIND_CHECK_RULES])]) 233]) 234