cmake-modules
cmake-modules copied to clipboard
EXCLUDEs additional directories which starts with the same name
Hello,
# Folder structure
.
|-- src/
|-- test/
|-- testmodules/
|-- CMakeLists.txt
setup_target_for_coverage_gcovr_html(
NAME ${PROJECT_NAME}_coverage_html
EXECUTABLE ${PROJECT_NAME} --gtest_output=xml:report.xml
BASE_DIRECTORY ${CMAKE_SOURCE_DIR}
EXCLUDE "test/*")
In the above example, the testmodules
also get excluded even if it was just the test
folder that I wanted to exclude.
Any help is appreciated. Thank you.
Checkout append_coverage_compiler_flags_to_target()
. If your cmake rule was target-based, you can generate report for specific target.
Thank you for your input. But could you expand on how this would help in the above context? I was having the trouble of excluding a directory (test
) whose name was the initial part of another directory (testmodules
) that I wanted to be included as part of the report.
A minimal example:
CMakeLists.txt
for src:
add_library(foo
"src/foo1.c"
"src/foo2.c")
# Only setup coverage for your target `foo`
include(CodeCoverage)
append_coverage_compiler_flags_to_target(foo)
CMakeLists.txt
for test:
# This is your test code
add_executable(bar
"test/test1.c"
"test/test2.c")
target_link_libraries(bar PRIVATE foo)
add_test(bar bar)
# Here we generate coverage report
setup_target_for_coverage_lcov(
NAME coverage
EXECUTABLE $<TARGET_FILE:bar>
)
In the above example, the following files will have report:
- src/foo1.c
- src/foo2.c
And following files does not generate report:
- test/test1.c
- test/test2.c
The issue is actually with the keyword EXCLUDE
. The example I provided above was just to provide some context to the issue. I shall try to explain better with a bit more elaborately another example.
# Folder structure
.
|-- CMakeLists.txt
|-- CodeCoverage.cmake
|-- src/
|-- cpp/
|-- core.hpp
|-- cppmodules/
|-- module_a/
|-- module_a.hpp
|-- module_a.cpp
|-- module_b/
|-- test/
|-- src/
|-- cppmodules/
|-- module_a/
|-- module_a_test.cpp
So under the src
folder I have placed a cpp
folder which can contains core header files included by classes in cppmodules/module_*
. The test
folder contains *_test.cpp
files for testing the corresponding module.
Now, when I perform a coverage test for every module I do not want to include the files under src/cpp/*
. However, they naturally are included when building the test executable. So as seen in the CMakeLists.txt
file I need to EXCLUDE
the src/cpp/*
.
This is where I face the issue where EXCLUDE
also removes the needed src/cppmodules/module_a/module_a.cpp
from the report. As of now, I have to perform a hack like excluding src/cpp/c*
or renaming the cpp
folder, in-order to get the coverage report of the module source file.
I have pasted below the code that was used to recreate the issue.
# CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(module_a_test LANGUAGES CXX)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS_DEBUG "-Og -g3")
set(CMAKE_MODULE_PATH ${module_a_test_SOURCE_DIR})
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip
)
set(BUILD_GMOCK OFF CACHE BOOL "" FORCE)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
include(CodeCoverage)
add_definitions("-DPFTP_TRACE_OUTPUT")
set(GCOVR_ADDITIONAL_ARGS -s --xml coverage.xml --exclude-throw-branches ${PROJECT_BINARY_DIR})
setup_target_for_coverage_gcovr_html(
NAME ${PROJECT_NAME}_coverage_html
EXECUTABLE ${PROJECT_NAME} --gtest_output=xml:report.xml
BASE_DIRECTORY ${module_a_test_SOURCE_DIR}
EXCLUDE "build/*" "Debug/*" "src/cpp/*") # !!! This exlcudes src/cppmodules/* aswell. I lose the coverage report of module_a.cpp
append_coverage_compiler_flags()
endif()
include_directories(
test/src/cppmodules/module_a
src/cppmodules/module_a
src/cpp
)
add_executable( ${PROJECT_NAME}
src/cppmodules/module_a/module_a.cpp
test/src/cppmodules/module_a/module_a_test.cpp
)
target_link_libraries(${PROJECT_NAME} gtest_main)
// module_a_test.cpp
#include <gtest/gtest.h>
#include "module_a.hpp"
TEST(ModuleA, IsCorrectModuleType)
{
ModuleA a;
EXPECT_TRUE(a.type == ModuleType::A);
}
// module_a.hpp
#ifndef MODULE_A_HPP_
#define MODULE_A_HPP_
#include "core.hpp"
class ModuleA {
public:
ModuleA();
~ModuleA() = default;
ModuleType type = ModuleType::A;
};
#endif
// module_a.cpp
#include "module_a.hpp"
ModuleA::ModuleA()
{
}
// core.hpp
#ifndef CORE_HPP_
#define CORE_HPP_
enum class ModuleType {
NONE = -1,
A = 0,
B = 1
};
#endif
Run the following after recreating the above setup to generate the coverage report,
# Install cmake >=3.16 and gcovr.
cmake -DCMAKE_BUILD_TYPE=Debug -B Debug
make -C Debug/ module_a_test_coverage_html
# See ./Debug/module_a_test_coverage_html