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

问题描述 投票:4回答:1

我目前正在将当前的构建环境从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中。

cmake googletest
1个回答
0
投票

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

为什么不起作用

gtest_discover_tests(gTestExe  PROPERTIES ENVIRONMENT "PATH=${NEWPATH}")

将不起作用是因为PATH内容之间用分号分隔,因此被CMake视为列表值。

[如果您查看GoogleTestAddTests.cmake文件(位于C:\Program Files\CMake\share\cmake-3.17\Modules中),它将使用PROPERTIES处理foreach参数。

脚本中[CM0]的PROPERTIES值现在看起来像这样:ENVIRONMENT;PATH=mypath;mypath2,并将mypath2视为第三个参数,而不是PATH环境变量的值。

CMake然后将生成以下行:

set_tests_properties( mytest PROPERTIES ENVIRONMENT PATH=mypath mypath2)

转义;将不起作用,因为列表在add_custom_command()中的GoogleTest.cmake中自动扩展了((cmake 3.17.1中的l。420)忽略任何转义形式。

为了防止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};\%PATH\%]==]"
 )

应该工作。

© www.soinside.com 2019 - 2024. All rights reserved.