[PATCH libinput] Hook up gcov for coverage reports

Peter Hutterer peter.hutterer at who-t.net
Mon Jan 9 02:56:57 UTC 2017


./configure --enable-gcov adds the required flags to link everything ready for
gcov. A new make gcov target runs the test suite, then pulls all the gcov bits
together into ./test/gcov-reports/ including a summary file.

The script to pull everything out is used in libevdev too, we just have an
extra condition here to ignore the selftest gcov bits (it overwrites the
useful litest.c coverage output).

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 Makefile.am                  |  3 +++
 configure.ac                 | 21 +++++++++++++++++++++
 src/Makefile.am              |  8 ++++++--
 test/Makefile.am             | 13 ++++++++++++-
 test/generate-gcov-report.sh | 42 ++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 84 insertions(+), 3 deletions(-)
 create mode 100755 test/generate-gcov-report.sh

diff --git a/Makefile.am b/Makefile.am
index c2001b3..dd98722 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -6,3 +6,6 @@ valgrind:
 	(cd test; $(MAKE) valgrind)
 
 AM_DISTCHECK_CONFIGURE_FLAGS = --disable-test-run
+
+gcov:
+	(cd test; $(MAKE) gcov)
diff --git a/configure.ac b/configure.ac
index 7c13a4e..cc501db 100644
--- a/configure.ac
+++ b/configure.ac
@@ -262,6 +262,26 @@ AM_CONDITIONAL(BUILD_DOCS, [test "x$build_documentation" = "xyes"])
 AM_CONDITIONAL(HAVE_LIBUNWIND, [test "x$HAVE_LIBUNWIND" = xyes])
 AM_CONDITIONAL(BUILD_EVENTGUI, [test "x$build_eventgui" = "xyes"])
 
+#######################
+# enable/disable gcov #
+#######################
+
+AC_ARG_ENABLE([gcov],
+              [AS_HELP_STRING([--enable-gcov],
+                              [Enable to enable coverage testing (default:disabled)])],
+	      [enable_gcov="$enableval"],
+              [enable_gcov=no])
+if test "x$enable_gcov" != "xno"; then
+       GCOV_CFLAGS="-fprofile-arcs -ftest-coverage"
+       GCOV_LDFLAGS="-fprofile-arcs -ftest-coverage"
+       enable_gcov=yes
+fi
+
+AM_CONDITIONAL([GCOV_ENABLED], [test "x$enable_gcov" != "xno"])
+AC_SUBST([GCOV_CFLAGS])
+AC_SUBST([GCOV_LDFLAGS])
+
+
 AC_CONFIG_FILES([Makefile
 		 doc/Makefile
 		 doc/libinput.doxygen
@@ -288,4 +308,5 @@ AC_MSG_RESULT([
 	Tests use valgrind	${VALGRIND}
 	Tests use libunwind	${HAVE_LIBUNWIND}
 	Build GUI event tool	${build_eventgui}
+	Enable gcov profiling	${enable_gcov}
 	])
diff --git a/src/Makefile.am b/src/Makefile.am
index 48e704a..eb15454 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -39,13 +39,15 @@ libinput_la_LIBADD = $(MTDEV_LIBS) \
 		     $(LIBEVDEV_LIBS) \
 		     $(LIBWACOM_LIBS) \
 		     libinput-util.la
+libinput_la_LDFLAGS = $(GCOV_LDFLAGS)
 
 libinput_la_CFLAGS = -I$(top_srcdir)/include \
 		     $(MTDEV_CFLAGS)	\
 		     $(LIBUDEV_CFLAGS)	\
 		     $(LIBEVDEV_CFLAGS)	\
 		     $(LIBWACOM_CFLAGS) \
-		     $(GCC_CFLAGS)
+		     $(GCC_CFLAGS) \
+		     $(GCOV_CFLAGS)
 EXTRA_libinput_la_DEPENDENCIES = $(srcdir)/libinput.sym
 
 libinput_util_la_SOURCES = \
@@ -53,9 +55,11 @@ libinput_util_la_SOURCES = \
 	libinput-util.h
 
 libinput_util_la_LIBADD =
+libinput_util_la_LDFLAGS = $(GCOV_LDFLAGS)
 libinput_util_la_CFLAGS = -I$(top_srcdir)/include \
 			  $(LIBUDEV_CFLAGS) \
-			  $(GCC_CFLAGS)
+			  $(GCC_CFLAGS) \
+			  $(GCOV_CFLAGS)
 
 libfilter_la_SOURCES = \
 	filter.c \
diff --git a/test/Makefile.am b/test/Makefile.am
index 2def2ae..a89ec61 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -6,7 +6,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include \
               $(LIBUDEV_CFLAGS) \
               -I$(top_builddir)/src # for libinput-version.h
 
-AM_CFLAGS = $(GCC_CFLAGS)
+AM_CFLAGS = $(GCC_CFLAGS) $(GCOV_CFLAGS)
 AM_CXXFLAGS = $(GCC_CXXFLAGS)
 
 TEST_LIBS = liblitest.la $(CHECK_LIBS) $(LIBUDEV_LIBS) $(LIBEVDEV_LIBS) $(top_builddir)/src/libinput.la
@@ -162,3 +162,14 @@ DISTCLEANFILES=test-suite-valgrind.log
 endif
 endif
 EXTRA_DIST=valgrind.suppressions
+
+if GCOV_ENABLED
+
+CLEANFILES = gcov-reports/*.gcov gcov-reports/summary.txt *.gcno *.gcda
+
+gcov: generate-gcov-report.sh check-TESTS
+	$(AM_V_GEN)$(srcdir)/generate-gcov-report.sh gcov-reports $(top_builddir)/src $(builddir)
+else
+gcov:
+	@echo "Run ./configure --enable-gcov to produce gcov reports" && false
+endif
diff --git a/test/generate-gcov-report.sh b/test/generate-gcov-report.sh
new file mode 100755
index 0000000..2d91371
--- /dev/null
+++ b/test/generate-gcov-report.sh
@@ -0,0 +1,42 @@
+#!/bin/bash -e
+
+if [[ $# -lt 2 ]]; then
+    echo "Usage: ./generate-gcov-report.sh <rel-target-dir> <srcdir> [<srcdir> ... ]"
+    exit 1
+fi
+
+target_dir=$1
+shift
+source_dirs=$*
+
+if [[ "${target_dir:0:1}" != '/' ]]; then
+    target_dir="$PWD/$target_dir"
+fi
+summary_file="$target_dir/summary.txt"
+
+mkdir -p "$target_dir"
+rm -f "$target_dir"/*.gcov
+
+for dir in $source_dirs; do
+	pushd "$dir" > /dev/null
+	for file in *.c; do
+		find ./ -name "*${file/\.c/.gcda}" \
+			\!  -path "*selftest*" \
+			-exec gcov {} \; > /dev/null
+	done
+	find ./ -name "*.gcov" \
+		\! -path "*/`basename "$target_dir"`/*" \
+		-exec mv {} "$target_dir" \;
+	popd > /dev/null
+done
+
+echo "========== coverage report ========" > "$summary_file"
+for file in "$target_dir"/*.gcov; do
+	total=`grep -v " -:" "$file" | wc -l`
+	missing=`grep "#####" "$file" | wc -l`
+	hit=$((total - missing));
+	percent=$((($hit * 100)/$total))
+	fname=`basename "$file"`
+	printf "%-50s total lines: %4s not tested: %4s (%3s%%)\n" "$fname" "$total" "$missing" "$percent">> "$summary_file"
+done
+echo "========== =============== ========" >> "$summary_file"
-- 
2.9.3



More information about the wayland-devel mailing list