加入CMake列表的最佳/最短方式

时间:2011-08-24 08:40:21

标签: list join 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"

4 个答案:

答案 0 :(得分:10)

通常使用简单的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

答案 1 :(得分:7)

答案 2 :(得分:6)

您可以使用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"

答案 3 :(得分:5)

当你不使用分号或者你可以(并且想要)逃避分号时,上面的答案是可以的。 我不想逃脱分号,所以我写了以下函数:

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'