Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you pass a list to CMake using -D?

Tags:

cmake

I'm trying to call add_test(), like so:

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} is a CMake list, and when I execute the above code, the resulting line in CTestTestfile.cmake only contains the first item in the list so, that I end up with the following arguments to cmake:

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

How can I pass in a list and have it invoke cmake like so:

"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"
like image 217
Dave Wade-Stein Avatar asked Jan 08 '14 00:01

Dave Wade-Stein


2 Answers

If you are using CMake version 2.8.11 or later you can use the generator expression $<SEMICOLON> to prevent the list expansion on an argument with ';':

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
)
like image 197
sakra Avatar answered Oct 21 '22 05:10

sakra


There possibly is (or will be) a better way than this, but you can use a workaround whereby you temporarily replace the CMake list separator (i.e. ;) with a different character.

I tend to use an ASCII control character to avoid accidentally substituting the ;s with a character which is used elsewhere in the variable (which would cause an error when swapping the replacement separators back out).

So, in your CMakeLists.txt you could do:

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
)

Then in SciTextCompare.cmake, you just need to swap the normal separators back in:

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

A minor point - you should probably prefer ${CMAKE_COMMAND} rather than cmake in case the CMake executable isn't in the system path.

like image 40
Fraser Avatar answered Oct 21 '22 05:10

Fraser