List 在CMake中加入列表的最佳/最短方法

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

将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}")
  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
的含义吗?