gcov generation fails with Ninja generator
gsauthof opened this issue · 7 comments
Steps to reproduce:
CMakeLists.txt:
cmake_minimum_required(VERSION 3.4)
project(test CXX)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/codecov/cmake" ${CMAKE_MODULE_PATH})
find_package(codecov)
add_executable(foo test.cc)
add_coverage(foo)
test.cc:
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
cout << "Hello World!\n";
return 0;
}
Setup:
$ git submodule add https://github.com/RWTH-ELP/CMake-codecov.git cmake/codecov
$ mkdir build
$ cd build
$ CXX=clang++ CC=clang cmake -G Ninja .. -DENABLE_COVERAGE=On
$ ninja-build -v foo
$ ./foo
$ ninja-build -v foo-gcov
Actual result:
$ ninja-build -v foo-gcov
[1/1] cd /home/juser/cmake-codecov-test/build/CMakeFiles/foo.dir && LLVM_COV_BIN=/usr/bin/llvm-cov /home/juser/cmake-codecov-test/cmake/codecov/cmake/llvm-cov-wrapper /home/juser/cmake-codecov-test/build/CMakeFiles/foo.dir/test.cc.gcno > /dev/null
../test.cc: No such file or directory
$ ninja-build -v foo-gcov
ninja: no work to do.
Expected result:
A .gcov
file under in the build directory, i.e. CMakeFiles/foo.dir/test.cc.gcov
.
I tested it on Fedora 23.
When compiling with the CMake makefile generator the gcov report is generated as expected.
I looked into this a bit. The difference is that when using the makefile generator, absolute path is used to pass test.cc
to the compiler, whereas the ninja generator uses paths relative to the build directory. And the exact path is embedded in the .gcno
file.
It turns out that geninfo
has a switch for this:
--base-directory directory
Use directory as base directory for relative paths.
But setting base-directory
to PROJECT_BINARY_DIR
instead of to PROJECT_SOURCE_DIR
has its own consequences, namely it conflicts with --no-external
:
--no-external
Specify whether to capture coverage data for external source files.
External source files are files which are not located in one of the directories specified by --directory or --base-directory.
The --directory
switch looks hopeful, but there is no such thing in geninfo
. It might be possible to use --no-external
in later phase on lcov
, or not use it at all and filter the files via --exclude
switch for lcov
. I'll investigate that later.
So the final solution for me was to replace --base-directory ${PROJECT_SOURCE_DIR}
with --base-directory ${PROJECT_BINARY_DIR}
in FindLcov.cmake
and disable adding the --no-external
flag. The external sources may then be manually filtered by setting LCOV_REMOVE_PATTERNS
.
I still see the problem with Ninja, which is the default generator for Visual Studio Code. With Makefiles all is fine. I'm no expert, but I think the cause is that Make works with absolute paths whereas Ninja works with paths relative to the binary directory.
I've commented on a closed issue, but I may open a new one if you wish.
Ah, wait, I'm talking about lcov. I assumed they would behave the same. Maybe they don't?
They don't. The foo-gcov
target as per the example in the description works. However the lcov-related targets fail. I'll submit another issue.