在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" 
+0

哦,是的,谢谢,这工作。但是这是否意味着我不能拥有一个元素包含分号的列表? – Geli

+1

我更新了问题以包含一个含有分号的元素的列表。 – Geli

+0

您原来的函数JOIN也无法处理分号。它使用cmake 2.8.5在Windows下输出“a:b:cc”。 – sakra

的答案是好的,当你不使用分号或当你可以(并且要)逃生他们。 我不想逃避分号,所以我写了下面的功能:

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'