m4/ax_code_coverage.m4
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Jul 16 11:07:18 2016 +0100 (2016-07-16)
changeset 61 31fb35727621
permissions -rw-r--r--
Support parallel installations. The idea is that for CAD screener, we want
to be able to install this on the same machine as a standard AVOT setup
(most notably for John's laptop). To allow for the possibility of a second
application that might have the same requirements, we add the concept of
vendor-specific distributions. Thus we can have one distribution for CAD
screener and one for The Next Big Thing. It doesn't seem trivial to have
both CAD screener and AVOT under the same vendor tag so we'll have to have
AVOT under "City Occupational" and CAD screener under "City Occupational Ltd"
or some such kludge.

Most of this is done although we are very short of test cases (in particular
we don't test that it's actually possible to install CAD screener in parallel
with AVOT or to update either of them once installed, which is fundamental).

We also have a lot of baggage left over, including an intercept of razor_set.
The problem that this was introduced to debug has been fixed but it looks
like there are a number of memory leaks which it might be useful to help
track down so it has been left in place for now.

There is still a lot of confusion in plover between path-based and URI-based
API. We should review the API, decide what we want and have a general clear up.

There is also confusion as to the purpose of RAZOR_ROOT (and meaning; path or
URI). This is not used at all in librazor (although it is used in razor.exe).
Ideally we shouldn't use it in plover or plover-gtk either although again, we
might want to support it or an equivalent in (some of) the various executables.

Work that would still to nice to do for CAD screener:

- uninstall (ideally as an installed program that hooks into Add/Remove programs
but even re-running the installer would be acceptable).
- xz support (smaller packages).
- repomd.xml and xml:base (would be needed for an Internet installer).
- graphical installer.
ali@38
     1
# ===========================================================================
ali@38
     2
#     http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html
ali@38
     3
# ===========================================================================
ali@38
     4
#
ali@38
     5
# SYNOPSIS
ali@38
     6
#
ali@38
     7
#   AX_CODE_COVERAGE()
ali@38
     8
#
ali@38
     9
# DESCRIPTION
ali@38
    10
#
ali@38
    11
#   Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS,
ali@38
    12
#   CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LDFLAGS which should be
ali@38
    13
#   included in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LDFLAGS variables of
ali@38
    14
#   every build target (program or library) which should be built with code
ali@38
    15
#   coverage support. Also defines CODE_COVERAGE_RULES which should be
ali@38
    16
#   substituted in your Makefile; and $enable_code_coverage which can be
ali@38
    17
#   used in subsequent configure output. CODE_COVERAGE_ENABLED is defined
ali@38
    18
#   and substituted, and corresponds to the value of the
ali@38
    19
#   --enable-code-coverage option, which defaults to being disabled.
ali@38
    20
#
ali@38
    21
#   Test also for gcov program and create GCOV variable that could be
ali@38
    22
#   substituted.
ali@38
    23
#
ali@38
    24
#   Note that all optimisation flags in CFLAGS must be disabled when code
ali@38
    25
#   coverage is enabled.
ali@38
    26
#
ali@38
    27
#   Usage example:
ali@38
    28
#
ali@38
    29
#   configure.ac:
ali@38
    30
#
ali@38
    31
#     AX_CODE_COVERAGE
ali@38
    32
#
ali@38
    33
#   Makefile.am:
ali@38
    34
#
ali@38
    35
#     @CODE_COVERAGE_RULES@
ali@38
    36
#     my_program_LIBS = ... $(CODE_COVERAGE_LDFLAGS) ...
ali@38
    37
#     my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ...
ali@38
    38
#     my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ...
ali@38
    39
#     my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ...
ali@38
    40
#
ali@38
    41
#   This results in a "check-code-coverage" rule being added to any
ali@38
    42
#   Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module
ali@38
    43
#   has been configured with --enable-code-coverage). Running `make
ali@38
    44
#   check-code-coverage` in that directory will run the module's test suite
ali@38
    45
#   (`make check`) and build a code coverage report detailing the code which
ali@38
    46
#   was touched, then print the URI for the report.
ali@38
    47
#
ali@38
    48
#   This code was derived from Makefile.decl in GLib, originally licenced
ali@38
    49
#   under LGPLv2.1+.
ali@38
    50
#
ali@38
    51
# LICENSE
ali@38
    52
#
ali@38
    53
#   Copyright (c) 2012, 2016 Philip Withnall
ali@38
    54
#   Copyright (c) 2012 Xan Lopez
ali@38
    55
#   Copyright (c) 2012 Christian Persch
ali@38
    56
#   Copyright (c) 2012 Paolo Borelli
ali@38
    57
#   Copyright (c) 2012 Dan Winship
ali@38
    58
#   Copyright (c) 2015 Bastien ROUCARIES
ali@38
    59
#
ali@38
    60
#   This library is free software; you can redistribute it and/or modify it
ali@38
    61
#   under the terms of the GNU Lesser General Public License as published by
ali@38
    62
#   the Free Software Foundation; either version 2.1 of the License, or (at
ali@38
    63
#   your option) any later version.
ali@38
    64
#
ali@38
    65
#   This library is distributed in the hope that it will be useful, but
ali@38
    66
#   WITHOUT ANY WARRANTY; without even the implied warranty of
ali@38
    67
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
ali@38
    68
#   General Public License for more details.
ali@38
    69
#
ali@38
    70
#   You should have received a copy of the GNU Lesser General Public License
ali@38
    71
#   along with this program. If not, see <http://www.gnu.org/licenses/>.
ali@38
    72
ali@38
    73
#serial 16
ali@38
    74
ali@38
    75
AC_DEFUN([AX_CODE_COVERAGE],[
ali@38
    76
	dnl Check for --enable-code-coverage
ali@38
    77
	AC_REQUIRE([AC_PROG_SED])
ali@38
    78
ali@38
    79
	# allow to override gcov location
ali@38
    80
	AC_ARG_WITH([gcov],
ali@38
    81
	  [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])],
ali@38
    82
	  [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov],
ali@38
    83
	  [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov])
ali@38
    84
ali@38
    85
	AC_MSG_CHECKING([whether to build with code coverage support])
ali@38
    86
	AC_ARG_ENABLE([code-coverage],
ali@38
    87
	  AS_HELP_STRING([--enable-code-coverage],
ali@38
    88
	  [Whether to enable code coverage support]),,
ali@38
    89
	  enable_code_coverage=no)
ali@38
    90
ali@38
    91
	AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes])
ali@38
    92
	AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage])
ali@38
    93
	AC_MSG_RESULT($enable_code_coverage)
ali@38
    94
ali@38
    95
	AS_IF([ test "$enable_code_coverage" = "yes" ], [
ali@38
    96
		# check for gcov
ali@38
    97
		AC_CHECK_TOOL([GCOV],
ali@38
    98
		  [$_AX_CODE_COVERAGE_GCOV_PROG_WITH],
ali@38
    99
		  [:])
ali@38
   100
		AS_IF([test "X$GCOV" = "X:"],
ali@38
   101
		  [AC_MSG_ERROR([gcov is needed to do coverage])])
ali@38
   102
		AC_SUBST([GCOV])
ali@38
   103
ali@38
   104
		dnl Check if gcc is being used
ali@38
   105
		AS_IF([ test "$GCC" = "no" ], [
ali@38
   106
			AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage])
ali@38
   107
		])
ali@38
   108
ali@38
   109
		# List of supported lcov versions.
ali@38
   110
		lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.12"
ali@38
   111
ali@38
   112
		AC_CHECK_PROG([LCOV], [lcov], [lcov])
ali@38
   113
		AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
ali@38
   114
ali@38
   115
		AS_IF([ test "$LCOV" ], [
ali@38
   116
			AC_CACHE_CHECK([for lcov version], ax_cv_lcov_version, [
ali@38
   117
				ax_cv_lcov_version=invalid
ali@38
   118
				lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'`
ali@38
   119
				for lcov_check_version in $lcov_version_list; do
ali@38
   120
					if test "$lcov_version" = "$lcov_check_version"; then
ali@38
   121
						ax_cv_lcov_version="$lcov_check_version (ok)"
ali@38
   122
					fi
ali@38
   123
				done
ali@38
   124
			])
ali@38
   125
		], [
ali@38
   126
			lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list"
ali@38
   127
			AC_MSG_ERROR([$lcov_msg])
ali@38
   128
		])
ali@38
   129
ali@38
   130
		case $ax_cv_lcov_version in
ali@38
   131
			""|invalid[)]
ali@38
   132
				lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)."
ali@38
   133
				AC_MSG_ERROR([$lcov_msg])
ali@38
   134
				LCOV="exit 0;"
ali@38
   135
			;;
ali@38
   136
		esac
ali@38
   137
ali@38
   138
		AS_IF([ test -z "$GENHTML" ], [
ali@38
   139
			AC_MSG_ERROR([Could not find genhtml from the lcov package])
ali@38
   140
		])
ali@38
   141
ali@38
   142
		dnl Build the code coverage flags
ali@38
   143
		CODE_COVERAGE_CPPFLAGS="-DNDEBUG"
ali@38
   144
		CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
ali@38
   145
		CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
ali@38
   146
		CODE_COVERAGE_LDFLAGS="-lgcov"
ali@38
   147
ali@38
   148
		AC_SUBST([CODE_COVERAGE_CPPFLAGS])
ali@38
   149
		AC_SUBST([CODE_COVERAGE_CFLAGS])
ali@38
   150
		AC_SUBST([CODE_COVERAGE_CXXFLAGS])
ali@38
   151
		AC_SUBST([CODE_COVERAGE_LDFLAGS])
ali@38
   152
	])
ali@38
   153
ali@38
   154
[CODE_COVERAGE_RULES='
ali@38
   155
# Code coverage
ali@38
   156
#
ali@38
   157
# Optional:
ali@38
   158
#  - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting.
ali@38
   159
#    Multiple directories may be specified, separated by whitespace.
ali@38
   160
#    (Default: $(top_builddir))
ali@38
   161
#  - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated
ali@38
   162
#    by lcov for code coverage. (Default:
ali@38
   163
#    $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info)
ali@38
   164
#  - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage
ali@38
   165
#    reports to be created. (Default:
ali@38
   166
#    $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage)
ali@38
   167
#  - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage,
ali@38
   168
#    set to 0 to disable it and leave empty to stay with the default.
ali@38
   169
#    (Default: empty)
ali@38
   170
#  - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov
ali@38
   171
#    instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
ali@38
   172
#  - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov
ali@38
   173
#    instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
ali@38
   174
#  - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov
ali@38
   175
#  - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the
ali@38
   176
#    collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
ali@38
   177
#  - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov
ali@38
   178
#    instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
ali@38
   179
#  - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering
ali@38
   180
#    lcov instance. (Default: empty)
ali@38
   181
#  - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov
ali@38
   182
#    instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
ali@38
   183
#  - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the
ali@38
   184
#    genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
ali@38
   185
#  - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml
ali@38
   186
#    instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT)
ali@38
   187
#  - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore
ali@38
   188
#
ali@38
   189
# The generated report will be titled using the $(PACKAGE_NAME) and
ali@38
   190
# $(PACKAGE_VERSION). In order to add the current git hash to the title,
ali@38
   191
# use the git-version-gen script, available online.
ali@38
   192
ali@38
   193
# Optional variables
ali@38
   194
CODE_COVERAGE_DIRECTORY ?= $(top_builddir)
ali@38
   195
CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info
ali@38
   196
CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage
ali@38
   197
CODE_COVERAGE_BRANCH_COVERAGE ?=
ali@38
   198
CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
ali@38
   199
--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
ali@38
   200
CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
ali@38
   201
CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)"
ali@38
   202
CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
ali@38
   203
CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
ali@38
   204
CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?=
ali@38
   205
CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
ali@38
   206
CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\
ali@38
   207
$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
ali@38
   208
--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
ali@38
   209
CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS)
ali@38
   210
CODE_COVERAGE_IGNORE_PATTERN ?=
ali@38
   211
ali@38
   212
code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V))
ali@38
   213
code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY))
ali@38
   214
code_coverage_v_lcov_cap_0 = @echo "  LCOV   --capture"\
ali@38
   215
 $(CODE_COVERAGE_OUTPUT_FILE);
ali@38
   216
code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V))
ali@38
   217
code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY))
ali@38
   218
code_coverage_v_lcov_ign_0 = @echo "  LCOV   --remove /tmp/*"\
ali@38
   219
 $(CODE_COVERAGE_IGNORE_PATTERN);
ali@38
   220
code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V))
ali@38
   221
code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY))
ali@38
   222
code_coverage_v_genhtml_0 = @echo "  GEN   " $(CODE_COVERAGE_OUTPUT_DIRECTORY);
ali@38
   223
code_coverage_quiet = $(code_coverage_quiet_$(V))
ali@38
   224
code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY))
ali@38
   225
code_coverage_quiet_0 = --quiet
ali@38
   226
ali@38
   227
# sanitizes the test-name: replaces with underscores: dashes and dots
ali@38
   228
code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1)))
ali@38
   229
ali@38
   230
# Use recursive makes in order to ignore errors during check
ali@38
   231
check-code-coverage:
ali@38
   232
ifeq ($(CODE_COVERAGE_ENABLED),yes)
ali@38
   233
	-$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check
ali@38
   234
	$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture
ali@38
   235
else
ali@38
   236
	@echo "Need to reconfigure with --enable-code-coverage"
ali@38
   237
endif
ali@38
   238
ali@38
   239
# Capture code coverage data
ali@38
   240
code-coverage-capture: code-coverage-capture-hook
ali@38
   241
ifeq ($(CODE_COVERAGE_ENABLED),yes)
ali@38
   242
	$(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)
ali@38
   243
	$(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)
ali@38
   244
	-@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp
ali@38
   245
	$(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)
ali@38
   246
	@echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html"
ali@38
   247
else
ali@38
   248
	@echo "Need to reconfigure with --enable-code-coverage"
ali@38
   249
endif
ali@38
   250
ali@38
   251
# Hook rule executed before code-coverage-capture, overridable by the user
ali@38
   252
code-coverage-capture-hook:
ali@38
   253
ali@38
   254
ifeq ($(CODE_COVERAGE_ENABLED),yes)
ali@38
   255
clean: code-coverage-clean
ali@38
   256
distclean: code-coverage-clean
ali@38
   257
code-coverage-clean:
ali@38
   258
	-$(LCOV) --directory $(top_builddir) -z
ali@38
   259
	-rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY)
ali@38
   260
	-find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete
ali@38
   261
endif
ali@38
   262
ali@38
   263
GITIGNOREFILES ?=
ali@38
   264
GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
ali@38
   265
ali@38
   266
A''M_DISTCHECK_CONFIGURE_FLAGS ?=
ali@38
   267
A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage
ali@38
   268
ali@38
   269
.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean
ali@38
   270
']
ali@38
   271
ali@38
   272
	AC_SUBST([CODE_COVERAGE_RULES])
ali@38
   273
	m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])])
ali@38
   274
])