gpt4 book ai didi

cmake - 使用 CMake,如何在 gtest_discover_tests --gtest_list_tests 调用上设置环境属性?

转载 作者:行者123 更新时间:2023-12-04 11:15:56 25 4
gpt4 key购买 nike

我目前正在将我们当前的构建环境从 MSBuild 迁移到 CMake。我有一种情况需要更新 PATH变量,以便单元测试可执行文件运行。这对 gtest_add_tests 来说不是问题,因为它使用源来识别测试。但是gtest_discover_tests ,它使用 --gtest_list_tests 执行单元测试标志,无法识别任何测试,因为 STATUS_DLL_NOT_FOUND在构建过程中遇到错误。

例如:

add_executable(gTestExe ...)
target_include_directories(gTestExe ...)
target_compile_definitions(gTestExe ...)
target_link_libraries(gTestExe ...)
set (NEWPATH "/path/to/bin;$ENV{PATH}")
STRING(REPLACE ";" "\\;" NEWPATH "${NEWPATH}")

这有效:
gtest_add_tests(TARGET gTestExe TEST_LIST allTests)
set_tests_properties(${all_tests} PROPERTIES ENVIRONMENT "PATH=${NEWPATH}")

但这不会:
#set_target_properties(gTestExe  PROPERTIES ENVIRONMENT "PATH=${NEWPATH}")
#set_property(DIRECTORY PROPERTY ENVIRONMENT "PATH=${NEWPATH}")
gtest_discover_tests(gTestExe PROPERTIES ENVIRONMENT "PATH=${NEWPATH}")

编辑:
使用 gtest_add_tests 添加时测试本身有效.问题是在构建后步骤中发现测试的调用 gtest_discover_tests注册失败,因为所需的库不在 PATH 中.

最佳答案

今天早上我遇到了同样的问题,我找到了一个(肮脏的?)解决方法。它不起作用的原因有点复杂,但解决方法很简单。
为什么它不起作用

gtest_discover_tests(gTestExe  PROPERTIES ENVIRONMENT "PATH=${NEWPATH}")
不起作用是因为 PATH 内容由分号分隔,因此被 CMake 视为列表值。
如果你看 GoogleTestAddTests.cmake文件(位于 C:\Program Files\CMake\share\cmake-3.17\Modules ),它处理 PROPERTIES带有 foreach 的参数. PROPERTIES脚本中此时 CMake 的值如下所示: ENVIRONMENT;PATH=mypath;mypath2并将对待 mypath2作为第三个参数而不是 PATH 环境变量的值。
然后 CMake 将生成以下行:
set_tests_properties( mytest PROPERTIES ENVIRONMENT PATH=mypath mypath2)
逃离 ;不会工作,因为列表会自动在 add_custom_command() 中展开在 GoogleTest.cmake (l. 420 in cmake 3.17.1) 忽略任何形式的转义。
要防止 cmake foreach 将路径中的每个值视为列表,您可以使用 bracket argument喜欢 :
gtest_discover_tests(gTestExe PROPERTIES ENVIRONMENT "[==[PATH=${NEWPATH}]==]")
然后 cmake foreach 会将您的参数视为一个实体。不幸的是,CMake 也会在生成的代码中放置一个括号,因为它包含 [ =也许空格:
# This line 
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
set(_args "${_args} [==[${_arg}]==]")
else()
set(_args "${_args} ${_arg}")
endif()
产生以下生成的脚本:
set_tests_properties( mytest PROPERTIES ENVIRONMENT [==[ [==[PATH=mypath;mypath2] ]==])
并且在执行测试时,cmake 将尝试读取仅删除第一个 bracket argument 的值。因为它们不嵌套。
可能的解决方法
所以要做到这一点,我们需要 CMake 不在我们自己的括号参数上使用括号参数。
首先制作 GoogleTestAddTests.cmake的本地副本文件在您自己的存储库中(位于 C:\Program Files\CMake\share\cmake-3.17\Modules 中)。
在您的本地副本 GoogleTestAddTests.cmake 的开头(l. 12) 替换函数 add_command通过这个:
function(add_command NAME)
set(_args "")
foreach(_arg ${ARGN})
# Patch : allow us to pass a bracket arguments and escape the containing list.
if (_arg MATCHES "^\\[==\\[.*\\]==\\]$")
string(REPLACE ";" "\;" _arg "${_arg}")
set(_args "${_args} ${_arg}")
# end of patch
elseif(_arg MATCHES "[^-./:a-zA-Z0-9_]")
set(_args "${_args} [==[${_arg}]==]")
else()
set(_args "${_args} ${_arg}")
endif()
endforeach()
set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE)
endfunction()
这将使 cmake 不在我们的括号列表中使用括号列表并自动转义 ;set_tests_properties也善待 ;作为列表。
最后我们需要 CMake 来使用我们的自定义 GoogleTestAddTests.cmake而不是 CMake 中的那个。
在您调用 include(GoogleTest) 之后设置变量 _GOOGLETEST_DISCOVER_TESTS_SCRIPT到您本地的路径 GoogleTestAddTests.cmake :
# Need google test
include(GoogleTest)

# Use our own version of GoogleTestAddTests.cmake
set(_GOOGLETEST_DISCOVER_TESTS_SCRIPT
${CMAKE_CURRENT_LIST_DIR}/GoogleTestAddTests.cmake
)
注意:在我的示例中,GoogleTestAddTests.cmake 就在处理 cmake 文件的旁边。
然后一个简单的调用
 gtest_discover_tests(my_target
PROPERTIES ENVIRONMENT "[==[PATH=${my_path};$ENV{PATH}]==]"
)
应该管用。

关于cmake - 使用 CMake,如何在 gtest_discover_tests --gtest_list_tests 调用上设置环境属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57541741/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com