在CMake中加入列表的最佳/最简单的方法
问题描述:
将CMake中的列表加入字符串的最佳方式是什么?在CMake中加入列表的最佳/最简单的方法
通过加入我的意思是转换SET(somelist“a”“b”“c \; c”)到“a:b:c; c”粘胶字符串(“:”)可以选择。下面的代码有效,但它真的很长,有没有更好的方法?
FUNCTION(JOIN LISTNAME GLUE OUTPUT)
SET(_TMP_STR "")
FOREACH(VAL ${${LISTNAME}})
SET(_TMP_STR "${_TMP_STR}${GLUE}${VAL}")
ENDFOREACH(VAL ${${LISTNAME}})
STRING(LENGTH "${GLUE}" GLUE_LEN)
STRING(LENGTH "${_TMP_STR}" OUT_LEN)
MATH(EXPR OUT_LEN ${OUT_LEN}-${GLUE_LEN})
STRING(SUBSTRING "${_TMP_STR}" ${GLUE_LEN} ${OUT_LEN} _TMP_STR)
SET(${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
ENDFUNCTION()
#USAGE:
SET(somelist "a" "b" "c\;c")
JOIN(somelist ":" output)
MESSAGE("${output}") # will output "a:b:c;c"
不幸的是使用STRING(REPLACE ...)不工作:
function(JOINSTRREPLACE VALUES GLUE OUTPUT)
string (REPLACE ";" "${GLUE}" _TMP_STR "${VALUES}")
set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
endfunction()
JOINSTRREPLACE("${somelist}" ":" output)
MESSAGE(${output}) # will output "a:b:c\:c"
答
通常这个任务是解决简单string REPLACE
命令。您可以在随cmake发布的脚本中找到许多这样的替换。但如果你真的需要关心分号你价值观里面,那么你可以使用下面的代码:以上
function(JOIN VALUES GLUE OUTPUT)
string (REGEX REPLACE "([^\\]|^);" "\\1${GLUE}" _TMP_STR "${VALUES}")
string (REGEX REPLACE "[\\](.)" "\\1" _TMP_STR "${_TMP_STR}") #fixes escaping
set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
endfunction()
SET(letters "" "\;a" b c "d\;d")
JOIN("${letters}" ":" output)
MESSAGE("${output}") # :;a:b:c:d;d
答
可以使用string REPLACE功能:
function(JOIN VALUES GLUE OUTPUT)
string (REPLACE ";" "${GLUE}" _TMP_STR "${VALUES}")
set (${OUTPUT} "${_TMP_STR}" PARENT_SCOPE)
endfunction()
#USAGE:
SET(somelist a b c)
JOIN("${somelist}" ":" output)
MESSAGE("${output}") # will output "a:b:c"
答
的答案是好的,当你不使用分号或当你可以(并且要)逃生他们。 我不想逃避分号,所以我写了下面的功能:
function(JOIN OUTPUT GLUE)
set(_TMP_RESULT "")
set(_GLUE "") # effective glue is empty at the beginning
foreach(arg ${ARGN})
set(_TMP_RESULT "${_TMP_RESULT}${_GLUE}${arg}")
set(_GLUE "${GLUE}")
endforeach()
set(${OUTPUT} "${_TMP_RESULT}" PARENT_SCOPE)
endfunction()
的优点是,该列表可以是空的,它并不一定要在一个变量(但可能在该地方写的调用)。
用法是:
set(SOME_LIST a b c d)
join(RESULT "/" ${SOME_LIST})
message(STATUS "RESULT='${RESULT}'") # outputs RESULT='a/b/c/d'
# or
join(RESULT " " e f g h)
message(STATUS "RESULT='${RESULT}'") # outputs RESULT='e f g h'
哦,是的,谢谢,这工作。但是这是否意味着我不能拥有一个元素包含分号的列表? – Geli
我更新了问题以包含一个含有分号的元素的列表。 – Geli
您原来的函数JOIN也无法处理分号。它使用cmake 2.8.5在Windows下输出“a:b:cc”。 – sakra