【问题标题】:How do I make ctest run a program with valgrind without dart?如何让 ctest 在没有 dart 的情况下使用 valgrind 运行程序?
【发布时间】:2020-02-29 19:51:16
【问题描述】:

我想编写一个 CMakeLists.txt 以便我可以正常运行测试或使用 valgrind 运行测试。我已经看到很多关于将 ctest 与 valgrind 集成的内容,但所有这些都假设您想要设置一个服务器以将测试结果提交到 dart 仪表板。我只想在我的机器上运行测试并在命令行上查看结果。

如果我必须执行 cmake -D VALGRIND=ON 那很好,但如果可能的话,我宁愿生成名为“foo”和“valgrind_foo”的测试。

【问题讨论】:

    标签: cmake valgrind


    【解决方案1】:

    我使用 valgrind 进行内存检查。为了配置 valgrind,我在构建系统中定义了以下变量:

    find_program( MEMORYCHECK_COMMAND valgrind )
    set( MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full" )
    

    另外,还有我的 valgrind 抑制文件:

    set( MEMORYCHECK_SUPPRESSIONS_FILE "${PROJECT_SOURCE_DIR}/valgrind_suppress.txt" )
    

    在编写好 CMakeLists.txt 文件并在其中正确配置 valgrind 后,您可以运行以下命令:

    cmake -G ... (to configure your build)
    ctest -D ExperimentalBuild (this will build your code)
    ctest -R testName -D ExperimentalTest (just runs the test)
    ctest -R testName -D ExperimentalMemCheck (to run the test under valgrind)
    

    这将欺骗您的构建系统在本地运行测试自动化。它希望你运行:

    ctest -R testName -D ExperimentalSubmit
    

    接下来,提交到(默认或您的)仪表板,但您无需执行此步骤即可运行所需的内容。结果将存储在 Testing/Temporary/ 目录中。

    【讨论】:

      【解决方案2】:

      似乎以下内容就足够了。我之前没有使用单独的参数,那是我的愚蠢。

      function(add_memcheck_test name binary)
        set(memcheck_command "${CMAKE_MEMORYCHECK_COMMAND} ${CMAKE_MEMORYCHECK_COMMAND_OPTIONS}")
        separate_arguments(memcheck_command)
        add_test(${name} ${binary} ${ARGN})
        add_test(memcheck_${name} ${memcheck_command} ./${binary} ${ARGN})
      endfunction(add_memcheck_test)
      
      function(set_memcheck_test_properties name)
        set_tests_properties(${name} ${ARGN})
        set_tests_properties(memcheck_${name} ${ARGN})
      endfunction(set_memcheck_test_properties)
      

      【讨论】:

      • 这似乎比创建实验版本更简单。
      【解决方案3】:

      我的情况很简单,我只使用了一个自定义目标:

      project(bftest)
      
      add_executable(bftest main.c)
      
      target_link_libraries(bftest LINK_PUBLIC bf)
      
      find_program(VALGRIND "valgrind")
      if(VALGRIND)
          add_custom_target(valgrind
              COMMAND "${VALGRIND}" --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes $<TARGET_FILE:bftest>)
      endif()
      

      【讨论】:

        【解决方案4】:

        您可以使用add_custom_target() 生成最小的“DartConfiguration.tcl”配置文件。然后您可以添加一个valgrind 自定义目标,该目标使用适当的参数调用ctest。这就是我通常的做法:

        find_program(VALGRIND "valgrind")
        if (VALGRIND)
            set(DART_CONFIG DartConfiguration.tcl)
            add_custom_target(${DART_CONFIG}
                COMMAND echo "MemoryCheckCommand: ${VALGRIND}" >> ${DART_CONFIG}
                COMMENT "Generating ${DART_CONFIG}"
            )
            set(VALGRIND_ARGS
                --leak-check=full
                --error-exitcode=255
            )
            set(LOGFILE memcheck.log)
            add_custom_target(valgrind        
                COMMAND ctest -O ${LOGFILE} -D ExperimentalMemCheck --overwrite MemoryCheckCommandOptions="${VALGRIND_ARGS}"
                COMMAND tail -n1 ${LOGFILE} | grep 'Memory checking results:' > /dev/null
                COMMAND rm -f ${LOGFILE}
                DEPENDS ${DART_CONFIG}
            )
        endif()
        

        希望这会有所帮助! :-)

        信用:https://github.com/ARMmbed/mbedtls/blob/development/CMakeLists.txt#L237

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-10-26
          • 1970-01-01
          • 1970-01-01
          • 2020-10-19
          • 1970-01-01
          • 2016-03-22
          • 2012-04-29
          相关资源
          最近更新 更多