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

Fix --exclude-directories option #266

Merged
merged 5 commits into from Jul 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
@@ -1,6 +1,7 @@
*.py[cod]

# C extensions
*.o
*.so

# Packages
Expand All @@ -22,9 +23,13 @@ lib64
pip-log.txt

# Unit test / coverage reports
.pytest_cache/
.coverage
*.gcda
*.gcno
.tox
nosetests.xml
testcase

# Translations
*.mo
Expand Down
1 change: 1 addition & 0 deletions AUTHORS.txt
Expand Up @@ -26,6 +26,7 @@ The following developers contributed to gcovr (ordered alphabetically):
libPhipp,
Lukas Atkinson,
Luke Woydziak,
Marek Kurdej,
Martin Mraz,
Matsumoto Taichi,
Matthew Stadelman,
Expand Down
41 changes: 41 additions & 0 deletions doc/source/guide.rst
Expand Up @@ -288,6 +288,47 @@ This is useful mostly when running gcov yourself,
and then invoking gcovr with :option:`-g`/:option:`--use-gcov-files`.
But these filters also apply when gcov is launched by gcovr.

Speeding up coverage data search
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The :option:`--exclude-directories` filter is used
while searching for raw coverage data
(or for existing ``.gcov`` files when :option:`--use-gcov-files` is active).
This filter is matched against directory paths, not file paths.
If a directory matches,
all its contents (files and subdirectories) will be excluded from the search.
For example, consider this build directory::

build/
├─ main.o
├─ main.gcda
├─ main.gcno
├─ a/
│ ├─ awesome_code.o
│ ├─ awesome_code.gcda
│ └─ awesome_code.gcno
└─ b/
├─ better_code.o
├─ better_code.gcda
└─ better_code.gcno

If we run ``gcovr --exclude-directories 'build/a$'``,
this will exclude anything in the ``build/a`` directory
but will use the coverage data for ``better_code.o`` and ``main.o``.

This can speed up gcovr when you have a complicated build directory structure.
Consider also using the :option:`search_paths`
or :option:`--object-directory` arguments
to specify where gcovr starts searching.
If you are unsure which directories are being searched,
run gcovr in :option:`--verbose` mode.

For each found coverage data file gcovr will invoke the ``gcov`` tool.
This is typically the slowest part,
and other filters can only be applied *after* this step.
In some cases, parallel execution with the :option:`-j` option
might be helpful to speed up processing.

Filters for symlinks
~~~~~~~~~~~~~~~~~~~~

Expand Down
28 changes: 28 additions & 0 deletions gcovr/tests/exclude-directories-relative/Makefile
@@ -0,0 +1,28 @@
CFLAGS= -fprofile-arcs -ftest-coverage -fPIC

all:
mkdir -p build/a build/b
$(CXX) $(CFLAGS) -c a/file1.cpp -o build/a/file1.o
$(CXX) $(CFLAGS) -c b/main.cpp -o build/b/main.o
$(CXX) $(CFLAGS) build/b/main.o build/a/file1.o -o testcase

run: txt xml html

GCOVR_TEST_OPTIONS = --exclude-directories 'build/a'

txt:
./testcase
$(GCOVR) $(GCOVR_TEST_OPTIONS) -d -o coverage.txt

xml:
./testcase
$(GCOVR) $(GCOVR_TEST_OPTIONS) -d -x -o coverage.xml

html:
./testcase
$(GCOVR) $(GCOVR_TEST_OPTIONS) -d --html-details -o coverage.html

clean:
rm -f testcase
rm -f *.gc* *.o
rm -f coverage.txt coverage.xml coverage*.html
4 changes: 4 additions & 0 deletions gcovr/tests/exclude-directories-relative/README
@@ -0,0 +1,4 @@
This test case was inspired by ticket #3884:

https://software.sandia.gov/trac/fast/ticket/3884

5 changes: 5 additions & 0 deletions gcovr/tests/exclude-directories-relative/a/file1.cpp
@@ -0,0 +1,5 @@

int bar()
{
return 0;
}
18 changes: 18 additions & 0 deletions gcovr/tests/exclude-directories-relative/b/main.cpp
@@ -0,0 +1,18 @@
#include <iostream>

int bar();

int foo(int param) {
if (param) {
return 1; //std::cout << "param not null." << std::endl;
} else {
return 0; //std::cout << "param is null." << std::endl;
}
}


int main(int argc, char* argv[]) {
foo(bar());

return 0;
}