是否有交叉编译器方法使用CMake禁用测试可执行文件的覆盖标志? [英] Is there a cross-compiler method to disable coverage flags for test executables using CMake?
问题描述
我正在创建通用C ++,CMake和计划在其中使用的 Catch 项目模板未来,并希望为其启用代码覆盖率报告.为此,我决定将以下CMake模块添加到模块列表中:
I am creating a generic C++, CMake, and Catch project template that I plan on using in the future, and want to enable code coverage reports for it. To do so, I decided to add the following CMake module into my list of Modules: CodeCoverage.cmake. My usage for this essentially boils down to the following snippet:
if (ENABLE_COVERAGE AND NOT CMAKE_CONFIGURATION_TYPES)
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "Coverage in a non-debug build may lead to misleading results! Setting build type to 'Debug'!")
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "" FORCE)
endif (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
include(CodeCoverage)
APPEND_COVERAGE_COMPILER_FLAGS()
if (NOT BUILD_TESTS)
message(STATUS "Tests must be enabled in a coverage build! Setting BUILD_TESTS to On!")
set(BUILD_TESTS On CACHE STRING "" FORCE)
endif (NOT BUILD_TESTS)
set(COVERAGE_EXCLUDES 'tests/*')
include(CodeCoverage)
APPEND_COVERAGE_COMPILER_FLAGS()
SETUP_TARGET_FOR_COVERAGE(NAME coverage EXECUTABLE tests DEPENDENCIES coverage)
else (ENABLE_COVERAGE AND NOT CMAKE_CONFIGURATION_TYPES)
# ...
endif (ENABLE_COVERAGE AND NOT CMAKE_CONFIGURATION_TYPES)
详细信息.
-
ENABLE_COVERAGE
是用于启用/禁用代码覆盖率的命令行标志,它将使用lcov/gcov生成. -
tests
是运行所有单元测试的可执行文件的名称. 首先,我使用add_subdirectory
添加其文件夹,然后在该文件夹中使用:
ENABLE_COVERAGE
is command line flag which I use to enable/disable code coverage, which will be generated using lcov/gcov.tests
is the name of my executable which runs all of my unit tests. First I useadd_subdirectory
to add its folder, and inside the folder I use:
set(TEST_SOURCES test_hello_world.cpp test_factorial.cpp)
add_executable(tests main.cpp ${TEST_SOURCES})
target_link_libraries(tests Project-Name-lib)
include(ParseAndAddCatchTests)
ParseAndAddCatchTests(tests)
我的问题:
当我通常运行我的make
脚本时,代码会轻松编译,包括测试可执行文件,需要大约10秒钟的时间来构建.但是,当我启用代码覆盖率时,代码将卡在构建main.cpp.o
(内部tests
)上,并且make
永远不会完成.当我运行make VERBOSE=1
时,将得到以下针对该对象运行的命令:
When I usually run my make
script, the code compiles with ease, including the test executable which takes ~10 seconds to build. However, when I enable coverage for my code, the code gets stuck on building main.cpp.o
(Inside tests
), and make
never finishes. When I run make VERBOSE=1
, I get the following command which is being run for said object:
cd project_dir/build/tests && /usr/bin/g++-5
-g -O0 --coverage -fprofile-arcs -ftest-coverage -g -O0
--coverage -fprofile-arcs -ftest-coverage -g
-I/project_dir/include -I/project_dir/build
-std=c++14 -o CMakeFiles/tests.dir/main.cpp.o -c /project_dir/main.cpp
(为了方便阅读,我缩短了一些路径,缩进的行是同一命令的一部分)
(I have shortened some of the paths for readability and indented lines are part of the same command)
显然,即使使用set(COVERAGE_EXCLUDES 'tests/*')
,编译器也会 still 将coverage标志附加到测试可执行文件,我认为这是构建时间较慢的原因.如果我的结论是正确的,那么我如何告诉编译器不将这些标志添加到我的测试可执行文件中?如果我的结论不正确,那么如何减少此可执行文件的构建时间? (我不想直接提及标志名称,因为这可能不适用于所有编译器(我的意思是GCC/Clang))
Apparently, even with set(COVERAGE_EXCLUDES 'tests/*')
, the compiler is still appending the coverage flags to the test executable, which I think is the source of the slow build time. If my conclusion is correct, then how can I tell the compiler to not add these flags to my test executable? If my conclusion is incorrect, then how can I reduce the build time for this executable? (I don't want to directly mention flag names, since that might not work across all compilers(By which I mean GCC/Clang))
在旁注中,我的main.cpp
包含:
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
一个示例测试文件包含:
And a sample test file contains:
#include <project-abbr/factorial.hpp>
#include "catch.hpp"
TEST_CASE("function factorial")
{
SECTION("normal arguments")
{
REQUIRE(factorial(2) == 2);
REQUIRE(factorial(3) == 6);
REQUIRE(factorial(4) == 24);
REQUIRE(factorial(5) == 120);
}
}
推荐答案
更新
以下代码并不是真正的解决方案.它仅对在源文件中仅定义的所有功能起作用.这意味着,如果您有模板库或仅标头库,则此解决方案是完全没用的.真正的解决方案是调用函数append_coverage_compiler_flags
,该函数可以完全覆盖.但是,这可能会导致编译冻结,如OP的帖子中所示...
The following code isn't really a solution. It works only for all functions that are defined only in source files. Meaning if you had a template library or a header only library, then this solution is completely useless. The true solution is to call the function append_coverage_compiler_flags
which allows for complete coverage. However, this may cause a compilation freeze, as shown in the OP's post...
好吧,我做了一些实验,看了看文档,发现了一个并不是真正理想的解决方案,但是仍然可以解决问题.我使用功能 target_compile_options
仅添加覆盖范围标记到我想要的目标,而不是模块中的功能ADD_COVERAGE_COMPILE_FLAGS()
,如下所示:
Ok, I experimented a bit, looked at the documentation, and found a solution which isn't really optimal but works nonetheless. I used the function target_compile_options
to only add the coverage flags to the targets I want instead of the function ADD_COVERAGE_COMPILE_FLAGS()
from the module, as follows:
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "Coverage in a non-debug build may lead to misleading results! Setting build type to 'Debug'!")
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "" FORCE)
endif (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
include(CodeCoverage)
if (NOT BUILD_TESTS)
message(STATUS "Tests must be enabled in a coverage build! Setting BUILD_TESTS to On!")
set(BUILD_TESTS On CACHE STRING "" FORCE)
endif (NOT BUILD_TESTS)
set(COVERAGE_EXCLUDES 'tests/*')
include(CodeCoverage)
include_directories(include ${PROJECT_BINARY_DIR})
add_subdirectory(src)
target_compile_options(Project-Name-lib PRIVATE "--coverage")
target_compile_options(Project-Name PRIVATE "--coverage")
SETUP_TARGET_FOR_COVERAGE(NAME coverage EXECUTABLE tests DEPENDENCIES coverage)
此解决方案有一个警告.显然,头文件不包含在代码覆盖范围内……
There is a caveat to this solution. Apparently, header files are not included in the code coverage...
这篇关于是否有交叉编译器方法使用CMake禁用测试可执行文件的覆盖标志?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!