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