I have successfully set up gcov in my project to generate HTML files with code coverage data using lcov. However, as I often work via SSH with a text console only, I'm looking for a way to generate annotated source files like git-blame does with the history:
covered source_line();
not covered other_source_line();
Is it possible somehow?
I'm going to assume you are referring to gcovr when you say gcov, since gcov does not output to HTML format. gcovr does output to HTML though. gcovr is basically just a wrapper for gcov.
In order to get the annotated source files, you need to simply use gcov.
gcov, by default, annotates source files.
To run with gcov, you just need to compile with -fprofile-arcs -ftest-coverage -fPIC -O0, and link in the gcov library(-lgcov).
Then run your program.
Then issue the following command:
gcov main.c
Where main.c is whatever file you want your annotated analysis on.
After that, you will notice a new file created(main.c.gcov). This is the file you are looking for.
Here's a link on gcov usage
Related
The program I want to profile with gcovr (or gcov/lcov) is located on a shared filesystem, along with the build directory from compiling the program, and I have multiple workers with which I intend to test my program, in parallel. To solve the race condition problem (the workers will all run my program, therefore all generating gcda files, named the same, in the same location on the shared filesystem), I redirect the gcda files to a separate target directory on each worker (as described here), and I have been running the following command:
gcovr -v -r /absolute/path/to/root --html --html-details -o test-details.html --object-directory=/absolute/path/to/object/dir /absolute/path/to/gcda/dir
where the last path is the search_paths, described here. I expected this to look in /absolute/path/to/root for the program source, /absolute/path/to/object/dir for the .o files, and /absolute/path/to/gcda/dir for the gcda files. However, I ran it with -v and I'm seeing that gcovr is running gcov commands in the form of this, from the root dir:
gcov /absolute/path/to/gcda/dir/file.gcda --branch-counts --branch-probabilities --preserve-paths --object-directory /absolute/path/to/gcda/dir
Again, I expected it to run in the form of this (look at the --object-directory path):
gcov /absolute/path/to/gcda/dir/file.gcda --branch-counts --branch-probabilities --preserve-paths --object-directory /absolute/path/to/object/dir
It behaves properly when run like the latter command, but gcovr is running the former. I'm only using gcovr instead of gcov because I have a large project (I know gcovr is built off of lcov). Does anyone know why it is behaving like this? (Is this the way it is supposed to run?) How can I make it so it behaves the way I want? Thanks in advance!
This was cross-posted to the gcovr issue tracker on GitHub, here's the summary:
Gcovr currently expects that the .gcda and .gcno files are right next to each other (which is usually the case). The search paths affect where gcovr searches for these files. The --object-directory only provides a default value for the search paths, but here you have overridden that with an explicit search path. The gcovr --object-directory option is not passed through to the gcov --object-directory option.
As of gcovr 4.1 there is no option to solve this. You will have to copy the .gcno files from the build directory into each directory with coverage data. Alternatively you can run gcov manually and then aggregate the .gcov files with gcovr -g ....
Additional notes:
gcov is not interested in the .o object files, only the .gcda files (written during test execution) and the .gcno files (written during compilation).
gcovr and lcov are not directly related
I have an entire library made in C. It has almost 10 folders with a lot of files.
I have created a filename.c file in root folder and trying to compile it in mac using gcc test.c -o test however its not including header files. Generally I have to add all the header files gcc test.c libaudio.c -o test
How can I compile entire project instead of just one file.
Makefiles will solve your problem. You can create your own rules to clear the project (remove the generated files), build the project indicating where is your compiler (compile the source files located in some specific path, extension, etc), set the output path and so on, without typing a large compilation order.
https://www.gnu.org/software/make/manual/make.html
Edit: There you will be able to find how to add shared, static or raw libraries to your proyect through makefiles.
Use a Makefile. make the utility the reads the configuration within the Makefile will automate the running of the individual commands, such that you only need to name the item you wish to be rebuilt.
make myprogram
And make will use the dependency information stored in the Makefile's rules to determine what other elements are "out of date", rebuilding those and assembling them into myprogram.
This is a decent "first time" tutorial for "make".
Here is the full blown documentation for "make"
Once you master the concepts within make, you can then use other tools that make maintaining Makefiles either easier, more portable, or both.
Some tools that improve upon "make" include "cmake", "automake", "the autotools collection", "scons", "waf", "rake", "doit", "ninja", "tup", "redo", and "sake". There are more, and some are programming language specific, or limited to a particular enviornment.
The reason I recommend "make" over the others is because "make" is a baseline that will always be present, and the features in the other tools are often not understood or recognized to be needed until you get enough experience with "make".
In C, the concept of project is not part of the language, it depends generally of the tools / platform / library you have to build.
On Linux based platforms, you may have a makefile describing the project, or the library may have a cmake script.
You should be able to find the build instructions in you library documentation.
I definitely recommend the make approach as it is scalable.
If you really only have a couple of files, gcc will accept multiple .c files on the command line and link them all to generate one executable.
I compile my code using gcc and gfortran. To generate coverage information, I used to add --coverage to both compiler flags (FFLAGS and CFLAGS), the compiler would generate .gcno files and upon running the program I would get .gcda files containing the coverage information.
After separating source and object directory (src/*.c and out/obj/*.o) the gcda files are not generated any more. At least I suppose it is due to that separation.
Is this fixable?
I'm trying to collect code coverage for the project that has c++ and c code both on Ubuntu.
I use '-fprofile-arcs' and '-ftest-coverage' values as CXXFLAGS and CFLAGS; '-lgcov' as LINKFLAGS.
Common C project structure is:
c_code\
src
unit_tests
src contains sources of static library.
unit_tests dir contain tests written with googletest framework e. g. tests of kind
TEST_F(test_case_name, test_name) {
some_gtest_assertions;
}
After the build googletest binary that should contain static library to test inside of it is launched.
Building and running of the project binaries results in generating of *.gcno and *.gcda files. However my C coverage results are empty (C++ is generated well).
lcov command has the folloiwng format:
lcov --capture --directory my_c_gcda_location --output-file c_coverage.info
Logs of lcov show the following for C-related gcda files:
gcov did not create any files for "my_c_gcda_location/*.gcda"`
There are also errors of kind:
*.gcda:stamp mismatch with notes file
Should I specify some additional parameters or perform some additional actions to get coverage results for C? Or what can be the reason of these issues?
You may get "stamp mismatch" when the .gcda files are newer than the .gcno files.
It can happen mostly for 2 reasons:
1. You might have re-build the code after running the test and before trace file generation.
2. The binary might be built in one machine and test was ran in other machine, whose time is ahead of the build machine.
For these two cases you have to just make sure the file creation time of .gcda is greater than .gcno and .c* files.
You can do that by just doing "touch *.gcda" and then run the lcov command.
I am generating code coverage data files (.gdca and .gcno) on an iOS project running on Xcode 4.5 using Apple LLVM Compiler 4.1.
Files are being generated under Library/Developer/Xcode/DerivedData/viewer-evgaabclrjcouydwveuptwroeofm/Build/Intermediates/viewer.build/Coverage-iphonesimulator/viewer_generic/viewer_generic.build/Objects-normal/i386.
All the (.o, .d, .dia, .gcda, .gdno) files are under this directory. There are no sub folders.
I am able to open individual .gcda files using Cover Story. Now I want to generate a report which can be viewed using cobertura.
I am trying to use gcovr for this. On terminal I got to the above folder
Command: gcovr -r `pwd` -x -v
Output:
(Several lines of similar output as below)
Running gcov: 'gcov /Users/abc/Library/Developer/Xcode/DerivedData/viewer-evgaabclrjcouydwveuptwroeofm/Build/Intermediates/viewer.build/Coverage-iphonesimulator/viewer_generic/viewer_generic.build/Objects-normal/i386/FILE_NAME.gcda --branch-counts --branch-probabilities --preserve-paths --object-directory /Users/abc/Library/Developer/Xcode/DerivedData/viewer-evgaabclrjcouydwveuptwroeofm/Build/Intermediates/viewer.build/Coverage-iphonesimulator/viewer_generic/viewer_generic.build/Objects-normal/i386' in '/Users/abc/Library/Developer/Xcode/DerivedData/viewer-evgaabclrjcouydwveuptwroeofm/Build/Intermediates/viewer.build/Coverage-iphonesimulator/viewer_generic/viewer_generic.build/Objects-normal/i386'
Parsing coverage data for file /Users/abc/Documents/Perforce/DPS-MacBookPro/depot/sandbox/Viewer-Labatt/Blue/viewers/ipadviewer/iphone/apps/viewer/Classes/view/zooming/FILE_NAME.mm
Filtering coverage data for file /Users/abc/Documents/Perforce/DPS-MacBookPro/depot/sandbox/Viewer-Labatt/Blue/viewers/ipadviewer/iphone/apps/viewer/Classes/view/zooming/FILE_NAME.mm
Gathered coveraged data for 0 files
<?xml version="1.0" ?>
<!DOCTYPE coverage
SYSTEM 'http://cobertura.sourceforge.net/xml/coverage-03.dtd'>
<coverage branch-rate="0.0" line-rate="0.0" timestamp="1354144430" version="gcovr 2.4 (r2774)">
<sources>
<source>
/Users/abc/Library/Developer/Xcode/DerivedData/viewer-evgaabclrjcouydwveuptwroeofm/Build/Intermediates/viewer.build/Coverage-iphonesimulator/viewer_generic/viewer_generic.build/Objects-normal/i386
</source>
</sources>
<packages/>
</coverage>
I am seeing a warning: gcno:version '404', prefer '402'
Please help me figure out why gcovr is unable to produce the report.
Tl;dr: The code coverage files that LLVM outputs are newer than the ones expected by gcovr. If you replace your version of gcovr with the linked version (version 2.4), then it should work. Maybe.
Back before LLVM, Xcode used GCC as its compiler. GCC included a tool called 'gcov', which generated all those files, .gcno, .gcda and their ilk.
Back then, Macs came preinstalled (and still do) with GCC version 4.2. So Xcode would compile your project with gcc 4.2, and then run gcov version 4.2, which would generate 4.2-versioned test coverage files. This worked fine for gcovr, because the pre-2.0 alpha version seems to have been written with gcov 4.2 in mind.
But when Apple switched to LLVM, things went squirrely. LLVM also outputs gcov-style test coverage files, if you set the 'Generate Test Coverage Files' flag in your target settings. BUT, LLVM defaults to outputting gcov 4.4 files, NOT 4.2.
This person had the idea that if we could tell LLVM to output the 4.2 version of the files (I think it may technically be able to), then it would solve the problem. That's probably true, but I don't know how to do that.
I did however, find a solution for myself. I opened up terminal, and checked my version of gcovr:
gcovr --version
It told me that my version of gcovr was actually gcovr 2.0-prerelease. This version doesn't support the gcov 4.4 versions of the test coverage files.
So I found a version that does.
Here's the page where it is hosted: https://software.sandia.gov/trac/fast/wiki/gcovr
And here is the link to the script itself: https://software.sandia.gov/trac/fast/export/2800/gcovr/trunk/scripts/gcovr
This script is gcovr 2.4, which supports up to gcc 4.8. Theoretically, it should be quite happy with the 4.4 versions of the test coverage files that LLVM outputs. That warning is now completely gone for me. Give it a shot, let me know how it goes!
Are you properly specifying the your object directory path? According to the gcovr documentation
--object-directory=OBJDIR: Specify the directory that contains the gcov data files. gcovr must be able to identify the path between the *.gcda files and the directory where gcc was originally run. Normally, gcovr can guess correctly. This option overrides gcovr's normal path detection and can specify either the path from gcc to the gcda file (i.e. what was passed to gcc's '-o' option), or the path from the gcda file to gcc's original working directory.
The following command works for me when run under the root directory of your project.
gcovr -r . --object-directory path_to_coverage_files -x > coverage.xml
Where the path_to_coverage_files is the directory where all your (.o, .d, .dia, .gcda, .gdno) files are.