我目前正在将我们当前的构建环境从 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}")
Run Code Online (Sandbox Code Playgroud)
这有效:
gtest_add_tests(TARGET gTestExe TEST_LIST allTests)
set_tests_properties(${all_tests} PROPERTIES ENVIRONMENT "PATH=${NEWPATH}")
Run Code Online (Sandbox Code Playgroud)
但这不会:
#set_target_properties(gTestExe PROPERTIES ENVIRONMENT "PATH=${NEWPATH}")
#set_property(DIRECTORY PROPERTY ENVIRONMENT "PATH=${NEWPATH}")
gtest_discover_tests(gTestExe PROPERTIES ENVIRONMENT "PATH=${NEWPATH}")
Run Code Online (Sandbox Code Playgroud)
编辑:使用gtest_add_tests. 问题是在gtest_discover_tests注册的后期构建步骤中发现测试的调用失败,因为所需的库不在PATH.
Bla*_*uze -1
今天早上我遇到了同样的问题,我找到了一个(肮脏的?)解决方法。不起作用的原因有点复杂,但解决方法很简单。
gtest_discover_tests(gTestExe PROPERTIES ENVIRONMENT "PATH=${NEWPATH}")
Run Code Online (Sandbox Code Playgroud)
不起作用是因为 PATH 内容由分号分隔,因此被 CMake 视为列表值。
如果您查看该GoogleTestAddTests.cmake文件(位于C:\Program Files\CMake\share\cmake-3.17\Modules),它会使用foreachPROPERTIES处理参数。
PROPERTIES对于 CMake 在脚本中的此时,该值看起来像这样:ENVIRONMENT;PATH=mypath;mypath2并且将被视为mypath2第三个参数,而不是 PATH 环境变量的值。
然后 CMake 将生成以下行:
set_tests_properties( mytest PROPERTIES ENVIRONMENT PATH=mypath mypath2)
Run Code Online (Sandbox Code Playgroud)
转义将;不起作用,因为列表会自动扩展 in add_custom_command()( GoogleTest.cmake cmake 3.17.1 中的 l. 420),忽略任何形式的转义。
为了防止 cmake foreach 将路径中的每个值视为列表,您可以使用括号参数,例如:
gtest_discover_tests(gTestExe PROPERTIES ENVIRONMENT "[==[PATH=${NEWPATH}]==]")
Run Code Online (Sandbox Code Playgroud)
然后,cmake foreach 会将您的参数视为一个实体。不幸的是,CMake 还会在生成的代码中放置一个括号,因为它包含[ =可能还有空格:
# This line
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
set(_args "${_args} [==[${_arg}]==]")
else()
set(_args "${_args} ${_arg}")
endif()
Run Code Online (Sandbox Code Playgroud)
生成以下脚本:
set_tests_properties( mytest PROPERTIES ENVIRONMENT [==[ [==[PATH=mypath;mypath2] ]==])
Run Code Online (Sandbox Code Playgroud)
当执行测试时,cmake 将尝试读取仅删除第一个括号参数的值,因为它们不嵌套。
因此,要做到这一点,我们需要 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()
Run Code Online (Sandbox Code Playgroud)
这将使 cmake 不在我们的括号列表上使用括号列表,并自动转义;asset_tests_properties并将 as 视为;列表。
最后,我们需要 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
)
Run Code Online (Sandbox Code Playgroud)
注意:在我的示例中,GoogleTestAddTests.cmake 位于处理 cmake 文件旁边。
然后一个简单的调用
gtest_discover_tests(my_target
PROPERTIES ENVIRONMENT "[==[PATH=${my_path};$ENV{PATH}]==]"
)
Run Code Online (Sandbox Code Playgroud)
应该管用。
| 归档时间: |
|
| 查看次数: |
1189 次 |
| 最近记录: |