5

I am running gcovr (3.3) on an out of source build like:

gcovr --root=/path/to/source --object-directory=/path/to/build

Now I want to exclude two different things from the report:

1) Any .cpp files that have "Test" in their name

--exclude='.*Test.*' does not seem to work

2) All source files in a directory (say /path/to/source/MyModule/)

--exclude='/path/to/source/MyModule/.*' does not seem to work.

--exclude-directories='/path/to/source/MyModule' also does not seem to work.

My questions

a) what is --exclude-directories for since it seems like you (should) be able to exclude a directory with the right regex passed to --exclude?

b) Any suggestions about why the --excludes do not work as expected? Perhaps these are not the right kind/style of regular expressions?

David Doria
  • 9,873
  • 17
  • 85
  • 147

1 Answers1

8

Both of these options are not well documented, so the main source of knowledge is source code.

a) what is --exclude-directories for since it seems like you (should) be able to exclude a directory with the right regex passed to --exclude?

--exclude-directories option used by gcovr to skip directories by it's name, not fullpath. It can be verified if you check the gcovr's source code. Magic is done in def link_walker(path) function:

    for root, dirs, files in os.walk(
        os.path.abspath(path), followlinks=True
    ):
        for exc in options.exclude_dirs:
            for d in dirs:
                m = exc.search(d)

According to the os.walk documentation, dirs is a list of the names of the subdirectories. E.g. to skip all directories starts with MyMod use --exclude-directories='MyMod.*'.

b) Any suggestions about why the --excludes do not work as expected? Perhaps these are not the right kind/style of regular expressions?

Your regular expression is correct. It's typical Python's regex.

To understand what is going on at --exclude option it's useful to enable -v output. With this option enabled, output should have lots of lines:

currdir      /cygdrive/f/test/path/to/source
gcov_fname   myfile.cpp.gcov
           ['        -', '    0', 'Source', 'myfile.cpp\n']
source_fname /cygdrive/f/test/path/to/source/myfile.gcda
root         /cygdrive/f/test/path/to/source
fname        /cygdrive/f/test/path/to/source/myfile.cpp
Parsing coverage data for file /cygdrive/f/test/path/to/source/myfile.cpp

This output produced by def process_gcov_data(data_fname, covdata, source_fname, options) function. If you check the source code you will see the following:

for exc in options.exclude:
    if (filtered_fname is not None and exc.match(filtered_fname)) or \
            exc.match(fname) or \
            exc.match(os.path.abspath(fname))

Exclude filter applies to fname printed above. It's the absolute filepath. Also it applies to all files which have coverage data. If file was excluded the following line should be in output (-v option required):

Excluding coverage data for file /cygdrive/f/test/path/to/source/myfile.cpp
Nikita
  • 6,270
  • 2
  • 24
  • 37
  • 1
    Thanks for the explanations. Two small follow ups: 1) I still don't understand the difference between `--exclude='.*/MyMod.*'` and `--exclude-directories='MyMod.*'`? 2) Can you explain the difference between `--exclude` and `--gcov-exclude=`? – David Doria Sep 28 '16 at 15:32
  • 2) `--gcov-exclude` excludes gcov data files. It applied against `myfile.cpp.gcov` files. `--exclude` excludes `cpp` files. – Nikita Sep 28 '16 at 15:43
  • but isn't there exactly one `.gcov` file per `.cpp` file? – David Doria Sep 28 '16 at 15:44
  • Right, but some times you need to process existent gcov data with `--use-gcov-files` option. In this case `--gcov-exclude` is the only option to exclude data files. – Nikita Sep 28 '16 at 15:46
  • What would be the use case for specifying `--use-gcov-files`? Why would you not just use `--root` and `--object-directory` like I'm doing? – David Doria Sep 28 '16 at 15:48
  • It's used in case you don't have `cpp` files and only gcov data files available. – Nikita Sep 28 '16 at 15:53
  • 1) `--exclude-directories='MyMod.*'` excludes all directories starts with `MyMod`. `--exclude='.*/MyMod.*'` excludes all the `.cpp` files which absolute path matches this regex. If you use the second one instead of the first it can skip `path/file/MyModule.cpp` instead of the folder `MyModule`. – Nikita Sep 28 '16 at 16:05
  • 1
    Sure, but you could just craft the regex to match a folder (something like `--exclude='.*/MyModule/.*'`), right? So I guess this is just really a helper then? I just I'm just trying to make sure I'm correctly that everything you can do with `--exclude-directory` you can also do with `--exclude` and the appropriate regex. – David Doria Sep 28 '16 at 16:21
  • Right, it's like a helper function – Nikita Sep 28 '16 at 16:27
  • how to mention multiple directories under --exlude-directories option? seems this is not working for me --exclude-directories=test,thrift.* , here I am trying to exclude test and thrift directory. – Ramkumar D Jul 03 '17 at 11:55
  • 1
    @RamkumarD the `--exclude` flag can be used multiple times: https://github.com/gcovr/gcovr/issues/151#issuecomment-370941127 – Jonathan E. Landrum Jun 01 '18 at 19:21