diff --git a/Makefile.am b/Makefile.am index c2001b3c..dd98722e 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 195862a7..1d6b7203 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 a2bc94c3..a7ce4720 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -39,13 +39,17 @@ libinput_la_LIBADD = $(MTDEV_LIBS) \ $(LIBEVDEV_LIBS) \ $(LIBWACOM_LIBS) \ libinput-util.la +libinput_la_LDFLAGS = $(GCOV_LDFLAGS) \ + -version-info $(LIBINPUT_LT_VERSION) -shared \ + -Wl,--version-script=$(srcdir)/libinput.sym 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 +57,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 \ @@ -64,9 +70,6 @@ libfilter_la_SOURCES = \ libfilter_la_LIBADD = libfilter_la_CFLAGS = -libinput_la_LDFLAGS = -version-info $(LIBINPUT_LT_VERSION) -shared \ - -Wl,--version-script=$(srcdir)/libinput.sym - pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libinput.pc diff --git a/test/Makefile.am b/test/Makefile.am index ba05729e..5980dba0 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 @@ -163,3 +163,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 00000000..2d913710 --- /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 [ ... ]" + 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"