diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2012-07-29 17:58:21 +0200 |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2012-08-31 23:43:17 +0100 |
commit | 493d55921f26ac3a9a3b7cc33756c88daace329e (patch) | |
tree | a6785d89a83cc9def778639f59d05145ec0a7e9d | |
parent | 4668cc8250c15119dc7bdbbf842da53f4fe478fe (diff) | |
download | gnome-common-493d55921f26ac3a9a3b7cc33756c88daace329e.tar.gz |
Bug 606720 — Add code coverage support
Add a GNOME_CODE_COVERAGE m4 macro to allow projects to easily add code
coverage support using lcov.
This is heavily based on the code coverage tooling from GLib (LGPLv2.1+),
originally written by Patrick Hulin and modified by Matthias Clasen, Stef
Walter and Simon McVittie since.
Closes: https://bugzilla.gnome.org/show_bug.cgi?id=606720
-rw-r--r-- | macros2/Makefile.am | 3 | ||||
-rw-r--r-- | macros2/gnome-autogen.sh | 3 | ||||
-rw-r--r-- | macros2/gnome-code-coverage.m4 | 150 |
3 files changed, 155 insertions, 1 deletions
diff --git a/macros2/Makefile.am b/macros2/Makefile.am index 5cfdc6f..07781be 100644 --- a/macros2/Makefile.am +++ b/macros2/Makefile.am @@ -2,7 +2,8 @@ GNOME2_MACROS = \ gnome-common.m4 \ - gnome-compiler-flags.m4 + gnome-compiler-flags.m4 \ + gnome-code-coverage.m4 EXTRA_DIST = $(GNOME2_MACROS) gnome-autogen.sh diff --git a/macros2/gnome-autogen.sh b/macros2/gnome-autogen.sh index 31fe6ae..2c40620 100644 --- a/macros2/gnome-autogen.sh +++ b/macros2/gnome-autogen.sh @@ -332,6 +332,9 @@ for configure_ac in $configure_files; do grep "^GNOME_CXX_WARNINGS" $configure_ac >/dev/null; then require_m4macro gnome-compiler-flags.m4 fi + if grep "^GNOME_CODE_COVERAGE" $configure_ac >/dev/null; then + require_m4macro gnome-code-coverage.m4 + fi done #tell Mandrake autoconf wrapper we want autoconf 2.5x, not 2.13 diff --git a/macros2/gnome-code-coverage.m4 b/macros2/gnome-code-coverage.m4 new file mode 100644 index 0000000..68ffd5e --- /dev/null +++ b/macros2/gnome-code-coverage.m4 @@ -0,0 +1,150 @@ +dnl GNOME_CODE_COVERAGE +dnl +dnl Defines CODE_COVERAGE_CFLAGS and CODE_COVERAGE_LDFLAGS which should be +dnl included in the CFLAGS and LIBS/LDFLAGS variables of every build target +dnl (program or library) which should be built with code coverage support. +dnl Also defines GNOME_CODE_COVERAGE_RULES which should be substituted in your +dnl Makefile; and $enable_code_coverage which can be used in subsequent +dnl configure output. +dnl +dnl Note that all optimisation flags in CFLAGS must be disabled when code +dnl coverage is enabled. +dnl +dnl Derived from Makefile.decl in GLib, originally licenced under LGPLv2.1+. +dnl This file is licenced under GPLv3. For the full gnome-common licence +dnl (GPLv3), see the COPYING file. +dnl +dnl Usage example: +dnl configure.ac: +dnl GNOME_CODE_COVERAGE +dnl +dnl Makefile.am: +dnl @GNOME_CODE_COVERAGE_RULES@ +dnl my_program_LIBS = … $(CODE_COVERAGE_LDFLAGS) … +dnl my_program_CFLAGS = … $(CODE_COVERAGE_CFLAGS) … + +AC_DEFUN([GNOME_CODE_COVERAGE],[ + dnl Check for --enable-code-coverage + AC_MSG_CHECKING([whether to build with code coverage support]) + AC_ARG_ENABLE([code-coverage], AS_HELP_STRING([--enable-code-coverage], [Whether to enable code coverage support]),, enable_code_coverage=no) + AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) + AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) + AC_MSG_RESULT($enable_code_coverage) + + AS_IF([ test "$enable_code_coverage" = "yes" ], [ + dnl Check if gcc is being used + AS_IF([ test "$GCC" = "no" ], [ + AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) + ]) + + # List of supported lcov versions. + lcov_version_list="1.6 1.7 1.8 1.9" + + AC_CHECK_PROG([LCOV], [lcov], [lcov]) + AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) + + AS_IF([ test "$LCOV" ], [ + AC_CACHE_CHECK([for lcov version], gnome_cv_lcov_version, [ + gnome_cv_lcov_version=invalid + lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` + for lcov_check_version in $lcov_version_list; do + if test "$lcov_version" = "$lcov_check_version"; then + gnome_cv_lcov_version="$lcov_check_version (ok)" + fi + done + ]) + ], [ + lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list" + AC_MSG_ERROR([$lcov_msg]) + ]) + + case $gnome_cv_lcov_version in + ""|invalid[)] + lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)." + AC_MSG_ERROR([$lcov_msg]) + LCOV="exit 0;" + ;; + esac + + AS_IF([ test -z "$GENHTML" ], [ + AC_MSG_ERROR([Could not find genhtml from the lcov package]) + ]) + + dnl Build the code coverage flags + CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" + CODE_COVERAGE_LDFLAGS="-lgcov" + + AC_SUBST([CODE_COVERAGE_CFLAGS]) + AC_SUBST([CODE_COVERAGE_LDFLAGS]) + ]) + +GNOME_CODE_COVERAGE_RULES=' +# Code coverage +# +# Optional: +# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. +# (Default: $(top_builddir)) +# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated +# by lcov for code coverage. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) +# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage +# reports to be created. (Default: +# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) +# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the lcov instance. +# (Default: empty) +# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml +# instance. (Default: empty) +# +# The generated report will be titled using the $(PACKAGE_NAME) and +# $(PACKAGE_VERSION). In order to add the current git hash to the title, +# use the git-version-gen script, available online. + +# Optional variables +CODE_COVERAGE_DIRECTORY ?= $(top_builddir) +CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info +CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage +CODE_COVERAGE_LCOV_OPTIONS ?= +CODE_COVERAGE_GENHTML_OPTIONS ?= + +# Use recursive makes in order to ignore errors during check +check-code-coverage: +ifdef CODE_COVERAGE_ENABLED + -$(MAKE) $(AM_MAKEFLAGS) -k check + $(MAKE) $(AM_MAKEFLAGS) code-coverage-capture +else + @echo "Need to reconfigure with --enable-code-coverage" +endif + +# Capture code coverage data +code-coverage-capture: code-coverage-capture-hook +ifdef CODE_COVERAGE_ENABLED + $(LCOV) --directory $(CODE_COVERAGE_DIRECTORY) --capture --output-file $(CODE_COVERAGE_OUTPUT_FILE).tmp --test-name "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_OPTIONS) + $(LCOV) --directory $(CODE_COVERAGE_DIRECTORY) --remove $(CODE_COVERAGE_OUTPUT_FILE).tmp "/tmp/*" --output-file $(CODE_COVERAGE_OUTPUT_FILE) + -rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp + LANG=C $(GENHTML) --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) + @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" +else + @echo "Need to reconfigure with --enable-code-coverage" +endif + +# Hook rule executed before code-coverage-capture, overridable by the user +code-coverage-capture-hook: + +clean: code-coverage-clean +code-coverage-clean: + -$(LCOV) --directory $(top_builddir) -z + -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) + -find . -name "*.gcda" -o -name "*.gcov" -delete + +GITIGNOREFILES ?= +GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) + +DISTCHECK_CONFIGURE_FLAGS ?= +DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage + +.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean +' + + AC_SUBST([GNOME_CODE_COVERAGE_RULES]) + m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([GNOME_CODE_COVERAGE_RULES])]) +]) |