【问题标题】:How to use gcov with Cmake如何在 Cmake 中使用 gcov
【发布时间】:2023-04-02 14:18:01
【问题描述】:

关于此事https://github.com/bilke/cmake-modules/blob/master/CodeCoverage.cmake

第一:

将此文件复制到您的 cmake 模块路径中。

我怎么知道我的 cmake 模块路径是什么?

使用函数 SETUP_TARGET_FOR_COVERAGE 创建自定义 目标

具体是什么意思?我怎么做?具体来说,我必须输入什么以及在哪里输入?

我不得不用 cmake 编译应用程序,否则我会用 gcc 来编译。

【问题讨论】:

  • CMake 模块路径是 /usr/share/cmake/Modules 或类似的。您可以从带有 cmake 包的已安装文件列表中推断出它:该目录中有很多 .cmake 模块。至于其他问题,请阅读您引用的文件中的USAGE 部分。简而言之,使用SETUP_TARGET_FOR_COVERAGE 创建的目标会运行一些workload 并收集该目录中可执行文件产生的覆盖率。如果您只想编译带有 gcov 支持的可执行文件,那么仅第 3 步(设置编译器标志)就足够了。

标签: c++ cmake gcov


【解决方案1】:

您通过调用设置 cmake 模块路径 set(CMAKE_MODULE_PATH <path>)

cmake 模块路径设置告诉 cmake 在哪里寻找 cmake 模块,例如 include 宏所包含的模块。

例如,我使用 CodeCoverage.cmake 的步骤是:

  1. 将 CodeCoverage.cmake 复制到我位于“scripts/cmake”的源文件夹中。
  2. 将以下内容添加到我的 CMakeLists.txt:

    set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/scripts/cmake)
    
    if (CMAKE_BUILD_TYPE STREQUAL "Coverage")
        include(CodeCoverage)
        setup_target_for_coverage(${PROJECT_NAME}_coverage ${TEST_TARGET} coverage)
    
        SET(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
        SET(CMAKE_C_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
    endif() #CMAKE_BUILD_TYPE STREQUAL "Coverage"
    
  3. 运行cmake-DCMAKE_BUILD_TYPE=Coverage

  4. 运行make

  5. 运行make <coverage_target>

注意:

  • ${TEST_TARGET} 是我用我之前在脚本中创建的单元测试目标的名称设置的变量。
  • <coverage_target> 是由${PROJECT_NAME}_coverage 生成的任何字符串。
  • 您不必像我一样使用if 来包装覆盖创建。
  • 由于我使用的是 AppleClang,我必须修复 CodeCoverage.cmake 脚本以允许它。现在的编写方式只允许 gcc 和 clang 3.0.0 或更高版本。

【讨论】:

  • 我在 CodeCoverage.cmake 中找不到 setup_target_for_coverage 函数。什么对我有用:setup_target_for_coverage_gcovr_xml(${PROJECT_NAME}_coverage NAME coverage)(然后进行 && 覆盖)
【解决方案2】:

具有零行 CMake 的 gcov

作为使用 CMake 模块进行 gcov 集成的替代方法,可以在完全不修改构建系统的情况下使用它。你只需要大约 5 行 shell。对于不太大或不太复杂的项目,这是一种不错的方法。

根据本书,必须将源文件名列表(不包括标题)提供给 gcov。这基于各种命名和目录约定:gcov 假定源文件具有类似foo.cfoo.cpp 的名称,并且相应的目标文件称为foo.o,并且与源文件位于同一目录中。但默认情况下,CMake 将它们命名为 foo.cpp.o。 gcov 去除给定源文件名的扩展名,然后添加.gcno.gcda 后缀。我们可以通过提供 gcov 而不是源文件,.gcda 文件来利用这些事实。事实证明,在这种情况下,gcov 会在正确的位置查找所有内容。

操作方法

  1. 通过将--coverage 标志添加到CMAKE_C_FLAGS 和/或CMAKE_CXX_FLAGS 来打开编译器和链接器标志中的覆盖率数据。这使得编译器在构建时生成 .gcno 文件,并使可执行文件在退出时转储 .gcda 文件。

  2. 为[运行测试/生成报告/清理覆盖数据]循环制作一个脚本。这是一个简单的 Bash 示例:

    # Ensure we are in the build directory and that coverage was enabled in the compiler
    grep -q -- --coverage CMakeCache.txt || exit 1
    
    # Clean up old runtime data
    find . -name '*.gcda' -exec rm {} \;
    
    # Run test command (specified as script arguments)
    # This can be anything that runs program(s) built by the project 
    "${@}"
    
    # Generate reports (.gcov files). All .gcda files in the build directory are passed as 
    gcov args.
    find . -name '*.gcda' | xargs gcov
    

这种方法的优点

  • 可以重复使用相同的脚本,而无需对每个感兴趣的项目执行 CMake 集成
  • 没有复杂的 CMake 代码
  • 轻松更改测试命令的灵活性。与 CMake 集成的 clean/run/report 循环可能有一个硬编码命令来运行所有测试,这通常比运行单个测试更没用(而且速度更慢)。

缺点

  • 完整路径信息丢失。每个 .gcov 文件的名称仅包含基本名称 (foo.gcov),而通常它会像 src#foo#foo.gcov 一样对完整路径进行编码。这可能会导致报告文件中的名称冲突。
  • 缺乏将依赖信息集成到构建系统中意味着您可能会在忘记重新构建时意外使用旧的 .gcno 文件(如果打开了 --coverage 后又关闭了)。

【讨论】:

    猜你喜欢
    • 2018-11-16
    • 2015-08-01
    • 2022-01-24
    • 2011-08-30
    • 2011-03-14
    • 2015-07-06
    • 2020-06-18
    • 2012-10-18
    相关资源
    最近更新 更多