@@ -211,6 +211,12 @@ HOST_GNU_TYPE= @host@
211211PROFILE_TASK= $(srcdir)/Tools/pybench/pybench.py -n 2 --with-gc --with-syscheck
212212#PROFILE_TASK= $(srcdir)/Lib/test/regrtest.py
213213
214+ # report files for gcov / lcov coverage report
215+ COVERAGE_INFO= $(abs_builddir)/coverage.info
216+ COVERAGE_REPORT=$(abs_builddir)/lcov-report
217+ COVERAGE_REPORT_OPTIONS=--no-branch-coverage --title "CPython lcov report"
218+
219+
214220# === Definitions added by makesetup ===
215221
216222
@@ -463,11 +469,48 @@ run_profile_task:
463469build_all_use_profile:
464470 $(MAKE) all CFLAGS="$(CFLAGS) -fprofile-use -fprofile-correction"
465471
472+ # Compile and run with gcov
473+ .PHONY=coverage coverage-lcov coverage-report
466474coverage:
467475 @echo "Building with support for coverage checking:"
468- $(MAKE) clean
476+ $(MAKE) clean profile-removal
469477 $(MAKE) all CFLAGS="$(CFLAGS) -O0 -pg -fprofile-arcs -ftest-coverage" LIBS="$(LIBS) -lgcov"
470478
479+ coverage-lcov:
480+ @echo "Creating Coverage HTML report with LCOV:"
481+ @rm -f $(COVERAGE_INFO)
482+ @rm -rf $(COVERAGE_REPORT)
483+ @lcov --capture --directory $(abs_builddir) \
484+ --base-directory $(realpath $(abs_builddir)) \
485+ --path $(realpath $(abs_srcdir)) \
486+ --output-file $(COVERAGE_INFO)
487+ : # remove 3rd party modules and system headers
488+ @lcov --remove $(COVERAGE_INFO) \
489+ '*/Modules/_ctypes/libffi*/*' \
490+ '*/Modules/_sha3/keccak/*' \
491+ '*/Modules/_decimal/libmpdec/*' \
492+ '*/Modules/expat/*' \
493+ '*/Modules/zlib/*' \
494+ '*/Include/*' \
495+ '/usr/include/*' \
496+ '/usr/local/include/*' \
497+ --output-file $(COVERAGE_INFO)
498+ @genhtml $(COVERAGE_INFO) --output-directory $(COVERAGE_REPORT) \
499+ $(COVERAGE_REPORT_OPTIONS)
500+ @echo
501+ @echo "lcov report at $(COVERAGE_REPORT)/index.html"
502+ @echo
503+
504+ coverage-report:
505+ : # force rebuilding of parser and importlib
506+ @touch $(GRAMMAR_INPUT)
507+ @touch $(srcdir)/Lib/importlib/_bootstrap.py
508+ : # build with coverage info
509+ $(MAKE) coverage
510+ : # run tests, ignore failures
511+ $(TESTRUNNER) $(TESTOPTS) || true
512+ : # build lcov report
513+ $(MAKE) coverage-lcov
471514
472515# Build the interpreter
473516$(BUILDPYTHON): Modules/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY)
@@ -1396,6 +1439,8 @@ clean: pycremoval
13961439
13971440profile-removal:
13981441 find . -name '*.gc??' -exec rm -f {} ';'
1442+ rm -f $(COVERAGE_INFO)
1443+ rm -rf $(COVERAGE_REPORT)
13991444
14001445clobber: clean profile-removal
14011446 -rm -f $(BUILDPYTHON) $(PGEN) $(LIBRARY) $(LDLIBRARY) $(DLLLIBRARY) \
0 commit comments