List 在CMake中加入列表的最佳/最短方法
将CMake中的列表加入字符串的最佳方式是什么 通过连接,我的意思是将集合(somelist“a”“b”“c\;c”)转换为“a:b:c;c”,其中粘合字符串(“:”)是可选择的。下面的代码可以工作,但是很长,有更好的方法吗List 在CMake中加入列表的最佳/最短方法,list,join,cmake,List,Join,Cmake,将CMake中的列表加入字符串的最佳方式是什么 通过连接,我的意思是将集合(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}") ENDFORE
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"
不幸的是,使用字符串(替换…)不起作用:
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"
您可以使用以下功能:
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()
通常使用简单的
stringreplace
命令来解决此任务。您可以在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
当您不使用分号或者您可以(并且想要)转义分号时,上面的答案是可以的。 我不喜欢转义分号,因此我编写了以下函数:
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'
CMake 3.12准备最终添加此上游:
哦,是的,谢谢,这很有效。但是这是否意味着我不能有一个元素包含分号的列表?我更新了问题,以包含一个包含分号的元素的列表。原始函数JOIN也不处理分号。它在带有cmake 2.8.5的Windows下输出“a:b:cc”。是的,你是对的,但我认为编辑后的那个可以工作。还是没有?它在linux下似乎对我有效,你能确认它在windows下不起作用吗?最新版本的JOIN在windows下用cmake 2.8.5为我输出“a:b:cc”。你能给我一些解释(或文档参考)来理解
GLUE
的含义吗?