@@ -107,24 +107,44 @@ int main(void) {
107107EOF 
108108
109109  generate_and_execute_instrumented_binary coverage_srcs/test \
110-       " $COVERAGE_DIR_VAR /coverage_srcs" 
111110      coverage_srcs/a.h coverage_srcs/a.cc \
112111      coverage_srcs/b.h \
113112      coverage_srcs/t.cc
114113
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 " 
123143
124144  #  All generated .gcno files need to be in the manifest otherwise
125145  #  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 " 
128148}
129149
130150#  Generates and executes an instrumented binary:
138158#  - path_to_binary destination of the binary produced by g++
139159function  generate_and_execute_instrumented_binary()  {
140160  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 \
152162      " $@ " " $path_to_binary " 
153163       ||  fail " Couldn't produce the instrumented binary for $@  \ 
154164            with path_to_binary $path_to_binary "  
274284
275285
276286function  test_cc_test_coverage_gcov()  {
287+     local  -r gcov_location=$( which gcov) 
277288    " $gcov_location " |  grep " LLVM" &&  \
278289      echo  " gcov LLVM version not supported. Skipping test." &&  return 
279290    #  gcov -v | grep "gcov" outputs a line that looks like this:
@@ -316,8 +327,16 @@ function test_cc_test_coverage_gcov() {
316327        fail " Number of lines in C++ gcov coverage output file is " 
317328        " $nr_lines  and different than 17" 
318329    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 
321340      output_file_json=" output_file.json" 
322341      zcat $agcda  $tgcda  >  $output_file_json 
323342
@@ -332,4 +351,4 @@ function test_cc_test_coverage_gcov() {
332351    fi 
333352}
334353
335- run_suite " Testing tools/test/collect_cc_coverage.sh" 
354+ run_suite " Testing tools/test/collect_cc_coverage.sh" 
0 commit comments