m4/ax_code_coverage.m4
changeset 89 e87a7db919c6
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/m4/ax_code_coverage.m4	Fri Mar 08 13:51:08 2019 +0000
     1.3 @@ -0,0 +1,274 @@
     1.4 +# ===========================================================================
     1.5 +#     http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html
     1.6 +# ===========================================================================
     1.7 +#
     1.8 +# SYNOPSIS
     1.9 +#
    1.10 +#   AX_CODE_COVERAGE()
    1.11 +#
    1.12 +# DESCRIPTION
    1.13 +#
    1.14 +#   Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS,
    1.15 +#   CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LDFLAGS which should be
    1.16 +#   included in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LDFLAGS variables of
    1.17 +#   every build target (program or library) which should be built with code
    1.18 +#   coverage support. Also defines CODE_COVERAGE_RULES which should be
    1.19 +#   substituted in your Makefile; and $enable_code_coverage which can be
    1.20 +#   used in subsequent configure output. CODE_COVERAGE_ENABLED is defined
    1.21 +#   and substituted, and corresponds to the value of the
    1.22 +#   --enable-code-coverage option, which defaults to being disabled.
    1.23 +#
    1.24 +#   Test also for gcov program and create GCOV variable that could be
    1.25 +#   substituted.
    1.26 +#
    1.27 +#   Note that all optimisation flags in CFLAGS must be disabled when code
    1.28 +#   coverage is enabled.
    1.29 +#
    1.30 +#   Usage example:
    1.31 +#
    1.32 +#   configure.ac:
    1.33 +#
    1.34 +#     AX_CODE_COVERAGE
    1.35 +#
    1.36 +#   Makefile.am:
    1.37 +#
    1.38 +#     @CODE_COVERAGE_RULES@
    1.39 +#     my_program_LIBS = ... $(CODE_COVERAGE_LDFLAGS) ...
    1.40 +#     my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ...
    1.41 +#     my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ...
    1.42 +#     my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ...
    1.43 +#
    1.44 +#   This results in a "check-code-coverage" rule being added to any
    1.45 +#   Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module
    1.46 +#   has been configured with --enable-code-coverage). Running `make
    1.47 +#   check-code-coverage` in that directory will run the module's test suite
    1.48 +#   (`make check`) and build a code coverage report detailing the code which
    1.49 +#   was touched, then print the URI for the report.
    1.50 +#
    1.51 +#   This code was derived from Makefile.decl in GLib, originally licenced
    1.52 +#   under LGPLv2.1+.
    1.53 +#
    1.54 +# LICENSE
    1.55 +#
    1.56 +#   Copyright (c) 2012, 2016 Philip Withnall
    1.57 +#   Copyright (c) 2012 Xan Lopez
    1.58 +#   Copyright (c) 2012 Christian Persch
    1.59 +#   Copyright (c) 2012 Paolo Borelli
    1.60 +#   Copyright (c) 2012 Dan Winship
    1.61 +#   Copyright (c) 2015 Bastien ROUCARIES
    1.62 +#
    1.63 +#   This library is free software; you can redistribute it and/or modify it
    1.64 +#   under the terms of the GNU Lesser General Public License as published by
    1.65 +#   the Free Software Foundation; either version 2.1 of the License, or (at
    1.66 +#   your option) any later version.
    1.67 +#
    1.68 +#   This library is distributed in the hope that it will be useful, but
    1.69 +#   WITHOUT ANY WARRANTY; without even the implied warranty of
    1.70 +#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
    1.71 +#   General Public License for more details.
    1.72 +#
    1.73 +#   You should have received a copy of the GNU Lesser General Public License
    1.74 +#   along with this program. If not, see <http://www.gnu.org/licenses/>.
    1.75 +
    1.76 +#serial 16
    1.77 +
    1.78 +AC_DEFUN([AX_CODE_COVERAGE],[
    1.79 +	dnl Check for --enable-code-coverage
    1.80 +	AC_REQUIRE([AC_PROG_SED])
    1.81 +
    1.82 +	# allow to override gcov location
    1.83 +	AC_ARG_WITH([gcov],
    1.84 +	  [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])],
    1.85 +	  [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov],
    1.86 +	  [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov])
    1.87 +
    1.88 +	AC_MSG_CHECKING([whether to build with code coverage support])
    1.89 +	AC_ARG_ENABLE([code-coverage],
    1.90 +	  AS_HELP_STRING([--enable-code-coverage],
    1.91 +	  [Whether to enable code coverage support]),,
    1.92 +	  enable_code_coverage=no)
    1.93 +
    1.94 +	AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes])
    1.95 +	AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage])
    1.96 +	AC_MSG_RESULT($enable_code_coverage)
    1.97 +
    1.98 +	AS_IF([ test "$enable_code_coverage" = "yes" ], [
    1.99 +		# check for gcov
   1.100 +		AC_CHECK_TOOL([GCOV],
   1.101 +		  [$_AX_CODE_COVERAGE_GCOV_PROG_WITH],
   1.102 +		  [:])
   1.103 +		AS_IF([test "X$GCOV" = "X:"],
   1.104 +		  [AC_MSG_ERROR([gcov is needed to do coverage])])
   1.105 +		AC_SUBST([GCOV])
   1.106 +
   1.107 +		dnl Check if gcc is being used
   1.108 +		AS_IF([ test "$GCC" = "no" ], [
   1.109 +			AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage])
   1.110 +		])
   1.111 +
   1.112 +		# List of supported lcov versions.
   1.113 +		lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.12"
   1.114 +
   1.115 +		AC_CHECK_PROG([LCOV], [lcov], [lcov])
   1.116 +		AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
   1.117 +
   1.118 +		AS_IF([ test "$LCOV" ], [
   1.119 +			AC_CACHE_CHECK([for lcov version], ax_cv_lcov_version, [
   1.120 +				ax_cv_lcov_version=invalid
   1.121 +				lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'`
   1.122 +				for lcov_check_version in $lcov_version_list; do
   1.123 +					if test "$lcov_version" = "$lcov_check_version"; then
   1.124 +						ax_cv_lcov_version="$lcov_check_version (ok)"
   1.125 +					fi
   1.126 +				done
   1.127 +			])
   1.128 +		], [
   1.129 +			lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list"
   1.130 +			AC_MSG_ERROR([$lcov_msg])
   1.131 +		])
   1.132 +
   1.133 +		case $ax_cv_lcov_version in
   1.134 +			""|invalid[)]
   1.135 +				lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)."
   1.136 +				AC_MSG_ERROR([$lcov_msg])
   1.137 +				LCOV="exit 0;"
   1.138 +			;;
   1.139 +		esac
   1.140 +
   1.141 +		AS_IF([ test -z "$GENHTML" ], [
   1.142 +			AC_MSG_ERROR([Could not find genhtml from the lcov package])
   1.143 +		])
   1.144 +
   1.145 +		dnl Build the code coverage flags
   1.146 +		CODE_COVERAGE_CPPFLAGS="-DNDEBUG"
   1.147 +		CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
   1.148 +		CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
   1.149 +		CODE_COVERAGE_LDFLAGS="-lgcov"
   1.150 +
   1.151 +		AC_SUBST([CODE_COVERAGE_CPPFLAGS])
   1.152 +		AC_SUBST([CODE_COVERAGE_CFLAGS])
   1.153 +		AC_SUBST([CODE_COVERAGE_CXXFLAGS])
   1.154 +		AC_SUBST([CODE_COVERAGE_LDFLAGS])
   1.155 +	])
   1.156 +
   1.157 +[CODE_COVERAGE_RULES='
   1.158 +# Code coverage
   1.159 +#
   1.160 +# Optional:
   1.161 +#  - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting.
   1.162 +#    Multiple directories may be specified, separated by whitespace.
   1.163 +#    (Default: $(top_builddir))
   1.164 +#  - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated
   1.165 +#    by lcov for code coverage. (Default:
   1.166 +#    $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info)
   1.167 +#  - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage
   1.168 +#    reports to be created. (Default:
   1.169 +#    $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage)
   1.170 +#  - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage,
   1.171 +#    set to 0 to disable it and leave empty to stay with the default.
   1.172 +#    (Default: empty)
   1.173 +#  - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov
   1.174 +#    instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
   1.175 +#  - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov
   1.176 +#    instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
   1.177 +#  - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov
   1.178 +#  - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the
   1.179 +#    collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
   1.180 +#  - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov
   1.181 +#    instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
   1.182 +#  - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering
   1.183 +#    lcov instance. (Default: empty)
   1.184 +#  - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov
   1.185 +#    instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
   1.186 +#  - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the
   1.187 +#    genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
   1.188 +#  - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml
   1.189 +#    instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT)
   1.190 +#  - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore
   1.191 +#
   1.192 +# The generated report will be titled using the $(PACKAGE_NAME) and
   1.193 +# $(PACKAGE_VERSION). In order to add the current git hash to the title,
   1.194 +# use the git-version-gen script, available online.
   1.195 +
   1.196 +# Optional variables
   1.197 +CODE_COVERAGE_DIRECTORY ?= $(top_builddir)
   1.198 +CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info
   1.199 +CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage
   1.200 +CODE_COVERAGE_BRANCH_COVERAGE ?=
   1.201 +CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
   1.202 +--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
   1.203 +CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
   1.204 +CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)"
   1.205 +CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
   1.206 +CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
   1.207 +CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?=
   1.208 +CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
   1.209 +CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\
   1.210 +$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
   1.211 +--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
   1.212 +CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS)
   1.213 +CODE_COVERAGE_IGNORE_PATTERN ?=
   1.214 +
   1.215 +code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V))
   1.216 +code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY))
   1.217 +code_coverage_v_lcov_cap_0 = @echo "  LCOV   --capture"\
   1.218 + $(CODE_COVERAGE_OUTPUT_FILE);
   1.219 +code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V))
   1.220 +code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY))
   1.221 +code_coverage_v_lcov_ign_0 = @echo "  LCOV   --remove /tmp/*"\
   1.222 + $(CODE_COVERAGE_IGNORE_PATTERN);
   1.223 +code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V))
   1.224 +code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY))
   1.225 +code_coverage_v_genhtml_0 = @echo "  GEN   " $(CODE_COVERAGE_OUTPUT_DIRECTORY);
   1.226 +code_coverage_quiet = $(code_coverage_quiet_$(V))
   1.227 +code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY))
   1.228 +code_coverage_quiet_0 = --quiet
   1.229 +
   1.230 +# sanitizes the test-name: replaces with underscores: dashes and dots
   1.231 +code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1)))
   1.232 +
   1.233 +# Use recursive makes in order to ignore errors during check
   1.234 +check-code-coverage:
   1.235 +ifeq ($(CODE_COVERAGE_ENABLED),yes)
   1.236 +	-$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check
   1.237 +	$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture
   1.238 +else
   1.239 +	@echo "Need to reconfigure with --enable-code-coverage"
   1.240 +endif
   1.241 +
   1.242 +# Capture code coverage data
   1.243 +code-coverage-capture: code-coverage-capture-hook
   1.244 +ifeq ($(CODE_COVERAGE_ENABLED),yes)
   1.245 +	$(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS)
   1.246 +	$(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS)
   1.247 +	-@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp
   1.248 +	$(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS)
   1.249 +	@echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html"
   1.250 +else
   1.251 +	@echo "Need to reconfigure with --enable-code-coverage"
   1.252 +endif
   1.253 +
   1.254 +# Hook rule executed before code-coverage-capture, overridable by the user
   1.255 +code-coverage-capture-hook:
   1.256 +
   1.257 +ifeq ($(CODE_COVERAGE_ENABLED),yes)
   1.258 +clean: code-coverage-clean
   1.259 +distclean: code-coverage-clean
   1.260 +code-coverage-clean:
   1.261 +	-$(LCOV) --directory $(top_builddir) -z
   1.262 +	-rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY)
   1.263 +	-find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete
   1.264 +endif
   1.265 +
   1.266 +GITIGNOREFILES ?=
   1.267 +GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
   1.268 +
   1.269 +A''M_DISTCHECK_CONFIGURE_FLAGS ?=
   1.270 +A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage
   1.271 +
   1.272 +.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean
   1.273 +']
   1.274 +
   1.275 +	AC_SUBST([CODE_COVERAGE_RULES])
   1.276 +	m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])])
   1.277 +])