Skip to content

Commit 6834cb5

Browse files
committed
Implement coverage option
To use pass -DCMAKE_BUILD_TYPE=Debug or Asan -DCOVERAGE=ON and build as usual, then do ninja lcov-initialize && ninja check && ninja lcov-collect. The result will be a directory, <Builddir>/Coverage containing lcov tracefiles, including an aggregate file gnucash.info which you can use for further processing. It will also report an overall summary. Note that only C/C++ files are included. There's one more target, lcov-generate-html, that you can run after lcov-collect. It will generate a simple website in <Builddir>/Coverage-HTML showing coverage by source directory (the directories in <Builddir> have coverage for generated files). Each directory path is a clickable link to a page that shows coverage for each source file; the filenames link to a page for each showing which lines have been exercised.
1 parent a3f1475 commit 6834cb5

File tree

28 files changed

+233
-3
lines changed

28 files changed

+233
-3
lines changed

CMakeLists.txt

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ option (WITH_OFX "compile with ofx support (needs LibOFX)" ON)
5454
option (WITH_PYTHON "enable python plugin and bindings" OFF)
5555
option (ENABLE_BINRELOC "compile with binary relocation support" ON)
5656
option (DISABLE_NLS "do not use Native Language Support" OFF)
57-
option (COVERAGE "Instrument an Asan build for coverage reporting" OFF)
57+
option (COVERAGE "Instrument a Debug or Asan build for coverage reporting" OFF)
5858
option (LEAKS "Report leaks for tests in a non-Apple Asan build." OFF)
5959
option (ODR "Report One Definition Rule violations in tests in a non-Apple Asan build." OFF)
6060
# ############################################################
@@ -628,7 +628,13 @@ elseif(UNIX)
628628
endif ()
629629
set(ASAN_LINK_OPTIONS -fsanitize=address -fsanitize=undefined)
630630
if (COVERAGE)
631-
list(APPEND ASAN_LINK_OPTIONS --coverage)
631+
include(GncCoverage)
632+
endif()
633+
if (COVERAGE)
634+
set(COVERAGE_COMPILE_OPTION --coverage)
635+
add_compile_options("$<$<CONFIG:Debug>:${COVERAGE_COMPILE_OPTION}>")
636+
add_link_options("$<$<CONFIG:Debug>:${COVERAGE_COMPILE_OPTION}>")
637+
list(APPEND ASAN_LINK_OPTIONS ${COVERAGE_COMPILE_OPTION})
632638
endif()
633639
set(ASAN_COMPILE_OPTIONS -g ${ASAN_LINK_OPTIONS})
634640
add_compile_options("$<$<CONFIG:Asan>:${ASAN_COMPILE_OPTIONS}>")
@@ -689,6 +695,10 @@ add_custom_target(check
689695
COMMAND ${CMAKE_CTEST_COMMAND}
690696
)
691697

698+
if (COVERAGE)
699+
add_dependencies(check lcov-initialize)
700+
endif()
701+
692702
set(gnucash_DOCS
693703
AUTHORS
694704
ChangeLog.1999
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#lcov command options:
2+
# -a, --add-tracefile (takes glob)
3+
# -c, --capture; create a trace file from the .da files
4+
# -e, --extract; a reduced scope for analysis
5+
# -l, --list; the contents of a tracefile
6+
# -r, --remove; remove pattern-match from tracefile
7+
# -z, --zerocounters; run this first, then -c -i
8+
# --diff
9+
# --summary
10+
# other necessary options:
11+
# --directory; points to the source root. If left off it analyzes the kernel
12+
# --no-external; only analyze code in --directory
13+
# --build-directory; where the .no when different from the .da files
14+
# --branch-coverage; to ensure branch info is saved
15+
# --demangle-cpp; requires c++filt
16+
17+
if (COVERAGE)
18+
find_program(LCOV lcov)
19+
find_program(GENINFO geninfo)
20+
find_program(GENHTML genhtml)
21+
find_program(CPPFILT c++filt)
22+
23+
if (NOT LCOV OR NOT GENINFO OR NOT GENHTML OR NOT CPPFILT)
24+
MESSAGE(WARNING "A required program for presenting coverage information isn't available, disabling coverage")
25+
set(COVERAGE OFF CACHE INTERNAL "")
26+
return()
27+
endif()
28+
else()
29+
return()
30+
endif()
31+
32+
execute_process(COMMAND lcov --version OUTPUT_VARIABLE lcov_version_response)
33+
string(REGEX MATCH "[-.0-9]+" lcov_version ${lcov_version_response})
34+
set(LCOV_VERSION ${lcov_version} CACHE INTERNAL "")
35+
36+
set(excludes_arg "")
37+
foreach (sys_path ${CMAKE_SYSTEM_PREFIX_PATH})
38+
list(APPEND excludes_arg "--exclude" "${sys_path}/*")
39+
endforeach()
40+
41+
set(ignores_arg "--ignore-errors" "unused,unused" "--ignore-errors" "mismatch,mismatch"
42+
"--ignore-errors" "empty,empty")
43+
list(APPEND ignores_arg "--rc" "geninfo_unexecuted_blocks=1")
44+
set(generate_flags "")
45+
set(geninfo_flags --quiet ${excludes_arg})
46+
if (LCOV_VERSION VERSION_GREATER_EQUAL "2.0")
47+
list(APPEND geninfo_flags ${ignores_arg})
48+
list(APPEND generate_flags "--branch-coverage" "--demangle-cpp" "c++filt")
49+
else()
50+
list(APPEND generate_flags "--rc" "lcov_branch_coverage=1" "--rc" "genhtml_demangle_cpp=1")
51+
endif()
52+
set(coverage_dir "${CMAKE_BINARY_DIR}/Coverage" CACHE INTERNAL "Directory to accumulate coverage tracefiles")
53+
set(coverage_html_dir "${CMAKE_BINARY_DIR}/Coverage-HTML" CACHE INTERNAL "Directory to place HTML coverage results pages")
54+
55+
file(MAKE_DIRECTORY ${coverage_dir})
56+
57+
add_custom_target(lcov-initialize)
58+
if (LCOV_VERSION VERSION_GREATER_EQUAL "2.0")
59+
add_custom_target(lcov-collect
60+
COMMAND lcov ${geninfo_flags} -a ${coverage_dir}/*.info -o ${coverage_dir}/gnucash.info
61+
COMMAND lcov --summary ${coverage_dir}/gnucash.info
62+
VERBATIM
63+
COMMAND_EXPAND_LISTS)
64+
else()
65+
file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/collect.sh
66+
CONTENT
67+
"#!/bin/bash
68+
if [ -e $2 ]
69+
then rm $2
70+
fi
71+
j=\"\"
72+
for i in $1/*.info
73+
do j=\"$j -a $i\"
74+
done
75+
lcov $j -o $2
76+
"
77+
FILE_PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE WORLD_EXECUTE)
78+
79+
add_custom_target(lcov-collect
80+
COMMAND ${CMAKE_COMMAND} -E env ${CMAKE_BINARY_DIR}/collect.sh ${coverage_dir} ${coverage_dir}/gnucash.info
81+
DEPENDS ${CMAKE_BINARY_DIR}/collect.sh
82+
VERBATIM
83+
COMMAND_EXPAND_LISTS)
84+
endif()
85+
set_target_properties(lcov-collect PROPERTIES ADDITIONAL_CLEAN_FILES "${coverage_dir}/gnucash.info")
86+
87+
add_custom_target(lcov-generate-html
88+
genhtml --quiet --output-directory "${coverage_html_dir}" --legend --function-coverage ${generate_flags} ${coverage_dir}/gnucash.info
89+
VERBATIM
90+
COMMAND_EXPAND_LISTS)
91+
set_target_properties(lcov-generate-html PROPERTIES ADDITIONAL_CLEAN_FILES "${coverage_html_dir}")
92+
93+
function (add_coverage_target tgt)
94+
get_target_property(build_dir ${tgt} BINARY_DIR)
95+
set(target_dir "${build_dir}/CMakeFiles/${tgt}.dir")
96+
97+
add_custom_target(lcov-initialize-${tgt}
98+
lcov ${geninfo_flags} -z --directory ${target_dir}
99+
COMMAND lcov ${geninfo_flags} ${generate_flags} -c -i --directory ${target_dir} -o "${coverage_dir}/${tgt}_base.info"
100+
VERBATIM
101+
COMMAND_EXPAND_LISTS)
102+
add_dependencies(lcov-initialize lcov-initialize-${tgt})
103+
add_dependencies(lcov-initialize-${tgt} ${tgt})
104+
105+
add_custom_target(lcov-collect-${tgt}
106+
COMMAND lcov ${geninfo_flags} ${generate_flags} -c --directory ${target_dir} -o "${coverage_dir}/${tgt}_result.info"
107+
VERBATIM
108+
COMMAND_EXPAND_LISTS)
109+
add_dependencies(lcov-collect lcov-collect-${tgt})
110+
set_target_properties(${tgt} PROPERTIES ADDITIONAL_CLEAN_FILES "${coverage_dir}/${tgt}_base.info;${coverage_dir}/${tgt}_result.info")
111+
endFunction()

gnucash/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ if (MAC_INTEGRATION)
160160
target_link_options(gnucash-cli PRIVATE -Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_SOURCE_DIR}/Info.plist)
161161
endif()
162162

163+
if (COVERAGE AND LCOV_VERSION VERSION_GREATER_EQUAL "2.0")
164+
add_coverage_target(gnucash)
165+
add_coverage_target(gnucash-cli)
166+
endif()
167+
163168
install(TARGETS gnucash gnucash-cli DESTINATION ${CMAKE_INSTALL_BINDIR})
164169
# No headers to install.
165170

gnucash/gnome-search/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ if (APPLE)
5555
set_target_properties (gnc-gnome-search PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/gnucash")
5656
endif()
5757

58+
if (COVERAGE)
59+
add_coverage_target(gnc-gnome-search)
60+
endif()
61+
5862
install(TARGETS gnc-gnome-search
5963
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/gnucash
6064
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/gnucash

gnucash/gnome-utils/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ if (MAC_INTEGRATION)
224224
target_link_libraries(gnc-gnome-utils ${OSX_EXTRA_LIBRARIES})
225225
endif()
226226

227+
if (COVERAGE)
228+
add_coverage_target(gnc-gnome-utils)
229+
endif()
230+
227231
target_include_directories(gnc-gnome-utils
228232
PUBLIC
229233
${CMAKE_CURRENT_SOURCE_DIR}

gnucash/gnome/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ if (MAC_INTEGRATION)
163163
target_link_libraries(gnc-gnome ${OSX_EXTRA_LIBRARIES})
164164
endif()
165165

166+
if (COVERAGE)
167+
add_coverage_target(gnc-gnome)
168+
endif()
166169

167170
install(TARGETS gnc-gnome
168171
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}

gnucash/html/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ if (APPLE)
7373
endif()
7474

7575
add_dependencies(gnc-html swig-gnc-html-c)
76+
77+
if (COVERAGE)
78+
add_coverage_target(gnc-html)
79+
endif()
80+
7681
install(TARGETS gnc-html
7782
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/gnucash
7883
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/gnucash

gnucash/import-export/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ if (APPLE)
6161
set_target_properties (gnc-generic-import PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_FULL_LIBDIR}")
6262
endif()
6363

64+
if (COVERAGE)
65+
add_coverage_target(gnc-generic-import)
66+
endif()
67+
6468
install(TARGETS gnc-generic-import
6569
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
6670
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}

gnucash/import-export/aqb/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ if(WITH_AQBANKING)
8181
set_target_properties (gncmod-aqbanking PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/gnucash")
8282
endif()
8383

84+
if (COVERAGE)
85+
add_coverage_target(gncmod-aqbanking)
86+
endif()
87+
8488
install(TARGETS gncmod-aqbanking
8589
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/gnucash
8690
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/gnucash

gnucash/import-export/bi-import/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ if (APPLE)
3737
set_target_properties (gnc-bi-import PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/gnucash")
3838
endif()
3939

40+
if (COVERAGE AND LCOV_VERSION VERSION_GREATER_EQUAL "2.0")
41+
add_coverage_target(gnc-bi-import)
42+
endif()
43+
4044
install(TARGETS gnc-bi-import
4145
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/gnucash
4246
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}/gnucash

0 commit comments

Comments
 (0)