如何在CMake的execute_process中传递列表变量?

时间:2018-09-06 14:19:20

标签: cmake

我想在execute_process的子目录中执行CMake命令,还希望将某些缓存变量作为-D选项传递。

如果变量的类型为字符串,则可以使用。但是,如果变量是列表,则在命令行中传递列表的typical method似乎无效。

我尝试了该答案中列出的所有组合。我什至尝试将mylist"\\;""\\\\;"一起加入。但是,execute_process似乎总是将'-DVal2=a\\;b\\;c\\;''-DVal2=a;b;c'拆包到-Dval2=a b c

如何防止这种情况?仅-DVal2=a\\;b\\;c有效,但这很烦人。

set(
    mylist
    a
    b
    c
)

set(
    cmake_args
    "-DVal1=abc"
    "'-DVal2=${mylist}'" #does not work, the execute_process will unpack it into seperated args
)

execute_process(
        COMMAND ${CMAKE_COMMAND} ${cmake_args} ${CMAKE_SOURCE_DIR}/subproject
        OUTPUT_FILE ${CMAKE_BINARY_DIR}/config.log
        ERROR_FILE ${CMAKE_BINARY_DIR}/config.log
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/subproject
        RESULT_VARIABLE config_result
)

2 个答案:

答案 0 :(得分:3)

在传递列表之前,在其上运行此行:

string(REPLACE ";" "\\;" escaped_list "${my_list}")

,然后传递escaped_list。另一方面,它将具有 与my_list完全相同。

例如,

set(my_list "a\;b" "c" "d")
string(REPLACE ";" "\\;" escaped_list "${my_list}")
execute_process(COMMAND ${CMAKE_COMMAND} -Dmy_list=${escaped_list} -P test.cmake)

(使用cmake 3.17测试)。

这在第一个分配给cmake_args并将其传递时也有效。 例如,

test1.cmake

# Construction.
set(my_list "a\;b" "c" "d")
set(other_list "e" "f\;g" "h")

# For debugging purposes.
message("my_list = \"${my_list}\".")
foreach(arg ${my_list})
  message("-> ${arg}")
endforeach()
message("other_list = \"${other_list}\".")
foreach(arg ${other_list})
  message("-> ${arg}")
endforeach()

# Encoding.
string(REPLACE ";" "\\;" escaped_list "${my_list}")
message("escaped_list = \"${escaped_list}\".")

string(REPLACE ";" "\\;" other_escaped_list "${other_list}")
message("other_escaped_list = \"${other_escaped_list}\".")

set(cmake_args "-Dother_list=${other_escaped_list}" "-Dmy_list=${escaped_list}")

execute_process(
  COMMAND
  ${CMAKE_COMMAND} ${cmake_args} -P test2.cmake
)

test2.cmake

# For debugging purpose.
message("my_list = \"${my_list}\".")
foreach(arg ${my_list})
  message("-> ${arg}")
endforeach()

message("other_list = \"${other_list}\".")
foreach(arg ${other_list})
  message("-> ${arg}")
endforeach()

正在运行的cmake -P test1.cmake的输出:

my_list = "a\;b;c;d".
-> a;b
-> c
-> d
other_list = "e;f\;g;h".
-> e
-> f;g
-> h
escaped_list = "a\\;b\;c\;d".
other_escaped_list = "e\;f\\;g\;h".
my_list = "a\;b;c;d".
-> a;b
-> c
-> d
other_list = "e;f\;g;h".
-> e
-> f;g
-> h

请仔细观察使用和不使用双引号的地方。

答案 1 :(得分:0)

我认为您需要转义;字符,该字符是CMake中列表的默认分隔符,但目前尚不清楚如何操作,以至于它对您不起作用。

所以,尝试这样的事情

set(mylist_str "")

foreach(item ${mylist})
  string(APPEND mylist_str ${item} "\;")
endforeach()

# this is for debugging
message(STATUS "List as string: ${mylist_str}")

set(cmake_args 
    "-DVal1=abc"
    "-DVal2=${mylist_str}"
    "-DVal3=\"${mylist_str}\"" # this has quotes around it
)

# this is for debugging
foreach(item ${cmake_args})
  message(STATUS "A list item: ${item}")
endforeach()