如何使用-D将列表传递给CMake?

时间:2014-01-08 00:00:13

标签: cmake

我正在尝试调用add_test(),如下所示:

add_test(NAME ${TEST_NAME} COMMAND cmake
  -DTEST_PROG:FILEPATH=${TEST_EXECUTABLE} 
 ...
  -DTEST_EXEC_DIRS:PATH=${TEST_EXEC_DIRS}
  -P SciTextCompare.cmake
)

$ {TEST_EXEC_DIRS}是一个CMake列表,当我执行上面的代码时,CTestTestfile.cmake中的结果行只包含列表中的第一项,所以我最终得到了以下cmake参数:

"cmake" "-DTEST_PROG:FILEPATH=C:/path/to/my/executable" ... "-DTEST_EXEC_DIRS:PATH=C:/first/dir/in/list" "-P" "SciTextCompare.cmake"

如何传入列表并让它像这样调用cmake:

"cmake" "-DTEST_PROG:FILEPATH=C:/path/to/my/executable" ... "-DTEST_EXEC_DIRS:PATH=C:/first/dir/in/list;C:/second/dir/in/list" "-P" "SciTextCompare.cmake"

2 个答案:

答案 0 :(得分:5)

如果您使用的是CMake版本2.8.11或更高版本,则可以使用generator expression $<SEMICOLON>来防止使用';'进行参数列表扩展:

cmake_minimum_required(VERSION 2.8.11)
...
string (REPLACE ";" "$<SEMICOLON>" GENERATOR_TEST_EXEC_DIRS "${TEST_EXEC_DIRS}")
add_test(NAME ${TEST_NAME} COMMAND ${CMAKE_COMMAND}
  -DTEST_PROG:FILEPATH=${TEST_EXECUTABLE} 
 ...
  -DTEST_EXEC_DIRS:PATH=${GENERATOR_TEST_EXEC_DIRS}
  -P SciTextCompare.cmake
)

答案 1 :(得分:2)

可能有(或将会)更好的方式,但您可以使用一种解决方法,暂时用不同的字符替换CMake列表分隔符(即;)。

我倾向于使用ASCII控制字符,以避免意外地用变量中其他地方使用的字符替换; s(这会在替换分隔符交换出来时导致错误。)

所以,在你的CMakeLists.txt中你可以这样做:

string(ASCII 2 WORKAROUND_SEPARATOR)

string(REPLACE ";" ${WORKAROUND_SEPARATOR}
       WORKAROUND_TEST_EXEC_DIRS "${TEST_EXEC_DIRS}")

add_test(NAME ${TEST_NAME} COMMAND ${CMAKE_COMMAND}
  -DTEST_PROG:FILEPATH=${TEST_EXECUTABLE}
  ...
  -DWORKAROUND_TEST_EXEC_DIRS:PATH=${WORKAROUND_TEST_EXEC_DIRS}
  -DWORKAROUND_SEPARATOR:INTERNAL=${WORKAROUND_SEPARATOR}
  -P SciTextCompare.cmake
)

然后在SciTextCompare.cmake中,您只需要重新连接普通分隔符:

string(REPLACE ${WORKAROUND_SEPARATOR} ";"
       TEST_EXEC_DIRS "${WORKAROUND_TEST_EXEC_DIRS}")

一个小问题 - 如果CMake可执行文件不在系统路径中,您应该更喜欢${CMAKE_COMMAND}而不是cmake