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

EXCLUDEs additional directories which starts with the same name #68

Open
sakthi-vivek opened this issue Mar 7, 2022 · 4 comments
Open

Comments

@sakthi-vivek
Copy link

sakthi-vivek commented Mar 7, 2022

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.

@qgymib
Copy link
Contributor

qgymib commented Mar 11, 2022

Checkout append_coverage_compiler_flags_to_target(). If your cmake rule was target-based, you can generate report for specific target.

@sakthi-vivek
Copy link
Author

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.

@qgymib
Copy link
Contributor

qgymib commented Mar 22, 2022

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

@sakthi-vivek
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants