我想在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
)
答案 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()