Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relative path parts are not resolved corrupting the package name #294

stoesselt opened this issue Jan 29, 2019 · 5 comments


Copy link

@stoesselt stoesselt commented Jan 29, 2019

I am using gcovr 3.2 on a Ubuntu 16.04 system and gcovr 4.1 on a Windows 10 machine via Jenkins. My command line paramters are
gcovr -x -r ../../.. -f '.*/pump/source/.*' --object-directory '${WORKSPACE}/tests/build/gcc' --exclude-unreachable-branches -o Coverage.xml

This does its job pretty well on the Ubuntu system. Only files in the folders pump/source/* are considered. Package names and file paths are correct in the output file. On the Windows machine, however, every file path and package is prefixed with tests/build/gcc/../../.. in the XML output. This messes up the Cobertura report.


This comment has been minimized.

Copy link

@latk latk commented Jan 29, 2019

To clarify, is the problem that the filters don't work correctly, or that the file paths in the Cobertura report are confusing?

While looking into this problem I realized that the oos and oos2 tests were exactly the same 🤦‍♂. Changing one to use --root .. or similar starts to introduce problems:

  • --root .. causes the filters to fail because they didn't normalize the file paths properly before matching the filter.
  • --root .. --filter .. does match the filters correctly, but now the output shows an absolute path instead of a path relative to the root.

So that's a real bug, thank you for pointing me towards this!

I have an experimental fix but it causes other tests to fail, so that needs more work first…


This comment has been minimized.

Copy link

@stoesselt stoesselt commented Jan 29, 2019

You are right, actually it is a doubled issue.

Before I used -f I used -e '.*/pump/external/.*' which did not work properly. There were still results from files within pump/external included in the output. Only in the end I came up with a working version (-f) which excluded the files successfully. So the filters don't work correctly.

However, in the version, where only the wanted files are included (-f), the package name and the class filename in the XML file have the prefix tests/build/gcc/../../.. (filename) respectively, see below. I would expect, that these relative path parts are resolved before creating the report (as it worked in version 3.2 (at least on Linux)).

unresolved relative path parts

latk added a commit to latk/gcovr that referenced this issue Jan 29, 2019
In an out of source build, the compiler will usually be called from
within the build directory:

    cd build; gcc ../src/foo.c -o foo.o

This means gcovr should be called in the same way:

    cd build; gcovr --root ../src .

(Note that the root should point to the source code root. In this case
the root and the search paths differ, so an explicit search path "." has
to be provided. The `--object-directory` option can also be used to
provide a search path, but this also changes some heuristics.)

The oos and oos2 tests were previously identical (oops). The oos2 test
was changed to model the above scenario.

This commit makes that work, without breaking tricky tests such as

The `--root` is turned into an `DirectoryPrefixFilter`. This filter will
now use the realpath() of the root, and will normpath() the path to be
matched. This will not break the match if the path below the root
contains symlinks, but does remove any `..` segments from the path that
might have been caused by the `gcc ../` style invocation.

(Possible failure mode if the root path contains symlinks?)

The normpath() version is also used as the file key in the coverage data
structures, thus leading to correct and concise reports that can remove
the root path from the front.

Fixes gcovr#294.
@latk latk closed this in a782972 Jan 29, 2019

This comment has been minimized.

Copy link

@latk latk commented Jan 29, 2019

Ok, this should be fixed in the development version. You can install gcovr directly from GitHub like

python3 -m pip install git+

(or you can download the gcovr source code as a ZIP archive and let pip install that…)

Can you confirm whether the fix works for you?


This comment has been minimized.

Copy link

@stoesselt stoesselt commented Jan 30, 2019

I can confirm that the relative path parts are resolved in the resulting XML file.

However, while gcovr -x -r ../../.. -f '.*/pump/source/.*' --object-directory '${WORKSPACE}/tests/build/gcc' --exclude-unreachable-branches -o Coverage.xml does what I need, executing gcovr -x -r ../../.. -e '.*/pump/build/.*' -e '.*/pump/external/.*' -e 'tests/.*' --object-directory 'C:/Repositories/P2/code_2/tests/build/gcc' --exclude-unreachable-branches -o Coverage.xml still has source files within tests folder in the output file, which should be excluded.


This comment has been minimized.

Copy link

@latk latk commented Jan 30, 2019

Thank you for testing the fix!

Please note that since gcovr 4, the meaning of filters and excludes was clarified: if they look like a relative path, they are matched to file paths that are relative to the current working directory, not relative to the root! So instead of

gcovr -r .. -e tests/

you would likely want something like

gcovr -r .. -e '\.\./tests/'

(and if the leading backslash confuses gcovr on Windows, then maybe use regex charclasses instead of escapes like -e '[.][.]/tests/').

It might be that these filters work slightly differently on gcovr 3 and 4, so I would encourage you to manually install the same gcovr version on all your systems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
2 participants
You can’t perform that action at this time.