@@ -107,24 +107,44 @@ int main(void) {
107
107
EOF
108
108
109
109
generate_and_execute_instrumented_binary coverage_srcs/test \
110
- " $COVERAGE_DIR_VAR /coverage_srcs" \
111
110
coverage_srcs/a.h coverage_srcs/a.cc \
112
111
coverage_srcs/b.h \
113
112
coverage_srcs/t.cc
114
113
115
- # g++ generates the notes files in the current directory. The documentation
116
- # (https://gcc.gnu.org/onlinedocs/gcc/Gcov-Data-Files.html#Gcov-Data-Files)
117
- # says they are placed in the same directory as the object file, but they
118
- # are not. Therefore we move them in the same directory.
119
- agcno=$( ls * a.gcno)
120
- tgcno=$( ls * t.gcno)
121
- mv $agcno coverage_srcs/$agcno
122
- mv $tgcno coverage_srcs/$tgcno
114
+ # Prior to version 11, g++ generates the notes files in the current directory
115
+ # instead of next to the object file despite the documentation indicating otherwise:
116
+ # https://gcc.gnu.org/onlinedocs/gcc/Gcov-Data-Files.html#Gcov-Data-Files
117
+ # This is fixed in g++ 11 so we have to handle both cases.
118
+
119
+ local not_found=0
120
+ ls coverage_srcs/* a.gcno > /dev/null 2>&1 || not_found=$?
121
+ if [[ $not_found -ne 0 ]]; then
122
+ agcno=$( ls * a.gcno)
123
+ tgcno=$( ls * t.gcno)
124
+ agcda=$( ls * a.gcda)
125
+ tgcda=$( ls * t.gcda)
126
+ mv $agcno coverage_srcs/$agcno
127
+ mv $tgcno coverage_srcs/$tgcno
128
+ mv $agcda coverage_srcs/$agcda
129
+ mv $tgcda coverage_srcs/$tgcda
130
+ fi
131
+ agcno=$( ls coverage_srcs/* a.gcno)
132
+ tgcno=$( ls coverage_srcs/* t.gcno)
133
+ agcda=$( ls coverage_srcs/* a.gcda)
134
+ tgcda=$( ls coverage_srcs/* t.gcda)
135
+ # Even though gcov expects the gcda files to be next to the gcno files,
136
+ # during Bazel execution this will not be the case. collect_cc_coverage.sh
137
+ # expects them to be in the COVERAGE_DIR and will move the gcno files itself.
138
+ # We cannot use -fprofile-dir during compilation because this causes the
139
+ # filenames to undergo mangling; see
140
+ # https://github.com/bazelbuild/bazel/issues/16229
141
+ mv $agcda " $COVERAGE_DIR_VAR /$agcda "
142
+ mv $tgcda " $COVERAGE_DIR_VAR /$tgcda "
123
143
124
144
# All generated .gcno files need to be in the manifest otherwise
125
145
# the coverage report will be incomplete.
126
- echo " coverage_srcs/ $tgcno " >> " $COVERAGE_MANIFEST_VAR "
127
- echo " coverage_srcs/ $agcno " >> " $COVERAGE_MANIFEST_VAR "
146
+ echo " $tgcno " >> " $COVERAGE_MANIFEST_VAR "
147
+ echo " $agcno " >> " $COVERAGE_MANIFEST_VAR "
128
148
}
129
149
130
150
# Generates and executes an instrumented binary:
138
158
# - path_to_binary destination of the binary produced by g++
139
159
function generate_and_execute_instrumented_binary() {
140
160
local path_to_binary=" ${1} " ; shift
141
- local gcda_directory=" ${1} " ; shift
142
- # -fprofile-arcs Instruments $path_to_binary. During execution the binary
143
- # records code coverage information.
144
- # -ftest-coverage Produces a notes (.gcno) file that coverage utilities
145
- # (e.g. gcov, lcov) can use to show a coverage report.
146
- # -fprofile-dir Sets the directory where the profile data (gcda) appears.
147
- #
148
- # The profile data files need to be at a specific location where the C++
149
- # coverage scripts expects them to be ($COVERAGE_DIR/path/to/sources/).
150
- g++ -fprofile-arcs -ftest-coverage \
151
- -fprofile-dir=" $gcda_directory " \
161
+ g++ -coverage \
152
162
" $@ " -o " $path_to_binary " \
153
163
|| fail " Couldn't produce the instrumented binary for $@ \
154
164
with path_to_binary $path_to_binary "
274
284
275
285
276
286
function test_cc_test_coverage_gcov() {
287
+ local -r gcov_location=$( which gcov)
277
288
" $gcov_location " -version | grep " LLVM" && \
278
289
echo " gcov LLVM version not supported. Skipping test." && return
279
290
# gcov -v | grep "gcov" outputs a line that looks like this:
@@ -316,8 +327,16 @@ function test_cc_test_coverage_gcov() {
316
327
fail " Number of lines in C++ gcov coverage output file is " \
317
328
" $nr_lines and different than 17"
318
329
else
319
- agcda=$( ls $COVERAGE_DIR_VAR /* a.gcda.gcov.json.gz)
320
- tgcda=$( ls $COVERAGE_DIR_VAR /* t.gcda.gcov.json.gz)
330
+ # There may or may not be "gcda" in the extension.
331
+ local not_found=0
332
+ ls $COVERAGE_DIR_VAR /* .gcda.gcov.json.gz > /dev/null 2>&1 || not_found=$?
333
+ if [[ $not_found -ne 0 ]]; then
334
+ agcda=$( ls $COVERAGE_DIR_VAR /* a.gcov.json.gz)
335
+ tgcda=$( ls $COVERAGE_DIR_VAR /* t.gcov.json.gz)
336
+ else
337
+ agcda=$( ls $COVERAGE_DIR_VAR /* a.gcda.gcov.json.gz)
338
+ tgcda=$( ls $COVERAGE_DIR_VAR /* t.gcda.gcov.json.gz)
339
+ fi
321
340
output_file_json=" output_file.json"
322
341
zcat $agcda $tgcda > $output_file_json
323
342
@@ -332,4 +351,4 @@ function test_cc_test_coverage_gcov() {
332
351
fi
333
352
}
334
353
335
- run_suite " Testing tools/test/collect_cc_coverage.sh"
354
+ run_suite " Testing tools/test/collect_cc_coverage.sh"
0 commit comments