]>
Commit | Line | Data |
---|---|---|
42f7b73b AX |
1 | # =========================================================================== |
2 | # https://www.gnu.org/software/autoconf-archive/ax_code_coverage.html | |
3 | # =========================================================================== | |
4 | # | |
5 | # SYNOPSIS | |
6 | # | |
7 | # AX_CODE_COVERAGE() | |
8 | # | |
9 | # DESCRIPTION | |
10 | # | |
11 | # Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS, | |
12 | # CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LIBS which should be included | |
13 | # in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LIBADD variables of every | |
14 | # build target (program or library) which should be built with code | |
15 | # coverage support. Also defines CODE_COVERAGE_RULES which should be | |
16 | # substituted in your Makefile; and $enable_code_coverage which can be | |
17 | # used in subsequent configure output. CODE_COVERAGE_ENABLED is defined | |
18 | # and substituted, and corresponds to the value of the | |
19 | # --enable-code-coverage option, which defaults to being disabled. | |
20 | # | |
21 | # Test also for gcov program and create GCOV variable that could be | |
22 | # substituted. | |
23 | # | |
24 | # Note that all optimization flags in CFLAGS must be disabled when code | |
25 | # coverage is enabled. | |
26 | # | |
27 | # Usage example: | |
28 | # | |
29 | # configure.ac: | |
30 | # | |
31 | # AX_CODE_COVERAGE | |
32 | # | |
33 | # Makefile.am: | |
34 | # | |
35 | # @CODE_COVERAGE_RULES@ | |
36 | # my_program_LIBS = ... $(CODE_COVERAGE_LIBS) ... | |
37 | # my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ... | |
38 | # my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ... | |
39 | # my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ... | |
40 | # | |
41 | # This results in a "check-code-coverage" rule being added to any | |
42 | # Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module | |
43 | # has been configured with --enable-code-coverage). Running `make | |
44 | # check-code-coverage` in that directory will run the module's test suite | |
45 | # (`make check`) and build a code coverage report detailing the code which | |
46 | # was touched, then print the URI for the report. | |
47 | # | |
48 | # In earlier versions of this macro, CODE_COVERAGE_LDFLAGS was defined | |
49 | # instead of CODE_COVERAGE_LIBS. They are both still defined, but use of | |
50 | # CODE_COVERAGE_LIBS is preferred for clarity; CODE_COVERAGE_LDFLAGS is | |
51 | # deprecated. They have the same value. | |
52 | # | |
53 | # This code was derived from Makefile.decl in GLib, originally licenced | |
54 | # under LGPLv2.1+. | |
55 | # | |
56 | # LICENSE | |
57 | # | |
58 | # Copyright (c) 2012, 2016 Philip Withnall | |
59 | # Copyright (c) 2012 Xan Lopez | |
60 | # Copyright (c) 2012 Christian Persch | |
61 | # Copyright (c) 2012 Paolo Borelli | |
62 | # Copyright (c) 2012 Dan Winship | |
63 | # Copyright (c) 2015 Bastien ROUCARIES | |
64 | # | |
65 | # This library is free software; you can redistribute it and/or modify it | |
66 | # under the terms of the GNU Lesser General Public License as published by | |
67 | # the Free Software Foundation; either version 2.1 of the License, or (at | |
68 | # your option) any later version. | |
69 | # | |
70 | # This library is distributed in the hope that it will be useful, but | |
71 | # WITHOUT ANY WARRANTY; without even the implied warranty of | |
72 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser | |
73 | # General Public License for more details. | |
74 | # | |
75 | # You should have received a copy of the GNU Lesser General Public License | |
76 | # along with this program. If not, see <https://www.gnu.org/licenses/>. | |
77 | ||
78 | #serial 25 | |
79 | ||
80 | AC_DEFUN([AX_CODE_COVERAGE],[ | |
81 | dnl Check for --enable-code-coverage | |
82 | AC_REQUIRE([AC_PROG_SED]) | |
83 | ||
84 | # allow to override gcov location | |
85 | AC_ARG_WITH([gcov], | |
86 | [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])], | |
87 | [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov], | |
88 | [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov]) | |
89 | ||
90 | AC_MSG_CHECKING([whether to build with code coverage support]) | |
91 | AC_ARG_ENABLE([code-coverage], | |
92 | AS_HELP_STRING([--enable-code-coverage], | |
93 | [Whether to enable code coverage support]),, | |
94 | enable_code_coverage=no) | |
95 | ||
96 | AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) | |
97 | AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) | |
98 | AC_MSG_RESULT($enable_code_coverage) | |
99 | ||
100 | AS_IF([ test "$enable_code_coverage" = "yes" ], [ | |
101 | # check for gcov | |
102 | AC_CHECK_TOOL([GCOV], | |
103 | [$_AX_CODE_COVERAGE_GCOV_PROG_WITH], | |
104 | [:]) | |
105 | AS_IF([test "X$GCOV" = "X:"], | |
106 | [AC_MSG_ERROR([gcov is needed to do coverage])]) | |
107 | AC_SUBST([GCOV]) | |
108 | ||
109 | dnl Check if gcc is being used | |
110 | AS_IF([ test "$GCC" = "no" ], [ | |
111 | AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) | |
112 | ]) | |
113 | ||
114 | AC_CHECK_PROG([LCOV], [lcov], [lcov]) | |
115 | AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) | |
116 | ||
117 | AS_IF([ test -z "$LCOV" ], [ | |
118 | AC_MSG_ERROR([To enable code coverage reporting you must have lcov installed]) | |
119 | ]) | |
120 | ||
121 | AS_IF([ test -z "$GENHTML" ], [ | |
122 | AC_MSG_ERROR([Could not find genhtml from the lcov package]) | |
123 | ]) | |
124 | ||
125 | dnl Build the code coverage flags | |
126 | dnl Define CODE_COVERAGE_LDFLAGS for backwards compatibility | |
127 | CODE_COVERAGE_CPPFLAGS="" | |
128 | CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" | |
129 | CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" | |
130 | CODE_COVERAGE_LIBS="-lgcov" | |
131 | CODE_COVERAGE_LDFLAGS="$CODE_COVERAGE_LIBS" | |
132 | ||
133 | AC_SUBST([CODE_COVERAGE_CPPFLAGS]) | |
134 | AC_SUBST([CODE_COVERAGE_CFLAGS]) | |
135 | AC_SUBST([CODE_COVERAGE_CXXFLAGS]) | |
136 | AC_SUBST([CODE_COVERAGE_LIBS]) | |
137 | AC_SUBST([CODE_COVERAGE_LDFLAGS]) | |
138 | ||
139 | [CODE_COVERAGE_RULES_CHECK=' | |
140 | -$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check | |
141 | $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture | |
142 | '] | |
143 | [CODE_COVERAGE_RULES_CAPTURE=' | |
144 | $(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS) | |
145 | $(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS) | |
146 | -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp | |
147 | $(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --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) | |
148 | @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" | |
149 | '] | |
150 | [CODE_COVERAGE_RULES_CLEAN=' | |
151 | clean: code-coverage-clean | |
152 | distclean: code-coverage-clean | |
153 | code-coverage-clean: | |
154 | -$(LCOV) --directory $(top_builddir) -z | |
155 | -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) | |
156 | -find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete | |
157 | '] | |
158 | ], [ | |
159 | [CODE_COVERAGE_RULES_CHECK=' | |
160 | @echo "Need to reconfigure with --enable-code-coverage" | |
161 | '] | |
162 | CODE_COVERAGE_RULES_CAPTURE="$CODE_COVERAGE_RULES_CHECK" | |
163 | CODE_COVERAGE_RULES_CLEAN='' | |
164 | ]) | |
165 | ||
166 | [CODE_COVERAGE_RULES=' | |
167 | # Code coverage | |
168 | # | |
169 | # Optional: | |
170 | # - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. | |
171 | # Multiple directories may be specified, separated by whitespace. | |
172 | # (Default: $(top_builddir)) | |
173 | # - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated | |
174 | # by lcov for code coverage. (Default: | |
175 | # $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) | |
176 | # - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage | |
177 | # reports to be created. (Default: | |
178 | # $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) | |
179 | # - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage, | |
180 | # set to 0 to disable it and leave empty to stay with the default. | |
181 | # (Default: empty) | |
182 | # - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov | |
183 | # instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) | |
184 | # - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov | |
185 | # instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) | |
186 | # - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov | |
187 | # - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the | |
188 | # collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) | |
189 | # - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov | |
190 | # instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) | |
191 | # - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering | |
192 | # lcov instance. (Default: empty) | |
193 | # - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov | |
194 | # instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) | |
195 | # - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the | |
196 | # genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE) | |
197 | # - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml | |
198 | # instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) | |
199 | # - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore | |
200 | # | |
201 | # The generated report will be titled using the $(PACKAGE_NAME) and | |
202 | # $(PACKAGE_VERSION). In order to add the current git hash to the title, | |
203 | # use the git-version-gen script, available online. | |
204 | ||
205 | # Optional variables | |
206 | CODE_COVERAGE_DIRECTORY ?= $(top_builddir) | |
207 | CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info | |
208 | CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage | |
209 | CODE_COVERAGE_BRANCH_COVERAGE ?= | |
210 | CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ | |
211 | --rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) | |
212 | CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT) | |
213 | CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)" | |
214 | CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH) | |
215 | CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT) | |
216 | CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?= | |
217 | CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT) | |
218 | CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\ | |
219 | $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\ | |
220 | --rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE)) | |
221 | CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT) | |
222 | CODE_COVERAGE_IGNORE_PATTERN ?= | |
223 | ||
224 | GITIGNOREFILES ?= | |
225 | GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) | |
226 | ||
227 | code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V)) | |
228 | code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY)) | |
229 | code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\ | |
230 | $(CODE_COVERAGE_OUTPUT_FILE); | |
231 | code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V)) | |
232 | code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY)) | |
233 | code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\ | |
234 | $(CODE_COVERAGE_IGNORE_PATTERN); | |
235 | code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V)) | |
236 | code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY)) | |
237 | code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY); | |
238 | code_coverage_quiet = $(code_coverage_quiet_$(V)) | |
239 | code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) | |
240 | code_coverage_quiet_0 = --quiet | |
241 | ||
242 | # sanitizes the test-name: replaces with underscores: dashes and dots | |
243 | code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1))) | |
244 | ||
245 | # Use recursive makes in order to ignore errors during check | |
246 | check-code-coverage:'"$CODE_COVERAGE_RULES_CHECK"' | |
247 | ||
248 | # Capture code coverage data | |
249 | code-coverage-capture: code-coverage-capture-hook'"$CODE_COVERAGE_RULES_CAPTURE"' | |
250 | ||
251 | # Hook rule executed before code-coverage-capture, overridable by the user | |
252 | code-coverage-capture-hook: | |
253 | ||
254 | '"$CODE_COVERAGE_RULES_CLEAN"' | |
255 | ||
256 | A''M_DISTCHECK_CONFIGURE_FLAGS ?= | |
257 | A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage | |
258 | ||
259 | .PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean | |
260 | '] | |
261 | ||
262 | AC_SUBST([CODE_COVERAGE_RULES]) | |
263 | m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])]) | |
264 | ]) |